* 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
+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.
--- /dev/null
+;; 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)")))
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 */
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;
}
\f
/* Print operand X (an rtx) in assembler syntax to file FILE.
return NULL_TREE;
}
\f
-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. */
/* 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)
#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
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
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. */
/* 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
\f
/* Should gcc use [%reg+%lo(xx)+offset] addresses? */
(include "niagara2.md")
-;; Operand and operator predicates.
+;; Operand and operator predicates and constraints
(include "predicates.md")
+(include "constraints.md")
;; Compare instructions.