diff options
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/config/sparc/constraints.md | 143 | ||||
-rw-r--r-- | gcc/config/sparc/sparc-protos.h | 2 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.c | 100 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.h | 88 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.md | 3 |
6 files changed, 193 insertions, 157 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index edc7f93..b0f8f52 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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. diff --git a/gcc/config/sparc/constraints.md b/gcc/config/sparc/constraints.md new file mode 100644 index 0000000..6d50564 --- /dev/null +++ b/gcc/config/sparc/constraints.md @@ -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)"))) diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h index a15837f..9950bd8 100644 --- a/gcc/config/sparc/sparc-protos.h +++ b/gcc/config/sparc/sparc-protos.h @@ -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 */ diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index fd56653..c69f618 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -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. */ diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index 191d6e8..5147494 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -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? */ diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index d0b7389..dc6c3a3 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -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. |