diff options
author | amylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-01-09 17:28:49 +0000 |
---|---|---|
committer | amylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-01-09 17:28:49 +0000 |
commit | 48ea55773270391b07804f5d6b4dfb28b7b3bd3f (patch) | |
tree | 71e3146782ec281fdcd5e689d1f1cbbe5f3c2286 /gcc/recog.c | |
parent | f35a3d21a719693dc824d933f7e8ce2d1245addf (diff) | |
download | gcc-48ea55773270391b07804f5d6b4dfb28b7b3bd3f.tar.gz |
* defaults.h (EXTRA_MEMORY_CONSTRAINT): Add STR argument.
(EXTRA_ADDRESS_CONSTRAINT): Likewise.
(CONSTRAINT_LEN): Provide default definition.
(CONST_OK_FOR_CONSTRAINT_P): Likewise.
(CONST_DOUBLE_OK_FOR_CONSTRAINT_P): Likewise.
(EXTRA_CONSTRAINT_STR): Likewise.
(REG_CLASS_FROM_CONSTRAINT): Define.
* genoutput.c (check_constraint_len, constraint_len): New functions.
(validate_insn_alternatives): Check CONSTRAINT_LEN for each
constraint / modifier.
(gen_insn): Call check_constraint_len.
* local-alloc.c (block_alloc): Update to use new macros / pass
second argument to EXTRA_{MEMORY,ADDRESS}_CONSTRAINT.
* ra-build.c (handle_asm_insn): Likewise.
* recog.c (asm_operand_ok, preprocess_constraints): Likewise.
(constrain_operands, peep2_find_free_register): Likewise.
* regclass.c (record_operand_costs, record_reg_classes): Likewise.
* regmove.c (find_matches): Likewise.
* reload.c (push_secondary_reload, find_reloads): Likewise.
(alternative_allows_memconst): Likewise.
* reload1.c (maybe_fix_stack_asms): Likewise.
(reload_cse_simplify_operands): Likewise.
* stmt.c (parse_output_constraint, parse_input_constraint): Likewise.
* doc/tm.texi (CONSTRAINT_LEN, REG_CLASS_FROM_CONSTRAINT): Document.
(CONST_OK_FOR_CONSTRAINT_P): Likewise.
(CONST_DOUBLE_OK_FOR_CONSTRAINT_P, EXTRA_CONSTRAINT_STR): Likewise.
(EXTRA_MEMORY_CONSTRAINT, EXTRA_ADDRESS_CONSTRAINT): Add STR argument.
* config/s390/s390.h (EXTRA_MEMORY_CONSTRAINT): Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@61119 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/recog.c')
-rw-r--r-- | gcc/recog.c | 169 |
1 files changed, 101 insertions, 68 deletions
diff --git a/gcc/recog.c b/gcc/recog.c index 340b2ee8b82..8d36e513e37 100644 --- a/gcc/recog.c +++ b/gcc/recog.c @@ -1681,18 +1681,21 @@ asm_operand_ok (op, constraint) while (*constraint) { - char c = *constraint++; + char c = *constraint; + int len; switch (c) { + case ',': + constraint++; + continue; case '=': case '+': case '*': case '%': - case '?': case '!': case '#': case '&': - case ',': + case '?': break; case '0': case '1': case '2': case '3': case '4': @@ -1701,25 +1704,27 @@ asm_operand_ok (op, constraint) proper matching constraint, but we can't actually fail the check if they didn't. Indicate that results are inconclusive. */ - while (ISDIGIT (*constraint)) + do constraint++; - result = -1; - break; + while (ISDIGIT (*constraint)); + if (! result) + result = -1; + continue; case 'p': if (address_operand (op, VOIDmode)) - return 1; + result = 1; break; case 'm': case 'V': /* non-offsettable */ if (memory_operand (op, VOIDmode)) - return 1; + result = 1; break; case 'o': /* offsettable */ if (offsettable_nonstrict_memref_p (op)) - return 1; + result = 1; break; case '<': @@ -1734,7 +1739,7 @@ asm_operand_ok (op, constraint) && (1 || GET_CODE (XEXP (op, 0)) == PRE_DEC || GET_CODE (XEXP (op, 0)) == POST_DEC)) - return 1; + result = 1; break; case '>': @@ -1742,7 +1747,7 @@ asm_operand_ok (op, constraint) && (1 || GET_CODE (XEXP (op, 0)) == PRE_INC || GET_CODE (XEXP (op, 0)) == POST_INC)) - return 1; + result = 1; break; case 'E': @@ -1750,18 +1755,18 @@ asm_operand_ok (op, constraint) if (GET_CODE (op) == CONST_DOUBLE || (GET_CODE (op) == CONST_VECTOR && GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_FLOAT)) - return 1; + result = 1; break; case 'G': if (GET_CODE (op) == CONST_DOUBLE - && CONST_DOUBLE_OK_FOR_LETTER_P (op, 'G')) - return 1; + && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (op, 'G', constraint)) + result = 1; break; case 'H': if (GET_CODE (op) == CONST_DOUBLE - && CONST_DOUBLE_OK_FOR_LETTER_P (op, 'H')) - return 1; + && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (op, 'H', constraint)) + result = 1; break; case 's': @@ -1777,94 +1782,100 @@ asm_operand_ok (op, constraint) && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op)) #endif ) - return 1; + result = 1; break; case 'n': if (GET_CODE (op) == CONST_INT || (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == VOIDmode)) - return 1; + result = 1; break; case 'I': if (GET_CODE (op) == CONST_INT - && CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')) - return 1; + && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), 'I', constraint)) + result = 1; break; case 'J': if (GET_CODE (op) == CONST_INT - && CONST_OK_FOR_LETTER_P (INTVAL (op), 'J')) - return 1; + && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), 'J', constraint)) + result = 1; break; case 'K': if (GET_CODE (op) == CONST_INT - && CONST_OK_FOR_LETTER_P (INTVAL (op), 'K')) - return 1; + && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), 'K', constraint)) + result = 1; break; case 'L': if (GET_CODE (op) == CONST_INT - && CONST_OK_FOR_LETTER_P (INTVAL (op), 'L')) - return 1; + && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), 'L', constraint)) + result = 1; break; case 'M': if (GET_CODE (op) == CONST_INT - && CONST_OK_FOR_LETTER_P (INTVAL (op), 'M')) - return 1; + && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), 'M', constraint)) + result = 1; break; case 'N': if (GET_CODE (op) == CONST_INT - && CONST_OK_FOR_LETTER_P (INTVAL (op), 'N')) - return 1; + && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), 'N', constraint)) + result = 1; break; case 'O': if (GET_CODE (op) == CONST_INT - && CONST_OK_FOR_LETTER_P (INTVAL (op), 'O')) - return 1; + && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), 'O', constraint)) + result = 1; break; case 'P': if (GET_CODE (op) == CONST_INT - && CONST_OK_FOR_LETTER_P (INTVAL (op), 'P')) - return 1; + && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), 'P', constraint)) + result = 1; break; case 'X': - return 1; + result = 1; case 'g': if (general_operand (op, VOIDmode)) - return 1; + result = 1; break; default: /* For all other letters, we first check for a register class, otherwise it is an EXTRA_CONSTRAINT. */ - if (REG_CLASS_FROM_LETTER (c) != NO_REGS) + if (REG_CLASS_FROM_CONSTRAINT (c, constraint) != NO_REGS) { case 'r': if (GET_MODE (op) == BLKmode) break; if (register_operand (op, VOIDmode)) - return 1; + result = 1; } -#ifdef EXTRA_CONSTRAINT - if (EXTRA_CONSTRAINT (op, c)) - return 1; - if (EXTRA_MEMORY_CONSTRAINT (c)) +#ifdef EXTRA_CONSTRAINT_STR + if (EXTRA_CONSTRAINT_STR (op, c, constraint)) + result = 1; + if (EXTRA_MEMORY_CONSTRAINT (c, constraint)) { /* Every memory operand can be reloaded to fit. */ if (memory_operand (op, VOIDmode)) - return 1; + result = 1; } - if (EXTRA_ADDRESS_CONSTRAINT (c)) + if (EXTRA_ADDRESS_CONSTRAINT (c, constraint)) { /* Every address operand can be reloaded to fit. */ if (address_operand (op, VOIDmode)) - return 1; + result = 1; } #endif break; } + len = CONSTRAINT_LEN (c, constraint); + do + constraint++; + while (--len && *constraint); + if (len) + return 0; } return result; @@ -2233,13 +2244,16 @@ preprocess_constraints () for (;;) { - char c = *p++; + char c = *p; if (c == '#') do - c = *p++; + c = *++p; while (c != ',' && c != '\0'); if (c == ',' || c == '\0') - break; + { + p++; + break; + } switch (c) { @@ -2265,11 +2279,11 @@ preprocess_constraints () case '5': case '6': case '7': case '8': case '9': { char *end; - op_alt[j].matches = strtoul (p - 1, &end, 10); + op_alt[j].matches = strtoul (p, &end, 10); recog_op_alt[op_alt[j].matches][j].matched = i; p = end; } - break; + continue; case 'm': op_alt[j].memory_ok = 1; @@ -2301,22 +2315,28 @@ preprocess_constraints () break; default: - if (EXTRA_MEMORY_CONSTRAINT (c)) + if (EXTRA_MEMORY_CONSTRAINT (c, p)) { op_alt[j].memory_ok = 1; break; } - if (EXTRA_ADDRESS_CONSTRAINT (c)) + if (EXTRA_ADDRESS_CONSTRAINT (c, p)) { op_alt[j].is_address = 1; - op_alt[j].class = reg_class_subunion[(int) op_alt[j].class] - [(int) MODE_BASE_REG_CLASS (VOIDmode)]; + op_alt[j].class + = (reg_class_subunion + [(int) op_alt[j].class] + [(int) MODE_BASE_REG_CLASS (VOIDmode)]); break; } - op_alt[j].class = reg_class_subunion[(int) op_alt[j].class][(int) REG_CLASS_FROM_LETTER ((unsigned char) c)]; + op_alt[j].class + = (reg_class_subunion + [(int) op_alt[j].class] + [(int) REG_CLASS_FROM_CONSTRAINT ((unsigned char) c, p)]); break; } + p += CONSTRAINT_LEN (c, p); } } } @@ -2331,7 +2351,7 @@ preprocess_constraints () alternative of constraints was matched: 0 for the first alternative, 1 for the next, etc. - In addition, when two operands are match + In addition, when two operands are required to match and it happens that the output operand is (reg) while the input operand is --(reg) or ++(reg) (a pre-inc or pre-dec), make the output operand look like the input. @@ -2390,6 +2410,7 @@ constrain_operands (strict) int offset = 0; int win = 0; int val; + int len; earlyclobber[opno] = 0; @@ -2414,9 +2435,16 @@ constrain_operands (strict) if (*p == 0 || *p == ',') win = 1; - while (*p && (c = *p++) != ',') - switch (c) + do + switch (c = *p, len = CONSTRAINT_LEN (c, p), c) { + case '\0': + len = 0; + break; + case ',': + c = '\0'; + break; + case '?': case '!': case '*': case '%': case '=': case '+': break; @@ -2424,8 +2452,10 @@ constrain_operands (strict) case '#': /* Ignore rest of this alternative as far as constraint checking is concerned. */ - while (*p && *p != ',') + do p++; + while (*p && *p != ','); + len = 0; break; case '&': @@ -2447,7 +2477,7 @@ constrain_operands (strict) char *end; int match; - match = strtoul (p - 1, &end, 10); + match = strtoul (p, &end, 10); p = end; if (strict < 0) @@ -2482,6 +2512,7 @@ constrain_operands (strict) funny_match[funny_match_index++].other = match; } } + len = 0; break; case 'p': @@ -2551,7 +2582,7 @@ constrain_operands (strict) case 'G': case 'H': if (GET_CODE (op) == CONST_DOUBLE - && CONST_DOUBLE_OK_FOR_LETTER_P (op, c)) + && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (op, c, p)) win = 1; break; @@ -2581,7 +2612,7 @@ constrain_operands (strict) case 'O': case 'P': if (GET_CODE (op) == CONST_INT - && CONST_OK_FOR_LETTER_P (INTVAL (op), c)) + && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), c, p)) win = 1; break; @@ -2612,7 +2643,8 @@ constrain_operands (strict) { enum reg_class class; - class = (c == 'r' ? GENERAL_REGS : REG_CLASS_FROM_LETTER (c)); + class = (c == 'r' + ? GENERAL_REGS : REG_CLASS_FROM_CONSTRAINT (c, p)); if (class != NO_REGS) { if (strict < 0 @@ -2624,11 +2656,11 @@ constrain_operands (strict) && reg_fits_class_p (op, class, offset, mode))) win = 1; } -#ifdef EXTRA_CONSTRAINT - else if (EXTRA_CONSTRAINT (op, c)) +#ifdef EXTRA_CONSTRAINT_STR + else if (EXTRA_CONSTRAINT_STR (op, c, p)) win = 1; - if (EXTRA_MEMORY_CONSTRAINT (c)) + if (EXTRA_MEMORY_CONSTRAINT (c, p)) { /* Every memory operand can be reloaded to fit. */ if (strict < 0 && GET_CODE (op) == MEM) @@ -2643,7 +2675,7 @@ constrain_operands (strict) && REGNO (op) >= FIRST_PSEUDO_REGISTER) win = 1; } - if (EXTRA_ADDRESS_CONSTRAINT (c)) + if (EXTRA_ADDRESS_CONSTRAINT (c, p)) { /* Every address operand can be reloaded to fit. */ if (strict < 0) @@ -2653,6 +2685,7 @@ constrain_operands (strict) break; } } + while (p += len, c); constraints[opno] = p; /* If this operand did not win somehow, @@ -3009,7 +3042,7 @@ peep2_find_free_register (from, to, class_str, mode, reg_set) } class = (class_str[0] == 'r' ? GENERAL_REGS - : REG_CLASS_FROM_LETTER (class_str[0])); + : REG_CLASS_FROM_CONSTRAINT (class_str[0], class_str)); for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) { |