diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1ca63349ec5..7a2f9fc57c3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2007-05-28 John David Anglin + + * 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. + 2007-05-28 Andrew Pinski PR c/31339 diff --git a/gcc/config/pa/constraints.md b/gcc/config/pa/constraints.md new file mode 100644 index 00000000000..d387d040e78 --- /dev/null +++ b/gcc/config/pa/constraints.md @@ -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))"))) diff --git a/gcc/config/pa/pa-protos.h b/gcc/config/pa/pa-protos.h index e91ac16c8e1..8d601828c5d 100644 --- a/gcc/config/pa/pa-protos.h +++ b/gcc/config/pa/pa-protos.h @@ -133,7 +133,8 @@ extern int insn_refs_are_delayed (rtx); 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); diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index 6cd2be73a32..f0a894a91ff 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -558,12 +558,12 @@ symbolic_expression_p (rtx x) /* 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 +576,36 @@ adddi3_operand (rtx op, enum machine_mode mode) && (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. */ diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h index b7edfe18533..d4e31c7df8b 100644 --- a/gcc/config/pa/pa.h +++ b/gcc/config/pa/pa.h @@ -481,45 +481,6 @@ extern struct rtx_def *hppa_pic_save_rtx (void); } \ } 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 @@ -1145,15 +1106,7 @@ extern int may_call_alloca; #define SYMBOL_REF_REFERENCED_P(RTX) \ ((SYMBOL_REF_FLAGS (RTX) & SYMBOL_FLAG_REFERENCED) != 0) -/* Subroutines for EXTRA_CONSTRAINT. - - 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)) +/* Defines for constraints.md. */ /* Return 1 iff OP is a scaled or unscaled index address. */ #define IS_INDEX_ADDR_P(OP) \ @@ -1172,74 +1125,6 @@ extern int may_call_alloca; && 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. diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md index 698579a4ba9..807e1ce53ff 100644 --- a/gcc/config/pa/pa.md +++ b/gcc/config/pa/pa.md @@ -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. diff --git a/gcc/config/pa/pa32-regs.h b/gcc/config/pa/pa32-regs.h index fa0f0f9c36e..782ad8d5f5c 100644 --- a/gcc/config/pa/pa32-regs.h +++ b/gcc/config/pa/pa32-regs.h @@ -300,16 +300,6 @@ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FPUPPER_REGS, FP_REGS, : (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) \ diff --git a/gcc/config/pa/pa64-regs.h b/gcc/config/pa/pa64-regs.h index e356407f8fd..26986e8bedc 100644 --- a/gcc/config/pa/pa64-regs.h +++ b/gcc/config/pa/pa64-regs.h @@ -266,18 +266,6 @@ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FPUPPER_REGS, FP_REGS, : (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) \