diff options
author | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-06-11 16:59:17 +0000 |
---|---|---|
committer | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-06-11 16:59:17 +0000 |
commit | 694494638c9f211c1e27c6c08b0d8dc7656e24e8 (patch) | |
tree | ebbbc6a5c16fb2f71c030dc719d566bd7b2d0538 /gcc/recog.c | |
parent | e3c57fd265541f5124639cc88955fb68edcbcdc8 (diff) | |
download | gcc-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.c | 234 |
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++) { |