diff options
author | John David Anglin <dave.anglin@nrc-cnrc.gc.ca> | 2003-08-09 00:31:24 +0000 |
---|---|---|
committer | John David Anglin <danglin@gcc.gnu.org> | 2003-08-09 00:31:24 +0000 |
commit | 561af708f99565ea6974718b6748a3ef59e5c5ca (patch) | |
tree | afe8cb232e6a4064dd823df57b505637fc7ef585 | |
parent | 9bea6f9863890313f78c4af8dfcd8a2b8f4baf98 (diff) | |
download | gcc-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/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/config/pa/pa.md | 73 |
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; }") |