This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[committed] Update constraint handling on PA
- From: "John David Anglin" <dave at hiauly1 dot hia dot nrc dot ca>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 28 May 2007 21:05:06 -0400 (EDT)
- Subject: [committed] Update constraint handling on PA
This patch updates the constraint handling on the PA. Tested on
hppa2.0w-hp-hpux11.11 and hppa-unknown-linux-gnu with no observed
regressions. Committed to trunk.
Dave
--
J. David Anglin dave.anglin@nrc-cnrc.gc.ca
National Research Council of Canada (613) 990-0752 (FAX: 952-6602)
2007-05-28 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
* pa/constraints.md: New file.
* pa.md: Include constraints.md.
* pa.c (cint_ok_for_move): Avoid using CONST_OK_FOR_LETTER_P.
(integer_store_memory_operand, ldil_cint_p): New functions.
* pa-protos.h (integer_store_memory_operand, ldil_cint_p): Declare.
* pa.h (CONST_OK_FOR_LETTER_P, CONST_DOUBLE_OK_FOR_LETTER_P,
IS_RELOADING_PSEUDO_P, EXTRA_CONSTRAINT): Remove.
* pa32-regs.h (REG_CLASS_FROM_LETTER): Remove.
* pa64-regs.h (REG_CLASS_FROM_LETTER): Remove.
--- /dev/null Sun May 27 17:20:44 2007
+++ config/pa/constraints.md Sun May 27 13:38:49 2007
@@ -0,0 +1,141 @@
+;; Constraint definitions for pa
+;; Copyright (C) 2007 Free Software Foundation, Inc.
+
+;; This file is part of GCC.
+
+;; 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.
+
+;; 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 GCC; see the file COPYING. If not, write to
+;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Unused letters:
+;;; ABCDEF H V XY
+;;; bcde ghijklmnop stuvw z
+
+;; Register constraints.
+(define_register_constraint "a" "R1_REGS"
+ "General register 1.")
+
+(define_register_constraint "f" "FP_REGS"
+ "Floating-point register.")
+
+(define_register_constraint "q" "SHIFT_REGS"
+ "Shift amount register.")
+
+;; Keep 'x' for backward compatibility with user asm.
+(define_register_constraint "x" "FP_REGS"
+ "Floating-point register.")
+
+(define_register_constraint "y" "TARGET_64BIT ? FP_REGS : FPUPPER_REGS"
+ "Upper floating-point register.")
+
+(define_register_constraint "Z" "ALL_REGS"
+ "Any register.")
+
+;; Integer constant constraints.
+(define_constraint "I"
+ "Signed 11-bit integer constant."
+ (and (match_code "const_int")
+ (match_test "VAL_11_BITS_P (ival)")))
+
+(define_constraint "J"
+ "Signed 14-bit integer constant."
+ (and (match_code "const_int")
+ (match_test "VAL_14_BITS_P (ival)")))
+
+(define_constraint "K"
+ "Integer constant that can be deposited with a zdepi instruction."
+ (and (match_code "const_int")
+ (match_test "zdepi_cint_p (ival)")))
+
+(define_constraint "L"
+ "Signed 5-bit integer constant."
+ (and (match_code "const_int")
+ (match_test "VAL_5_BITS_P (ival)")))
+
+(define_constraint "M"
+ "Integer constant 0."
+ (and (match_code "const_int")
+ (match_test "ival == 0")))
+
+(define_constraint "N"
+ "Integer constant that can be loaded with a ldil instruction."
+ (and (match_code "const_int")
+ (match_test "ldil_cint_p (ival)")))
+
+(define_constraint "O"
+ "Integer constant such that ival+1 is a power of 2."
+ (and (match_code "const_int")
+ (match_test "(ival & (ival + 1)) == 0")))
+
+(define_constraint "P"
+ "Integer constant that can be used as an and mask in depi and
+ extru instructions."
+ (and (match_code "const_int")
+ (match_test "and_mask_p (ival)")))
+
+(define_constraint "S"
+ "Integer constant 31."
+ (and (match_code "const_int")
+ (match_test "ival == 31")))
+
+(define_constraint "U"
+ "Integer constant 63."
+ (and (match_code "const_int")
+ (match_test "ival == 63")))
+
+;; Floating-point constant constraints.
+(define_constraint "G"
+ "Floating-point constant 0."
+ (and (match_code "const_double")
+ (match_test "GET_MODE_CLASS (mode) == MODE_FLOAT
+ && op == CONST0_RTX (mode)")))
+
+;; Extra constraints.
+(define_constraint "A"
+ "A LO_SUM DLT memory operand."
+ (and (match_code "mem")
+ (match_test "IS_LO_SUM_DLT_ADDR_P (XEXP (op, 0))")))
+
+(define_constraint "Q"
+ "A memory operand that can be used as the destination operand of an
+ integer store, or the source operand of an integer load. That is
+ any memory operand that isn't a symbolic, indexed or lo_sum memory
+ operand. Note that an unassigned pseudo register is such a memory
+ operand. We accept unassigned pseudo registers because reload
+ generates them and then doesn't re-recognize the insn, causing
+ constrain_operands to fail."
+ (match_test "integer_store_memory_operand (op, mode)"))
+
+(define_constraint "R"
+ "A scaled or unscaled indexed memory operand that can be used as the
+ source address in integer and floating-point loads."
+ (and (match_code "mem")
+ (match_test "IS_INDEX_ADDR_P (XEXP (op, 0))")))
+
+(define_constraint "T"
+ "A memory operand for floating-point loads and stores."
+ (and (match_code "mem")
+ (match_test "!IS_LO_SUM_DLT_ADDR_P (XEXP (op, 0))
+ && !IS_INDEX_ADDR_P (XEXP (op, 0))
+ && memory_address_p ((GET_MODE_SIZE (mode) == 4
+ ? SFmode : DFmode),
+ XEXP (op, 0))")))
+
+;; We could allow short displacements but GO_IF_LEGITIMATE_ADDRESS
+;; can't tell when a long displacement is valid.
+(define_constraint "W"
+ "A register indirect memory operand."
+ (and (match_code "mem")
+ (match_test "REG_P (XEXP (op, 0))
+ && REG_OK_FOR_BASE_P (XEXP (op, 0))")))
Index: config/pa/pa.md
===================================================================
--- config/pa/pa.md (revision 125102)
+++ config/pa/pa.md (working copy)
@@ -636,7 +636,10 @@
(eq_attr "cpu" "8000"))
"inm_8000,fdivsqrt_8000*6,rnm_8000")
+;; Operand and operator predicates and constraints
+
(include "predicates.md")
+(include "constraints.md")
;; Compare instructions.
;; This controls RTL generation and register allocation.
Index: config/pa/pa-protos.h
===================================================================
--- config/pa/pa-protos.h (revision 125102)
+++ config/pa/pa-protos.h (working copy)
@@ -133,7 +133,8 @@
extern rtx get_deferred_plabel (rtx);
#endif /* RTX_CODE */
-/* Prototype function used in macro CONST_OK_FOR_LETTER_P. */
+extern int integer_store_memory_operand (rtx, enum machine_mode);
+extern int ldil_cint_p (HOST_WIDE_INT);
extern int zdepi_cint_p (unsigned HOST_WIDE_INT);
extern void override_options (void);
Index: config/pa/pa.c
===================================================================
--- config/pa/pa.c (revision 125102)
+++ config/pa/pa.c (working copy)
@@ -558,12 +554,12 @@
/* Accept any constant that can be moved in one instruction into a
general register. */
int
-cint_ok_for_move (HOST_WIDE_INT intval)
+cint_ok_for_move (HOST_WIDE_INT ival)
{
/* OK if ldo, ldil, or zdepi, can be used. */
- return (CONST_OK_FOR_LETTER_P (intval, 'J')
- || CONST_OK_FOR_LETTER_P (intval, 'N')
- || CONST_OK_FOR_LETTER_P (intval, 'K'));
+ return (VAL_14_BITS_P (ival)
+ || ldil_cint_p (ival)
+ || zdepi_cint_p (ival));
}
/* Return truth value of whether OP can be used as an operand in a
@@ -576,6 +572,36 @@
&& (TARGET_64BIT ? INT_14_BITS (op) : INT_11_BITS (op))));
}
+/* True iff the operand OP can be used as the destination operand of
+ an integer store. This also implies the operand could be used as
+ the source operand of an integer load. Symbolic, lo_sum and indexed
+ memory operands are not allowed. We accept reloading pseudos and
+ other memory operands. */
+int
+integer_store_memory_operand (rtx op, enum machine_mode mode)
+{
+ return ((reload_in_progress
+ && REG_P (op)
+ && REGNO (op) >= FIRST_PSEUDO_REGISTER
+ && reg_renumber [REGNO (op)] < 0)
+ || (GET_CODE (op) == MEM
+ && (reload_in_progress || memory_address_p (mode, XEXP (op, 0)))
+ && !symbolic_memory_operand (op, VOIDmode)
+ && !IS_LO_SUM_DLT_ADDR_P (XEXP (op, 0))
+ && !IS_INDEX_ADDR_P (XEXP (op, 0))));
+}
+
+/* True iff ldil can be used to load this CONST_INT. The least
+ significant 11 bits of the value must be zero and the value must
+ not change sign when extended from 32 to 64 bits. */
+int
+ldil_cint_p (HOST_WIDE_INT ival)
+{
+ HOST_WIDE_INT x = ival & (((HOST_WIDE_INT) -1 << 31) | 0x7ff);
+
+ return x == 0 || x == ((HOST_WIDE_INT) -1 << 31);
+}
+
/* True iff zdepi can be used to generate this CONST_INT.
zdepi first sign extends a 5-bit signed number to a given field
length, then places this field anywhere in a zero. */
Index: config/pa/pa.h
===================================================================
--- config/pa/pa.h (revision 125102)
+++ config/pa/pa.h (working copy)
@@ -481,46 +480,7 @@
} \
} while (0)
-/* The letters I, J, K, L and M in a register constraint string
- can be used to stand for particular ranges of immediate operands.
- This macro defines what the ranges are.
- C is the letter, and VALUE is a constant value.
- Return 1 if VALUE is in the range specified by C.
- `I' is used for the 11-bit constants.
- `J' is used for the 14-bit constants.
- `K' is used for values that can be moved with a zdepi insn.
- `L' is used for the 5-bit constants.
- `M' is used for 0.
- `N' is used for values with the least significant 11 bits equal to zero
- and when sign extended from 32 to 64 bits the
- value does not change.
- `O' is used for numbers n such that n+1 is a power of 2.
- */
-
-#define CONST_OK_FOR_LETTER_P(VALUE, C) \
- ((C) == 'I' ? VAL_11_BITS_P (VALUE) \
- : (C) == 'J' ? VAL_14_BITS_P (VALUE) \
- : (C) == 'K' ? zdepi_cint_p (VALUE) \
- : (C) == 'L' ? VAL_5_BITS_P (VALUE) \
- : (C) == 'M' ? (VALUE) == 0 \
- : (C) == 'N' ? (((VALUE) & (((HOST_WIDE_INT) -1 << 31) | 0x7ff)) == 0 \
- || (((VALUE) & (((HOST_WIDE_INT) -1 << 31) | 0x7ff)) \
- == (HOST_WIDE_INT) -1 << 31)) \
- : (C) == 'O' ? (((VALUE) & ((VALUE) + 1)) == 0) \
- : (C) == 'P' ? and_mask_p (VALUE) \
- : 0)
-
-/* Similar, but for floating or large integer constants, and defining letters
- G and H. Here VALUE is the CONST_DOUBLE rtx itself.
-
- For PA, `G' is the floating-point constant zero. `H' is undefined. */
-
-#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
- ((C) == 'G' ? (GET_MODE_CLASS (GET_MODE (VALUE)) == MODE_FLOAT \
- && (VALUE) == CONST0_RTX (GET_MODE (VALUE))) \
- : 0)
-
/* The class value for index registers, and the one for base regs. */
#define INDEX_REG_CLASS GENERAL_REGS
#define BASE_REG_CLASS GENERAL_REGS
@@ -1145,16 +1105,8 @@
#define SYMBOL_REF_REFERENCED_P(RTX) \
((SYMBOL_REF_FLAGS (RTX) & SYMBOL_FLAG_REFERENCED) != 0)
-/* Subroutines for EXTRA_CONSTRAINT.
+/* Defines for constraints.md. */
- Return 1 iff OP is a pseudo which did not get a hard register and
- we are running the reload pass. */
-#define IS_RELOADING_PSEUDO_P(OP) \
- ((reload_in_progress \
- && GET_CODE (OP) == REG \
- && REGNO (OP) >= FIRST_PSEUDO_REGISTER \
- && reg_renumber [REGNO (OP)] < 0))
-
/* Return 1 iff OP is a scaled or unscaled index address. */
#define IS_INDEX_ADDR_P(OP) \
(GET_CODE (OP) == PLUS \
@@ -1172,74 +1124,6 @@
&& REG_OK_FOR_BASE_P (XEXP (OP, 0)) \
&& GET_CODE (XEXP (OP, 1)) == UNSPEC)
-/* Optional extra constraints for this machine. Borrowed from sparc.h.
-
- `A' is a LO_SUM DLT memory operand.
-
- `Q' is any memory operand that isn't a symbolic, indexed or lo_sum
- memory operand. Note that an unassigned pseudo register is such a
- memory operand. Needed because reload will generate these things
- and then not re-recognize the insn, causing constrain_operands to
- fail.
-
- `R' is a scaled/unscaled indexed memory operand.
-
- `S' is the constant 31.
-
- `T' is for floating-point loads and stores.
-
- `U' is the constant 63.
-
- `W' is a register indirect memory operand. We could allow short
- displacements but GO_IF_LEGITIMATE_ADDRESS can't tell when a
- long displacement is valid. This is only used for prefetch
- instructions with the `sl' completer. */
-
-#define EXTRA_CONSTRAINT(OP, C) \
- ((C) == 'Q' ? \
- (IS_RELOADING_PSEUDO_P (OP) \
- || (GET_CODE (OP) == MEM \
- && (reload_in_progress \
- || memory_address_p (GET_MODE (OP), XEXP (OP, 0))) \
- && !symbolic_memory_operand (OP, VOIDmode) \
- && !IS_LO_SUM_DLT_ADDR_P (XEXP (OP, 0)) \
- && !IS_INDEX_ADDR_P (XEXP (OP, 0)))) \
- : ((C) == 'W' ? \
- (GET_CODE (OP) == MEM \
- && REG_P (XEXP (OP, 0)) \
- && REG_OK_FOR_BASE_P (XEXP (OP, 0))) \
- : ((C) == 'A' ? \
- (GET_CODE (OP) == MEM \
- && IS_LO_SUM_DLT_ADDR_P (XEXP (OP, 0))) \
- : ((C) == 'R' ? \
- (GET_CODE (OP) == MEM \
- && IS_INDEX_ADDR_P (XEXP (OP, 0))) \
- : ((C) == 'T' ? \
- (GET_CODE (OP) == MEM \
- && !IS_LO_SUM_DLT_ADDR_P (XEXP (OP, 0)) \
- && !IS_INDEX_ADDR_P (XEXP (OP, 0)) \
- /* Floating-point loads and stores are used to load \
- integer values as well as floating-point values. \
- They don't have the same set of REG+D address modes \
- as integer loads and stores. PA 1.x supports only \
- short displacements. PA 2.0 supports long displacements \
- but the base register needs to be aligned. \
- \
- The checks in GO_IF_LEGITIMATE_ADDRESS for SFmode and \
- DFmode test the validity of an address for use in a \
- floating point load or store. So, we use SFmode/DFmode \
- to see if the address is valid for a floating-point \
- load/store operation. */ \
- && memory_address_p ((GET_MODE_SIZE (GET_MODE (OP)) == 4 \
- ? SFmode \
- : DFmode), \
- XEXP (OP, 0))) \
- : ((C) == 'S' ? \
- (GET_CODE (OP) == CONST_INT && INTVAL (OP) == 31) \
- : ((C) == 'U' ? \
- (GET_CODE (OP) == CONST_INT && INTVAL (OP) == 63) : 0)))))))
-
-
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
and check its validity for a certain class.
We have two alternate definitions for each of them.
Index: config/pa/pa32-regs.h
===================================================================
--- config/pa/pa32-regs.h (revision 125102)
+++ config/pa/pa32-regs.h (working copy)
@@ -300,16 +300,6 @@
: (REGNO) < 88 ? FPUPPER_REGS \
: SHIFT_REGS)
-/* Get reg_class from a letter such as appears in the machine description. */
-/* Keep 'x' for backward compatibility with user asm. */
-#define REG_CLASS_FROM_LETTER(C) \
- ((C) == 'f' ? FP_REGS : \
- (C) == 'y' ? FPUPPER_REGS : \
- (C) == 'x' ? FP_REGS : \
- (C) == 'q' ? SHIFT_REGS : \
- (C) == 'a' ? R1_REGS : \
- (C) == 'Z' ? ALL_REGS : NO_REGS)
-
/* Return the maximum number of consecutive registers
needed to represent mode MODE in a register of class CLASS. */
#define CLASS_MAX_NREGS(CLASS, MODE) \
Index: config/pa/pa64-regs.h
===================================================================
--- config/pa/pa64-regs.h (revision 125102)
+++ config/pa/pa64-regs.h (working copy)
@@ -266,18 +266,6 @@
: (REGNO) < 60 ? FP_REGS \
: SHIFT_REGS)
-
-/* Get reg_class from a letter such as appears in the machine description. */
-/* Keep 'x' for backward compatibility with user asm. */
-#define REG_CLASS_FROM_LETTER(C) \
- ((C) == 'f' ? FP_REGS : \
- (C) == 'y' ? FP_REGS : \
- (C) == 'x' ? FP_REGS : \
- (C) == 'q' ? SHIFT_REGS : \
- (C) == 'a' ? R1_REGS : \
- (C) == 'Z' ? ALL_REGS : NO_REGS)
-
-
/* Return the maximum number of consecutive registers
needed to represent mode MODE in a register of class CLASS. */
#define CLASS_MAX_NREGS(CLASS, MODE) \