diff options
Diffstat (limited to 'gcc/config/pa/pa.md')
-rw-r--r-- | gcc/config/pa/pa.md | 122 |
1 files changed, 64 insertions, 58 deletions
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md index 35369966d59..b5c994017ba 100644 --- a/gcc/config/pa/pa.md +++ b/gcc/config/pa/pa.md @@ -1,23 +1,23 @@ -;;- Machine description for HP PA-RISC architecture for GNU C compiler +;;- Machine description for HP PA-RISC architecture for GCC compiler ;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, ;; 2002, 2003 Free Software Foundation, Inc. ;; Contributed by the Center for Software Science at the University ;; of Utah. -;; This file is part of GNU CC. +;; This file is part of GCC. -;; GNU CC is free software; you can redistribute it and/or modify +;; GCC is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2, or (at your option) ;; any later version. -;; GNU CC is distributed in the hope that it will be useful, +;; GCC is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License -;; along with GNU CC; see the file COPYING. If not, write to +;; along with GCC; see the file COPYING. If not, write to ;; the Free Software Foundation, 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. @@ -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,34 +7154,34 @@ "" " { - /* 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) - { - if ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 64 - || (unsigned HOST_WIDE_INT) INTVAL (operands[3]) > 63) - FAIL; - emit_insn (gen_extzv_64 (operands[0], operands[1], - operands[2], operands[3])); - } + emit_insn (gen_extzv_64 (operands[0], operands[1], + operands[2], operands[3])); else - { - if ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 32 - || (unsigned HOST_WIDE_INT) INTVAL (operands[3]) > 31) - 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; }") (define_insn "extzv_32" [(set (match_operand:SI 0 "register_operand" "=r") (zero_extract:SI (match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "uint32_operand" "") - (match_operand:SI 3 "uint32_operand" "")))] + (match_operand:SI 2 "uint5_operand" "") + (match_operand:SI 3 "uint5_operand" "")))] "" "{extru|extrw,u} %1,%3+%2-1,%2,%0" [(set_attr "type" "shift") @@ -7216,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" "") @@ -7224,34 +7226,34 @@ "" " { - /* 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) - { - if ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 64 - || (unsigned HOST_WIDE_INT) INTVAL (operands[3]) > 63) - FAIL; - emit_insn (gen_extv_64 (operands[0], operands[1], - operands[2], operands[3])); - } + emit_insn (gen_extv_64 (operands[0], operands[1], + operands[2], operands[3])); else - { - if ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 32 - || (unsigned HOST_WIDE_INT) INTVAL (operands[3]) > 31) - 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; }") (define_insn "extv_32" [(set (match_operand:SI 0 "register_operand" "=r") (sign_extract:SI (match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "uint32_operand" "") - (match_operand:SI 3 "uint32_operand" "")))] + (match_operand:SI 2 "uint5_operand" "") + (match_operand:SI 3 "uint5_operand" "")))] "" "{extrs|extrw,s} %1,%3+%2-1,%2,%0" [(set_attr "type" "shift") @@ -7287,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" "") @@ -7296,29 +7298,33 @@ "" " { + 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) - { - if ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 64 - || (unsigned HOST_WIDE_INT) INTVAL (operands[3]) > 63) - FAIL; - emit_insn (gen_insv_64 (operands[0], operands[1], - operands[2], operands[3])); - } + emit_insn (gen_insv_64 (operands[0], operands[1], + operands[2], operands[3])); else - { - if ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 32 - || (unsigned HOST_WIDE_INT) INTVAL (operands[3]) > 31) - 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; }") (define_insn "insv_32" [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,r") - (match_operand:SI 1 "uint32_operand" "") - (match_operand:SI 2 "uint32_operand" "")) + (match_operand:SI 1 "uint5_operand" "") + (match_operand:SI 2 "uint5_operand" "")) (match_operand:SI 3 "arith5_operand" "r,L"))] "" "@ |