constraints.md: New file.
* 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. From-SVN: r125157
This commit is contained in:
parent
a87db577fb
commit
5b28114174
@ -1,3 +1,15 @@
|
||||
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.
|
||||
|
||||
2007-05-28 Andrew Pinski <Andrew_pinski@playstation.sony.com>
|
||||
|
||||
PR c/31339
|
||||
|
141
gcc/config/pa/constraints.md
Normal file
141
gcc/config/pa/constraints.md
Normal file
@ -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))")))
|
@ -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);
|
||||
|
@ -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. */
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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) \
|
||||
|
@ -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) \
|
||||
|
Loading…
Reference in New Issue
Block a user