comparison gcc/genflags.c @ 16:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents f6334be47118
children 84e7813d76e9
comparison
equal deleted inserted replaced
15:561a7518be6b 16:04ced10e8804
1 /* Generate from machine description: 1 /* Generate from machine description:
2 - some flags HAVE_... saying which simple standard instructions are 2 - some flags HAVE_... saying which simple standard instructions are
3 available for this machine. 3 available for this machine.
4 Copyright (C) 1987, 1991, 1995, 1998, 1999, 2000, 2003, 2004, 2007, 2010 4 Copyright (C) 1987-2017 Free Software Foundation, Inc.
5 Free Software Foundation, Inc.
6 5
7 This file is part of GCC. 6 This file is part of GCC.
8 7
9 GCC is free software; you can redistribute it and/or modify it under 8 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free 9 the terms of the GNU General Public License as published by the Free
41 static int max_opno; 40 static int max_opno;
42 41
43 static void max_operand_1 (rtx); 42 static void max_operand_1 (rtx);
44 static int num_operands (rtx); 43 static int num_operands (rtx);
45 static void gen_proto (rtx); 44 static void gen_proto (rtx);
46 static void gen_macro (const char *, int, int);
47 static void gen_insn (int, rtx);
48 45
49 /* Count the number of match_operand's found. */ 46 /* Count the number of match_operand's found. */
50 47
51 static void 48 static void
52 max_operand_1 (rtx x) 49 max_operand_1 (rtx x)
92 max_operand_1 (XVECEXP (insn, 1, i)); 89 max_operand_1 (XVECEXP (insn, 1, i));
93 90
94 return max_opno + 1; 91 return max_opno + 1;
95 } 92 }
96 93
97 /* Print out a wrapper macro for a function which corrects the number
98 of arguments it takes. Any missing arguments are assumed to be at
99 the end. */
100 static void
101 gen_macro (const char *name, int real, int expect)
102 {
103 int i;
104
105 gcc_assert (real <= expect);
106 gcc_assert (real);
107
108 /* #define GEN_CALL(A, B, C, D) gen_call((A), (B)) */
109 fputs ("#define GEN_", stdout);
110 for (i = 0; name[i]; i++)
111 putchar (TOUPPER (name[i]));
112
113 putchar('(');
114 for (i = 0; i < expect - 1; i++)
115 printf ("%c, ", i + 'A');
116 printf ("%c) gen_%s (", i + 'A', name);
117
118 for (i = 0; i < real - 1; i++)
119 printf ("(%c), ", i + 'A');
120 printf ("(%c))\n", i + 'A');
121 }
122
123 /* Print out prototype information for a generator function. If the 94 /* Print out prototype information for a generator function. If the
124 insn pattern has been elided, print out a dummy generator that 95 insn pattern has been elided, print out a dummy generator that
125 does nothing. */ 96 does nothing. */
126 97
127 static void 98 static void
129 { 100 {
130 int num = num_operands (insn); 101 int num = num_operands (insn);
131 int i; 102 int i;
132 const char *name = XSTR (insn, 0); 103 const char *name = XSTR (insn, 0);
133 int truth = maybe_eval_c_test (XSTR (insn, 2)); 104 int truth = maybe_eval_c_test (XSTR (insn, 2));
134
135 /* Many md files don't refer to the last two operands passed to the
136 call patterns. This means their generator functions will be two
137 arguments too short. Instead of changing every md file to touch
138 those operands, we wrap the prototypes in macros that take the
139 correct number of arguments. */
140 if (name[0] == 'c' || name[0] == 's')
141 {
142 if (!strcmp (name, "call")
143 || !strcmp (name, "call_pop")
144 || !strcmp (name, "sibcall")
145 || !strcmp (name, "sibcall_pop"))
146 gen_macro (name, num, 4);
147 else if (!strcmp (name, "call_value")
148 || !strcmp (name, "call_value_pop")
149 || !strcmp (name, "sibcall_value")
150 || !strcmp (name, "sibcall_value_pop"))
151 gen_macro (name, num, 5);
152 }
153 105
154 if (truth != 0) 106 if (truth != 0)
155 printf ("extern rtx gen_%-*s (", max_id_len, name); 107 printf ("extern rtx gen_%-*s (", max_id_len, name);
156 else 108 else
157 printf ("static inline rtx gen_%-*s (", max_id_len, name); 109 printf ("static inline rtx gen_%-*s (", max_id_len, name);
186 } 138 }
187 139
188 } 140 }
189 141
190 static void 142 static void
191 gen_insn (int line_no, rtx insn) 143 gen_insn (md_rtx_info *info)
192 { 144 {
145 rtx insn = info->def;
193 const char *name = XSTR (insn, 0); 146 const char *name = XSTR (insn, 0);
194 const char *p; 147 const char *p;
195 const char *lt, *gt; 148 const char *lt, *gt;
196 int len; 149 int len;
197 int truth = maybe_eval_c_test (XSTR (insn, 2)); 150 int truth = maybe_eval_c_test (XSTR (insn, 2));
198 151
199 lt = strchr (name, '<'); 152 lt = strchr (name, '<');
200 if (lt && strchr (lt + 1, '>')) 153 if (lt && strchr (lt + 1, '>'))
201 { 154 {
202 message_with_line (line_no, "unresolved iterator"); 155 error_at (info->loc, "unresolved iterator");
203 have_error = 1;
204 return; 156 return;
205 } 157 }
206 158
207 gt = strchr (name, '>'); 159 gt = strchr (name, '>');
208 if (lt || gt) 160 if (lt || gt)
209 { 161 {
210 message_with_line (line_no, 162 error_at (info->loc, "unmatched angle brackets, likely "
211 "unmatched angle brackets, likely " 163 "an error in iterator syntax");
212 "an error in iterator syntax");
213 have_error = 1;
214 return; 164 return;
215 } 165 }
216 166
217 /* Don't mention instructions whose names are the null string 167 /* Don't mention instructions whose names are the null string
218 or begin with '*'. They are in the machine description just 168 or begin with '*'. They are in the machine description just
246 196
247 obstack_grow (&obstack, &insn, sizeof (rtx)); 197 obstack_grow (&obstack, &insn, sizeof (rtx));
248 } 198 }
249 199
250 int 200 int
251 main (int argc, char **argv) 201 main (int argc, const char **argv)
252 { 202 {
253 rtx desc;
254 rtx dummy; 203 rtx dummy;
255 rtx *insns; 204 rtx *insns;
256 rtx *insn_ptr; 205 rtx *insn_ptr;
257 206
258 progname = "genflags"; 207 progname = "genflags";
270 puts ("#ifndef GCC_INSN_FLAGS_H"); 219 puts ("#ifndef GCC_INSN_FLAGS_H");
271 puts ("#define GCC_INSN_FLAGS_H\n"); 220 puts ("#define GCC_INSN_FLAGS_H\n");
272 221
273 /* Read the machine description. */ 222 /* Read the machine description. */
274 223
275 while (1) 224 md_rtx_info info;
276 { 225 while (read_md_rtx (&info))
277 int line_no, insn_code_number = 0; 226 switch (GET_CODE (info.def))
278 227 {
279 desc = read_md_rtx (&line_no, &insn_code_number); 228 case DEFINE_INSN:
280 if (desc == NULL) 229 case DEFINE_EXPAND:
230 gen_insn (&info);
281 break; 231 break;
282 if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND) 232
283 gen_insn (line_no, desc); 233 default:
284 } 234 break;
235 }
285 236
286 /* Print out the prototypes now. */ 237 /* Print out the prototypes now. */
287 dummy = (rtx) 0; 238 dummy = (rtx) 0;
288 obstack_grow (&obstack, &dummy, sizeof (rtx)); 239 obstack_grow (&obstack, &dummy, sizeof (rtx));
289 insns = XOBFINISH (&obstack, rtx *); 240 insns = XOBFINISH (&obstack, rtx *);
290 241
291 for (insn_ptr = insns; *insn_ptr; insn_ptr++) 242 for (insn_ptr = insns; *insn_ptr; insn_ptr++)
292 gen_proto (*insn_ptr); 243 gen_proto (*insn_ptr);
293 244
294 puts("\n#endif /* GCC_INSN_FLAGS_H */"); 245 puts ("\n#endif /* GCC_INSN_FLAGS_H */");
295 246
296 if (have_error || ferror (stdout) || fflush (stdout) || fclose (stdout)) 247 if (have_error || ferror (stdout) || fflush (stdout) || fclose (stdout))
297 return FATAL_EXIT_CODE; 248 return FATAL_EXIT_CODE;
298 249
299 return SUCCESS_EXIT_CODE; 250 return SUCCESS_EXIT_CODE;