Mercurial > hg > CbC > CbC_gcc
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) |