daily update
[binutils.git] / opcodes / i386-gen.c
blobb9d055ff5249ccecde3fcc9cc2b4a8a46046474d
1 /* Copyright 2007, 2008 Free Software Foundation, Inc.
3 This file is part of the GNU opcodes library.
5 This library is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3, or (at your option)
8 any later version.
10 It is distributed in the hope that it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
13 License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
18 MA 02110-1301, USA. */
20 #include "sysdep.h"
21 #include <stdio.h>
22 #include <errno.h>
23 #include "getopt.h"
24 #include "libiberty.h"
25 #include "hashtab.h"
26 #include "safe-ctype.h"
28 #include "i386-opc.h"
30 #include <libintl.h>
31 #define _(String) gettext (String)
33 static const char *program_name = NULL;
34 static int debug = 0;
36 typedef struct initializer
38 const char *name;
39 const char *init;
40 } initializer;
42 static initializer cpu_flag_init [] =
44 { "CPU_UNKNOWN_FLAGS",
45 "unknown" },
46 { "CPU_GENERIC32_FLAGS",
47 "Cpu186|Cpu286|Cpu386" },
48 { "CPU_GENERIC64_FLAGS",
49 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2|CpuLM" },
50 { "CPU_NONE_FLAGS",
51 "0" },
52 { "CPU_I186_FLAGS",
53 "Cpu186" },
54 { "CPU_I286_FLAGS",
55 "Cpu186|Cpu286" },
56 { "CPU_I386_FLAGS",
57 "Cpu186|Cpu286|Cpu386" },
58 { "CPU_I486_FLAGS",
59 "Cpu186|Cpu286|Cpu386|Cpu486" },
60 { "CPU_I586_FLAGS",
61 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
62 { "CPU_I686_FLAGS",
63 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686" },
64 { "CPU_P2_FLAGS",
65 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuMMX" },
66 { "CPU_P3_FLAGS",
67 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuMMX|CpuSSE" },
68 { "CPU_P4_FLAGS",
69 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2" },
70 { "CPU_NOCONA_FLAGS",
71 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuLM" },
72 { "CPU_CORE_FLAGS",
73 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
74 { "CPU_CORE2_FLAGS",
75 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuLM" },
76 { "CPU_K6_FLAGS",
77 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuK6|CpuMMX" },
78 { "CPU_K6_2_FLAGS",
79 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuK6|CpuMMX|Cpu3dnow" },
80 { "CPU_ATHLON_FLAGS",
81 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuK6|CpuMMX|Cpu3dnow|Cpu3dnowA" },
82 { "CPU_K8_FLAGS",
83 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuK6|CpuK8|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuLM" },
84 { "CPU_AMDFAM10_FLAGS",
85 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuK6|CpuK8|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM" },
86 { "CPU_MMX_FLAGS",
87 "CpuMMX" },
88 { "CPU_SSE_FLAGS",
89 "CpuMMX|CpuSSE" },
90 { "CPU_SSE2_FLAGS",
91 "CpuMMX|CpuSSE|CpuSSE2" },
92 { "CPU_SSE3_FLAGS",
93 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
94 { "CPU_SSSE3_FLAGS",
95 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3" },
96 { "CPU_SSE4_1_FLAGS",
97 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1" },
98 { "CPU_SSE4_2_FLAGS",
99 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2" },
100 { "CPU_VMX_FLAGS",
101 "CpuVMX" },
102 { "CPU_SMX_FLAGS",
103 "CpuSMX" },
104 { "CPU_XSAVE_FLAGS",
105 "CpuXsave" },
106 { "CPU_AES_FLAGS",
107 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAES" },
108 { "CPU_PCLMUL_FLAGS",
109 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuPCLMUL" },
110 { "CPU_FMA_FLAGS",
111 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA" },
112 { "CPU_MOVBE_FLAGS",
113 "CpuMovbe" },
114 { "CPU_EPT_FLAGS",
115 "CpuEPT" },
116 { "CPU_3DNOW_FLAGS",
117 "CpuMMX|Cpu3dnow" },
118 { "CPU_3DNOWA_FLAGS",
119 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
120 { "CPU_PADLOCK_FLAGS",
121 "CpuPadLock" },
122 { "CPU_SVME_FLAGS",
123 "CpuSVME" },
124 { "CPU_SSE4A_FLAGS",
125 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
126 { "CPU_ABM_FLAGS",
127 "CpuABM" },
128 { "CPU_SSE5_FLAGS",
129 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuSSE5"},
130 { "CPU_AVX_FLAGS",
131 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
134 static initializer operand_type_init [] =
136 { "OPERAND_TYPE_NONE",
137 "0" },
138 { "OPERAND_TYPE_REG8",
139 "Reg8" },
140 { "OPERAND_TYPE_REG16",
141 "Reg16" },
142 { "OPERAND_TYPE_REG32",
143 "Reg32" },
144 { "OPERAND_TYPE_REG64",
145 "Reg64" },
146 { "OPERAND_TYPE_IMM1",
147 "Imm1" },
148 { "OPERAND_TYPE_IMM8",
149 "Imm8" },
150 { "OPERAND_TYPE_IMM8S",
151 "Imm8S" },
152 { "OPERAND_TYPE_IMM16",
153 "Imm16" },
154 { "OPERAND_TYPE_IMM32",
155 "Imm32" },
156 { "OPERAND_TYPE_IMM32S",
157 "Imm32S" },
158 { "OPERAND_TYPE_IMM64",
159 "Imm64" },
160 { "OPERAND_TYPE_BASEINDEX",
161 "BaseIndex" },
162 { "OPERAND_TYPE_DISP8",
163 "Disp8" },
164 { "OPERAND_TYPE_DISP16",
165 "Disp16" },
166 { "OPERAND_TYPE_DISP32",
167 "Disp32" },
168 { "OPERAND_TYPE_DISP32S",
169 "Disp32S" },
170 { "OPERAND_TYPE_DISP64",
171 "Disp64" },
172 { "OPERAND_TYPE_INOUTPORTREG",
173 "InOutPortReg" },
174 { "OPERAND_TYPE_SHIFTCOUNT",
175 "ShiftCount" },
176 { "OPERAND_TYPE_CONTROL",
177 "Control" },
178 { "OPERAND_TYPE_TEST",
179 "Test" },
180 { "OPERAND_TYPE_DEBUG",
181 "FloatReg" },
182 { "OPERAND_TYPE_FLOATREG",
183 "FloatReg" },
184 { "OPERAND_TYPE_FLOATACC",
185 "FloatAcc" },
186 { "OPERAND_TYPE_SREG2",
187 "SReg2" },
188 { "OPERAND_TYPE_SREG3",
189 "SReg3" },
190 { "OPERAND_TYPE_ACC",
191 "Acc" },
192 { "OPERAND_TYPE_JUMPABSOLUTE",
193 "JumpAbsolute" },
194 { "OPERAND_TYPE_REGMMX",
195 "RegMMX" },
196 { "OPERAND_TYPE_REGXMM",
197 "RegXMM" },
198 { "OPERAND_TYPE_REGYMM",
199 "RegYMM" },
200 { "OPERAND_TYPE_ESSEG",
201 "EsSeg" },
202 { "OPERAND_TYPE_ACC32",
203 "Reg32|Acc|Dword" },
204 { "OPERAND_TYPE_ACC64",
205 "Reg64|Acc|Qword" },
206 { "OPERAND_TYPE_INOUTPORTREG",
207 "InOutPortReg" },
208 { "OPERAND_TYPE_REG16_INOUTPORTREG",
209 "Reg16|InOutPortReg" },
210 { "OPERAND_TYPE_DISP16_32",
211 "Disp16|Disp32" },
212 { "OPERAND_TYPE_ANYDISP",
213 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
214 { "OPERAND_TYPE_IMM16_32",
215 "Imm16|Imm32" },
216 { "OPERAND_TYPE_IMM16_32S",
217 "Imm16|Imm32S" },
218 { "OPERAND_TYPE_IMM16_32_32S",
219 "Imm16|Imm32|Imm32S" },
220 { "OPERAND_TYPE_IMM32_32S_DISP32",
221 "Imm32|Imm32S|Disp32" },
222 { "OPERAND_TYPE_IMM64_DISP64",
223 "Imm64|Disp64" },
224 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
225 "Imm32|Imm32S|Imm64|Disp32" },
226 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
227 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
228 { "OPERAND_TYPE_VEX_IMM4",
229 "VEX_Imm4" },
232 typedef struct bitfield
234 int position;
235 int value;
236 const char *name;
237 } bitfield;
239 #define BITFIELD(n) { n, 0, #n }
241 static bitfield cpu_flags[] =
243 BITFIELD (Cpu186),
244 BITFIELD (Cpu286),
245 BITFIELD (Cpu386),
246 BITFIELD (Cpu486),
247 BITFIELD (Cpu586),
248 BITFIELD (Cpu686),
249 BITFIELD (CpuP4),
250 BITFIELD (CpuK6),
251 BITFIELD (CpuK8),
252 BITFIELD (CpuMMX),
253 BITFIELD (CpuSSE),
254 BITFIELD (CpuSSE2),
255 BITFIELD (CpuSSE3),
256 BITFIELD (CpuSSSE3),
257 BITFIELD (CpuSSE4_1),
258 BITFIELD (CpuSSE4_2),
259 BITFIELD (CpuAVX),
260 BITFIELD (CpuSSE4a),
261 BITFIELD (CpuSSE5),
262 BITFIELD (Cpu3dnow),
263 BITFIELD (Cpu3dnowA),
264 BITFIELD (CpuPadLock),
265 BITFIELD (CpuSVME),
266 BITFIELD (CpuVMX),
267 BITFIELD (CpuSMX),
268 BITFIELD (CpuABM),
269 BITFIELD (CpuXsave),
270 BITFIELD (CpuAES),
271 BITFIELD (CpuPCLMUL),
272 BITFIELD (CpuFMA),
273 BITFIELD (CpuLM),
274 BITFIELD (CpuMovbe),
275 BITFIELD (CpuEPT),
276 BITFIELD (Cpu64),
277 BITFIELD (CpuNo64),
278 #ifdef CpuUnused
279 BITFIELD (CpuUnused),
280 #endif
283 static bitfield opcode_modifiers[] =
285 BITFIELD (D),
286 BITFIELD (W),
287 BITFIELD (Modrm),
288 BITFIELD (ShortForm),
289 BITFIELD (Jump),
290 BITFIELD (JumpDword),
291 BITFIELD (JumpByte),
292 BITFIELD (JumpInterSegment),
293 BITFIELD (FloatMF),
294 BITFIELD (FloatR),
295 BITFIELD (FloatD),
296 BITFIELD (Size16),
297 BITFIELD (Size32),
298 BITFIELD (Size64),
299 BITFIELD (IgnoreSize),
300 BITFIELD (DefaultSize),
301 BITFIELD (No_bSuf),
302 BITFIELD (No_wSuf),
303 BITFIELD (No_lSuf),
304 BITFIELD (No_sSuf),
305 BITFIELD (No_qSuf),
306 BITFIELD (No_ldSuf),
307 BITFIELD (FWait),
308 BITFIELD (IsString),
309 BITFIELD (RegKludge),
310 BITFIELD (FirstXmm0),
311 BITFIELD (Implicit1stXmm0),
312 BITFIELD (ByteOkIntel),
313 BITFIELD (ToDword),
314 BITFIELD (ToQword),
315 BITFIELD (AddrPrefixOp0),
316 BITFIELD (IsPrefix),
317 BITFIELD (ImmExt),
318 BITFIELD (NoRex64),
319 BITFIELD (Rex64),
320 BITFIELD (Ugh),
321 BITFIELD (Drex),
322 BITFIELD (Drexv),
323 BITFIELD (Drexc),
324 BITFIELD (Vex),
325 BITFIELD (Vex256),
326 BITFIELD (VexNDD),
327 BITFIELD (VexNDS),
328 BITFIELD (VexW0),
329 BITFIELD (VexW1),
330 BITFIELD (Vex0F),
331 BITFIELD (Vex0F38),
332 BITFIELD (Vex0F3A),
333 BITFIELD (Vex3Sources),
334 BITFIELD (VexImmExt),
335 BITFIELD (SSE2AVX),
336 BITFIELD (NoAVX),
337 BITFIELD (OldGcc),
338 BITFIELD (ATTMnemonic),
339 BITFIELD (ATTSyntax),
340 BITFIELD (IntelSyntax),
343 static bitfield operand_types[] =
345 BITFIELD (Reg8),
346 BITFIELD (Reg16),
347 BITFIELD (Reg32),
348 BITFIELD (Reg64),
349 BITFIELD (FloatReg),
350 BITFIELD (RegMMX),
351 BITFIELD (RegXMM),
352 BITFIELD (RegYMM),
353 BITFIELD (Imm8),
354 BITFIELD (Imm8S),
355 BITFIELD (Imm16),
356 BITFIELD (Imm32),
357 BITFIELD (Imm32S),
358 BITFIELD (Imm64),
359 BITFIELD (Imm1),
360 BITFIELD (BaseIndex),
361 BITFIELD (Disp8),
362 BITFIELD (Disp16),
363 BITFIELD (Disp32),
364 BITFIELD (Disp32S),
365 BITFIELD (Disp64),
366 BITFIELD (InOutPortReg),
367 BITFIELD (ShiftCount),
368 BITFIELD (Control),
369 BITFIELD (Debug),
370 BITFIELD (Test),
371 BITFIELD (SReg2),
372 BITFIELD (SReg3),
373 BITFIELD (Acc),
374 BITFIELD (FloatAcc),
375 BITFIELD (JumpAbsolute),
376 BITFIELD (EsSeg),
377 BITFIELD (RegMem),
378 BITFIELD (Mem),
379 BITFIELD (Byte),
380 BITFIELD (Word),
381 BITFIELD (Dword),
382 BITFIELD (Fword),
383 BITFIELD (Qword),
384 BITFIELD (Tbyte),
385 BITFIELD (Xmmword),
386 BITFIELD (Ymmword),
387 BITFIELD (Unspecified),
388 BITFIELD (Anysize),
389 BITFIELD (Vex_Imm4),
390 #ifdef OTUnused
391 BITFIELD (OTUnused),
392 #endif
395 static int lineno;
396 static const char *filename;
398 static int
399 compare (const void *x, const void *y)
401 const bitfield *xp = (const bitfield *) x;
402 const bitfield *yp = (const bitfield *) y;
403 return xp->position - yp->position;
406 static void
407 fail (const char *message, ...)
409 va_list args;
411 va_start (args, message);
412 fprintf (stderr, _("%s: Error: "), program_name);
413 vfprintf (stderr, message, args);
414 va_end (args);
415 xexit (1);
418 static void
419 process_copyright (FILE *fp)
421 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
422 /* Copyright 2007, 2008 Free Software Foundation, Inc.\n\
424 This file is part of the GNU opcodes library.\n\
426 This library is free software; you can redistribute it and/or modify\n\
427 it under the terms of the GNU General Public License as published by\n\
428 the Free Software Foundation; either version 3, or (at your option)\n\
429 any later version.\n\
431 It is distributed in the hope that it will be useful, but WITHOUT\n\
432 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
433 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
434 License for more details.\n\
436 You should have received a copy of the GNU General Public License\n\
437 along with this program; if not, write to the Free Software\n\
438 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
439 MA 02110-1301, USA. */\n");
442 /* Remove leading white spaces. */
444 static char *
445 remove_leading_whitespaces (char *str)
447 while (ISSPACE (*str))
448 str++;
449 return str;
452 /* Remove trailing white spaces. */
454 static void
455 remove_trailing_whitespaces (char *str)
457 size_t last = strlen (str);
459 if (last == 0)
460 return;
464 last--;
465 if (ISSPACE (str [last]))
466 str[last] = '\0';
467 else
468 break;
470 while (last != 0);
473 /* Find next field separated by SEP and terminate it. Return a
474 pointer to the one after it. */
476 static char *
477 next_field (char *str, char sep, char **next, char *last)
479 char *p;
481 p = remove_leading_whitespaces (str);
482 for (str = p; *str != sep && *str != '\0'; str++);
484 *str = '\0';
485 remove_trailing_whitespaces (p);
487 *next = str + 1;
489 if (p >= last)
490 abort ();
492 return p;
495 static void
496 set_bitfield (const char *f, bitfield *array, unsigned int size)
498 unsigned int i;
500 if (strcmp (f, "CpuSledgehammer") == 0)
501 f= "CpuK8";
502 else if (strcmp (f, "Mmword") == 0)
503 f= "Qword";
504 else if (strcmp (f, "Oword") == 0)
505 f= "Xmmword";
507 for (i = 0; i < size; i++)
508 if (strcasecmp (array[i].name, f) == 0)
510 array[i].value = 1;
511 return;
514 fail (_("%s: %d: Unknown bitfield: %s\n"), filename, lineno, f);
517 static void
518 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
519 int macro, const char *comma, const char *indent)
521 unsigned int i;
523 fprintf (table, "%s{ { ", indent);
525 for (i = 0; i < size - 1; i++)
527 fprintf (table, "%d, ", flags[i].value);
528 if (((i + 1) % 20) == 0)
530 /* We need \\ for macro. */
531 if (macro)
532 fprintf (table, " \\\n %s", indent);
533 else
534 fprintf (table, "\n %s", indent);
538 fprintf (table, "%d } }%s\n", flags[i].value, comma);
541 static void
542 process_i386_cpu_flag (FILE *table, char *flag, int macro,
543 const char *comma, const char *indent)
545 char *str, *next, *last;
546 bitfield flags [ARRAY_SIZE (cpu_flags)];
548 /* Copy the default cpu flags. */
549 memcpy (flags, cpu_flags, sizeof (cpu_flags));
551 if (strcasecmp (flag, "unknown") == 0)
553 unsigned int i;
555 /* We turn on everything except for cpu64 in case of
556 CPU_UNKNOWN_FLAGS. */
557 for (i = 0; i < ARRAY_SIZE (flags); i++)
558 if (flags[i].position != Cpu64)
559 flags[i].value = 1;
561 else if (strcmp (flag, "0"))
563 last = flag + strlen (flag);
564 for (next = flag; next && next < last; )
566 str = next_field (next, '|', &next, last);
567 if (str)
568 set_bitfield (str, flags, ARRAY_SIZE (flags));
572 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
573 comma, indent);
576 static void
577 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
579 unsigned int i;
581 fprintf (table, " { ");
583 for (i = 0; i < size - 1; i++)
585 fprintf (table, "%d, ", modifier[i].value);
586 if (((i + 1) % 20) == 0)
587 fprintf (table, "\n ");
590 fprintf (table, "%d },\n", modifier[i].value);
593 static void
594 process_i386_opcode_modifier (FILE *table, char *mod)
596 char *str, *next, *last;
597 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
599 /* Copy the default opcode modifier. */
600 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
602 if (strcmp (mod, "0"))
604 last = mod + strlen (mod);
605 for (next = mod; next && next < last; )
607 str = next_field (next, '|', &next, last);
608 if (str)
609 set_bitfield (str, modifiers, ARRAY_SIZE (modifiers));
612 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
615 static void
616 output_operand_type (FILE *table, bitfield *types, unsigned int size,
617 int macro, const char *indent)
619 unsigned int i;
621 fprintf (table, "{ { ");
623 for (i = 0; i < size - 1; i++)
625 fprintf (table, "%d, ", types[i].value);
626 if (((i + 1) % 20) == 0)
628 /* We need \\ for macro. */
629 if (macro)
630 fprintf (table, "\\\n%s", indent);
631 else
632 fprintf (table, "\n%s", indent);
636 fprintf (table, "%d } }", types[i].value);
639 static void
640 process_i386_operand_type (FILE *table, char *op, int macro,
641 const char *indent)
643 char *str, *next, *last;
644 bitfield types [ARRAY_SIZE (operand_types)];
646 /* Copy the default operand type. */
647 memcpy (types, operand_types, sizeof (types));
649 if (strcmp (op, "0"))
651 last = op + strlen (op);
652 for (next = op; next && next < last; )
654 str = next_field (next, '|', &next, last);
655 if (str)
656 set_bitfield (str, types, ARRAY_SIZE (types));
659 output_operand_type (table, types, ARRAY_SIZE (types), macro,
660 indent);
663 static void
664 output_i386_opcode (FILE *table, const char *name, char *str,
665 char *last)
667 unsigned int i;
668 char *operands, *base_opcode, *extension_opcode, *opcode_length;
669 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
671 /* Find number of operands. */
672 operands = next_field (str, ',', &str, last);
674 /* Find base_opcode. */
675 base_opcode = next_field (str, ',', &str, last);
677 /* Find extension_opcode. */
678 extension_opcode = next_field (str, ',', &str, last);
680 /* Find opcode_length. */
681 opcode_length = next_field (str, ',', &str, last);
683 /* Find cpu_flags. */
684 cpu_flags = next_field (str, ',', &str, last);
686 /* Find opcode_modifier. */
687 opcode_modifier = next_field (str, ',', &str, last);
689 /* Remove the first {. */
690 str = remove_leading_whitespaces (str);
691 if (*str != '{')
692 abort ();
693 str = remove_leading_whitespaces (str + 1);
695 i = strlen (str);
697 /* There are at least "X}". */
698 if (i < 2)
699 abort ();
701 /* Remove trailing white spaces and }. */
704 i--;
705 if (ISSPACE (str[i]) || str[i] == '}')
706 str[i] = '\0';
707 else
708 break;
710 while (i != 0);
712 last = str + i;
714 /* Find operand_types. */
715 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
717 if (str >= last)
719 operand_types [i] = NULL;
720 break;
723 operand_types [i] = next_field (str, ',', &str, last);
724 if (*operand_types[i] == '0')
726 if (i != 0)
727 operand_types[i] = NULL;
728 break;
732 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
733 name, operands, base_opcode, extension_opcode,
734 opcode_length);
736 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ");
738 process_i386_opcode_modifier (table, opcode_modifier);
740 fprintf (table, " { ");
742 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
744 if (operand_types[i] == NULL || *operand_types[i] == '0')
746 if (i == 0)
747 process_i386_operand_type (table, "0", 0, "\t ");
748 break;
751 if (i != 0)
752 fprintf (table, ",\n ");
754 process_i386_operand_type (table, operand_types[i], 0,
755 "\t ");
757 fprintf (table, " } },\n");
760 struct opcode_hash_entry
762 struct opcode_hash_entry *next;
763 char *name;
764 char *opcode;
767 /* Calculate the hash value of an opcode hash entry P. */
769 static hashval_t
770 opcode_hash_hash (const void *p)
772 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
773 return htab_hash_string (entry->name);
776 /* Compare a string Q against an opcode hash entry P. */
778 static int
779 opcode_hash_eq (const void *p, const void *q)
781 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
782 const char *name = (const char *) q;
783 return strcmp (name, entry->name) == 0;
786 static void
787 process_i386_opcodes (FILE *table)
789 FILE *fp;
790 char buf[2048];
791 unsigned int i, j;
792 char *str, *p, *last, *name;
793 struct opcode_hash_entry **hash_slot, **entry, *next;
794 htab_t opcode_hash_table;
795 struct opcode_hash_entry **opcode_array;
796 unsigned int opcode_array_size = 1024;
798 filename = "i386-opc.tbl";
799 fp = fopen (filename, "r");
801 if (fp == NULL)
802 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
803 xstrerror (errno));
805 i = 0;
806 opcode_array = (struct opcode_hash_entry **)
807 xmalloc (sizeof (*opcode_array) * opcode_array_size);
809 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
810 opcode_hash_eq, NULL,
811 xcalloc, free);
813 fprintf (table, "\n/* i386 opcode table. */\n\n");
814 fprintf (table, "const template i386_optab[] =\n{\n");
816 /* Put everything on opcode array. */
817 while (!feof (fp))
819 if (fgets (buf, sizeof (buf), fp) == NULL)
820 break;
822 lineno++;
824 p = remove_leading_whitespaces (buf);
826 /* Skip comments. */
827 str = strstr (p, "//");
828 if (str != NULL)
829 str[0] = '\0';
831 /* Remove trailing white spaces. */
832 remove_trailing_whitespaces (p);
834 switch (p[0])
836 case '#':
837 /* Ignore comments. */
838 case '\0':
839 continue;
840 break;
841 default:
842 break;
845 last = p + strlen (p);
847 /* Find name. */
848 name = next_field (p, ',', &str, last);
850 /* Get the slot in hash table. */
851 hash_slot = (struct opcode_hash_entry **)
852 htab_find_slot_with_hash (opcode_hash_table, name,
853 htab_hash_string (name),
854 INSERT);
856 if (*hash_slot == NULL)
858 /* It is the new one. Put it on opcode array. */
859 if (i >= opcode_array_size)
861 /* Grow the opcode array when needed. */
862 opcode_array_size += 1024;
863 opcode_array = (struct opcode_hash_entry **)
864 xrealloc (opcode_array,
865 sizeof (*opcode_array) * opcode_array_size);
868 opcode_array[i] = (struct opcode_hash_entry *)
869 xmalloc (sizeof (struct opcode_hash_entry));
870 opcode_array[i]->next = NULL;
871 opcode_array[i]->name = xstrdup (name);
872 opcode_array[i]->opcode = xstrdup (str);
873 *hash_slot = opcode_array[i];
874 i++;
876 else
878 /* Append it to the existing one. */
879 entry = hash_slot;
880 while ((*entry) != NULL)
881 entry = &(*entry)->next;
882 *entry = (struct opcode_hash_entry *)
883 xmalloc (sizeof (struct opcode_hash_entry));
884 (*entry)->next = NULL;
885 (*entry)->name = (*hash_slot)->name;
886 (*entry)->opcode = xstrdup (str);
890 /* Process opcode array. */
891 for (j = 0; j < i; j++)
893 for (next = opcode_array[j]; next; next = next->next)
895 name = next->name;
896 str = next->opcode;
897 last = str + strlen (str);
898 output_i386_opcode (table, name, str, last);
902 fclose (fp);
904 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
906 process_i386_cpu_flag (table, "0", 0, ",", " ");
908 process_i386_opcode_modifier (table, "0");
910 fprintf (table, " { ");
911 process_i386_operand_type (table, "0", 0, "\t ");
912 fprintf (table, " } }\n");
914 fprintf (table, "};\n");
917 static void
918 process_i386_registers (FILE *table)
920 FILE *fp;
921 char buf[2048];
922 char *str, *p, *last;
923 char *reg_name, *reg_type, *reg_flags, *reg_num;
924 char *dw2_32_num, *dw2_64_num;
926 filename = "i386-reg.tbl";
927 fp = fopen (filename, "r");
928 if (fp == NULL)
929 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
930 xstrerror (errno));
932 fprintf (table, "\n/* i386 register table. */\n\n");
933 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
935 while (!feof (fp))
937 if (fgets (buf, sizeof (buf), fp) == NULL)
938 break;
940 lineno++;
942 p = remove_leading_whitespaces (buf);
944 /* Skip comments. */
945 str = strstr (p, "//");
946 if (str != NULL)
947 str[0] = '\0';
949 /* Remove trailing white spaces. */
950 remove_trailing_whitespaces (p);
952 switch (p[0])
954 case '#':
955 fprintf (table, "%s\n", p);
956 case '\0':
957 continue;
958 break;
959 default:
960 break;
963 last = p + strlen (p);
965 /* Find reg_name. */
966 reg_name = next_field (p, ',', &str, last);
968 /* Find reg_type. */
969 reg_type = next_field (str, ',', &str, last);
971 /* Find reg_flags. */
972 reg_flags = next_field (str, ',', &str, last);
974 /* Find reg_num. */
975 reg_num = next_field (str, ',', &str, last);
977 fprintf (table, " { \"%s\",\n ", reg_name);
979 process_i386_operand_type (table, reg_type, 0, "\t");
981 /* Find 32-bit Dwarf2 register number. */
982 dw2_32_num = next_field (str, ',', &str, last);
984 /* Find 64-bit Dwarf2 register number. */
985 dw2_64_num = next_field (str, ',', &str, last);
987 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
988 reg_flags, reg_num, dw2_32_num, dw2_64_num);
991 fclose (fp);
993 fprintf (table, "};\n");
995 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
998 static void
999 process_i386_initializers (void)
1001 unsigned int i;
1002 FILE *fp = fopen ("i386-init.h", "w");
1003 char *init;
1005 if (fp == NULL)
1006 fail (_("can't create i386-init.h, errno = %s\n"),
1007 xstrerror (errno));
1009 process_copyright (fp);
1011 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1013 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1014 init = xstrdup (cpu_flag_init[i].init);
1015 process_i386_cpu_flag (fp, init, 1, "", " ");
1016 free (init);
1019 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1021 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1022 init = xstrdup (operand_type_init[i].init);
1023 process_i386_operand_type (fp, init, 1, " ");
1024 free (init);
1026 fprintf (fp, "\n");
1028 fclose (fp);
1031 /* Program options. */
1032 #define OPTION_SRCDIR 200
1034 struct option long_options[] =
1036 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1037 {"debug", no_argument, NULL, 'd'},
1038 {"version", no_argument, NULL, 'V'},
1039 {"help", no_argument, NULL, 'h'},
1040 {0, no_argument, NULL, 0}
1043 static void
1044 print_version (void)
1046 printf ("%s: version 1.0\n", program_name);
1047 xexit (0);
1050 static void
1051 usage (FILE * stream, int status)
1053 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1054 program_name);
1055 xexit (status);
1059 main (int argc, char **argv)
1061 extern int chdir (char *);
1062 char *srcdir = NULL;
1063 int c;
1064 FILE *table;
1066 program_name = *argv;
1067 xmalloc_set_program_name (program_name);
1069 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1070 switch (c)
1072 case OPTION_SRCDIR:
1073 srcdir = optarg;
1074 break;
1075 case 'V':
1076 case 'v':
1077 print_version ();
1078 break;
1079 case 'd':
1080 debug = 1;
1081 break;
1082 case 'h':
1083 case '?':
1084 usage (stderr, 0);
1085 default:
1086 case 0:
1087 break;
1090 if (optind != argc)
1091 usage (stdout, 1);
1093 if (srcdir != NULL)
1094 if (chdir (srcdir) != 0)
1095 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1096 srcdir, xstrerror (errno));
1098 /* Check the unused bitfield in i386_cpu_flags. */
1099 #ifndef CpuUnused
1100 c = CpuNumOfBits - CpuMax - 1;
1101 if (c)
1102 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1103 #endif
1105 /* Check the unused bitfield in i386_operand_type. */
1106 #ifndef OTUnused
1107 c = OTNumOfBits - OTMax - 1;
1108 if (c)
1109 fail (_("%d unused bits in i386_operand_type.\n"), c);
1110 #endif
1112 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1113 compare);
1115 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1116 sizeof (opcode_modifiers [0]), compare);
1118 qsort (operand_types, ARRAY_SIZE (operand_types),
1119 sizeof (operand_types [0]), compare);
1121 table = fopen ("i386-tbl.h", "w");
1122 if (table == NULL)
1123 fail (_("can't create i386-tbl.h, errno = %s\n"),
1124 xstrerror (errno));
1126 process_copyright (table);
1128 process_i386_opcodes (table);
1129 process_i386_registers (table);
1130 process_i386_initializers ();
1132 fclose (table);
1134 exit (0);