aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/pa/pa.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/pa/pa.md')
-rw-r--r--gcc/config/pa/pa.md122
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"))]
""
"@