comparison gcc/genoutput.c @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
comparison
equal deleted inserted replaced
131:84e7813d76e9 145:1830386684a0
1 /* Generate code from to output assembler insns as recognized from rtl. 1 /* Generate code from to output assembler insns as recognized from rtl.
2 Copyright (C) 1987-2018 Free Software Foundation, Inc. 2 Copyright (C) 1987-2020 Free Software Foundation, Inc.
3 3
4 This file is part of GCC. 4 This file is part of GCC.
5 5
6 GCC is free software; you can redistribute it and/or modify it under 6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free 7 the terms of the GNU General Public License as published by the Free
141 #define INSN_OUTPUT_FORMAT_FUNCTION 3 /* const char * (*)(...) */ 141 #define INSN_OUTPUT_FORMAT_FUNCTION 3 /* const char * (*)(...) */
142 142
143 /* Record in this chain all information that we will output, 143 /* Record in this chain all information that we will output,
144 associated with the code number of the insn. */ 144 associated with the code number of the insn. */
145 145
146 struct data 146 class data
147 { 147 {
148 struct data *next; 148 public:
149 class data *next;
149 const char *name; 150 const char *name;
150 const char *template_code; 151 const char *template_code;
151 file_location loc; 152 file_location loc;
152 int code_number; 153 int code_number;
153 int n_generator_args; /* Number of arguments passed to generator */ 154 int n_generator_args; /* Number of arguments passed to generator */
158 int output_format; /* INSN_OUTPUT_FORMAT_*. */ 159 int output_format; /* INSN_OUTPUT_FORMAT_*. */
159 struct operand_data operand[MAX_MAX_OPERANDS]; 160 struct operand_data operand[MAX_MAX_OPERANDS];
160 }; 161 };
161 162
162 /* This variable points to the first link in the insn chain. */ 163 /* This variable points to the first link in the insn chain. */
163 static struct data *idata; 164 static class data *idata;
164 165
165 /* This variable points to the end of the insn chain. This is where 166 /* This variable points to the end of the insn chain. This is where
166 everything relevant from the machien description is appended to. */ 167 everything relevant from the machien description is appended to. */
167 static struct data **idata_end; 168 static class data **idata_end;
168 169
169 170
170 static void output_prologue (void); 171 static void output_prologue (void);
171 static void output_operand_data (void); 172 static void output_operand_data (void);
172 static void output_insn_data (void); 173 static void output_insn_data (void);
173 static void output_get_insn_name (void); 174 static void output_get_insn_name (void);
174 static void scan_operands (struct data *, rtx, int, int); 175 static void scan_operands (class data *, rtx, int, int);
175 static int compare_operands (struct operand_data *, 176 static int compare_operands (struct operand_data *,
176 struct operand_data *); 177 struct operand_data *);
177 static void place_operands (struct data *); 178 static void place_operands (class data *);
178 static void process_template (struct data *, const char *); 179 static void process_template (class data *, const char *);
179 static void validate_insn_alternatives (struct data *); 180 static void validate_insn_alternatives (class data *);
180 static void validate_insn_operands (struct data *); 181 static void validate_insn_operands (class data *);
181 182
182 struct constraint_data 183 class constraint_data
183 { 184 {
184 struct constraint_data *next_this_letter; 185 public:
186 class constraint_data *next_this_letter;
185 file_location loc; 187 file_location loc;
186 unsigned int namelen; 188 unsigned int namelen;
187 char name[1]; 189 char name[1];
188 }; 190 };
189 191
190 /* All machine-independent constraint characters (except digits) that 192 /* All machine-independent constraint characters (except digits) that
191 are handled outside the define*_constraint mechanism. */ 193 are handled outside the define*_constraint mechanism. */
192 static const char indep_constraints[] = ",=+%*?!^$#&g"; 194 static const char indep_constraints[] = ",=+%*?!^$#&g";
193 195
194 static struct constraint_data * 196 static class constraint_data *
195 constraints_by_letter_table[1 << CHAR_BIT]; 197 constraints_by_letter_table[1 << CHAR_BIT];
196 198
197 static int mdep_constraint_len (const char *, file_location, int); 199 static int mdep_constraint_len (const char *, file_location, int);
198 static void note_constraint (md_rtx_info *); 200 static void note_constraint (md_rtx_info *);
199 201
273 } 275 }
274 276
275 static void 277 static void
276 output_insn_data (void) 278 output_insn_data (void)
277 { 279 {
278 struct data *d; 280 class data *d;
279 int name_offset = 0; 281 int name_offset = 0;
280 int next_name_offset; 282 int next_name_offset;
281 const char * last_name = 0; 283 const char * last_name = 0;
282 const char * next_name = 0; 284 const char * next_name = 0;
283 struct data *n; 285 class data *n;
284 286
285 for (n = idata, next_name_offset = 1; n; n = n->next, next_name_offset++) 287 for (n = idata, next_name_offset = 1; n; n = n->next, next_name_offset++)
286 if (n->name) 288 if (n->name)
287 { 289 {
288 next_name = n->name; 290 next_name = n->name;
419 421
420 THIS_ADDRESS_P is nonzero if the containing rtx was an ADDRESS. 422 THIS_ADDRESS_P is nonzero if the containing rtx was an ADDRESS.
421 THIS_STRICT_LOW is nonzero if the containing rtx was a STRICT_LOW_PART. */ 423 THIS_STRICT_LOW is nonzero if the containing rtx was a STRICT_LOW_PART. */
422 424
423 static void 425 static void
424 scan_operands (struct data *d, rtx part, int this_address_p, 426 scan_operands (class data *d, rtx part, int this_address_p,
425 int this_strict_low) 427 int this_strict_low)
426 { 428 {
427 int i, j; 429 int i, j;
428 const char *format_ptr; 430 const char *format_ptr;
429 int opno; 431 int opno;
561 563
562 /* Scan the list of operands we've already committed to output and either 564 /* Scan the list of operands we've already committed to output and either
563 find a subsequence that is the same, or allocate a new one at the end. */ 565 find a subsequence that is the same, or allocate a new one at the end. */
564 566
565 static void 567 static void
566 place_operands (struct data *d) 568 place_operands (class data *d)
567 { 569 {
568 struct operand_data *od, *od2; 570 struct operand_data *od, *od2;
569 int i; 571 int i;
570 572
571 if (d->n_operands == 0) 573 if (d->n_operands == 0)
615 /* Process an assembler template from a define_insn or a define_peephole. 617 /* Process an assembler template from a define_insn or a define_peephole.
616 It is either the assembler code template, a list of assembler code 618 It is either the assembler code template, a list of assembler code
617 templates, or C code to generate the assembler code template. */ 619 templates, or C code to generate the assembler code template. */
618 620
619 static void 621 static void
620 process_template (struct data *d, const char *template_code) 622 process_template (class data *d, const char *template_code)
621 { 623 {
622 const char *cp; 624 const char *cp;
623 int i; 625 int i;
624 626
625 /* Templates starting with * contain straight code to be run. */ 627 /* Templates starting with * contain straight code to be run. */
738 } 740 }
739 741
740 /* Check insn D for consistency in number of constraint alternatives. */ 742 /* Check insn D for consistency in number of constraint alternatives. */
741 743
742 static void 744 static void
743 validate_insn_alternatives (struct data *d) 745 validate_insn_alternatives (class data *d)
744 { 746 {
745 int n = 0, start; 747 int n = 0, start;
746 748
747 /* Make sure all the operands have the same number of alternatives 749 /* Make sure all the operands have the same number of alternatives
748 in their constraints. Let N be that number. */ 750 in their constraints. Let N be that number. */
821 } 823 }
822 824
823 /* Verify that there are no gaps in operand numbers for INSNs. */ 825 /* Verify that there are no gaps in operand numbers for INSNs. */
824 826
825 static void 827 static void
826 validate_insn_operands (struct data *d) 828 validate_insn_operands (class data *d)
827 { 829 {
828 int i; 830 int i;
829 831
830 for (i = 0; i < d->n_operands; ++i) 832 for (i = 0; i < d->n_operands; ++i)
831 if (d->operand[i].seen == 0) 833 if (d->operand[i].seen == 0)
832 error_at (d->loc, "missing operand %d", i); 834 error_at (d->loc, "missing operand %d", i);
833 } 835 }
834 836
835 static void 837 static void
836 validate_optab_operands (struct data *d) 838 validate_optab_operands (class data *d)
837 { 839 {
838 if (!d->name || d->name[0] == '\0' || d->name[0] == '*') 840 if (!d->name || d->name[0] == '\0' || d->name[0] == '*')
839 return; 841 return;
840 842
841 /* Miscellaneous tests. */ 843 /* Miscellaneous tests. */
976 } 978 }
977 979
978 static void 980 static void
979 init_insn_for_nothing (void) 981 init_insn_for_nothing (void)
980 { 982 {
981 idata = XCNEW (struct data); 983 idata = XCNEW (class data);
982 new (idata) data (); 984 new (idata) data ();
983 idata->name = "*placeholder_for_nothing"; 985 idata->name = "*placeholder_for_nothing";
984 idata->loc = file_location ("<internal>", 0, 0); 986 idata->loc = file_location ("<internal>", 0, 0);
985 idata_end = &idata->next; 987 idata_end = &idata->next;
986 } 988 }
1084 static void 1086 static void
1085 note_constraint (md_rtx_info *info) 1087 note_constraint (md_rtx_info *info)
1086 { 1088 {
1087 rtx exp = info->def; 1089 rtx exp = info->def;
1088 const char *name = XSTR (exp, 0); 1090 const char *name = XSTR (exp, 0);
1089 struct constraint_data **iter, **slot, *new_cdata; 1091 class constraint_data **iter, **slot, *new_cdata;
1090 1092
1091 if (strcmp (name, "TARGET_MEM_CONSTRAINT") == 0) 1093 if (strcmp (name, "TARGET_MEM_CONSTRAINT") == 0)
1092 name = general_mem; 1094 name = general_mem;
1093 unsigned int namelen = strlen (name); 1095 unsigned int namelen = strlen (name);
1094 1096
1134 message_at ((*iter)->loc, "of constraint '%s' " 1136 message_at ((*iter)->loc, "of constraint '%s' "
1135 "(defined here)", (*iter)->name); 1137 "(defined here)", (*iter)->name);
1136 return; 1138 return;
1137 } 1139 }
1138 } 1140 }
1139 new_cdata = XNEWVAR (struct constraint_data, 1141 new_cdata = XNEWVAR (class constraint_data,
1140 sizeof (struct constraint_data) + namelen); 1142 sizeof (class constraint_data) + namelen);
1141 new (new_cdata) constraint_data (); 1143 new (new_cdata) constraint_data ();
1142 strcpy (CONST_CAST (char *, new_cdata->name), name); 1144 strcpy (CONST_CAST (char *, new_cdata->name), name);
1143 new_cdata->namelen = namelen; 1145 new_cdata->namelen = namelen;
1144 new_cdata->loc = info->loc; 1146 new_cdata->loc = info->loc;
1145 new_cdata->next_this_letter = *slot; 1147 new_cdata->next_this_letter = *slot;
1151 is no such constraint. Does not expect to be called for generic 1153 is no such constraint. Does not expect to be called for generic
1152 constraints. */ 1154 constraints. */
1153 static int 1155 static int
1154 mdep_constraint_len (const char *s, file_location loc, int opno) 1156 mdep_constraint_len (const char *s, file_location loc, int opno)
1155 { 1157 {
1156 struct constraint_data *p; 1158 class constraint_data *p;
1157 1159
1158 p = constraints_by_letter_table[(unsigned int)s[0]]; 1160 p = constraints_by_letter_table[(unsigned int)s[0]];
1159 1161
1160 if (p) 1162 if (p)
1161 for (; p; p = p->next_this_letter) 1163 for (; p; p = p->next_this_letter)