aboutsummaryrefslogtreecommitdiff
path: root/gcc/recog.c
diff options
context:
space:
mode:
authorBernd Schmidt <crux@pool.informatik.rwth-aachen.de>1998-12-04 12:55:59 +0000
committerBernd Schmidt <crux@gcc.gnu.org>1998-12-04 12:55:59 +0000
commitf62a15e367dd53a270f7766c5c62a82629478d3e (patch)
tree7eac8b63b458dd5da67b48a5a4d8ca0d0304223f /gcc/recog.c
parent71eb0b9ec35acd4843115354a94be4dcb150f7af (diff)
downloadgcc-f62a15e367dd53a270f7766c5c62a82629478d3e.zip
gcc-f62a15e367dd53a270f7766c5c62a82629478d3e.tar.gz
gcc-f62a15e367dd53a270f7766c5c62a82629478d3e.tar.bz2
final.c (cleanup_subreg_operands): Delete some unused code.
* final.c (cleanup_subreg_operands): Delete some unused code. * recog.h (MAX_RECOG_ALTERNATIVES): New macro. (struct insn_alternative): New structure definition. (recog_op_alt): Declare variable. (preprocess_constraints): Declare function. * recog.c (recog_op_alt): New variable. (extract_insn): Verify number of alternatives is in range. (preprocess_constraints): New function. * reg-stack.c: Include recog.h. (constrain_asm_operands): Delete. (get_asm_operand_lengths): Delete. (get_asm_operand_n_inputs): New function. (record_asm_reg_life): Delete OPERANDS, CONSTRAINTS, N_INPUTS and N_OUTPUTS args. All callers changed. Compute number of inputs and outputs here by calling get_asm_operand_n_inputs. Instead of constrain_asm_operands, call extract_insn, constrain_operands and preprocess_constaints. Use information computed by these functions throughout. (record_reg_life): Delete code that is unused due to changes in record_asm_reg_life. (subst_asm_stack_regs): Delete OPERANDS, OPERAND_LOC, CONSTRAINTS, N_INPUTS and N_OUTPUTS args. All callers changed. Similar changes as in record_asm_reg_life. (subst_stack_regs): Move n_operands declaration into the if statement where it's used. Delete code that is unused due to changes in subst_asm_stack_regs. * stmt.c (expand_asm_operands): Verify number of alternatives is in range. * Makefile.in (reg-stack.o): Depend on recog.h. From-SVN: r24090
Diffstat (limited to 'gcc/recog.c')
-rw-r--r--gcc/recog.c111
1 files changed, 111 insertions, 0 deletions
diff --git a/gcc/recog.c b/gcc/recog.c
index 6ae7a31..19bc3b2 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -96,6 +96,10 @@ enum op_type recog_op_type[MAX_RECOG_OPERANDS];
char recog_operand_address_p[MAX_RECOG_OPERANDS];
#endif
+/* Contains a vector of operand_alternative structures for every operand.
+ Set up by preprocess_constraints. */
+struct operand_alternative recog_op_alt[MAX_RECOG_OPERANDS][MAX_RECOG_ALTERNATIVES];
+
/* On return from `constrain_operands', indicate which alternative
was satisfied. */
@@ -1803,8 +1807,115 @@ extract_insn (insn)
recog_op_type[i] = (recog_constraints[i][0] == '=' ? OP_OUT
: recog_constraints[i][0] == '+' ? OP_INOUT
: OP_IN);
+
+ if (recog_n_alternatives > MAX_RECOG_ALTERNATIVES)
+ abort ();
}
+/* After calling extract_insn, you can use this function to extract some
+ information from the constraint strings into a more usable form.
+ The collected data is stored in recog_op_alt. */
+void
+preprocess_constraints ()
+{
+ int i;
+
+ for (i = 0; i < recog_n_operands; i++)
+ {
+ int j;
+ struct operand_alternative *op_alt;
+ char *p = recog_constraints[i];
+
+ op_alt = recog_op_alt[i];
+
+ for (j = 0; j < recog_n_alternatives; j++)
+ {
+ op_alt[j].class = NO_REGS;
+ op_alt[j].constraint = p;
+ op_alt[j].matches = -1;
+ op_alt[j].matched = -1;
+
+ if (*p == '\0' || *p == ',')
+ {
+ op_alt[j].anything_ok = 1;
+ continue;
+ }
+
+ for (;;)
+ {
+ char c = *p++;
+ if (c == '#')
+ do
+ c = *p++;
+ while (c != ',' && c != '\0');
+ if (c == ',' || c == '\0')
+ break;
+
+ 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':
+#ifdef EXTRA_CONSTRAINT
+ case 'Q': case 'R': case 'S': case 'T': case 'U':
+#endif
+ /* These don't say anything we care about. */
+ break;
+
+ case '?':
+ op_alt[j].reject += 6;
+ break;
+ case '!':
+ op_alt[j].reject += 600;
+ break;
+ case '&':
+ op_alt[j].earlyclobber = 1;
+ break;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ op_alt[j].matches = c - '0';
+ op_alt[op_alt[j].matches].matched = i;
+ break;
+
+ case 'm':
+ op_alt[j].memory_ok = 1;
+ break;
+ case '<':
+ op_alt[j].decmem_ok = 1;
+ break;
+ case '>':
+ op_alt[j].incmem_ok = 1;
+ break;
+ case 'V':
+ op_alt[j].nonoffmem_ok = 1;
+ break;
+ case 'o':
+ op_alt[j].offmem_ok = 1;
+ break;
+ case 'X':
+ op_alt[j].anything_ok = 1;
+ break;
+
+ case 'p':
+ op_alt[j].class = reg_class_subunion[(int) op_alt[j].class][(int) BASE_REG_CLASS];
+ break;
+
+ case 'g': case 'r':
+ op_alt[j].class = reg_class_subunion[(int) op_alt[j].class][(int) GENERAL_REGS];
+ break;
+
+ default:
+ op_alt[j].class = reg_class_subunion[(int) op_alt[j].class][(int) REG_CLASS_FROM_LETTER (c)];
+ break;
+ }
+ }
+ }
+ }
+}
+
#ifdef REGISTER_CONSTRAINTS
/* Check the operands of an insn against the insn's operand constraints