summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog39
-rw-r--r--gcc/Makefile.in20
-rw-r--r--gcc/config/i386/i386.c1
-rw-r--r--gcc/config/rs6000/constraints.md158
-rw-r--r--gcc/config/rs6000/predicates.md14
-rw-r--r--gcc/config/rs6000/rs6000.c48
-rw-r--r--gcc/config/rs6000/rs6000.h101
-rw-r--r--gcc/config/rs6000/rs6000.md11
-rw-r--r--gcc/genemit.c1
-rw-r--r--gcc/genoutput.c1
-rw-r--r--gcc/genpeep.c5
-rw-r--r--gcc/genpreds.c33
-rw-r--r--gcc/genrecog.c1
13 files changed, 277 insertions, 156 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 519980b1b35..8a29a797602 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,42 @@
+2006-03-29 David Edelsohn <edelsohn@gnu.org>
+
+ * genemit.c (main): Add tm-constrs.h to included headers.
+ * genoutput.c (output_prologue): Add tm-constrs.h to included headers.
+ * genpeep.c (main): Add tm-constrs.h to included headers.
+ * genpreds.c (write_satisfies_constraint_fns): Rename to ...
+ (write_tm_constrs_h): this and write complete file.
+ (write_tm_preds_h): Do not emit satisfies_constraint fns.
+ (write_insn_preds_c): Add tm-constrs.h to included headers.
+ (gen_constrs): New variable.
+ (parse_option): Parse "-c".
+ (main): Invoke write_tm_constrs_h.
+ * genrecog.c (write_header): Add tm-constrs.h to included headers.
+ * Makefile.in (STAGECOPYSTUFF): Add tm-constrs.h.
+ (object_out_file): Add tm-constrs.h dependency.
+ (insn-emit.o): Same.
+ (insn-output.o): Same.
+ (insn-peep.o): Same.
+ (insn-preds.o): Same.
+ (insn-recog.o): Same.
+ (tm-constsr.h): New target.
+ (s-constrs-h): New target.
+
+ * config/rs6000/constraints.md: New file.
+ * config/rs6000/rs6000.c: Include tm-constrs.h.
+ (num_insn_constant_wide): Convert to satisfies_constraint.
+ (rs6000_rtx_costs): Convert to satisfies_constraint.
+ * config/rs6000/rs6000.h (REG_CLASS_FROM_LETTER): Delete.
+ (CONST_OK_FOR_LETTER_P): Delete.
+ (CONST_DOUBLE_OK_FOR_LETTER_P): Delete.
+ (EXTRA_CONSTRAINT): Delete.
+ (EXTRA_MEMORY_CONSTRAINT): Delete.
+ (EXTRA_ADDRESS_CONSTRAINT): Delete.
+ * config/rs6000/predicates.md: Convert to satisfies_constraint.
+ * config/rs6000/rs6000.md: Include constraints.md. Convert to
+ satisfies_constraint.
+
+ * config/i386/i386.c: Include tm-constrs.h.
+
2006-03-29 Sebastian Pop <pop@cri.ensmp.fr>
* tree-loop-linear.c (compute_data_dependences_for_loop): Adjust calls.
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 234247ba6a3..51db2ea020d 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1016,7 +1016,7 @@ BACKEND = main.o @TREEBROWSER@ libbackend.a $(CPPLIB) $(LIBDECNUMBER)
STAGECOPYSTUFF = insn-flags.h insn-config.h insn-codes.h \
insn-output.c insn-recog.c insn-emit.c insn-extract.c insn-peep.c \
insn-attr.h insn-attrtab.c insn-opinit.c insn-preds.c insn-constants.h \
- tm-preds.h \
+ tm-preds.h tm-constrs.h \
tree-check.h min-insn-modes.c insn-modes.c insn-modes.h \
genrtl.c genrtl.h gt-*.h gtype-*.h gtype-desc.c gtyp-gen.h
@@ -2601,7 +2601,7 @@ $(out_object_file): $(out_file) $(CONFIG_H) coretypes.h $(TM_H) $(TREE_H) \
$(RTL_H) $(REGS_H) hard-reg-set.h insn-config.h conditions.h \
output.h $(INSN_ATTR_H) $(SYSTEM_H) toplev.h $(TARGET_H) libfuncs.h \
$(TARGET_DEF_H) $(FUNCTION_H) $(SCHED_INT_H) $(TM_P_H) $(EXPR_H) \
- langhooks.h $(GGC_H) $(OPTABS_H) $(REAL_H)
+ langhooks.h $(GGC_H) $(OPTABS_H) $(REAL_H) tm-constrs.h
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) \
$(out_file) $(OUTPUT_OPTION)
@@ -2660,7 +2660,7 @@ insn-automata.o : insn-automata.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
insn-emit.o : insn-emit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(EXPR_H) $(REAL_H) output.h insn-config.h $(OPTABS_H) \
reload.h $(RECOG_H) toplev.h $(FUNCTION_H) $(FLAGS_H) hard-reg-set.h \
- $(RESOURCE_H) $(TM_P_H) $(BASIC_BLOCK_H)
+ $(RESOURCE_H) $(TM_P_H) $(BASIC_BLOCK_H) tm-constrs.h
insn-extract.o : insn-extract.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(RTL_H) toplev.h insn-config.h $(RECOG_H)
insn-modes.o : insn-modes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
@@ -2672,18 +2672,18 @@ insn-output.o : insn-output.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(RTL_H) $(GGC_H) $(REGS_H) $(REAL_H) conditions.h \
hard-reg-set.h insn-config.h $(INSN_ATTR_H) $(EXPR_H) output.h \
$(RECOG_H) $(FUNCTION_H) toplev.h $(FLAGS_H) insn-codes.h $(TM_P_H) \
- $(TARGET_H)
+ $(TARGET_H) tm-constrs.h
insn-peep.o : insn-peep.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(REGS_H) output.h insn-config.h $(RECOG_H) except.h \
- $(FUNCTION_H) $(TM_P_H) $(REAL_H)
+ $(FUNCTION_H) $(TM_P_H) $(REAL_H) tm-constrs.h
insn-preds.o : insn-preds.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(RTL_H) $(TREE_H) insn-config.h $(RECOG_H) output.h \
$(FLAGS_H) $(FUNCTION_H) hard-reg-set.h $(RESOURCE_H) $(TM_P_H) \
- toplev.h reload.h $(REGS_H) $(REAL_H)
+ toplev.h reload.h $(REGS_H) $(REAL_H) tm-constrs.h
insn-recog.o : insn-recog.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(RTL_H) insn-config.h $(RECOG_H) output.h $(FLAGS_H) \
$(FUNCTION_H) hard-reg-set.h $(RESOURCE_H) $(TM_P_H) toplev.h \
- reload.h $(REAL_H)
+ reload.h $(REAL_H) tm-constrs.h
# For each of the files generated by running a generator program over
# the machine description, the following pair of static pattern rules
@@ -2783,6 +2783,7 @@ s-modes-m: build/genmodes$(build_exeext)
insn-preds.c: s-preds; @true
tm-preds.h: s-preds-h; @true
+tm-constrs.h: s-constrs-h; @true
s-preds: $(MD_DEPS) build/genpreds$(build_exeext)
$(RUN_GEN) build/genpreds$(build_exeext) $(md_file) > tmp-preds.c
@@ -2794,6 +2795,11 @@ s-preds-h: $(MD_DEPS) build/genpreds$(build_exeext)
$(SHELL) $(srcdir)/../move-if-change tmp-preds.h tm-preds.h
$(STAMP) s-preds-h
+s-constrs-h: $(MD_DEPS) build/genpreds$(build_exeext)
+ $(RUN_GEN) build/genpreds$(build_exeext) -c $(md_file) > tmp-constrs.h
+ $(SHELL) $(srcdir)/../move-if-change tmp-constrs.h tm-constrs.h
+ $(STAMP) s-constrs-h
+
GTFILES = $(srcdir)/input.h $(srcdir)/coretypes.h \
$(CPP_ID_DATA_H) $(host_xm_file_list) \
$(tm_file_list) $(HASHTAB_H) $(SPLAY_TREE_H) $(srcdir)/bitmap.h \
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 699c5ea59cf..5ba4a52d651 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -49,6 +49,7 @@ Boston, MA 02110-1301, USA. */
#include "cgraph.h"
#include "tree-gimple.h"
#include "dwarf2.h"
+#include "tm-constrs.h"
#ifndef CHECK_STACK_LIMIT
#define CHECK_STACK_LIMIT (-1)
diff --git a/gcc/config/rs6000/constraints.md b/gcc/config/rs6000/constraints.md
new file mode 100644
index 00000000000..114ba8ac2eb
--- /dev/null
+++ b/gcc/config/rs6000/constraints.md
@@ -0,0 +1,158 @@
+;; Constraint definitions for RS6000
+;; Copyright (C) 2006 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 2, 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 COPYING. If not, write to
+;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;; Register constraints
+
+(define_register_constraint "f" "TARGET_HARD_FLOAT && TARGET_FPRS
+ ? FLOAT_REGS : NO_REGS"
+ "@internal")
+
+(define_register_constraint "b" "BASE_REGS"
+ "@internal")
+
+(define_register_constraint "h" "SPECIAL_REGS"
+ "@internal")
+
+(define_register_constraint "q" "MQ_REGS"
+ "@internal")
+
+(define_register_constraint "c" "CTR_REGS"
+ "@internal")
+
+(define_register_constraint "l" "LINK_REGS"
+ "@internal")
+
+(define_register_constraint "v" "ALTIVEC_REGS"
+ "@internal")
+
+(define_register_constraint "x" "CR0_REGS"
+ "@internal")
+
+(define_register_constraint "y" "CR_REGS"
+ "@internal")
+
+(define_register_constraint "z" "XER_REGS"
+ "@internal")
+
+;; Integer constraints
+
+(define_constraint "I"
+ "A signed 16-bit constant"
+ (and (match_code "const_int")
+ (match_test "(unsigned HOST_WIDE_INT) (ival + 0x8000) < 0x10000")))
+
+(define_constraint "J"
+ "high-order 16 bits nonzero"
+ (and (match_code "const_int")
+ (match_test "(ival & (~ (unsigned HOST_WIDE_INT) 0xffff0000)) == 0")))
+
+(define_constraint "K"
+ "low-order 16 bits nonzero"
+ (and (match_code "const_int")
+ (match_test "(ival & (~ (HOST_WIDE_INT) 0xffff)) == 0")))
+
+(define_constraint "L"
+ "signed 16-bit constant shifted left 16 bits"
+ (and (match_code "const_int")
+ (match_test "((ival & 0xffff) == 0
+ && (ival >> 31 == -1 || ival >> 31 == 0))")))
+
+(define_constraint "M"
+ "constant greater than 31"
+ (and (match_code "const_int")
+ (match_test "(ival) > 31")))
+
+(define_constraint "N"
+ "positive constant that is an exact power of two"
+ (and (match_code "const_int")
+ (match_test "ival > 0 && exact_log2 (ival) >= 0")))
+
+(define_constraint "O"
+ "constant zero"
+ (and (match_code "const_int")
+ (match_test "ival == 0")))
+
+(define_constraint "P"
+ "constant whose negation is signed 16-bit constant"
+ (and (match_code "const_int")
+ (match_test "(unsigned HOST_WIDE_INT) ((- ival) + 0x8000) < 0x10000")))
+
+;; Floating-point constraints
+
+(define_constraint "G"
+ "Constant that can be copied into GPR with two insns for DF/DI
+ and one for SF."
+ (and (match_code "const_double")
+ (match_test "num_insns_constant (op, mode)
+ == (mode == SFmode ? 1 : 2)")))
+
+(define_constraint "H"
+ "DF/DI constant that takes three insns."
+ (and (match_code "const_double")
+ (match_test "num_insns_constant (op, mode) == 3")))
+
+;; Memory constraints
+
+(define_memory_constraint "Q"
+ "Memory operand that is just an offset from a reg"
+ (and (match_code "mem")
+ (match_test "GET_CODE (XEXP (op, 0)) == REG")))
+
+(define_memory_constraint "Y"
+ "Indexed or word-aligned displacement memory operand"
+ (match_operand 0 "word_offset_memref_operand"))
+
+(define_memory_constraint "Z"
+ "Indexed or indirect memory operand"
+ (match_operand 0 "indexed_or_indirect_operand"))
+
+;; Address constraints
+
+(define_address_constraint "a"
+ "Indexed or indirect address operand"
+ (match_operand 0 "indexed_or_indirect_address"))
+
+(define_constraint "R"
+ "AIX TOC entry"
+ (match_test "legitimate_constant_pool_address_p (op)"))
+
+;; General constraints
+
+(define_constraint "S"
+ "Constant that can be placed into a 64-bit mask operand"
+ (match_operand 0 "mask64_operand"))
+
+(define_constraint "T"
+ "Constant that can be placed into a 32-bit mask operand"
+ (match_operand 0 "mask_operand"))
+
+(define_constraint "U"
+ "V.4 small data reference"
+ (and (match_test "DEFAULT_ABI == ABI_V4")
+ (match_operand 0 "small_data_operand")))
+
+(define_constraint "t"
+ "AND masks that can be performed by two rldic{l,r} insns
+ (but excluding those that could match other constraints of anddi3)"
+ (and (and (and (match_operand 0 "mask64_2_operand")
+ (match_test "(fixed_regs[CR0_REGNO]
+ || !logical_operand (op, DImode))"))
+ (not (match_operand 0 "mask_operand")))
+ (not (match_operand 0 "mask64_operand"))))
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index 8d24d8f74c5..e0486a9b06f 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -63,12 +63,12 @@
;; Return 1 if op is a constant integer that can fit in a D field.
(define_predicate "short_cint_operand"
(and (match_code "const_int")
- (match_test "CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')")))
+ (match_test "satisfies_constraint_I (op)")))
;; Return 1 if op is a constant integer that can fit in an unsigned D field.
(define_predicate "u_short_cint_operand"
(and (match_code "const_int")
- (match_test "CONST_OK_FOR_LETTER_P (INTVAL (op), 'K')")))
+ (match_test "satisfies_constraint_K (op)")))
;; Return 1 if op is a constant integer that cannot fit in a signed D field.
(define_predicate "non_short_cint_operand"
@@ -117,7 +117,7 @@
;; or equal to const, which does not work for zero.
(define_predicate "reg_or_neg_short_operand"
(if_then_else (match_code "const_int")
- (match_test "CONST_OK_FOR_LETTER_P (INTVAL (op), 'P')
+ (match_test "satisfies_constraint_P (op)
&& INTVAL (op) != 0")
(match_operand 0 "gpc_reg_operand")))
@@ -400,15 +400,15 @@
;; as the operand of a `mode' add insn.
(define_predicate "add_operand"
(if_then_else (match_code "const_int")
- (match_test "CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
- || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L')")
+ (match_test "satisfies_constraint_I (op)
+ || satisfies_constraint_L (op)")
(match_operand 0 "gpc_reg_operand")))
;; Return 1 if OP is a constant but not a valid add_operand.
(define_predicate "non_add_cint_operand"
(and (match_code "const_int")
- (match_test "!CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
- && !CONST_OK_FOR_LETTER_P (INTVAL (op), 'L')")))
+ (match_test "!satisfies_constraint_I (op)
+ && !satisfies_constraint_L (op)")))
;; Return 1 if the operand is a constant that can be used as the operand
;; of an OR or XOR.
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index fbe4615fa55..aeecdfe7ce2 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -56,6 +56,7 @@
#include "tree-gimple.h"
#include "intl.h"
#include "params.h"
+#include "tm-constrs.h"
#if TARGET_XCOFF
#include "xcoffout.h" /* get declarations of xcoff_*_section_name */
#endif
@@ -1992,11 +1993,11 @@ int
num_insns_constant_wide (HOST_WIDE_INT value)
{
/* signed constant loadable with {cal|addi} */
- if (CONST_OK_FOR_LETTER_P (value, 'I'))
+ if (satisfies_constraint_I (GEN_INT (value)))
return 1;
/* constant loadable with {cau|addis} */
- else if (CONST_OK_FOR_LETTER_P (value, 'L'))
+ else if (satisfies_constraint_L (GEN_INT (value)))
return 1;
#if HOST_BITS_PER_WIDE_INT == 64
@@ -18515,19 +18516,21 @@ rs6000_rtx_costs (rtx x, int code, int outer_code, int *total)
if (((outer_code == SET
|| outer_code == PLUS
|| outer_code == MINUS)
- && (CONST_OK_FOR_LETTER_P (INTVAL (x), 'I')
- || CONST_OK_FOR_LETTER_P (INTVAL (x), 'L')))
+ && (satisfies_constraint_I (x)
+ || satisfies_constraint_L (x)))
|| (outer_code == AND
- && (CONST_OK_FOR_LETTER_P (INTVAL (x), 'K')
- || (CONST_OK_FOR_LETTER_P (INTVAL (x),
- mode == SImode ? 'L' : 'J'))
+ && (satisfies_constraint_K (x)
+ || (mode == SImode
+ ? satisfies_constraint_L (x)
+ : satisfies_constraint_J (x))
|| mask_operand (x, mode)
|| (mode == DImode
&& mask64_operand (x, DImode))))
|| ((outer_code == IOR || outer_code == XOR)
- && (CONST_OK_FOR_LETTER_P (INTVAL (x), 'K')
- || (CONST_OK_FOR_LETTER_P (INTVAL (x),
- mode == SImode ? 'L' : 'J'))))
+ && (satisfies_constraint_K (x)
+ || (mode == SImode
+ ? satisfies_constraint_L (x)
+ : satisfies_constraint_J (x))))
|| outer_code == ASHIFT
|| outer_code == ASHIFTRT
|| outer_code == LSHIFTRT
@@ -18535,22 +18538,23 @@ rs6000_rtx_costs (rtx x, int code, int outer_code, int *total)
|| outer_code == ROTATERT
|| outer_code == ZERO_EXTRACT
|| (outer_code == MULT
- && CONST_OK_FOR_LETTER_P (INTVAL (x), 'I'))
+ && satisfies_constraint_I (x))
|| ((outer_code == DIV || outer_code == UDIV
|| outer_code == MOD || outer_code == UMOD)
&& exact_log2 (INTVAL (x)) >= 0)
|| (outer_code == COMPARE
- && (CONST_OK_FOR_LETTER_P (INTVAL (x), 'I')
- || CONST_OK_FOR_LETTER_P (INTVAL (x), 'K')))
+ && (satisfies_constraint_I (x)
+ || satisfies_constraint_K (x)))
|| (outer_code == EQ
- && (CONST_OK_FOR_LETTER_P (INTVAL (x), 'I')
- || CONST_OK_FOR_LETTER_P (INTVAL (x), 'K')
- || (CONST_OK_FOR_LETTER_P (INTVAL (x),
- mode == SImode ? 'L' : 'J'))))
+ && (satisfies_constraint_I (x)
+ || satisfies_constraint_K (x)
+ || (mode == SImode
+ ? satisfies_constraint_L (x)
+ : satisfies_constraint_J (x))))
|| (outer_code == GTU
- && CONST_OK_FOR_LETTER_P (INTVAL (x), 'I'))
+ && satisfies_constraint_I (x))
|| (outer_code == LTU
- && CONST_OK_FOR_LETTER_P (INTVAL (x), 'P')))
+ && satisfies_constraint_P (x)))
{
*total = 0;
return true;
@@ -18573,8 +18577,8 @@ rs6000_rtx_costs (rtx x, int code, int outer_code, int *total)
case CONST_DOUBLE:
if (mode == DImode
&& ((outer_code == AND
- && (CONST_OK_FOR_LETTER_P (INTVAL (x), 'K')
- || CONST_OK_FOR_LETTER_P (INTVAL (x), 'L')
+ && (satisfies_constraint_K (x)
+ || satisfies_constraint_L (x)
|| mask_operand (x, DImode)
|| mask64_operand (x, DImode)))
|| ((outer_code == IOR || outer_code == XOR)
@@ -18664,7 +18668,7 @@ rs6000_rtx_costs (rtx x, int code, int outer_code, int *total)
case MULT:
if (GET_CODE (XEXP (x, 1)) == CONST_INT
- && CONST_OK_FOR_LETTER_P (INTVAL (XEXP (x, 1)), 'I'))
+ && satisfies_constraint_I (XEXP (x, 1)))
{
if (INTVAL (XEXP (x, 1)) >= -256
&& INTVAL (XEXP (x, 1)) <= 255)
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index bfa7074247e..b31d4372f95 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -1057,107 +1057,6 @@ enum reg_class
#define INDEX_REG_CLASS GENERAL_REGS
#define BASE_REG_CLASS BASE_REGS
-/* Get reg_class from a letter such as appears in the machine description. */
-
-#define REG_CLASS_FROM_LETTER(C) \
- ((C) == 'f' ? ((TARGET_HARD_FLOAT && TARGET_FPRS) ? FLOAT_REGS : NO_REGS) \
- : (C) == 'b' ? BASE_REGS \
- : (C) == 'h' ? SPECIAL_REGS \
- : (C) == 'q' ? MQ_REGS \
- : (C) == 'c' ? CTR_REGS \
- : (C) == 'l' ? LINK_REGS \
- : (C) == 'v' ? ALTIVEC_REGS \
- : (C) == 'x' ? CR0_REGS \
- : (C) == 'y' ? CR_REGS \
- : (C) == 'z' ? XER_REGS \
- : NO_REGS)
-
-/* The letters I, J, K, L, M, N, and P in a register constraint string
- can be used to stand for particular ranges of immediate operands.
- 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 a signed 16-bit constant
- `J' is a constant with only the high-order 16 bits nonzero
- `K' is a constant with only the low-order 16 bits nonzero
- `L' is a signed 16-bit constant shifted left 16 bits
- `M' is a constant that is greater than 31
- `N' is a positive constant that is an exact power of two
- `O' is the constant zero
- `P' is a constant whose negation is a signed 16-bit constant */
-
-#define CONST_OK_FOR_LETTER_P(VALUE, C) \
- ( (C) == 'I' ? (unsigned HOST_WIDE_INT) ((VALUE) + 0x8000) < 0x10000 \
- : (C) == 'J' ? ((VALUE) & (~ (unsigned HOST_WIDE_INT) 0xffff0000)) == 0 \
- : (C) == 'K' ? ((VALUE) & (~ (HOST_WIDE_INT) 0xffff)) == 0 \
- : (C) == 'L' ? (((VALUE) & 0xffff) == 0 \
- && ((VALUE) >> 31 == -1 || (VALUE) >> 31 == 0)) \
- : (C) == 'M' ? (VALUE) > 31 \
- : (C) == 'N' ? (VALUE) > 0 && exact_log2 (VALUE) >= 0 \
- : (C) == 'O' ? (VALUE) == 0 \
- : (C) == 'P' ? (unsigned HOST_WIDE_INT) ((- (VALUE)) + 0x8000) < 0x10000 \
- : 0)
-
-/* Similar, but for floating constants, and defining letters G and H.
- Here VALUE is the CONST_DOUBLE rtx itself.
-
- We flag for special constants when we can copy the constant into
- a general register in two insns for DF/DI and one insn for SF.
-
- 'H' is used for DI/DF constants that take 3 insns. */
-
-#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
- ( (C) == 'G' ? (num_insns_constant (VALUE, GET_MODE (VALUE)) \
- == ((GET_MODE (VALUE) == SFmode) ? 1 : 2)) \
- : (C) == 'H' ? (num_insns_constant (VALUE, GET_MODE (VALUE)) == 3) \
- : 0)
-
-/* Optional extra constraints for this machine.
-
- 'Q' means that is a memory operand that is just an offset from a reg.
- 'R' is for AIX TOC entries.
- 'S' is a constant that can be placed into a 64-bit mask operand.
- 'T' is a constant that can be placed into a 32-bit mask operand.
- 'U' is for V.4 small data references.
- 'W' is a vector constant that can be easily generated (no mem refs).
- 'Y' is an indexed or word-aligned displacement memory operand.
- 'Z' is an indexed or indirect memory operand.
- 'a' is an indexed or indirect address operand.
- 't' is for AND masks that can be performed by two rldic{l,r} insns
- (but excluding those that could match other constraints of anddi3.) */
-
-#define EXTRA_CONSTRAINT(OP, C) \
- ((C) == 'Q' ? GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == REG \
- : (C) == 'R' ? legitimate_constant_pool_address_p (OP) \
- : (C) == 'S' ? mask64_operand (OP, DImode) \
- : (C) == 'T' ? mask_operand (OP, GET_MODE (OP)) \
- : (C) == 'U' ? (DEFAULT_ABI == ABI_V4 \
- && small_data_operand (OP, GET_MODE (OP))) \
- : (C) == 't' ? (mask64_2_operand (OP, DImode) \
- && (fixed_regs[CR0_REGNO] \
- || !logical_operand (OP, DImode)) \
- && !mask_operand (OP, DImode) \
- && !mask64_operand (OP, DImode)) \
- : (C) == 'W' ? (easy_vector_constant (OP, GET_MODE (OP))) \
- : (C) == 'Y' ? (word_offset_memref_operand (OP, GET_MODE (OP))) \
- : (C) == 'Z' ? (indexed_or_indirect_operand (OP, GET_MODE (OP))) \
- : (C) == 'a' ? (indexed_or_indirect_address (OP, GET_MODE (OP))) \
- : 0)
-
-/* Define which constraints are memory constraints. Tell reload
- that any memory address can be reloaded by copying the
- memory address into a base register if required. */
-
-#define EXTRA_MEMORY_CONSTRAINT(C, STR) \
- ((C) == 'Q' || (C) == 'Y' || (C) == 'Z')
-
-/* Define which constraints should be treated like address constraints
- by the reload pass. */
-
-#define EXTRA_ADDRESS_CONSTRAINT(C, STR) \
- ((C) == 'a')
-
/* 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
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 06670d2ac36..1cee3c80919 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -126,6 +126,7 @@
(include "power5.md")
(include "predicates.md")
+(include "constraints.md")
(include "darwin.md")
@@ -1434,7 +1435,6 @@
(plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
(match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
""
- "
{
if (<MODE>mode == DImode && ! TARGET_POWERPC64)
{
@@ -1451,7 +1451,7 @@
HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
- if (<MODE>mode == DImode && !CONST_OK_FOR_LETTER_P (rest, 'L'))
+ if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
FAIL;
/* The ordering here is important for the prolog expander.
@@ -1461,7 +1461,7 @@
emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
DONE;
}
-}")
+})
;; Discourage ai/addic because of carry but provide it in an alternative
;; allowing register zero as source.
@@ -1559,14 +1559,13 @@
""
[(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
(set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
-"
{
HOST_WIDE_INT val = INTVAL (operands[2]);
HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
operands[4] = GEN_INT (low);
- if (<MODE>mode == SImode || CONST_OK_FOR_LETTER_P (rest, 'L'))
+ if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
operands[3] = GEN_INT (rest);
else if (! no_new_pseudos)
{
@@ -1577,7 +1576,7 @@
}
else
FAIL;
-}")
+})
(define_insn "one_cmpl<mode>2"
[(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
diff --git a/gcc/genemit.c b/gcc/genemit.c
index 7c743005477..79db84e7b30 100644
--- a/gcc/genemit.c
+++ b/gcc/genemit.c
@@ -844,6 +844,7 @@ from the machine description file `md'. */\n\n");
printf ("#include \"resource.h\"\n");
printf ("#include \"reload.h\"\n");
printf ("#include \"toplev.h\"\n");
+ printf ("#include \"tm-constrs.h\"\n");
printf ("#include \"ggc.h\"\n\n");
printf ("#include \"basic-block.h\"\n\n");
printf ("#define FAIL return (end_sequence (), _val)\n");
diff --git a/gcc/genoutput.c b/gcc/genoutput.c
index 4eac5818729..ddece1c2309 100644
--- a/gcc/genoutput.c
+++ b/gcc/genoutput.c
@@ -244,6 +244,7 @@ output_prologue (void)
printf ("#include \"toplev.h\"\n");
printf ("#include \"output.h\"\n");
printf ("#include \"target.h\"\n");
+ printf ("#include \"tm-constrs.h\"\n");
}
static void
diff --git a/gcc/genpeep.c b/gcc/genpeep.c
index ad4b5a11351..5c5804b6fad 100644
--- a/gcc/genpeep.c
+++ b/gcc/genpeep.c
@@ -376,8 +376,9 @@ from the machine description file `md'. */\n\n");
printf ("#include \"output.h\"\n");
printf ("#include \"real.h\"\n");
printf ("#include \"recog.h\"\n");
- printf ("#include \"except.h\"\n\n");
- printf ("#include \"function.h\"\n\n");
+ printf ("#include \"except.h\"\n");
+ printf ("#include \"function.h\"\n");
+ printf ("#include \"tm-constrs.h\"\n\n");
printf ("#ifdef HAVE_peephole\n");
printf ("extern rtx peep_operand[];\n\n");
diff --git a/gcc/genpreds.c b/gcc/genpreds.c
index 425e7253f09..5289ebb0445 100644
--- a/gcc/genpreds.c
+++ b/gcc/genpreds.c
@@ -947,13 +947,19 @@ write_regclass_for_constraint (void)
/* Write out the functions which compute whether a given value matches
a given non-register constraint. */
static void
-write_satisfies_constraint_fns (void)
+write_tm_constrs_h (void)
{
struct constraint_data *c;
+ struct pred_data *p;
+
+ printf ("\
+/* Generated automatically by the program '%s'\n\
+ from the machine description file '%s'. */\n\n", progname, in_fname);
+
+ puts ("\
+#ifndef GCC_TM_CONSTRS_H\n\
+#define GCC_TM_CONSTRS_H\n");
- /* A fair number of places include tm_p.h without including rtl.h. */
- puts ("#ifdef GCC_RTL_H\n");
-
FOR_ALL_CONSTRAINTS (c)
if (!c->is_register)
{
@@ -995,8 +1001,7 @@ write_satisfies_constraint_fns (void)
write_predicate_expr (c->exp);
fputs (";\n}\n", stdout);
}
-
- puts ("\n#endif /* rtl.h visible */\n");
+ puts ("#endif /* tm-constrs.h */");
}
/* Write out the wrapper function, constraint_satisfied_p, that maps
@@ -1172,10 +1177,6 @@ write_tm_preds_h (void)
"insn_extra_address_constraint (lookup_constraint (s_))\n");
else
puts ("#define EXTRA_ADDRESS_CONSTRAINT(c_,s_) false\n");
-
- if (have_const_int_constraints || have_const_dbl_constraints
- || have_extra_constraints)
- write_satisfies_constraint_fns ();
}
puts ("#endif /* tm-preds.h */");
@@ -1216,7 +1217,8 @@ write_insn_preds_c (void)
#include \"resource.h\"\n\
#include \"toplev.h\"\n\
#include \"reload.h\"\n\
-#include \"regs.h\"\n");
+#include \"regs.h\"\n\
+#include \"tm-constrs.h\"\n");
FOR_ALL_PREDICATES (p)
write_one_predicate_function (p);
@@ -1242,6 +1244,8 @@ write_insn_preds_c (void)
/* Argument parsing. */
static bool gen_header;
+static bool gen_constrs;
+
static bool
parse_option (const char *opt)
{
@@ -1250,6 +1254,11 @@ parse_option (const char *opt)
gen_header = true;
return 1;
}
+ else if (!strcmp (opt, "-c"))
+ {
+ gen_constrs = true;
+ return 1;
+ }
else
return 0;
}
@@ -1291,6 +1300,8 @@ main (int argc, char **argv)
if (gen_header)
write_tm_preds_h ();
+ else if (gen_constrs)
+ write_tm_constrs_h ();
else
write_insn_preds_c ();
diff --git a/gcc/genrecog.c b/gcc/genrecog.c
index a72243c403f..a65137ab377 100644
--- a/gcc/genrecog.c
+++ b/gcc/genrecog.c
@@ -2496,6 +2496,7 @@ write_header (void)
#include \"resource.h\"\n\
#include \"toplev.h\"\n\
#include \"reload.h\"\n\
+#include \"tm-constrs.h\"\n\
\n");
puts ("\n\