Commit 777e635f by Richard Sandiford Committed by Richard Sandiford

system.h (REG_CLASS_FROM_CONSTRAINT): Poison.

gcc/
	* system.h (REG_CLASS_FROM_CONSTRAINT): Poison.
	(REG_CLASS_FOR_CONSTRAINT, EXTRA_CONSTRAINT_STR): Likewise.
	(EXTRA_MEMORY_CONSTRAINT, EXTRA_ADDRESS_CONSTRAINT): Likewise.
	* genpreds.c (print_type_tree): New function.
	(write_tm_preds_h): Remove REG_CLASS_FROM_CONSTRAINT,
	REG_CLASS_FOR_CONSTRAINT, EXTRA_MEMORY_CONSTRAINT,
	EXTRA_ADDRESS_CONSTRAINT and EXTRA_CONSTRAINT_STR.
	Write out enum constraint_type and get_constraint_type.
	* lra-constraints.c (satisfies_memory_constraint_p): Take a
	constraint_num rather than a constraint string.
	(satisfies_address_constraint_p): Likewise.
	(reg_class_from_constraints): Avoid old constraint macros.
	(process_alt_operands, process_address_1): Likewise.
	(curr_insn_transform): Likewise.
	* ira-costs.c (record_reg_classes): Likewise.
	(record_operand_costs): Likewise.
	* ira-lives.c (single_reg_class): Likewise.
	(ira_implicitly_set_insn_hard_regs): Likewise.
	* ira.c (ira_setup_alts, ira_get_dup_out_num): Likewise.
	* postreload.c (reload_cse_simplify_operands): Likewise.
	* recog.c (asm_operand_ok, preprocess_constraints): Likewise.
	(constrain_operands, peep2_find_free_register): Likewise.
	* reload.c (push_secondary_reload, scratch_reload_class): Likewise.
	(find_reloads, alternative_allows_const_pool_ref): Likewise.
	* reload1.c (maybe_fix_stack_asms): Likewise.
	* stmt.c (parse_output_constraint, parse_input_constraint): Likewise.
	* targhooks.c (default_secondary_reload): Likewise.
	* config/m32c/m32c.c (m32c_matches_constraint_p): Avoid reference
	to EXTRA_CONSTRAINT_STR.
	* config/sparc/constraints.md (U): Likewise REG_CLASS_FROM_CONSTRAINT.

From-SVN: r211471
parent 9e6b7874
2014-06-11 Richard Sandiford <rdsandiford@googlemail.com> 2014-06-11 Richard Sandiford <rdsandiford@googlemail.com>
* system.h (REG_CLASS_FROM_CONSTRAINT): Poison.
(REG_CLASS_FOR_CONSTRAINT, EXTRA_CONSTRAINT_STR): Likewise.
(EXTRA_MEMORY_CONSTRAINT, EXTRA_ADDRESS_CONSTRAINT): Likewise.
* genpreds.c (print_type_tree): New function.
(write_tm_preds_h): Remove REG_CLASS_FROM_CONSTRAINT,
REG_CLASS_FOR_CONSTRAINT, EXTRA_MEMORY_CONSTRAINT,
EXTRA_ADDRESS_CONSTRAINT and EXTRA_CONSTRAINT_STR.
Write out enum constraint_type and get_constraint_type.
* lra-constraints.c (satisfies_memory_constraint_p): Take a
constraint_num rather than a constraint string.
(satisfies_address_constraint_p): Likewise.
(reg_class_from_constraints): Avoid old constraint macros.
(process_alt_operands, process_address_1): Likewise.
(curr_insn_transform): Likewise.
* ira-costs.c (record_reg_classes): Likewise.
(record_operand_costs): Likewise.
* ira-lives.c (single_reg_class): Likewise.
(ira_implicitly_set_insn_hard_regs): Likewise.
* ira.c (ira_setup_alts, ira_get_dup_out_num): Likewise.
* postreload.c (reload_cse_simplify_operands): Likewise.
* recog.c (asm_operand_ok, preprocess_constraints): Likewise.
(constrain_operands, peep2_find_free_register): Likewise.
* reload.c (push_secondary_reload, scratch_reload_class): Likewise.
(find_reloads, alternative_allows_const_pool_ref): Likewise.
* reload1.c (maybe_fix_stack_asms): Likewise.
* stmt.c (parse_output_constraint, parse_input_constraint): Likewise.
* targhooks.c (default_secondary_reload): Likewise.
* config/m32c/m32c.c (m32c_matches_constraint_p): Avoid reference
to EXTRA_CONSTRAINT_STR.
* config/sparc/constraints.md (U): Likewise REG_CLASS_FROM_CONSTRAINT.
2014-06-11 Richard Sandiford <rdsandiford@googlemail.com>
* genpreds.c (write_constraint_satisfied_p_1): Replace with... * genpreds.c (write_constraint_satisfied_p_1): Replace with...
(write_constraint_satisfied_p_array): ...this new function. (write_constraint_satisfied_p_array): ...this new function.
(write_tm_preds_h): Replace write_constraint_satisfied_p_1 with (write_tm_preds_h): Replace write_constraint_satisfied_p_1 with
......
...@@ -854,7 +854,7 @@ m32c_cannot_change_mode_class (enum machine_mode from, ...@@ -854,7 +854,7 @@ m32c_cannot_change_mode_class (enum machine_mode from,
#define A0_OR_PSEUDO(x) (IS_REG(x, A0_REGNO) || REGNO (x) >= FIRST_PSEUDO_REGISTER) #define A0_OR_PSEUDO(x) (IS_REG(x, A0_REGNO) || REGNO (x) >= FIRST_PSEUDO_REGISTER)
/* Implements EXTRA_CONSTRAINT_STR (see next function too). 'S' is /* Implements matching for constraints (see next function too). 'S' is
for memory constraints, plus "Rpa" for PARALLEL rtx's we use for for memory constraints, plus "Rpa" for PARALLEL rtx's we use for
call return values. */ call return values. */
bool bool
......
...@@ -171,7 +171,7 @@ ...@@ -171,7 +171,7 @@
;; define_register_constraint would. This currently means that we cannot ;; define_register_constraint would. This currently means that we cannot
;; use LRA on Sparc, since the constraint processing of LRA really depends ;; use LRA on Sparc, since the constraint processing of LRA really depends
;; upon whether an extra constraint is for registers or not. It uses ;; upon whether an extra constraint is for registers or not. It uses
;; REG_CLASS_FROM_CONSTRAINT, and checks it against NO_REGS. ;; reg_class_for_constraint, and checks it against NO_REGS.
(define_constraint "U" (define_constraint "U"
"Pseudo-register or hard even-numbered integer register" "Pseudo-register or hard even-numbered integer register"
(and (match_test "TARGET_ARCH32") (and (match_test "TARGET_ARCH32")
......
...@@ -1232,6 +1232,33 @@ write_range_function (const char *name, unsigned int start, unsigned int end) ...@@ -1232,6 +1232,33 @@ write_range_function (const char *name, unsigned int start, unsigned int end)
"}\n\n", name); "}\n\n", name);
} }
/* VEC is a list of key/value pairs, with the keys being lower bounds
of a range. Output a decision tree that handles the keys covered by
[VEC[START], VEC[END]), returning FALLBACK for keys lower then VEC[START]'s.
INDENT is the number of spaces to indent the code. */
static void
print_type_tree (const vec <std::pair <unsigned int, const char *> > &vec,
unsigned int start, unsigned int end, const char *fallback,
unsigned int indent)
{
while (start < end)
{
unsigned int mid = (start + end) / 2;
printf ("%*sif (c >= CONSTRAINT_%s)\n",
indent, "", enum_order[vec[mid].first]->c_name);
if (mid + 1 == end)
print_type_tree (vec, mid + 1, end, vec[mid].second, indent + 2);
else
{
printf ("%*s{\n", indent + 2, "");
print_type_tree (vec, mid + 1, end, vec[mid].second, indent + 4);
printf ("%*s}\n", indent + 2, "");
}
end = mid;
}
printf ("%*sreturn %s;\n", indent, "", fallback);
}
/* Write tm-preds.h. Unfortunately, it is impossible to forward-declare /* Write tm-preds.h. Unfortunately, it is impossible to forward-declare
an enumeration in portable C, so we have to condition all these an enumeration in portable C, so we have to condition all these
prototypes on HAVE_MACHINE_MODES. */ prototypes on HAVE_MACHINE_MODES. */
...@@ -1321,21 +1348,13 @@ write_tm_preds_h (void) ...@@ -1321,21 +1348,13 @@ write_tm_preds_h (void)
" if (insn_extra_register_constraint (c))\n" " if (insn_extra_register_constraint (c))\n"
" return reg_class_for_constraint_1 (c);\n" " return reg_class_for_constraint_1 (c);\n"
" return NO_REGS;\n" " return NO_REGS;\n"
"}\n" "}\n");
"\n"
"#define REG_CLASS_FROM_CONSTRAINT(c_,s_) \\\n"
" reg_class_for_constraint (lookup_constraint (s_))\n"
"#define REG_CLASS_FOR_CONSTRAINT(x_) \\\n"
" reg_class_for_constraint (x_)\n");
else else
puts ("static inline enum reg_class\n" puts ("static inline enum reg_class\n"
"reg_class_for_constraint (enum constraint_num)\n" "reg_class_for_constraint (enum constraint_num)\n"
"{\n" "{\n"
" return NO_REGS;\n" " return NO_REGS;\n"
"}\n\n" "}\n");
"#define REG_CLASS_FROM_CONSTRAINT(c_,s_) NO_REGS\n"
"#define REG_CLASS_FOR_CONSTRAINT(x_) \\\n"
" NO_REGS\n");
if (have_const_int_constraints) if (have_const_int_constraints)
puts ("extern bool insn_const_int_ok_for_constraint " puts ("extern bool insn_const_int_ok_for_constraint "
"(HOST_WIDE_INT, enum constraint_num);\n" "(HOST_WIDE_INT, enum constraint_num);\n"
...@@ -1347,19 +1366,27 @@ write_tm_preds_h (void) ...@@ -1347,19 +1366,27 @@ write_tm_preds_h (void)
" constraint_satisfied_p (v_, lookup_constraint (s_))\n"); " constraint_satisfied_p (v_, lookup_constraint (s_))\n");
else else
puts ("#define CONST_DOUBLE_OK_FOR_CONSTRAINT_P(v_,c_,s_) 0\n"); puts ("#define CONST_DOUBLE_OK_FOR_CONSTRAINT_P(v_,c_,s_) 0\n");
if (have_extra_constraints)
puts ("#define EXTRA_CONSTRAINT_STR(v_,c_,s_) \\\n" puts ("enum constraint_type\n"
" constraint_satisfied_p (v_, lookup_constraint (s_))\n"); "{\n"
if (have_memory_constraints) " CT_REGISTER,\n"
puts ("#define EXTRA_MEMORY_CONSTRAINT(c_,s_) " " CT_MEMORY,\n"
"insn_extra_memory_constraint (lookup_constraint (s_))\n"); " CT_ADDRESS,\n"
else " CT_FIXED_FORM\n"
puts ("#define EXTRA_MEMORY_CONSTRAINT(c_,s_) false\n"); "};\n"
if (have_address_constraints) "\n"
puts ("#define EXTRA_ADDRESS_CONSTRAINT(c_,s_) " "static inline enum constraint_type\n"
"insn_extra_address_constraint (lookup_constraint (s_))\n"); "get_constraint_type (enum constraint_num c)\n"
else "{");
puts ("#define EXTRA_ADDRESS_CONSTRAINT(c_,s_) false\n"); auto_vec <std::pair <unsigned int, const char *>, 3> values;
if (memory_start != memory_end)
values.safe_push (std::make_pair (memory_start, "CT_MEMORY"));
if (address_start != address_end)
values.safe_push (std::make_pair (address_start, "CT_ADDRESS"));
if (address_end != num_constraints)
values.safe_push (std::make_pair (address_end, "CT_FIXED_FORM"));
print_type_tree (values, 0, values.length (), "CT_REGISTER", 2);
puts ("}");
} }
puts ("#endif /* tm-preds.h */"); puts ("#endif /* tm-preds.h */");
......
...@@ -753,25 +753,28 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops, ...@@ -753,25 +753,28 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
break; break;
default: default:
if (REG_CLASS_FROM_CONSTRAINT (c, p) != NO_REGS) enum constraint_num cn = lookup_constraint (p);
classes[i] = ira_reg_class_subunion[classes[i]] enum reg_class cl;
[REG_CLASS_FROM_CONSTRAINT (c, p)]; switch (get_constraint_type (cn))
#ifdef EXTRA_CONSTRAINT_STR
else if (EXTRA_CONSTRAINT_STR (op, c, p))
win = 1;
if (EXTRA_MEMORY_CONSTRAINT (c, p))
{ {
case CT_REGISTER:
cl = reg_class_for_constraint (cn);
if (cl != NO_REGS)
classes[i] = ira_reg_class_subunion[classes[i]][cl];
break;
case CT_MEMORY:
/* Every MEM can be reloaded to fit. */ /* Every MEM can be reloaded to fit. */
insn_allows_mem[i] = allows_mem[i] = 1; insn_allows_mem[i] = allows_mem[i] = 1;
if (MEM_P (op)) if (MEM_P (op))
win = 1; win = 1;
} break;
if (EXTRA_ADDRESS_CONSTRAINT (c, p))
{ case CT_ADDRESS:
/* Every address can be reloaded to fit. */ /* Every address can be reloaded to fit. */
allows_addr = 1; allows_addr = 1;
if (address_operand (op, GET_MODE (op))) if (address_operand (op, GET_MODE (op))
|| constraint_satisfied_p (op, cn))
win = 1; win = 1;
/* We know this operand is an address, so we /* We know this operand is an address, so we
want it to be allocated to a hard register want it to be allocated to a hard register
...@@ -781,8 +784,13 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops, ...@@ -781,8 +784,13 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
= ira_reg_class_subunion[classes[i]] = ira_reg_class_subunion[classes[i]]
[base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, [base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
ADDRESS, SCRATCH)]; ADDRESS, SCRATCH)];
break;
case CT_FIXED_FORM:
if (constraint_satisfied_p (op, cn))
win = 1;
break;
} }
#endif
break; break;
} }
p += CONSTRAINT_LEN (c, p); p += CONSTRAINT_LEN (c, p);
...@@ -1275,8 +1283,8 @@ record_operand_costs (rtx insn, enum reg_class *pref) ...@@ -1275,8 +1283,8 @@ record_operand_costs (rtx insn, enum reg_class *pref)
XEXP (recog_data.operand[i], 0), XEXP (recog_data.operand[i], 0),
0, MEM, SCRATCH, frequency * 2); 0, MEM, SCRATCH, frequency * 2);
else if (constraints[i][0] == 'p' else if (constraints[i][0] == 'p'
|| EXTRA_ADDRESS_CONSTRAINT (constraints[i][0], || (insn_extra_address_constraint
constraints[i])) (lookup_constraint (constraints[i]))))
record_address_regs (VOIDmode, ADDR_SPACE_GENERIC, record_address_regs (VOIDmode, ADDR_SPACE_GENERIC,
recog_data.operand[i], 0, ADDRESS, SCRATCH, recog_data.operand[i], 0, ADDRESS, SCRATCH,
frequency * 2); frequency * 2);
......
...@@ -759,6 +759,7 @@ single_reg_class (const char *constraints, rtx op, rtx equiv_const) ...@@ -759,6 +759,7 @@ single_reg_class (const char *constraints, rtx op, rtx equiv_const)
{ {
int c; int c;
enum reg_class cl, next_cl; enum reg_class cl, next_cl;
enum constraint_num cn;
cl = NO_REGS; cl = NO_REGS;
alternative_mask enabled = recog_data.enabled_alternatives; alternative_mask enabled = recog_data.enabled_alternatives;
...@@ -849,20 +850,19 @@ single_reg_class (const char *constraints, rtx op, rtx equiv_const) ...@@ -849,20 +850,19 @@ single_reg_class (const char *constraints, rtx op, rtx equiv_const)
case 'A': case 'B': case 'C': case 'D': case 'A': case 'B': case 'C': case 'D':
case 'Q': case 'R': case 'S': case 'T': case 'U': case 'Q': case 'R': case 'S': case 'T': case 'U':
case 'W': case 'Y': case 'Z': case 'W': case 'Y': case 'Z':
#ifdef EXTRA_CONSTRAINT_STR
/* ??? Is this the best way to handle memory constraints? */ /* ??? Is this the best way to handle memory constraints? */
if (EXTRA_MEMORY_CONSTRAINT (c, constraints) cn = lookup_constraint (constraints);
|| EXTRA_ADDRESS_CONSTRAINT (c, constraints)) if (insn_extra_memory_constraint (cn)
|| insn_extra_address_constraint (cn))
return NO_REGS; return NO_REGS;
if (EXTRA_CONSTRAINT_STR (op, c, constraints) if (constraint_satisfied_p (op, cn)
|| (equiv_const != NULL_RTX || (equiv_const != NULL_RTX
&& CONSTANT_P (equiv_const) && CONSTANT_P (equiv_const)
&& EXTRA_CONSTRAINT_STR (equiv_const, c, constraints))) && constraint_satisfied_p (equiv_const, cn)))
return NO_REGS; return NO_REGS;
#endif
next_cl = (c == 'r' next_cl = (c == 'r'
? GENERAL_REGS ? GENERAL_REGS
: REG_CLASS_FROM_CONSTRAINT (c, constraints)); : reg_class_for_constraint (cn));
if (next_cl == NO_REGS) if (next_cl == NO_REGS)
break; break;
if (cl == NO_REGS if (cl == NO_REGS
...@@ -950,7 +950,7 @@ ira_implicitly_set_insn_hard_regs (HARD_REG_SET *set) ...@@ -950,7 +950,7 @@ ira_implicitly_set_insn_hard_regs (HARD_REG_SET *set)
case 'W': case 'Y': case 'Z': case 'W': case 'Y': case 'Z':
cl = (c == 'r' cl = (c == 'r'
? GENERAL_REGS ? GENERAL_REGS
: REG_CLASS_FROM_CONSTRAINT (c, p)); : reg_class_for_constraint (lookup_constraint (p)));
if (cl != NO_REGS) if (cl != NO_REGS)
{ {
/* There is no register pressure problem if all of the /* There is no register pressure problem if all of the
......
...@@ -1922,24 +1922,29 @@ ira_setup_alts (rtx insn, HARD_REG_SET &alts) ...@@ -1922,24 +1922,29 @@ ira_setup_alts (rtx insn, HARD_REG_SET &alts)
break; break;
case 'o': case 'o':
case 'r':
goto op_success; goto op_success;
break; break;
default: default:
{ {
enum reg_class cl; enum constraint_num cn = lookup_constraint (p);
switch (get_constraint_type (cn))
cl = (c == 'r' ? GENERAL_REGS : REG_CLASS_FROM_CONSTRAINT (c, p)); {
if (cl != NO_REGS) case CT_REGISTER:
goto op_success; if (reg_class_for_constraint (cn) != NO_REGS)
#ifdef EXTRA_CONSTRAINT_STR goto op_success;
else if (EXTRA_CONSTRAINT_STR (op, c, p)) break;
goto op_success;
else if (EXTRA_MEMORY_CONSTRAINT (c, p)) case CT_ADDRESS:
goto op_success; case CT_MEMORY:
else if (EXTRA_ADDRESS_CONSTRAINT (c, p)) goto op_success;
goto op_success;
#endif case CT_FIXED_FORM:
if (constraint_satisfied_p (op, cn))
goto op_success;
break;
}
break; break;
} }
} }
...@@ -1972,9 +1977,6 @@ ira_get_dup_out_num (int op_num, HARD_REG_SET &alts) ...@@ -1972,9 +1977,6 @@ ira_get_dup_out_num (int op_num, HARD_REG_SET &alts)
int curr_alt, c, original, dup; int curr_alt, c, original, dup;
bool ignore_p, use_commut_op_p; bool ignore_p, use_commut_op_p;
const char *str; const char *str;
#ifdef EXTRA_CONSTRAINT_STR
rtx op;
#endif
if (op_num < 0 || recog_data.n_alternatives == 0) if (op_num < 0 || recog_data.n_alternatives == 0)
return -1; return -1;
...@@ -1985,9 +1987,7 @@ ira_get_dup_out_num (int op_num, HARD_REG_SET &alts) ...@@ -1985,9 +1987,7 @@ ira_get_dup_out_num (int op_num, HARD_REG_SET &alts)
use_commut_op_p = false; use_commut_op_p = false;
for (;;) for (;;)
{ {
#ifdef EXTRA_CONSTRAINT_STR rtx op = recog_data.operand[op_num];
op = recog_data.operand[op_num];
#endif
for (curr_alt = 0, ignore_p = !TEST_HARD_REG_BIT (alts, curr_alt), for (curr_alt = 0, ignore_p = !TEST_HARD_REG_BIT (alts, curr_alt),
original = -1;;) original = -1;;)
...@@ -2010,6 +2010,9 @@ ira_get_dup_out_num (int op_num, HARD_REG_SET &alts) ...@@ -2010,6 +2010,9 @@ ira_get_dup_out_num (int op_num, HARD_REG_SET &alts)
case 'g': case 'g':
goto fail; goto fail;
case 'r': case 'r':
if (!targetm.class_likely_spilled_p (GENERAL_REGS))
goto fail;
break;
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
case 'h': case 'j': case 'k': case 'l': case 'h': case 'j': case 'k': case 'l':
case 'q': case 't': case 'u': case 'q': case 't': case 'u':
...@@ -2018,19 +2021,13 @@ ira_get_dup_out_num (int op_num, HARD_REG_SET &alts) ...@@ -2018,19 +2021,13 @@ ira_get_dup_out_num (int op_num, HARD_REG_SET &alts)
case 'Q': case 'R': case 'S': case 'T': case 'U': case 'Q': case 'R': case 'S': case 'T': case 'U':
case 'W': case 'Y': case 'Z': case 'W': case 'Y': case 'Z':
{ {
enum reg_class cl; enum constraint_num cn = lookup_constraint (str);
enum reg_class cl = reg_class_for_constraint (cn);
cl = (c == 'r' if (cl != NO_REGS
? GENERAL_REGS : REG_CLASS_FROM_CONSTRAINT (c, str)); && !targetm.class_likely_spilled_p (cl))
if (cl != NO_REGS) goto fail;
{ if (constraint_satisfied_p (op, cn))
if (! targetm.class_likely_spilled_p (cl))
goto fail;
}
#ifdef EXTRA_CONSTRAINT_STR
else if (EXTRA_CONSTRAINT_STR (op, c, str))
goto fail; goto fail;
#endif
break; break;
} }
......
...@@ -394,40 +394,38 @@ valid_address_p (struct address_info *ad) ...@@ -394,40 +394,38 @@ valid_address_p (struct address_info *ad)
return valid_address_p (ad->mode, *ad->outer, ad->as); return valid_address_p (ad->mode, *ad->outer, ad->as);
} }
#ifdef EXTRA_CONSTRAINT_STR
/* Return true if the eliminated form of memory reference OP satisfies /* Return true if the eliminated form of memory reference OP satisfies
extra memory constraint CONSTRAINT. */ extra memory constraint CONSTRAINT. */
static bool static bool
satisfies_memory_constraint_p (rtx op, const char *constraint) satisfies_memory_constraint_p (rtx op, enum constraint_num constraint)
{ {
struct address_info ad; struct address_info ad;
decompose_mem_address (&ad, op); decompose_mem_address (&ad, op);
address_eliminator eliminator (&ad); address_eliminator eliminator (&ad);
return EXTRA_CONSTRAINT_STR (op, *constraint, constraint); return constraint_satisfied_p (op, constraint);
} }
/* Return true if the eliminated form of address AD satisfies extra /* Return true if the eliminated form of address AD satisfies extra
address constraint CONSTRAINT. */ address constraint CONSTRAINT. */
static bool static bool
satisfies_address_constraint_p (struct address_info *ad, satisfies_address_constraint_p (struct address_info *ad,
const char *constraint) enum constraint_num constraint)
{ {
address_eliminator eliminator (ad); address_eliminator eliminator (ad);
return EXTRA_CONSTRAINT_STR (*ad->outer, *constraint, constraint); return constraint_satisfied_p (*ad->outer, constraint);
} }
/* Return true if the eliminated form of address OP satisfies extra /* Return true if the eliminated form of address OP satisfies extra
address constraint CONSTRAINT. */ address constraint CONSTRAINT. */
static bool static bool
satisfies_address_constraint_p (rtx op, const char *constraint) satisfies_address_constraint_p (rtx op, enum constraint_num constraint)
{ {
struct address_info ad; struct address_info ad;
decompose_lea_address (&ad, &op); decompose_lea_address (&ad, &op);
return satisfies_address_constraint_p (&ad, constraint); return satisfies_address_constraint_p (&ad, constraint);
} }
#endif
/* Initiate equivalences for LRA. As we keep original equivalences /* Initiate equivalences for LRA. As we keep original equivalences
before any elimination, we need to make copies otherwise any change before any elimination, we need to make copies otherwise any change
...@@ -982,21 +980,20 @@ reg_class_from_constraints (const char *p) ...@@ -982,21 +980,20 @@ reg_class_from_constraints (const char *p)
break; break;
default: default:
if (REG_CLASS_FROM_CONSTRAINT (c, p) == NO_REGS) enum constraint_num cn = lookup_constraint (p);
enum reg_class cl = reg_class_for_constraint (cn);
if (cl == NO_REGS)
{ {
#ifdef EXTRA_CONSTRAINT_STR if (insn_extra_address_constraint (cn))
if (EXTRA_ADDRESS_CONSTRAINT (c, p))
op_class op_class
= (reg_class_subunion = (reg_class_subunion
[op_class][base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, [op_class][base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
ADDRESS, SCRATCH)]); ADDRESS, SCRATCH)]);
#endif
break; break;
} }
op_class op_class = reg_class_subunion[op_class][cl];
= reg_class_subunion[op_class][REG_CLASS_FROM_CONSTRAINT (c, p)]; break;
break;
} }
while ((p += len), c); while ((p += len), c);
return op_class; return op_class;
...@@ -1712,6 +1709,7 @@ process_alt_operands (int only_alternative) ...@@ -1712,6 +1709,7 @@ process_alt_operands (int only_alternative)
bool this_alternative_offmemok; bool this_alternative_offmemok;
bool scratch_p; bool scratch_p;
enum machine_mode mode; enum machine_mode mode;
enum constraint_num cn;
opalt_num = nalt * n_operands + nop; opalt_num = nalt * n_operands + nop;
if (curr_static_id->operand_alternative[opalt_num].anything_ok) if (curr_static_id->operand_alternative[opalt_num].anything_ok)
...@@ -2030,76 +2028,55 @@ process_alt_operands (int only_alternative) ...@@ -2030,76 +2028,55 @@ process_alt_operands (int only_alternative)
/* Drop through into 'r' case. */ /* Drop through into 'r' case. */
case 'r': case 'r':
this_alternative cl = GENERAL_REGS;
= reg_class_subunion[this_alternative][GENERAL_REGS];
IOR_HARD_REG_SET (this_alternative_set,
reg_class_contents[GENERAL_REGS]);
if (costly_p)
{
this_costly_alternative
= (reg_class_subunion
[this_costly_alternative][GENERAL_REGS]);
IOR_HARD_REG_SET (this_costly_alternative_set,
reg_class_contents[GENERAL_REGS]);
}
goto reg; goto reg;
default: default:
if (REG_CLASS_FROM_CONSTRAINT (c, p) == NO_REGS) cn = lookup_constraint (p);
switch (get_constraint_type (cn))
{ {
#ifdef EXTRA_CONSTRAINT_STR case CT_REGISTER:
if (EXTRA_MEMORY_CONSTRAINT (c, p)) cl = reg_class_for_constraint (cn);
{ if (cl != NO_REGS)
if (MEM_P (op) goto reg;
&& satisfies_memory_constraint_p (op, p)) break;
win = true;
else if (spilled_pseudo_p (op))
win = true;
/* If we didn't already win, we can reload
constants via force_const_mem or put the
pseudo value into memory, or make other
memory by reloading the address like for
'o'. */
if (CONST_POOL_OK_P (mode, op)
|| MEM_P (op) || REG_P (op))
badop = false;
constmemok = true;
offmemok = true;
break;
}
if (EXTRA_ADDRESS_CONSTRAINT (c, p))
{
if (satisfies_address_constraint_p (op, p))
win = true;
/* If we didn't already win, we can reload
the address into a base register. */
cl = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
ADDRESS, SCRATCH);
this_alternative
= reg_class_subunion[this_alternative][cl];
IOR_HARD_REG_SET (this_alternative_set,
reg_class_contents[cl]);
if (costly_p)
{
this_costly_alternative
= (reg_class_subunion
[this_costly_alternative][cl]);
IOR_HARD_REG_SET (this_costly_alternative_set,
reg_class_contents[cl]);
}
badop = false;
break;
}
if (EXTRA_CONSTRAINT_STR (op, c, p)) case CT_MEMORY:
if (MEM_P (op)
&& satisfies_memory_constraint_p (op, cn))
win = true;
else if (spilled_pseudo_p (op))
win = true;
/* If we didn't already win, we can reload constants
via force_const_mem or put the pseudo value into
memory, or make other memory by reloading the
address like for 'o'. */
if (CONST_POOL_OK_P (mode, op)
|| MEM_P (op) || REG_P (op))
badop = false;
constmemok = true;
offmemok = true;
break;
case CT_ADDRESS:
/* If we didn't already win, we can reload the address
into a base register. */
if (satisfies_address_constraint_p (op, cn))
win = true;
cl = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
ADDRESS, SCRATCH);
badop = false;
goto reg;
case CT_FIXED_FORM:
if (constraint_satisfied_p (op, cn))
win = true; win = true;
#endif
break; break;
} }
break;
cl = REG_CLASS_FROM_CONSTRAINT (c, p); reg:
this_alternative = reg_class_subunion[this_alternative][cl]; this_alternative = reg_class_subunion[this_alternative][cl];
IOR_HARD_REG_SET (this_alternative_set, IOR_HARD_REG_SET (this_alternative_set,
reg_class_contents[cl]); reg_class_contents[cl]);
...@@ -2110,7 +2087,6 @@ process_alt_operands (int only_alternative) ...@@ -2110,7 +2087,6 @@ process_alt_operands (int only_alternative)
IOR_HARD_REG_SET (this_costly_alternative_set, IOR_HARD_REG_SET (this_costly_alternative_set,
reg_class_contents[cl]); reg_class_contents[cl]);
} }
reg:
if (mode == BLKmode) if (mode == BLKmode)
break; break;
winreg = true; winreg = true;
...@@ -2856,10 +2832,11 @@ process_address_1 (int nop, rtx *before, rtx *after) ...@@ -2856,10 +2832,11 @@ process_address_1 (int nop, rtx *before, rtx *after)
rtx new_reg; rtx new_reg;
rtx op = *curr_id->operand_loc[nop]; rtx op = *curr_id->operand_loc[nop];
const char *constraint = curr_static_id->operand[nop].constraint; const char *constraint = curr_static_id->operand[nop].constraint;
enum constraint_num cn = lookup_constraint (constraint);
bool change_p; bool change_p;
if (constraint[0] == 'p' if (constraint[0] == 'p'
|| EXTRA_ADDRESS_CONSTRAINT (constraint[0], constraint)) || insn_extra_address_constraint (cn))
decompose_lea_address (&ad, curr_id->operand_loc[nop]); decompose_lea_address (&ad, curr_id->operand_loc[nop]);
else if (MEM_P (op)) else if (MEM_P (op))
decompose_mem_address (&ad, op); decompose_mem_address (&ad, op);
...@@ -2888,14 +2865,12 @@ process_address_1 (int nop, rtx *before, rtx *after) ...@@ -2888,14 +2865,12 @@ process_address_1 (int nop, rtx *before, rtx *after)
&& process_addr_reg (ad.index_term, before, NULL, INDEX_REG_CLASS)) && process_addr_reg (ad.index_term, before, NULL, INDEX_REG_CLASS))
change_p = true; change_p = true;
#ifdef EXTRA_CONSTRAINT_STR /* Target hooks sometimes don't treat extra-constraint addresses as
/* Target hooks sometimes reject extra constraint addresses -- use legitimate address_operands, so handle them specially. */
EXTRA_CONSTRAINT_STR for the validation. */
if (constraint[0] != 'p' if (constraint[0] != 'p'
&& EXTRA_ADDRESS_CONSTRAINT (constraint[0], constraint) && insn_extra_address_constraint (cn)
&& satisfies_address_constraint_p (&ad, constraint)) && satisfies_address_constraint_p (&ad, cn))
return change_p; return change_p;
#endif
/* There are three cases where the shape of *AD.INNER may now be invalid: /* There are three cases where the shape of *AD.INNER may now be invalid:
...@@ -3617,11 +3592,10 @@ curr_insn_transform (void) ...@@ -3617,11 +3592,10 @@ curr_insn_transform (void)
{ {
if (c == TARGET_MEM_CONSTRAINT || c == 'o') if (c == TARGET_MEM_CONSTRAINT || c == 'o')
break; break;
#ifdef EXTRA_CONSTRAINT_STR enum constraint_num cn = lookup_constraint (constraint);
if (EXTRA_MEMORY_CONSTRAINT (c, constraint) if (insn_extra_memory_constraint (cn)
&& satisfies_memory_constraint_p (tem, constraint)) && satisfies_memory_constraint_p (tem, cn))
break; break;
#endif
} }
if (c == '\0' || c == ',' || c == '#') if (c == '\0' || c == ',' || c == '#')
continue; continue;
......
...@@ -574,8 +574,8 @@ reload_cse_simplify_operands (rtx insn, rtx testreg) ...@@ -574,8 +574,8 @@ reload_cse_simplify_operands (rtx insn, rtx testreg)
default: default:
rclass rclass
= (reg_class_subunion = (reg_class_subunion
[(int) rclass] [rclass]
[(int) REG_CLASS_FROM_CONSTRAINT ((unsigned char) c, p)]); [reg_class_for_constraint (lookup_constraint (p))]);
break; break;
case ',': case '\0': case ',': case '\0':
......
...@@ -1729,6 +1729,7 @@ asm_operand_ok (rtx op, const char *constraint, const char **constraints) ...@@ -1729,6 +1729,7 @@ asm_operand_ok (rtx op, const char *constraint, const char **constraints)
while (*constraint) while (*constraint)
{ {
enum constraint_num cn;
char c = *constraint; char c = *constraint;
int len; int len;
switch (c) switch (c)
...@@ -1902,27 +1903,37 @@ asm_operand_ok (rtx op, const char *constraint, const char **constraints) ...@@ -1902,27 +1903,37 @@ asm_operand_ok (rtx op, const char *constraint, const char **constraints)
result = 1; result = 1;
break; break;
case 'r':
reg:
if (!result
&& GET_MODE (op) != BLKmode
&& register_operand (op, VOIDmode))
result = 1;
break;
default: default:
/* For all other letters, we first check for a register class, cn = lookup_constraint (constraint);
otherwise it is an EXTRA_CONSTRAINT. */ switch (get_constraint_type (cn))
if (REG_CLASS_FROM_CONSTRAINT (c, constraint) != NO_REGS)
{ {
case 'r': case CT_REGISTER:
if (GET_MODE (op) == BLKmode) if (reg_class_for_constraint (cn) != NO_REGS)
break; goto reg;
if (register_operand (op, VOIDmode)) break;
result = 1;
case CT_MEMORY:
/* Every memory operand can be reloaded to fit. */
result = result || memory_operand (op, VOIDmode);
break;
case CT_ADDRESS:
/* Every address operand can be reloaded to fit. */
result = result || address_operand (op, VOIDmode);
break;
case CT_FIXED_FORM:
result = result || constraint_satisfied_p (op, cn);
break;
} }
#ifdef EXTRA_CONSTRAINT_STR
else if (EXTRA_MEMORY_CONSTRAINT (c, constraint))
/* Every memory operand can be reloaded to fit. */
result = result || memory_operand (op, VOIDmode);
else if (EXTRA_ADDRESS_CONSTRAINT (c, constraint))
/* Every address operand can be reloaded to fit. */
result = result || address_operand (op, VOIDmode);
else if (EXTRA_CONSTRAINT_STR (op, c, constraint))
result = 1;
#endif
break; break;
} }
len = CONSTRAINT_LEN (c, constraint); len = CONSTRAINT_LEN (c, constraint);
...@@ -2434,13 +2445,21 @@ preprocess_constraints (int n_operands, int n_alternatives, ...@@ -2434,13 +2445,21 @@ preprocess_constraints (int n_operands, int n_alternatives,
break; break;
default: default:
if (EXTRA_MEMORY_CONSTRAINT (c, p)) enum constraint_num cn = lookup_constraint (p);
enum reg_class cl;
switch (get_constraint_type (cn))
{ {
case CT_REGISTER:
cl = reg_class_for_constraint (cn);
if (cl != NO_REGS)
op_alt[i].cl = reg_class_subunion[op_alt[i].cl][cl];
break;
case CT_MEMORY:
op_alt[i].memory_ok = 1; op_alt[i].memory_ok = 1;
break; break;
}
if (EXTRA_ADDRESS_CONSTRAINT (c, p)) case CT_ADDRESS:
{
op_alt[i].is_address = 1; op_alt[i].is_address = 1;
op_alt[i].cl op_alt[i].cl
= (reg_class_subunion = (reg_class_subunion
...@@ -2448,12 +2467,10 @@ preprocess_constraints (int n_operands, int n_alternatives, ...@@ -2448,12 +2467,10 @@ preprocess_constraints (int n_operands, int n_alternatives,
[(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
ADDRESS, SCRATCH)]); ADDRESS, SCRATCH)]);
break; break;
}
op_alt[i].cl case CT_FIXED_FORM:
= (reg_class_subunion break;
[(int) op_alt[i].cl] }
[(int) REG_CLASS_FROM_CONSTRAINT ((unsigned char) c, p)]);
break; break;
} }
p += CONSTRAINT_LEN (c, p); p += CONSTRAINT_LEN (c, p);
...@@ -2846,9 +2863,12 @@ constrain_operands (int strict) ...@@ -2846,9 +2863,12 @@ constrain_operands (int strict)
default: default:
{ {
enum reg_class cl; enum reg_class cl;
enum constraint_num cn = (c == 'r'
? CONSTRAINT__UNKNOWN
: lookup_constraint (p));
cl = (c == 'r' cl = (c == 'r'
? GENERAL_REGS : REG_CLASS_FROM_CONSTRAINT (c, p)); ? GENERAL_REGS : reg_class_for_constraint (cn));
if (cl != NO_REGS) if (cl != NO_REGS)
{ {
if (strict < 0 if (strict < 0
...@@ -2860,11 +2880,11 @@ constrain_operands (int strict) ...@@ -2860,11 +2880,11 @@ constrain_operands (int strict)
&& reg_fits_class_p (op, cl, offset, mode))) && reg_fits_class_p (op, cl, offset, mode)))
win = 1; win = 1;
} }
#ifdef EXTRA_CONSTRAINT_STR
else if (EXTRA_CONSTRAINT_STR (op, c, p)) else if (constraint_satisfied_p (op, cn))
win = 1; win = 1;
else if (EXTRA_MEMORY_CONSTRAINT (c, p) else if (insn_extra_memory_constraint (cn)
/* Every memory operand can be reloaded to fit. */ /* Every memory operand can be reloaded to fit. */
&& ((strict < 0 && MEM_P (op)) && ((strict < 0 && MEM_P (op))
/* Before reload, accept what reload can turn /* Before reload, accept what reload can turn
...@@ -2874,7 +2894,7 @@ constrain_operands (int strict) ...@@ -2874,7 +2894,7 @@ constrain_operands (int strict)
|| (reload_in_progress && REG_P (op) || (reload_in_progress && REG_P (op)
&& REGNO (op) >= FIRST_PSEUDO_REGISTER))) && REGNO (op) >= FIRST_PSEUDO_REGISTER)))
win = 1; win = 1;
else if (EXTRA_ADDRESS_CONSTRAINT (c, p) else if (insn_extra_address_constraint (cn)
/* Every address operand can be reloaded to fit. */ /* Every address operand can be reloaded to fit. */
&& strict < 0) && strict < 0)
win = 1; win = 1;
...@@ -2885,10 +2905,9 @@ constrain_operands (int strict) ...@@ -2885,10 +2905,9 @@ constrain_operands (int strict)
&& REGNO (op) >= FIRST_PSEUDO_REGISTER && REGNO (op) >= FIRST_PSEUDO_REGISTER
&& reg_renumber[REGNO (op)] < 0 && reg_renumber[REGNO (op)] < 0
&& reg_equiv_mem (REGNO (op)) != 0 && reg_equiv_mem (REGNO (op)) != 0
&& EXTRA_CONSTRAINT_STR && constraint_satisfied_p
(reg_equiv_mem (REGNO (op)), c, p)) (reg_equiv_mem (REGNO (op)), cn))
win = 1; win = 1;
#endif
break; break;
} }
} }
...@@ -3283,7 +3302,7 @@ peep2_find_free_register (int from, int to, const char *class_str, ...@@ -3283,7 +3302,7 @@ peep2_find_free_register (int from, int to, const char *class_str,
} }
cl = (class_str[0] == 'r' ? GENERAL_REGS cl = (class_str[0] == 'r' ? GENERAL_REGS
: REG_CLASS_FROM_CONSTRAINT (class_str[0], class_str)); : reg_class_for_constraint (lookup_constraint (class_str)));
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
{ {
......
...@@ -401,8 +401,8 @@ push_secondary_reload (int in_p, rtx x, int opnum, int optional, ...@@ -401,8 +401,8 @@ push_secondary_reload (int in_p, rtx x, int opnum, int optional,
scratch_constraint++; scratch_constraint++;
letter = *scratch_constraint; letter = *scratch_constraint;
scratch_class = (letter == 'r' ? GENERAL_REGS scratch_class = (letter == 'r' ? GENERAL_REGS
: REG_CLASS_FROM_CONSTRAINT ((unsigned char) letter, : (reg_class_for_constraint
scratch_constraint)); (lookup_constraint (scratch_constraint))));
rclass = scratch_class; rclass = scratch_class;
mode = insn_data[(int) icode].operand[2].mode; mode = insn_data[(int) icode].operand[2].mode;
...@@ -560,8 +560,7 @@ scratch_reload_class (enum insn_code icode) ...@@ -560,8 +560,7 @@ scratch_reload_class (enum insn_code icode)
scratch_letter = *scratch_constraint; scratch_letter = *scratch_constraint;
if (scratch_letter == 'r') if (scratch_letter == 'r')
return GENERAL_REGS; return GENERAL_REGS;
rclass = REG_CLASS_FROM_CONSTRAINT ((unsigned char) scratch_letter, rclass = reg_class_for_constraint (lookup_constraint (scratch_constraint));
scratch_constraint);
gcc_assert (rclass != NO_REGS); gcc_assert (rclass != NO_REGS);
return rclass; return rclass;
} }
...@@ -2852,7 +2851,8 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, ...@@ -2852,7 +2851,8 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
/* Ignore things like match_operator operands. */ /* Ignore things like match_operator operands. */
; ;
else if (constraints[i][0] == 'p' else if (constraints[i][0] == 'p'
|| EXTRA_ADDRESS_CONSTRAINT (constraints[i][0], constraints[i])) || (insn_extra_address_constraint
(lookup_constraint (constraints[i]))))
{ {
address_operand_reloaded[i] address_operand_reloaded[i]
= find_reloads_address (recog_data.operand_mode[i], (rtx*) 0, = find_reloads_address (recog_data.operand_mode[i], (rtx*) 0,
...@@ -3094,6 +3094,8 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, ...@@ -3094,6 +3094,8 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
operand. */ operand. */
int constmemok = 0; int constmemok = 0;
int earlyclobber = 0; int earlyclobber = 0;
enum constraint_num cn;
enum reg_class cl;
/* If the predicate accepts a unary operator, it means that /* If the predicate accepts a unary operator, it means that
we need to reload the operand, but do not do this for we need to reload the operand, but do not do this for
...@@ -3489,71 +3491,74 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, ...@@ -3489,71 +3491,74 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
/* Drop through into 'r' case. */ /* Drop through into 'r' case. */
case 'r': case 'r':
this_alternative[i] cl = GENERAL_REGS;
= reg_class_subunion[this_alternative[i]][(int) GENERAL_REGS];
goto reg; goto reg;
default: default:
if (REG_CLASS_FROM_CONSTRAINT (c, p) == NO_REGS) cn = lookup_constraint (p);
switch (get_constraint_type (cn))
{ {
#ifdef EXTRA_CONSTRAINT_STR case CT_REGISTER:
if (EXTRA_MEMORY_CONSTRAINT (c, p)) cl = reg_class_for_constraint (cn);
{ if (cl != NO_REGS)
if (force_reload) goto reg;
break; break;
if (EXTRA_CONSTRAINT_STR (operand, c, p))
win = 1;
/* If the address was already reloaded,
we win as well. */
else if (MEM_P (operand)
&& address_reloaded[i] == 1)
win = 1;
/* Likewise if the address will be reloaded because
reg_equiv_address is nonzero. For reg_equiv_mem
we have to check. */
else if (REG_P (operand)
&& REGNO (operand) >= FIRST_PSEUDO_REGISTER
&& reg_renumber[REGNO (operand)] < 0
&& ((reg_equiv_mem (REGNO (operand)) != 0
&& EXTRA_CONSTRAINT_STR (reg_equiv_mem (REGNO (operand)), c, p))
|| (reg_equiv_address (REGNO (operand)) != 0)))
win = 1;
/* If we didn't already win, we can reload
constants via force_const_mem, and other
MEMs by reloading the address like for 'o'. */
if (CONST_POOL_OK_P (operand_mode[i], operand)
|| MEM_P (operand))
badop = 0;
constmemok = 1;
offmemok = 1;
break;
}
if (EXTRA_ADDRESS_CONSTRAINT (c, p))
{
if (EXTRA_CONSTRAINT_STR (operand, c, p))
win = 1;
/* If we didn't already win, we can reload
the address into a base register. */
this_alternative[i]
= base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
ADDRESS, SCRATCH);
badop = 0;
break;
}
if (EXTRA_CONSTRAINT_STR (operand, c, p)) case CT_MEMORY:
if (force_reload)
break;
if (constraint_satisfied_p (operand, cn))
win = 1;
/* If the address was already reloaded,
we win as well. */
else if (MEM_P (operand) && address_reloaded[i] == 1)
win = 1;
/* Likewise if the address will be reloaded because
reg_equiv_address is nonzero. For reg_equiv_mem
we have to check. */
else if (REG_P (operand)
&& REGNO (operand) >= FIRST_PSEUDO_REGISTER
&& reg_renumber[REGNO (operand)] < 0
&& ((reg_equiv_mem (REGNO (operand)) != 0
&& (constraint_satisfied_p
(reg_equiv_mem (REGNO (operand)),
cn)))
|| (reg_equiv_address (REGNO (operand))
!= 0)))
win = 1;
/* If we didn't already win, we can reload
constants via force_const_mem, and other
MEMs by reloading the address like for 'o'. */
if (CONST_POOL_OK_P (operand_mode[i], operand)
|| MEM_P (operand))
badop = 0;
constmemok = 1;
offmemok = 1;
break;
case CT_ADDRESS:
if (constraint_satisfied_p (operand, cn))
win = 1;
/* If we didn't already win, we can reload
the address into a base register. */
this_alternative[i]
= base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
ADDRESS, SCRATCH);
badop = 0;
break;
case CT_FIXED_FORM:
if (constraint_satisfied_p (operand, cn))
win = 1; win = 1;
#endif
break; break;
} }
break;
this_alternative[i]
= (reg_class_subunion
[this_alternative[i]]
[(int) REG_CLASS_FROM_CONSTRAINT (c, p)]);
reg: reg:
this_alternative[i]
= reg_class_subunion[this_alternative[i]][cl];
if (GET_MODE (operand) == BLKmode) if (GET_MODE (operand) == BLKmode)
break; break;
winreg = 1; winreg = 1;
...@@ -4687,11 +4692,10 @@ alternative_allows_const_pool_ref (rtx mem ATTRIBUTE_UNUSED, ...@@ -4687,11 +4692,10 @@ alternative_allows_const_pool_ref (rtx mem ATTRIBUTE_UNUSED,
{ {
if (c == TARGET_MEM_CONSTRAINT || c == 'o') if (c == TARGET_MEM_CONSTRAINT || c == 'o')
return true; return true;
#ifdef EXTRA_CONSTRAINT_STR enum constraint_num cn = lookup_constraint (constraint);
if (EXTRA_MEMORY_CONSTRAINT (c, constraint) if (insn_extra_memory_constraint (cn)
&& (mem == NULL || EXTRA_CONSTRAINT_STR (mem, c, constraint))) && (mem == NULL || constraint_satisfied_p (mem, cn)))
return true; return true;
#endif
} }
return false; return false;
} }
......
...@@ -1437,13 +1437,15 @@ maybe_fix_stack_asms (void) ...@@ -1437,13 +1437,15 @@ maybe_fix_stack_asms (void)
break; break;
default: default:
if (EXTRA_ADDRESS_CONSTRAINT (c, p)) enum constraint_num cn = lookup_constraint (p);
if (insn_extra_address_constraint (cn))
cls = (int) reg_class_subunion[cls] cls = (int) reg_class_subunion[cls]
[(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
ADDRESS, SCRATCH)]; ADDRESS, SCRATCH)];
else else
cls = (int) reg_class_subunion[cls] cls = (int) reg_class_subunion[cls]
[(int) REG_CLASS_FROM_CONSTRAINT (c, p)]; [reg_class_for_constraint (cn)];
break;
} }
p += CONSTRAINT_LEN (c, p); p += CONSTRAINT_LEN (c, p);
} }
......
...@@ -322,12 +322,11 @@ parse_output_constraint (const char **constraint_p, int operand_num, ...@@ -322,12 +322,11 @@ parse_output_constraint (const char **constraint_p, int operand_num,
default: default:
if (!ISALPHA (*p)) if (!ISALPHA (*p))
break; break;
if (REG_CLASS_FROM_CONSTRAINT (*p, p) != NO_REGS) enum constraint_num cn = lookup_constraint (p);
if (reg_class_for_constraint (cn) != NO_REGS
|| insn_extra_address_constraint (cn))
*allows_reg = true; *allows_reg = true;
#ifdef EXTRA_CONSTRAINT_STR else if (insn_extra_memory_constraint (cn))
else if (EXTRA_ADDRESS_CONSTRAINT (*p, p))
*allows_reg = true;
else if (EXTRA_MEMORY_CONSTRAINT (*p, p))
*allows_mem = true; *allows_mem = true;
else else
{ {
...@@ -337,7 +336,6 @@ parse_output_constraint (const char **constraint_p, int operand_num, ...@@ -337,7 +336,6 @@ parse_output_constraint (const char **constraint_p, int operand_num,
*allows_reg = true; *allows_reg = true;
*allows_mem = true; *allows_mem = true;
} }
#endif
break; break;
} }
...@@ -454,13 +452,11 @@ parse_input_constraint (const char **constraint_p, int input_num, ...@@ -454,13 +452,11 @@ parse_input_constraint (const char **constraint_p, int input_num,
error ("invalid punctuation %qc in constraint", constraint[j]); error ("invalid punctuation %qc in constraint", constraint[j]);
return false; return false;
} }
if (REG_CLASS_FROM_CONSTRAINT (constraint[j], constraint + j) enum constraint_num cn = lookup_constraint (constraint + j);
!= NO_REGS) if (reg_class_for_constraint (cn) != NO_REGS
|| insn_extra_address_constraint (cn))
*allows_reg = true; *allows_reg = true;
#ifdef EXTRA_CONSTRAINT_STR else if (insn_extra_memory_constraint (cn))
else if (EXTRA_ADDRESS_CONSTRAINT (constraint[j], constraint + j))
*allows_reg = true;
else if (EXTRA_MEMORY_CONSTRAINT (constraint[j], constraint + j))
*allows_mem = true; *allows_mem = true;
else else
{ {
...@@ -470,7 +466,6 @@ parse_input_constraint (const char **constraint_p, int input_num, ...@@ -470,7 +466,6 @@ parse_input_constraint (const char **constraint_p, int input_num,
*allows_reg = true; *allows_reg = true;
*allows_mem = true; *allows_mem = true;
} }
#endif
break; break;
} }
......
...@@ -930,7 +930,10 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN; ...@@ -930,7 +930,10 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN;
GO_IF_MODE_DEPENDENT_ADDRESS DELAY_SLOTS_FOR_EPILOGUE \ GO_IF_MODE_DEPENDENT_ADDRESS DELAY_SLOTS_FOR_EPILOGUE \
ELIGIBLE_FOR_EPILOGUE_DELAY TARGET_C99_FUNCTIONS TARGET_HAS_SINCOS \ ELIGIBLE_FOR_EPILOGUE_DELAY TARGET_C99_FUNCTIONS TARGET_HAS_SINCOS \
REG_CLASS_FROM_LETTER CONST_OK_FOR_LETTER_P \ REG_CLASS_FROM_LETTER CONST_OK_FOR_LETTER_P \
CONST_DOUBLE_OK_FOR_LETTER_P EXTRA_CONSTRAINT CONST_DOUBLE_OK_FOR_LETTER_P EXTRA_CONSTRAINT \
REG_CLASS_FROM_CONSTRAINT REG_CLASS_FOR_CONSTRAINT \
EXTRA_CONSTRAINT_STR EXTRA_MEMORY_CONSTRAINT \
EXTRA_ADDRESS_CONSTRAINT
/* Hooks that are no longer used. */ /* Hooks that are no longer used. */
#pragma GCC poison LANG_HOOKS_FUNCTION_MARK LANG_HOOKS_FUNCTION_FREE \ #pragma GCC poison LANG_HOOKS_FUNCTION_MARK LANG_HOOKS_FUNCTION_FREE \
......
...@@ -936,8 +936,8 @@ default_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED, ...@@ -936,8 +936,8 @@ default_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED,
insn_letter = *insn_constraint; insn_letter = *insn_constraint;
insn_class insn_class
= (insn_letter == 'r' ? GENERAL_REGS = (insn_letter == 'r' ? GENERAL_REGS
: REG_CLASS_FROM_CONSTRAINT ((unsigned char) insn_letter, : (reg_class_for_constraint
insn_constraint)); (lookup_constraint (insn_constraint))));
gcc_assert (insn_class != NO_REGS); gcc_assert (insn_class != NO_REGS);
} }
...@@ -954,8 +954,8 @@ default_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED, ...@@ -954,8 +954,8 @@ default_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED,
scratch_letter = *scratch_constraint; scratch_letter = *scratch_constraint;
scratch_class scratch_class
= (scratch_letter == 'r' ? GENERAL_REGS = (scratch_letter == 'r' ? GENERAL_REGS
: REG_CLASS_FROM_CONSTRAINT ((unsigned char) scratch_letter, : (reg_class_for_constraint
scratch_constraint)); (lookup_constraint (scratch_constraint))));
if (reg_class_subset_p (reload_class, insn_class)) if (reg_class_subset_p (reload_class, insn_class))
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment