constraints.md: New file.
authorEric Botcazou <ebotcazou@adacore.com>
Tue, 23 Sep 2008 21:45:06 +0000 (21:45 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Tue, 23 Sep 2008 21:45:06 +0000 (21:45 +0000)
* 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

gcc/ChangeLog
gcc/config/sparc/constraints.md [new file with mode: 0644]
gcc/config/sparc/sparc-protos.h
gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.h
gcc/config/sparc/sparc.md

index edc7f93..b0f8f52 100644 (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.
diff --git a/gcc/config/sparc/constraints.md b/gcc/config/sparc/constraints.md
new file mode 100644 (file)
index 0000000..6d50564
--- /dev/null
@@ -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)")))
index a15837f..9950bd8 100644 (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 */
 
index fd56653..c69f618 100644 (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;
 }
 \f
 /* 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;
 }
 \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.  */
index 191d6e8..5147494 100644 (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
 \f
 /* Should gcc use [%reg+%lo(xx)+offset] addresses?  */
index d0b7389..dc6c3a3 100644 (file)
 (include "niagara2.md")
 
 
-;; Operand and operator predicates.
+;; Operand and operator predicates and constraints
 
 (include "predicates.md")
+(include "constraints.md")
 
 
 ;; Compare instructions.