summaryrefslogtreecommitdiff
path: root/gcc/genoutput.c
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>1999-09-14 04:19:34 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>1999-09-14 04:19:34 +0000
commitae9660c87616b7088dee7ed41b203b5fdea0217c (patch)
treeddfa019fe74f8976a92fcdd7a45d5f6e82b77a46 /gcc/genoutput.c
parentd3cc0e20db1d458bd162b59a3ed4eb423ea9eb2c (diff)
downloadgcc-ae9660c87616b7088dee7ed41b203b5fdea0217c.tar.gz
* recog.h (INSN_OUTPUT_FORMAT_*): New.
(struct insn_data): Merge `template' and `outfun' into `output'. Add `output_format'. * genoutput.c (INSN_OUTPUT_FORMAT_*): New. (struct data): Remove `outfun'; add `output_format'. (name_for_index): Remove declaration. (output_insn_data): Handle output formats. (process_template): Emit the bare array for @. (gen_expand, gen_split): Set output_format to NONE. * output.h (get_insn_template): Declare. * final.c (get_insn_template): New. (final_scan_insn): Use it. * toplev.c (compile_file): Likewise. * c4x/c4x.c (c4x_process_after_reload): Likewise. * i860/i860.c (output_delayed_branch): Likewise. (output_delay_insn): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@29389 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/genoutput.c')
-rw-r--r--gcc/genoutput.c133
1 files changed, 61 insertions, 72 deletions
diff --git a/gcc/genoutput.c b/gcc/genoutput.c
index 9c44d7e6475..d40433f2942 100644
--- a/gcc/genoutput.c
+++ b/gcc/genoutput.c
@@ -29,27 +29,24 @@ Boston, MA 02111-1307, USA. */
a. `name' is the name for that pattern. Nameless patterns are
given a name.
- b. `template' is the template for output of that insn,
-
- c. `outfun' is the function that returns a template to use for output of
- that insn. This is used only in the cases where the template is not
- constant. These cases are specified by a * or @ at the beginning of the
- template string in the machine description. They are identified for the
- sake of other parts of the compiler by a zero element in `template'.
-
- d. `genfun' is the function to generate a body for that pattern,
+ b. `output' hold either the output template, an array of output
+ templates, or an output function.
+
+ c. `genfun' is the function to generate a body for that pattern,
given operands as arguments.
- e. `n_operands' is the number of distinct operands in the pattern
+ d. `n_operands' is the number of distinct operands in the pattern
for that insn,
- f. `n_dups' is the number of match_dup's that appear in the insn's
+ e. `n_dups' is the number of match_dup's that appear in the insn's
pattern. This says how many elements of `recog_data.dup_loc' are
significant after an insn has been recognized.
- g. `n_alternatives' is the number of alternatives in the constraints
+ f. `n_alternatives' is the number of alternatives in the constraints
of each pattern.
+ g. `output_format' tells what type of thing `output' is.
+
h. `operand' is the base of an array of operand data for the insn.
2. An array of `struct insn_operand data', used by `operand' above.
@@ -144,6 +141,13 @@ static struct operand_data null_operand =
static struct operand_data *odata = &null_operand;
static struct operand_data **odata_end = &null_operand.next;
+/* Must match the constants in recog.h. */
+
+#define INSN_OUTPUT_FORMAT_NONE 0 /* abort */
+#define INSN_OUTPUT_FORMAT_SINGLE 1 /* const char * */
+#define INSN_OUTPUT_FORMAT_MULTI 2 /* const char * const * */
+#define INSN_OUTPUT_FORMAT_FUNCTION 3 /* const char * (*)(...) */
+
/* Record in this chain all information that we will output,
associated with the code number of the insn. */
@@ -151,14 +155,14 @@ struct data
{
struct data *next;
char *name;
- char *template; /* string such as "movl %1,%0" */
+ char *template;
int code_number;
int index_number;
int n_operands; /* Number of operands this insn recognizes */
int n_dups; /* Number times match_dup appears in pattern */
int n_alternatives; /* Number of alternatives in each constraint */
- char outfun; /* Nonzero means this has an output function */
int operand_number; /* Operand index in the big array. */
+ int output_format; /* INSN_OUTPUT_FORMAT_*. */
struct operand_data operand[MAX_MAX_OPERANDS];
};
@@ -172,7 +176,6 @@ static struct data *idata, **idata_end = &idata;
static int have_constraints;
-static char * name_for_index PROTO((int));
static void output_prologue PROTO((void));
static void output_predicate_decls PROTO((void));
static void output_operand_data PROTO((void));
@@ -353,15 +356,21 @@ output_insn_data ()
printf (" \"%s+%d\",\n", last_name, name_offset);
}
- if (d->template)
- printf (" \"%s\",\n", d->template);
- else
- printf (" 0,\n");
-
- if (d->outfun)
- printf (" output_%d,\n", d->code_number);
- else
- printf (" 0,\n");
+ switch (d->output_format)
+ {
+ case INSN_OUTPUT_FORMAT_NONE:
+ printf (" 0,\n");
+ break;
+ case INSN_OUTPUT_FORMAT_SINGLE:
+ printf (" \"%s\",\n", d->template);
+ break;
+ case INSN_OUTPUT_FORMAT_MULTI:
+ case INSN_OUTPUT_FORMAT_FUNCTION:
+ printf (" output_%d,\n", d->code_number);
+ break;
+ default:
+ abort ();
+ }
if (d->name && d->name[0] != '*')
printf (" gen_%s,\n", d->name);
@@ -371,7 +380,8 @@ output_insn_data ()
printf (" &operand_data[%d],\n", d->operand_number);
printf (" %d,\n", d->n_operands);
printf (" %d,\n", d->n_dups);
- printf (" %d\n", d->n_alternatives);
+ printf (" %d,\n", d->n_alternatives);
+ printf (" %d\n", d->output_format);
printf(" },\n");
}
@@ -637,44 +647,39 @@ process_template (d, template)
register char *cp;
register int i;
- /* We need to consider only the instructions whose assembler code template
- starts with a * or @. These are the ones where C code is run to decide
- on a template to use. So for all others just return now. */
-
- if (template[0] != '*' && template[0] != '@')
+ /* Templates starting with * contain straight code to be run. */
+ if (template[0] == '*')
{
- d->template = template;
- d->outfun = 0;
- return;
- }
+ d->template = 0;
+ d->output_format = INSN_OUTPUT_FORMAT_FUNCTION;
- d->template = 0;
- d->outfun = 1;
-
- printf ("\nstatic const char *output_%d PROTO ((rtx *, rtx));\n",
- d->code_number);
- printf ("\nstatic const char *\n");
- printf ("output_%d (operands, insn)\n", d->code_number);
- printf (" rtx *operands ATTRIBUTE_UNUSED;\n");
- printf (" rtx insn ATTRIBUTE_UNUSED;\n");
- printf ("{\n");
+ printf ("\nstatic const char *output_%d PROTO ((rtx *, rtx));\n",
+ d->code_number);
+ puts ("\nstatic const char *");
+ printf ("output_%d (operands, insn)\n", d->code_number);
+ puts (" rtx *operands ATTRIBUTE_UNUSED;");
+ puts (" rtx insn ATTRIBUTE_UNUSED;");
+ puts ("{");
+
+ puts (template + 1);
+ puts ("}");
+ }
/* If the assembler code template starts with a @ it is a newline-separated
- list of assembler code templates, one for each alternative. So produce
- a routine to select the correct one. */
-
- if (template[0] == '@')
+ list of assembler code templates, one for each alternative. */
+ else if (template[0] == '@')
{
+ d->template = 0;
+ d->output_format = INSN_OUTPUT_FORMAT_MULTI;
- printf (" static const char *const strings_%d[] = {\n",
- d->code_number);
+ printf ("\nstatic const char * const output_%d[] = {\n", d->code_number);
for (i = 0, cp = &template[1]; *cp; )
{
while (*cp == '\n' || *cp == ' ' || *cp== '\t')
cp++;
- printf (" \"");
+ printf (" \"");
while (*cp != '\n' && *cp != '\0')
{
putchar (*cp);
@@ -685,29 +690,13 @@ process_template (d, template)
i++;
}
- printf (" };\n");
- printf (" return strings_%d[which_alternative];\n", d->code_number);
-
- if (i != d->n_alternatives)
- fatal ("Insn pattern %d has %d alternatives but %d assembler choices",
- d->index_number, d->n_alternatives, i);
-
+ printf ("};\n");
}
else
{
- /* The following is done in a funny way to get around problems in
- VAX-11 "C" on VMS. It is the equivalent of:
- printf ("%s\n", &template[1])); */
- cp = &template[1];
- while (*cp)
- {
- putchar (*cp);
- cp++;
- }
- putchar ('\n');
+ d->template = template;
+ d->output_format = INSN_OUTPUT_FORMAT_SINGLE;
}
-
- printf ("}\n");
}
/* Check insn D for consistency in number of constraint alternatives. */
@@ -849,7 +838,7 @@ gen_expand (insn)
d->n_operands = max_opno + 1;
d->n_dups = num_dups;
d->template = 0;
- d->outfun = 0;
+ d->output_format = INSN_OUTPUT_FORMAT_NONE;
validate_insn_alternatives (d);
place_operands (d);
@@ -889,7 +878,7 @@ gen_split (split)
d->n_dups = 0;
d->n_alternatives = 0;
d->template = 0;
- d->outfun = 0;
+ d->output_format = INSN_OUTPUT_FORMAT_NONE;
place_operands (d);
}