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:
Eric Botcazou 2008-09-23 21:45:06 +00:00 committed by Eric Botcazou
parent 8179c2f253
commit 157891a301
6 changed files with 193 additions and 157 deletions

View File

@ -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.

View 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)")))

View File

@ -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 */

View File

@ -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. */

View File

@ -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? */

View File

@ -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.