This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: define_constraints patch, re-revised
Appended is an updated patch that creates a new header file
tm-constrs.h containing the satisfies_constraint_* static inline
functions.
The patch updates the dependencies using configure.ac
tm_p_file_list, although it could be done in Makefile.in TM_P_H line. I
am not sure which is better.
How do we proceed?
David
* genemit.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.
* Makefile.in (STAGECOPYSTUFF): Add tm-constrs.h.
(tm-constsr.h): New target.
(s-constrs-h): New target.
* configure.ac (tm_p_file): Add tm-constrs.h.
Only add to tm_p_file_list.
* 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.
Index: genemit.c
===================================================================
*** genemit.c (revision 112215)
--- genemit.c (working copy)
*************** from the machine description file `md'.
*** 844,849 ****
--- 844,850 ----
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");
Index: genpreds.c
===================================================================
*** genpreds.c (revision 112225)
--- genpreds.c (working copy)
*************** write_regclass_for_constraint (void)
*** 947,959 ****
/* Write out the functions which compute whether a given value matches
a given non-register constraint. */
static void
! write_satisfies_constraint_fns (void)
{
struct constraint_data *c;
- /* 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)
{
--- 947,972 ----
/* Write out the functions which compute whether a given value matches
a given non-register constraint. */
static 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\
+ \n\
+ #ifdef HAVE_MACHINE_MODES");
+
+ FOR_ALL_PREDICATES (p)
+ printf ("extern int %s (rtx, enum machine_mode);\n", p->name);
+
+ puts ("#endif /* HAVE_MACHINE_MODES */\n");
FOR_ALL_CONSTRAINTS (c)
if (!c->is_register)
{
*************** write_satisfies_constraint_fns (void)
*** 995,1002 ****
write_predicate_expr (c->exp);
fputs (";\n}\n", stdout);
}
!
! puts ("\n#endif /* rtl.h visible */\n");
}
/* Write out the wrapper function, constraint_satisfied_p, that maps
--- 1008,1014 ----
write_predicate_expr (c->exp);
fputs (";\n}\n", stdout);
}
! puts ("#endif /* tm-constrs.h */");
}
/* Write out the wrapper function, constraint_satisfied_p, that maps
*************** write_tm_preds_h (void)
*** 1172,1181 ****
"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 */");
--- 1184,1189 ----
*************** write_insn_preds_c (void)
*** 1216,1222 ****
#include \"resource.h\"\n\
#include \"toplev.h\"\n\
#include \"reload.h\"\n\
! #include \"regs.h\"\n");
FOR_ALL_PREDICATES (p)
write_one_predicate_function (p);
--- 1224,1231 ----
#include \"resource.h\"\n\
#include \"toplev.h\"\n\
#include \"reload.h\"\n\
! #include \"regs.h\"\n\
! #include \"tm-constrs.h\"\n");
FOR_ALL_PREDICATES (p)
write_one_predicate_function (p);
*************** write_insn_preds_c (void)
*** 1242,1247 ****
--- 1251,1258 ----
/* Argument parsing. */
static bool gen_header;
+ static bool gen_constrs;
+
static bool
parse_option (const char *opt)
{
*************** parse_option (const char *opt)
*** 1250,1255 ****
--- 1261,1271 ----
gen_header = true;
return 1;
}
+ else if (!strcmp (opt, "-c"))
+ {
+ gen_constrs = true;
+ return 1;
+ }
else
return 0;
}
*************** main (int argc, char **argv)
*** 1291,1296 ****
--- 1307,1317 ----
if (gen_header)
write_tm_preds_h ();
+ else if (gen_constrs
+ && (have_const_int_constraints
+ || have_const_dbl_constraints
+ || have_extra_constraints))
+ write_tm_constrs_h ();
else
write_insn_preds_c ();
Index: Makefile.in
===================================================================
*** Makefile.in (revision 112215)
--- Makefile.in (working copy)
*************** BACKEND = main.o @TREEBROWSER@ libbacken
*** 1016,1022 ****
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 \
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
--- 1016,1022 ----
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-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
*************** s-modes-m: build/genmodes$(build_exeext)
*** 2782,2787 ****
--- 2782,2788 ----
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
*************** s-preds-h: $(MD_DEPS) build/genpreds$(bu
*** 2792,2797 ****
--- 2793,2803 ----
$(RUN_GEN) build/genpreds$(build_exeext) -h $(md_file) > tmp-preds.h
$(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) \
Index: configure.ac
===================================================================
*** configure.ac (revision 112215)
--- configure.ac (working copy)
*************** fi
*** 1454,1460 ****
AC_SUBST(build_subdir)
tm_file="${tm_file} defaults.h"
! tm_p_file="${tm_p_file} tm-preds.h"
host_xm_file="auto-host.h ansidecl.h ${host_xm_file}"
build_xm_file="${build_auto} ansidecl.h ${build_xm_file}"
# We don't want ansidecl.h in target files, write code there in ISO/GNU C.
--- 1454,1460 ----
AC_SUBST(build_subdir)
tm_file="${tm_file} defaults.h"
! tm_p_file="${tm_p_file} tm-preds.h tm-constrs.h"
host_xm_file="auto-host.h ansidecl.h ${host_xm_file}"
build_xm_file="${build_auto} ansidecl.h ${build_xm_file}"
# We don't want ansidecl.h in target files, write code there in ISO/GNU C.
*************** for f in $tm_p_file; do
*** 1614,1619 ****
--- 1614,1622 ----
tm-preds.h )
tm_p_file_list="${tm_p_file_list} $f"
tm_p_include_list="${tm_p_include_list} $f"
+ ;;
+ tm-constrs.h )
+ tm_p_file_list="${tm_p_file_list} $f"
;;
* )
tm_p_file_list="${tm_p_file_list} \$(srcdir)/config/$f"
Index: config/rs6000/rs6000.c
===================================================================
*** config/rs6000/rs6000.c (revision 112215)
--- config/rs6000/rs6000.c (working copy)
***************
*** 56,61 ****
--- 56,62 ----
#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
*************** int
*** 1991,2001 ****
num_insns_constant_wide (HOST_WIDE_INT value)
{
/* signed constant loadable with {cal|addi} */
! if (CONST_OK_FOR_LETTER_P (value, 'I'))
return 1;
/* constant loadable with {cau|addis} */
! else if (CONST_OK_FOR_LETTER_P (value, 'L'))
return 1;
#if HOST_BITS_PER_WIDE_INT == 64
--- 1992,2002 ----
num_insns_constant_wide (HOST_WIDE_INT value)
{
/* signed constant loadable with {cal|addi} */
! if (satisfies_constraint_I (GEN_INT (value)))
return 1;
/* constant loadable with {cau|addis} */
! else if (satisfies_constraint_L (GEN_INT (value)))
return 1;
#if HOST_BITS_PER_WIDE_INT == 64
*************** rs6000_rtx_costs (rtx x, int code, int o
*** 18487,18505 ****
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')))
|| (outer_code == AND
! && (CONST_OK_FOR_LETTER_P (INTVAL (x), 'K')
! || (CONST_OK_FOR_LETTER_P (INTVAL (x),
! mode == SImode ? 'L' : 'J'))
|| 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'))))
|| outer_code == ASHIFT
|| outer_code == ASHIFTRT
|| outer_code == LSHIFTRT
--- 18488,18508 ----
if (((outer_code == SET
|| outer_code == PLUS
|| outer_code == MINUS)
! && (satisfies_constraint_I (x)
! || satisfies_constraint_L (x)))
|| (outer_code == AND
! && (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)
! && (satisfies_constraint_K (x)
! || (mode == SImode
! ? satisfies_constraint_L (x)
! : satisfies_constraint_J (x))))
|| outer_code == ASHIFT
|| outer_code == ASHIFTRT
|| outer_code == LSHIFTRT
*************** rs6000_rtx_costs (rtx x, int code, int o
*** 18507,18528 ****
|| outer_code == ROTATERT
|| outer_code == ZERO_EXTRACT
|| (outer_code == MULT
! && CONST_OK_FOR_LETTER_P (INTVAL (x), 'I'))
|| ((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')))
|| (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'))))
|| (outer_code == GTU
! && CONST_OK_FOR_LETTER_P (INTVAL (x), 'I'))
|| (outer_code == LTU
! && CONST_OK_FOR_LETTER_P (INTVAL (x), 'P')))
{
*total = 0;
return true;
--- 18510,18532 ----
|| outer_code == ROTATERT
|| outer_code == ZERO_EXTRACT
|| (outer_code == MULT
! && satisfies_constraint_I (x))
|| ((outer_code == DIV || outer_code == UDIV
|| outer_code == MOD || outer_code == UMOD)
&& exact_log2 (INTVAL (x)) >= 0)
|| (outer_code == COMPARE
! && (satisfies_constraint_I (x)
! || satisfies_constraint_K (x)))
|| (outer_code == EQ
! && (satisfies_constraint_I (x)
! || satisfies_constraint_K (x)
! || (mode == SImode
! ? satisfies_constraint_L (x)
! : satisfies_constraint_J (x))))
|| (outer_code == GTU
! && satisfies_constraint_I (x))
|| (outer_code == LTU
! && satisfies_constraint_P (x)))
{
*total = 0;
return true;
*************** rs6000_rtx_costs (rtx x, int code, int o
*** 18545,18552 ****
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')
|| mask_operand (x, DImode)
|| mask64_operand (x, DImode)))
|| ((outer_code == IOR || outer_code == XOR)
--- 18549,18556 ----
case CONST_DOUBLE:
if (mode == DImode
&& ((outer_code == AND
! && (satisfies_constraint_K (x)
! || satisfies_constraint_L (x)
|| mask_operand (x, DImode)
|| mask64_operand (x, DImode)))
|| ((outer_code == IOR || outer_code == XOR)
*************** rs6000_rtx_costs (rtx x, int code, int o
*** 18636,18642 ****
case MULT:
if (GET_CODE (XEXP (x, 1)) == CONST_INT
! && CONST_OK_FOR_LETTER_P (INTVAL (XEXP (x, 1)), 'I'))
{
if (INTVAL (XEXP (x, 1)) >= -256
&& INTVAL (XEXP (x, 1)) <= 255)
--- 18640,18646 ----
case MULT:
if (GET_CODE (XEXP (x, 1)) == CONST_INT
! && satisfies_constraint_I (XEXP (x, 1)))
{
if (INTVAL (XEXP (x, 1)) >= -256
&& INTVAL (XEXP (x, 1)) <= 255)
Index: config/rs6000/rs6000.h
===================================================================
*** config/rs6000/rs6000.h (revision 112215)
--- config/rs6000/rs6000.h (working copy)
*************** enum reg_class
*** 1057,1163 ****
#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
--- 1057,1062 ----
Index: config/rs6000/predicates.md
===================================================================
*** config/rs6000/predicates.md (revision 112215)
--- config/rs6000/predicates.md (working copy)
***************
*** 63,74 ****
;; 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')")))
;; 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')")))
;; Return 1 if op is a constant integer that cannot fit in a signed D field.
(define_predicate "non_short_cint_operand"
--- 63,74 ----
;; 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 "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 "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,123 ****
;; 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')
&& INTVAL (op) != 0")
(match_operand 0 "gpc_reg_operand")))
--- 117,123 ----
;; 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 "satisfies_constraint_P (op)
&& INTVAL (op) != 0")
(match_operand 0 "gpc_reg_operand")))
***************
*** 400,414 ****
;; 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_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')")))
;; Return 1 if the operand is a constant that can be used as the operand
;; of an OR or XOR.
--- 400,414 ----
;; as the operand of a `mode' add insn.
(define_predicate "add_operand"
(if_then_else (match_code "const_int")
! (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 "!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.
Index: config/rs6000/rs6000.md
===================================================================
*** config/rs6000/rs6000.md (revision 112215)
--- config/rs6000/rs6000.md (working copy)
***************
*** 126,131 ****
--- 126,132 ----
(include "power5.md")
(include "predicates.md")
+ (include "constraints.md")
(include "darwin.md")
***************
*** 1434,1440 ****
(plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
(match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
""
- "
{
if (<MODE>mode == DImode && ! TARGET_POWERPC64)
{
--- 1435,1440 ----
***************
*** 1451,1457 ****
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'))
FAIL;
/* The ordering here is important for the prolog expander.
--- 1451,1457 ----
HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
! if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
FAIL;
/* The ordering here is important for the prolog expander.
***************
*** 1461,1467 ****
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.
--- 1461,1467 ----
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,1572 ****
""
[(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'))
operands[3] = GEN_INT (rest);
else if (! no_new_pseudos)
{
--- 1559,1571 ----
""
[(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 || satisfies_constraint_L (GEN_INT (rest)))
operands[3] = GEN_INT (rest);
else if (! no_new_pseudos)
{
***************
*** 1577,1583 ****
}
else
FAIL;
! }")
(define_insn "one_cmpl<mode>2"
[(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
--- 1576,1582 ----
}
else
FAIL;
! })
(define_insn "one_cmpl<mode>2"
[(set (match_operand:GPR 0 "gpc_reg_operand" "=r")