]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
pa.md (extzv, extv, insv): Fix operand limit checks.
authorJohn David Anglin <dave.anglin@nrc-cnrc.gc.ca>
Sat, 9 Aug 2003 00:31:24 +0000 (00:31 +0000)
committerJohn David Anglin <danglin@gcc.gnu.org>
Sat, 9 Aug 2003 00:31:24 +0000 (00:31 +0000)
* pa.md (extzv, extv, insv): Fix operand limit checks.  Fail if
source/destination is not a register operand.

From-SVN: r70267

gcc/ChangeLog
gcc/config/pa/pa.md

index 7663d3afefa891746b39b1c6707efb22ca7bb3dc..b0f4213ffd1edb97c843f0320d9745c10e59eb57 100644 (file)
@@ -1,3 +1,8 @@
+2003-08-08  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
+
+       * pa.md (extzv, extv, insv): Fix operand limit checks.  Fail if
+       source/destination is not a register operand.
+
 2003-08-08  Richard Henderson  <rth@redhat.com>
 
         PR target/11535
index 053775687e560279acc967e6917cb7b4f265a265..bba626ecd7c6bf2e22cc72b1138b80a140f953e1 100644 (file)
   [(set_attr "type" "branch")
    (set_attr "length" "4")])
 
+;;; Operands 2 and 3 are assumed to be CONST_INTs.
 (define_expand "extzv"
   [(set (match_operand 0 "register_operand" "")
        (zero_extract (match_operand 1 "register_operand" "")
   ""
   "
 {
-  /* PA extraction insns don't support zero length bitfields.  */
-  if (INTVAL (operands[2]) == 0)
+  HOST_WIDE_INT len = INTVAL (operands[2]);
+  HOST_WIDE_INT pos = INTVAL (operands[3]);
+
+  /* PA extraction insns don't support zero length bitfields or fields
+     extending beyond the left or right-most bits.  Also, we reject lengths
+     equal to a word as they are better handled by the move patterns.  */
+  if (len <= 0 || len >= BITS_PER_WORD || pos < 0 || pos + len > BITS_PER_WORD)
+    FAIL;
+
+  /* From mips.md: extract_bit_field doesn't verify that our source
+     matches the predicate, so check it again here.  */
+  if (!register_operand (operands[1], VOIDmode))
     FAIL;
 
   if (TARGET_64BIT)
     emit_insn (gen_extzv_64 (operands[0], operands[1],
                             operands[2], operands[3]));
   else
-    {
-      if (! uint5_operand (operands[2], SImode)
-         || ! uint5_operand (operands[3], SImode))
-       FAIL;
-      emit_insn (gen_extzv_32 (operands[0], operands[1],
-                              operands[2], operands[3]));
-    }
+    emit_insn (gen_extzv_32 (operands[0], operands[1],
+                            operands[2], operands[3]));
   DONE;
 }")
 
   [(set_attr "type" "shift")
    (set_attr "length" "4")])
 
+;;; Operands 2 and 3 are assumed to be CONST_INTs.
 (define_expand "extv"
   [(set (match_operand 0 "register_operand" "")
        (sign_extract (match_operand 1 "register_operand" "")
   ""
   "
 {
-  /* PA extraction insns don't support zero length bitfields.  */
-  if (INTVAL (operands[2]) == 0)
+  HOST_WIDE_INT len = INTVAL (operands[2]);
+  HOST_WIDE_INT pos = INTVAL (operands[3]);
+
+  /* PA extraction insns don't support zero length bitfields or fields
+     extending beyond the left or right-most bits.  Also, we reject lengths
+     equal to a word as they are better handled by the move patterns.  */
+  if (len <= 0 || len >= BITS_PER_WORD || pos < 0 || pos + len > BITS_PER_WORD)
+    FAIL;
+
+  /* From mips.md: extract_bit_field doesn't verify that our source
+     matches the predicate, so check it again here.  */
+  if (!register_operand (operands[1], VOIDmode))
     FAIL;
 
   if (TARGET_64BIT)
     emit_insn (gen_extv_64 (operands[0], operands[1],
                            operands[2], operands[3]));
   else
-    {
-      if (! uint5_operand (operands[2], SImode)
-         || ! uint5_operand (operands[3], SImode))
-       FAIL;
-      emit_insn (gen_extv_32 (operands[0], operands[1],
-                             operands[2], operands[3]));
-    }
+    emit_insn (gen_extv_32 (operands[0], operands[1],
+                           operands[2], operands[3]));
   DONE;
 }")
 
   [(set_attr "type" "shift")
    (set_attr "length" "4")])
 
-;; Only specify the mode operands 0, the rest are assumed to be word_mode.
+;;; Operands 1 and 2 are assumed to be CONST_INTs.
 (define_expand "insv"
   [(set (zero_extract (match_operand 0 "register_operand" "")
                       (match_operand 1 "uint32_operand" "")
   ""
   "
 {
+  HOST_WIDE_INT len = INTVAL (operands[1]);
+  HOST_WIDE_INT pos = INTVAL (operands[2]);
+
+  /* PA insertion insns don't support zero length bitfields or fields
+     extending beyond the left or right-most bits.  Also, we reject lengths
+     equal to a word as they are better handled by the move patterns.  */
+  if (len <= 0 || len >= BITS_PER_WORD || pos < 0 || pos + len > BITS_PER_WORD)
+    FAIL;
+
+  /* From mips.md: insert_bit_field doesn't verify that our destination
+     matches the predicate, so check it again here.  */
+  if (!register_operand (operands[0], VOIDmode))
+    FAIL;
+
   if (TARGET_64BIT)
     emit_insn (gen_insv_64 (operands[0], operands[1],
                            operands[2], operands[3]));
   else
-    {
-      if (! uint5_operand (operands[2], SImode)
-         || ! uint5_operand (operands[3], SImode))
-       FAIL;
-      emit_insn (gen_insv_32 (operands[0], operands[1],
-                             operands[2], operands[3]));
-    }
+    emit_insn (gen_insv_32 (operands[0], operands[1],
+                           operands[2], operands[3]));
   DONE;
 }")