aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn David Anglin <dave.anglin@nrc-cnrc.gc.ca>2003-08-09 00:31:24 +0000
committerJohn David Anglin <danglin@gcc.gnu.org>2003-08-09 00:31:24 +0000
commit561af708f99565ea6974718b6748a3ef59e5c5ca (patch)
treeafe8cb232e6a4064dd823df57b505637fc7ef585
parent9bea6f9863890313f78c4af8dfcd8a2b8f4baf98 (diff)
downloadgcc-561af708f99565ea6974718b6748a3ef59e5c5ca.zip
gcc-561af708f99565ea6974718b6748a3ef59e5c5ca.tar.gz
gcc-561af708f99565ea6974718b6748a3ef59e5c5ca.tar.bz2
pa.md (extzv, extv, insv): Fix operand limit checks.
* pa.md (extzv, extv, insv): Fix operand limit checks. Fail if source/destination is not a register operand. From-SVN: r70267
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/pa/pa.md73
2 files changed, 52 insertions, 26 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7663d3a..b0f4213 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
index 0537756..bba626e 100644
--- a/gcc/config/pa/pa.md
+++ b/gcc/config/pa/pa.md
@@ -7145,6 +7145,7 @@
[(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" "")
@@ -7153,21 +7154,26 @@
""
"
{
- /* 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;
}")
@@ -7211,6 +7217,7 @@
[(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" "")
@@ -7219,21 +7226,26 @@
""
"
{
- /* 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;
}")
@@ -7277,7 +7289,7 @@
[(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" "")
@@ -7286,17 +7298,26 @@
""
"
{
+ 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;
}")