constraints.md: New file.
* config/sparc/constraints.md: New file. * config/sparc/sparc.md: Include it. * config/sparc/sparc-protos.h (memory_ok_for_ldd): Declare. (sparc_extra_constraint_check): Delete. * config/sparc/sparc.c (register_ok_for_ldd): Minor tweaks. (memory_ok_for_ldd): New predicate. (sparc_extra_constraint_check): Delete. * config/sparc/sparc.h (REG_CLASS_FROM_LETTER): Likewise. (CONST_OK_FOR_LETTER_P): Likewise. (CONST_DOUBLE_OK_FOR_LETTER_P): Likewise. (EXTRA_CONSTRAINT): Likewise. From-SVN: r140619
This commit is contained in:
parent
8179c2f253
commit
157891a301
6 changed files with 193 additions and 157 deletions
|
@ -1,3 +1,17 @@
|
|||
2008-09-23 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* config/sparc/constraints.md: New file.
|
||||
* config/sparc/sparc.md: Include it.
|
||||
* config/sparc/sparc-protos.h (memory_ok_for_ldd): Declare.
|
||||
(sparc_extra_constraint_check): Delete.
|
||||
* config/sparc/sparc.c (register_ok_for_ldd): Minor tweaks.
|
||||
(memory_ok_for_ldd): New predicate.
|
||||
(sparc_extra_constraint_check): Delete.
|
||||
* config/sparc/sparc.h (REG_CLASS_FROM_LETTER): Likewise.
|
||||
(CONST_OK_FOR_LETTER_P): Likewise.
|
||||
(CONST_DOUBLE_OK_FOR_LETTER_P): Likewise.
|
||||
(EXTRA_CONSTRAINT): Likewise.
|
||||
|
||||
2008-08-23 Steve Ellcey <sje@cup.hp.com>
|
||||
|
||||
* regrename.c (do_replace): Copy REG_POINTER value to new reg.
|
||||
|
|
143
gcc/config/sparc/constraints.md
Normal file
143
gcc/config/sparc/constraints.md
Normal file
|
@ -0,0 +1,143 @@
|
|||
;; Constraint definitions for SPARC.
|
||||
;; Copyright (C) 2008 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 3, 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 COPYING3. If not see
|
||||
;; <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Unused letters:
|
||||
;;; ABCD P Z
|
||||
;;; a jkl q tuvwxyz
|
||||
|
||||
|
||||
;; Register constraints
|
||||
|
||||
(define_register_constraint "b" "(TARGET_V9 && TARGET_VIS ? EXTRA_FP_REGS : NO_REGS)"
|
||||
"Any floating-point register in VIS mode")
|
||||
|
||||
(define_register_constraint "c" "FPCC_REGS"
|
||||
"Floating-point condition code register")
|
||||
|
||||
(define_register_constraint "d" "(TARGET_V9 && TARGET_VIS ? FP_REGS : NO_REGS)"
|
||||
"Lower floating-point register in VIS mode")
|
||||
|
||||
;; In the non-V9 case, coerce V9 'e' class to 'f', so we can use 'e' in the
|
||||
;; MD file for V8 and V9.
|
||||
(define_register_constraint "e" "TARGET_V9 ? EXTRA_FP_REGS : FP_REGS"
|
||||
"Any floating-point register")
|
||||
|
||||
(define_register_constraint "f" "FP_REGS"
|
||||
"Lower floating-point register")
|
||||
|
||||
(define_register_constraint "h" "(TARGET_V9 && TARGET_V8PLUS ? I64_REGS : NO_REGS)"
|
||||
"64-bit global or out register in V8+ mode")
|
||||
|
||||
|
||||
;; Floating-point constant constraints
|
||||
|
||||
(define_constraint "G"
|
||||
"The floating-point zero constant"
|
||||
(and (match_code "const_double")
|
||||
(match_test "const_zero_operand (op, mode)")))
|
||||
|
||||
|
||||
;; Integer constant constraints
|
||||
|
||||
(define_constraint "H"
|
||||
"Valid operand of double arithmetic operation"
|
||||
(and (match_code "const_double")
|
||||
(match_test "arith_double_operand (op, DImode)")))
|
||||
|
||||
(define_constraint "I"
|
||||
"Signed 13-bit integer constant"
|
||||
(and (match_code "const_int")
|
||||
(match_test "SPARC_SIMM13_P (ival)")))
|
||||
|
||||
(define_constraint "J"
|
||||
"The integer zero constant"
|
||||
(and (match_code "const_int")
|
||||
(match_test "ival == 0")))
|
||||
|
||||
(define_constraint "K"
|
||||
"Signed 32-bit constant that can be loaded with a sethi instruction"
|
||||
(and (match_code "const_int")
|
||||
(match_test "SPARC_SETHI32_P (ival)")))
|
||||
|
||||
(define_constraint "L"
|
||||
"Signed 11-bit integer constant"
|
||||
(and (match_code "const_int")
|
||||
(match_test "SPARC_SIMM11_P (ival)")))
|
||||
|
||||
(define_constraint "M"
|
||||
"Signed 10-bit integer constant"
|
||||
(and (match_code "const_int")
|
||||
(match_test "SPARC_SIMM10_P (ival)")))
|
||||
|
||||
(define_constraint "N"
|
||||
"Signed constant that can be loaded with a sethi instruction"
|
||||
(and (match_code "const_int")
|
||||
(match_test "SPARC_SETHI_P (ival)")))
|
||||
|
||||
(define_constraint "O"
|
||||
"The 4096 constant"
|
||||
(and (match_code "const_int")
|
||||
(match_test "ival == 4096")))
|
||||
|
||||
|
||||
;; Extra constraints
|
||||
;; Our memory extra constraints have to emulate the behavior of 'm' and 'o',
|
||||
;; i.e. accept pseudo-registers during reload.
|
||||
|
||||
(define_constraint "Q"
|
||||
"Floating-point constant that can be loaded with a sethi instruction"
|
||||
(and (match_code "const_double")
|
||||
(match_test "fp_sethi_p (op)")))
|
||||
|
||||
(define_constraint "R"
|
||||
"Floating-point constant that can be loaded with a move instruction"
|
||||
(and (match_code "const_double")
|
||||
(match_test "fp_mov_p (op)")))
|
||||
|
||||
(define_constraint "S"
|
||||
"Floating-point constant that can be loaded with a high/lo_sum sequence"
|
||||
(and (match_code "const_double")
|
||||
(match_test "fp_high_losum_p (op)")))
|
||||
|
||||
;; Not needed in 64-bit mode
|
||||
(define_constraint "T"
|
||||
"Memory reference whose address is aligned to 8-byte boundary"
|
||||
(and (match_test "TARGET_ARCH32")
|
||||
(match_code "mem,reg")
|
||||
(match_test "memory_ok_for_ldd (op)")))
|
||||
|
||||
;; Not needed in 64-bit mode
|
||||
(define_constraint "U"
|
||||
"Pseudo-register or hard even-numbered integer register"
|
||||
(and (match_test "TARGET_ARCH32")
|
||||
(match_code "reg")
|
||||
(ior (match_test "REGNO (op) < FIRST_PSEUDO_REGISTER")
|
||||
(not (match_test "reload_in_progress && reg_renumber [REGNO (op)] < 0")))
|
||||
(match_test "register_ok_for_ldd (op)")))
|
||||
|
||||
;; Equivalent to 'T' but available in 64-bit mode
|
||||
(define_constraint "W"
|
||||
"Memory reference for 'e' constraint floating-point register"
|
||||
(and (match_code "mem,reg")
|
||||
(match_test "memory_ok_for_ldd (op)")))
|
||||
|
||||
(define_constraint "Y"
|
||||
"The vector zero constant"
|
||||
(and (match_code "const_vector")
|
||||
(match_test "const_zero_operand (op, mode)")))
|
|
@ -107,13 +107,13 @@ extern int mem_min_alignment (rtx, int);
|
|||
extern int pic_address_needs_scratch (rtx);
|
||||
extern int reg_unused_after (rtx, rtx);
|
||||
extern int register_ok_for_ldd (rtx);
|
||||
extern int memory_ok_for_ldd (rtx);
|
||||
extern int registers_ok_for_ldd_peep (rtx, rtx);
|
||||
extern int v9_regcmp_p (enum rtx_code);
|
||||
/* Function used for V8+ code generation. Returns 1 if the high
|
||||
32 bits of REG are 0 before INSN. */
|
||||
extern int sparc_check_64 (rtx, rtx);
|
||||
extern rtx gen_df_reg (rtx, int);
|
||||
extern int sparc_extra_constraint_check (rtx, int, int);
|
||||
extern void sparc_expand_compare_and_swap_12 (rtx, rtx, rtx, rtx);
|
||||
#endif /* RTX_CODE */
|
||||
|
||||
|
|
|
@ -6744,21 +6744,49 @@ mems_ok_for_ldd_peep (rtx mem1, rtx mem2, rtx dependent_reg_rtx)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* Return 1 if reg is a pseudo, or is the first register in
|
||||
a hard register pair. This makes it a candidate for use in
|
||||
/* Return 1 if reg is a pseudo, or is the first register in
|
||||
a hard register pair. This makes it suitable for use in
|
||||
ldd and std insns. */
|
||||
|
||||
int
|
||||
register_ok_for_ldd (rtx reg)
|
||||
{
|
||||
/* We might have been passed a SUBREG. */
|
||||
if (GET_CODE (reg) != REG)
|
||||
if (!REG_P (reg))
|
||||
return 0;
|
||||
|
||||
if (REGNO (reg) < FIRST_PSEUDO_REGISTER)
|
||||
return (REGNO (reg) % 2 == 0);
|
||||
else
|
||||
return 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Return 1 if OP is a memory whose address is known to be
|
||||
aligned to 8-byte boundary, or a pseudo during reload.
|
||||
This makes it suitable for use in ldd and std insns. */
|
||||
|
||||
int
|
||||
memory_ok_for_ldd (rtx op)
|
||||
{
|
||||
if (MEM_P (op))
|
||||
{
|
||||
/* In 64-bit mode, we assume that the address is word-aligned. */
|
||||
if (TARGET_ARCH32 && !mem_min_alignment (op, 8))
|
||||
return 0;
|
||||
|
||||
if ((reload_in_progress || reload_completed)
|
||||
&& !strict_memory_address_p (Pmode, XEXP (op, 0)))
|
||||
return 0;
|
||||
}
|
||||
else if (REG_P (op) && REGNO (op) >= FIRST_PSEUDO_REGISTER)
|
||||
{
|
||||
if (!(reload_in_progress && reg_renumber [REGNO (op)] < 0))
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Print operand X (an rtx) in assembler syntax to file FILE.
|
||||
|
@ -8356,68 +8384,6 @@ sparc_fold_builtin (tree fndecl, tree arglist, bool ignore)
|
|||
return NULL_TREE;
|
||||
}
|
||||
|
||||
int
|
||||
sparc_extra_constraint_check (rtx op, int c, int strict)
|
||||
{
|
||||
int reload_ok_mem;
|
||||
|
||||
if (TARGET_ARCH64
|
||||
&& (c == 'T' || c == 'U'))
|
||||
return 0;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 'Q':
|
||||
return fp_sethi_p (op);
|
||||
|
||||
case 'R':
|
||||
return fp_mov_p (op);
|
||||
|
||||
case 'S':
|
||||
return fp_high_losum_p (op);
|
||||
|
||||
case 'U':
|
||||
if (! strict
|
||||
|| (GET_CODE (op) == REG
|
||||
&& (REGNO (op) < FIRST_PSEUDO_REGISTER
|
||||
|| reg_renumber[REGNO (op)] >= 0)))
|
||||
return register_ok_for_ldd (op);
|
||||
|
||||
return 0;
|
||||
|
||||
case 'W':
|
||||
case 'T':
|
||||
break;
|
||||
|
||||
case 'Y':
|
||||
return const_zero_operand (op, GET_MODE (op));
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Our memory extra constraints have to emulate the
|
||||
behavior of 'm' and 'o' in order for reload to work
|
||||
correctly. */
|
||||
if (GET_CODE (op) == MEM)
|
||||
{
|
||||
reload_ok_mem = 0;
|
||||
if ((TARGET_ARCH64 || mem_min_alignment (op, 8))
|
||||
&& (! strict
|
||||
|| strict_memory_address_p (Pmode, XEXP (op, 0))))
|
||||
reload_ok_mem = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
reload_ok_mem = (reload_in_progress
|
||||
&& GET_CODE (op) == REG
|
||||
&& REGNO (op) >= FIRST_PSEUDO_REGISTER
|
||||
&& reg_renumber [REGNO (op)] < 0);
|
||||
}
|
||||
|
||||
return reload_ok_mem;
|
||||
}
|
||||
|
||||
/* ??? This duplicates information provided to the compiler by the
|
||||
??? scheduler description. Some day, teach genautomata to output
|
||||
??? the latencies and then CSE will just use that. */
|
||||
|
|
|
@ -1210,42 +1210,6 @@ extern char leaf_reg_remap[];
|
|||
/* Local macro to handle the two v9 classes of FP regs. */
|
||||
#define FP_REG_CLASS_P(CLASS) ((CLASS) == FP_REGS || (CLASS) == EXTRA_FP_REGS)
|
||||
|
||||
/* Get reg_class from a letter such as appears in the machine description.
|
||||
In the not-v9 case, coerce v9's 'e' class to 'f', so we can use 'e' in the
|
||||
.md file for v8 and v9.
|
||||
'd' and 'b' are used for single and double precision VIS operations,
|
||||
if TARGET_VIS.
|
||||
'h' is used for V8+ 64 bit global and out registers. */
|
||||
|
||||
#define REG_CLASS_FROM_LETTER(C) \
|
||||
(TARGET_V9 \
|
||||
? ((C) == 'f' ? FP_REGS \
|
||||
: (C) == 'e' ? EXTRA_FP_REGS \
|
||||
: (C) == 'c' ? FPCC_REGS \
|
||||
: ((C) == 'd' && TARGET_VIS) ? FP_REGS\
|
||||
: ((C) == 'b' && TARGET_VIS) ? EXTRA_FP_REGS\
|
||||
: ((C) == 'h' && TARGET_V8PLUS) ? I64_REGS\
|
||||
: NO_REGS) \
|
||||
: ((C) == 'f' ? FP_REGS \
|
||||
: (C) == 'e' ? FP_REGS \
|
||||
: (C) == 'c' ? FPCC_REGS \
|
||||
: NO_REGS))
|
||||
|
||||
/* The letters I, J, K, L, M, N, O, P in a register constraint string
|
||||
can be used to stand for particular ranges of CONST_INTs.
|
||||
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 range of constants an insn can actually contain.
|
||||
`J' is used for the range which is just zero (since that is R0).
|
||||
`K' is used for constants which can be loaded with a single sethi insn.
|
||||
`L' is used for the range of constants supported by the movcc insns.
|
||||
`M' is used for the range of constants supported by the movrcc insns.
|
||||
`N' is like K, but for constants wider than 32 bits.
|
||||
`O' is used for the range which is just 4096.
|
||||
`P' is free. */
|
||||
|
||||
/* Predicates for 10-bit, 11-bit and 13-bit signed constants. */
|
||||
#define SPARC_SIMM10_P(X) ((unsigned HOST_WIDE_INT) (X) + 0x200 < 0x400)
|
||||
#define SPARC_SIMM11_P(X) ((unsigned HOST_WIDE_INT) (X) + 0x400 < 0x800)
|
||||
|
@ -1272,24 +1236,6 @@ extern char leaf_reg_remap[];
|
|||
#define SPARC_SETHI32_P(X) \
|
||||
(SPARC_SETHI_P ((unsigned HOST_WIDE_INT) (X) & GET_MODE_MASK (SImode)))
|
||||
|
||||
#define CONST_OK_FOR_LETTER_P(VALUE, C) \
|
||||
((C) == 'I' ? SPARC_SIMM13_P (VALUE) \
|
||||
: (C) == 'J' ? (VALUE) == 0 \
|
||||
: (C) == 'K' ? SPARC_SETHI32_P (VALUE) \
|
||||
: (C) == 'L' ? SPARC_SIMM11_P (VALUE) \
|
||||
: (C) == 'M' ? SPARC_SIMM10_P (VALUE) \
|
||||
: (C) == 'N' ? SPARC_SETHI_P (VALUE) \
|
||||
: (C) == 'O' ? (VALUE) == 4096 \
|
||||
: 0)
|
||||
|
||||
/* Similar, but for CONST_DOUBLEs, and defining letters G and H.
|
||||
Here VALUE is the CONST_DOUBLE rtx itself. */
|
||||
|
||||
#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
|
||||
((C) == 'G' ? const_zero_operand (VALUE, GET_MODE (VALUE)) \
|
||||
: (C) == 'H' ? arith_double_operand (VALUE, DImode) \
|
||||
: 0)
|
||||
|
||||
/* Given an rtx X being reloaded into a reg required to be
|
||||
in class CLASS, return the class of reg to actually use.
|
||||
In general this is just CLASS; but on some machines
|
||||
|
@ -1888,28 +1834,6 @@ do { \
|
|||
After reload, it makes no difference, since pseudo regs have
|
||||
been eliminated by then. */
|
||||
|
||||
/* Optional extra constraints for this machine.
|
||||
|
||||
'Q' handles floating point constants which can be moved into
|
||||
an integer register with a single sethi instruction.
|
||||
|
||||
'R' handles floating point constants which can be moved into
|
||||
an integer register with a single mov instruction.
|
||||
|
||||
'S' handles floating point constants which can be moved into
|
||||
an integer register using a high/lo_sum sequence.
|
||||
|
||||
'T' handles memory addresses where the alignment is known to
|
||||
be at least 8 bytes.
|
||||
|
||||
`U' handles all pseudo registers or a hard even numbered
|
||||
integer register, needed for ldd/std instructions.
|
||||
|
||||
'W' handles the memory operand when moving operands in/out
|
||||
of 'e' constraint floating point registers.
|
||||
|
||||
'Y' handles the zero vector constant. */
|
||||
|
||||
#ifndef REG_OK_STRICT
|
||||
|
||||
/* Nonzero if X is a hard reg that can be used as an index
|
||||
|
@ -1923,15 +1847,6 @@ do { \
|
|||
or if it is a pseudo reg. */
|
||||
#define REG_OK_FOR_BASE_P(X) REG_OK_FOR_INDEX_P (X)
|
||||
|
||||
/* 'T', 'U' are for aligned memory loads which aren't needed for arch64.
|
||||
'W' is like 'T' but is assumed true on arch64.
|
||||
|
||||
Remember to accept pseudo-registers for memory constraints if reload is
|
||||
in progress. */
|
||||
|
||||
#define EXTRA_CONSTRAINT(OP, C) \
|
||||
sparc_extra_constraint_check(OP, C, 0)
|
||||
|
||||
#else
|
||||
|
||||
/* Nonzero if X is a hard reg that can be used as an index. */
|
||||
|
@ -1939,9 +1854,6 @@ do { \
|
|||
/* Nonzero if X is a hard reg that can be used as a base reg. */
|
||||
#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
|
||||
|
||||
#define EXTRA_CONSTRAINT(OP, C) \
|
||||
sparc_extra_constraint_check(OP, C, 1)
|
||||
|
||||
#endif
|
||||
|
||||
/* Should gcc use [%reg+%lo(xx)+offset] addresses? */
|
||||
|
|
|
@ -320,9 +320,10 @@
|
|||
(include "niagara2.md")
|
||||
|
||||
|
||||
;; Operand and operator predicates.
|
||||
;; Operand and operator predicates and constraints
|
||||
|
||||
(include "predicates.md")
|
||||
(include "constraints.md")
|
||||
|
||||
|
||||
;; Compare instructions.
|
||||
|
|
Loading…
Add table
Reference in a new issue