summaryrefslogtreecommitdiff
path: root/gcc/recog.c
diff options
context:
space:
mode:
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2014-06-11 16:59:17 +0000
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2014-06-11 16:59:17 +0000
commit694494638c9f211c1e27c6c08b0d8dc7656e24e8 (patch)
treeebbbc6a5c16fb2f71c030dc719d566bd7b2d0538 /gcc/recog.c
parente3c57fd265541f5124639cc88955fb68edcbcdc8 (diff)
downloadgcc-694494638c9f211c1e27c6c08b0d8dc7656e24e8.tar.gz
gcc/
* common.md: New file. * doc/md.texi: Update description of generic, machine-independent constraints. * config/s390/constraints.md (e): Delete. * Makefile.in (md_file): Include common.md. * config/m32c/t-m32c (md_file): Likewise. * genpreds.c (general_mem): New array. (generic_constraint_letters): Remove constraints now defined by common.md. (add_constraint): Map TARGET_MEM_CONSTRAINT to general_mem. Allow the first character to be '<' or '>' as well. * genoutput.c (general_mem): New array. (indep_constraints): Remove constraints now defined by common.md. (note_constraint): Map TARGET_MEM_CONSTRAINT to general_mem. Remove special handling of 'm'. * ira-costs.c (record_reg_classes): Remove special handling of constraints now defined by common.md. * ira.c (ira_setup_alts, ira_get_dup_out_num): Likewise. * ira-lives.c (single_reg_class): Likewise. (ira_implicitly_set_insn_hard_regs): Likewise. * lra-constraints.c (reg_class_from_constraints): Likewise. (process_alt_operands, process_address, curr_insn_transform): Likewise. * postreload.c (reload_cse_simplify_operands): Likewise. * reload.c (push_secondary_reload, scratch_reload_class) (find_reloads, alternative_allows_const_pool_ref): Likewise. * reload1.c (maybe_fix_stack_asms): Likewise. * targhooks.c (default_secondary_reload): Likewise. * stmt.c (parse_output_constraint): Likewise. * recog.c (preprocess_constraints): Likewise. (constrain_operands, peep2_find_free_register): Likewise. (asm_operand_ok): Likewise, but add a comment saying why 'o' must be handled specially. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@211475 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/recog.c')
-rw-r--r--gcc/recog.c234
1 files changed, 27 insertions, 207 deletions
diff --git a/gcc/recog.c b/gcc/recog.c
index 4d72919378f..8d10a4f4112 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -1737,15 +1737,6 @@ asm_operand_ok (rtx op, const char *constraint, const char **constraints)
case ',':
constraint++;
continue;
- case '=':
- case '+':
- case '*':
- case '%':
- case '!':
- case '#':
- case '&':
- case '?':
- break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
@@ -1774,98 +1765,47 @@ asm_operand_ok (rtx op, const char *constraint, const char **constraints)
}
continue;
- case 'p':
- if (address_operand (op, VOIDmode))
- result = 1;
- break;
-
- case TARGET_MEM_CONSTRAINT:
- case 'V': /* non-offsettable */
- if (memory_operand (op, VOIDmode))
- result = 1;
- break;
+ /* The rest of the compiler assumes that reloading the address
+ of a MEM into a register will make it fit an 'o' constraint.
+ That is, if it sees a MEM operand for an 'o' constraint,
+ it assumes that (mem (base-reg)) will fit.
+ That assumption fails on targets that don't have offsettable
+ addresses at all. We therefore need to treat 'o' asm
+ constraints as a special case and only accept operands that
+ are already offsettable, thus proving that at least one
+ offsettable address exists. */
case 'o': /* offsettable */
if (offsettable_nonstrict_memref_p (op))
result = 1;
break;
- case '<':
- /* ??? Before auto-inc-dec, auto inc/dec insns are not supposed to exist,
- excepting those that expand_call created. Further, on some
- machines which do not have generalized auto inc/dec, an inc/dec
- is not a memory_operand.
-
- Match any memory and hope things are resolved after reload. */
-
- if (MEM_P (op)
- && (1
- || GET_CODE (XEXP (op, 0)) == PRE_DEC
- || GET_CODE (XEXP (op, 0)) == POST_DEC))
- result = 1;
-#ifdef AUTO_INC_DEC
- incdec_ok = true;
-#endif
- break;
-
- case '>':
- if (MEM_P (op)
- && (1
- || GET_CODE (XEXP (op, 0)) == PRE_INC
- || GET_CODE (XEXP (op, 0)) == POST_INC))
- result = 1;
-#ifdef AUTO_INC_DEC
- incdec_ok = true;
-#endif
- break;
-
- case 'E':
- case 'F':
- if (CONST_DOUBLE_AS_FLOAT_P (op)
- || (GET_CODE (op) == CONST_VECTOR
- && GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_FLOAT))
- result = 1;
- break;
-
- case 's':
- if (CONST_SCALAR_INT_P (op))
- break;
- /* Fall through. */
-
- case 'i':
- if (CONSTANT_P (op) && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op)))
- result = 1;
- break;
-
- case 'n':
- if (CONST_SCALAR_INT_P (op))
- result = 1;
- break;
-
- case 'X':
- result = 1;
- break;
-
case 'g':
if (general_operand (op, VOIDmode))
result = 1;
break;
- case 'r':
- reg:
- if (!result
- && GET_MODE (op) != BLKmode
- && register_operand (op, VOIDmode))
- result = 1;
- break;
+#ifdef AUTO_INC_DEC
+ case '<':
+ case '>':
+ /* ??? Before auto-inc-dec, auto inc/dec insns are not supposed
+ to exist, excepting those that expand_call created. Further,
+ on some machines which do not have generalized auto inc/dec,
+ an inc/dec is not a memory_operand.
+ Match any memory and hope things are resolved after reload. */
+ incdec_ok = true;
+#endif
default:
cn = lookup_constraint (constraint);
switch (get_constraint_type (cn))
{
case CT_REGISTER:
- if (reg_class_for_constraint (cn) != NO_REGS)
- goto reg;
+ if (!result
+ && reg_class_for_constraint (cn) != NO_REGS
+ && GET_MODE (op) != BLKmode
+ && register_operand (op, VOIDmode))
+ result = 1;
break;
case CT_CONST_INT:
@@ -2339,14 +2279,6 @@ preprocess_constraints (int n_operands, int n_alternatives,
switch (c)
{
- case '=': case '+': case '*': case '%':
- case 'E': case 'F': case 'G': case 'H':
- case 's': case 'i': case 'n':
- case 'I': case 'J': case 'K': case 'L':
- case 'M': case 'N': case 'O': case 'P':
- /* These don't say anything we care about. */
- break;
-
case '?':
op_alt[i].reject += 6;
break;
@@ -2367,22 +2299,11 @@ preprocess_constraints (int n_operands, int n_alternatives,
}
continue;
- case TARGET_MEM_CONSTRAINT:
- op_alt[i].memory_ok = 1;
- break;
case 'X':
op_alt[i].anything_ok = 1;
break;
- case 'p':
- op_alt[i].is_address = 1;
- op_alt[i].cl = reg_class_subunion[(int) op_alt[i].cl]
- [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
- ADDRESS, SCRATCH)];
- break;
-
case 'g':
- case 'r':
op_alt[i].cl =
reg_class_subunion[(int) op_alt[i].cl][(int) GENERAL_REGS];
break;
@@ -2592,10 +2513,6 @@ constrain_operands (int strict)
c = '\0';
break;
- case '?': case '!': case '*': case '%':
- case '=': case '+':
- break;
-
case '#':
/* Ignore rest of this alternative as far as
constraint checking is concerned. */
@@ -2695,106 +2612,10 @@ constrain_operands (int strict)
win = 1;
break;
- case 'X':
- /* This is used for a MATCH_SCRATCH in the cases when
- we don't actually need anything. So anything goes
- any time. */
- win = 1;
- break;
-
- case TARGET_MEM_CONSTRAINT:
- /* Memory operands must be valid, to the extent
- required by STRICT. */
- if (MEM_P (op))
- {
- if (strict > 0
- && !strict_memory_address_addr_space_p
- (GET_MODE (op), XEXP (op, 0),
- MEM_ADDR_SPACE (op)))
- break;
- if (strict == 0
- && !memory_address_addr_space_p
- (GET_MODE (op), XEXP (op, 0),
- MEM_ADDR_SPACE (op)))
- break;
- win = 1;
- }
- /* Before reload, accept what reload can turn into mem. */
- else if (strict < 0 && CONSTANT_P (op))
- win = 1;
- /* During reload, accept a pseudo */
- else if (reload_in_progress && REG_P (op)
- && REGNO (op) >= FIRST_PSEUDO_REGISTER)
- win = 1;
- break;
-
- case '<':
- if (MEM_P (op)
- && (GET_CODE (XEXP (op, 0)) == PRE_DEC
- || GET_CODE (XEXP (op, 0)) == POST_DEC))
- win = 1;
- break;
-
- case '>':
- if (MEM_P (op)
- && (GET_CODE (XEXP (op, 0)) == PRE_INC
- || GET_CODE (XEXP (op, 0)) == POST_INC))
- win = 1;
- break;
-
- case 'E':
- case 'F':
- if (CONST_DOUBLE_AS_FLOAT_P (op)
- || (GET_CODE (op) == CONST_VECTOR
- && GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_FLOAT))
- win = 1;
- break;
-
- case 's':
- if (CONST_SCALAR_INT_P (op))
- break;
- case 'i':
- if (CONSTANT_P (op))
- win = 1;
- break;
-
- case 'n':
- if (CONST_SCALAR_INT_P (op))
- win = 1;
- break;
-
- case 'V':
- if (MEM_P (op)
- && ((strict > 0 && ! offsettable_memref_p (op))
- || (strict < 0
- && !(CONSTANT_P (op) || MEM_P (op)))
- || (reload_in_progress
- && !(REG_P (op)
- && REGNO (op) >= FIRST_PSEUDO_REGISTER))))
- win = 1;
- break;
-
- case 'o':
- if ((strict > 0 && offsettable_memref_p (op))
- || (strict == 0 && offsettable_nonstrict_memref_p (op))
- /* Before reload, accept what reload can handle. */
- || (strict < 0
- && (CONSTANT_P (op) || MEM_P (op)))
- /* During reload, accept a pseudo */
- || (reload_in_progress && REG_P (op)
- && REGNO (op) >= FIRST_PSEUDO_REGISTER))
- win = 1;
- break;
-
default:
{
- enum reg_class cl;
- enum constraint_num cn = (c == 'r'
- ? CONSTRAINT__UNKNOWN
- : lookup_constraint (p));
-
- cl = (c == 'r'
- ? GENERAL_REGS : reg_class_for_constraint (cn));
+ enum constraint_num cn = lookup_constraint (p);
+ enum reg_class cl = reg_class_for_constraint (cn);
if (cl != NO_REGS)
{
if (strict < 0
@@ -3227,8 +3048,7 @@ peep2_find_free_register (int from, int to, const char *class_str,
from = peep2_buf_position (from + 1);
}
- cl = (class_str[0] == 'r' ? GENERAL_REGS
- : reg_class_for_constraint (lookup_constraint (class_str)));
+ cl = reg_class_for_constraint (lookup_constraint (class_str));
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
{