This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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)					\


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]