gas/
[binutils.git] / opcodes / i386-gen.c
blobb0fe00d2d2428a6a69795dddc3843ed092817bb5
1 /* Copyright 2007, 2008, 2009
2 Free Software Foundation, Inc.
4 This file is part of the GNU opcodes library.
6 This library is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
11 It is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
21 #include "sysdep.h"
22 #include <stdio.h>
23 #include <errno.h>
24 #include "getopt.h"
25 #include "libiberty.h"
26 #include "hashtab.h"
27 #include "safe-ctype.h"
29 #include "i386-opc.h"
31 #include <libintl.h>
32 #define _(String) gettext (String)
34 static const char *program_name = NULL;
35 static int debug = 0;
37 typedef struct initializer
39 const char *name;
40 const char *init;
41 } initializer;
43 static initializer cpu_flag_init [] =
45 { "CPU_UNKNOWN_FLAGS",
46 "unknown" },
47 { "CPU_GENERIC32_FLAGS",
48 "Cpu186|Cpu286|Cpu386" },
49 { "CPU_GENERIC64_FLAGS",
50 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2|CpuLM" },
51 { "CPU_NONE_FLAGS",
52 "0" },
53 { "CPU_I186_FLAGS",
54 "Cpu186" },
55 { "CPU_I286_FLAGS",
56 "Cpu186|Cpu286" },
57 { "CPU_I386_FLAGS",
58 "Cpu186|Cpu286|Cpu386" },
59 { "CPU_I486_FLAGS",
60 "Cpu186|Cpu286|Cpu386|Cpu486" },
61 { "CPU_I586_FLAGS",
62 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
63 { "CPU_I686_FLAGS",
64 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686" },
65 { "CPU_P2_FLAGS",
66 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuMMX" },
67 { "CPU_P3_FLAGS",
68 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuMMX|CpuSSE" },
69 { "CPU_P4_FLAGS",
70 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2" },
71 { "CPU_NOCONA_FLAGS",
72 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuLM" },
73 { "CPU_CORE_FLAGS",
74 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
75 { "CPU_CORE2_FLAGS",
76 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuLM" },
77 { "CPU_K6_FLAGS",
78 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuK6|CpuMMX" },
79 { "CPU_K6_2_FLAGS",
80 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuK6|CpuMMX|Cpu3dnow" },
81 { "CPU_ATHLON_FLAGS",
82 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuK6|CpuMMX|Cpu3dnow|Cpu3dnowA" },
83 { "CPU_K8_FLAGS",
84 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuK6|CpuK8|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuRdtscp|CpuLM" },
85 { "CPU_AMDFAM10_FLAGS",
86 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuK6|CpuK8|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuRdtscp|CpuLM" },
87 { "CPU_MMX_FLAGS",
88 "CpuMMX" },
89 { "CPU_SSE_FLAGS",
90 "CpuMMX|CpuSSE" },
91 { "CPU_SSE2_FLAGS",
92 "CpuMMX|CpuSSE|CpuSSE2" },
93 { "CPU_SSE3_FLAGS",
94 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
95 { "CPU_SSSE3_FLAGS",
96 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3" },
97 { "CPU_SSE4_1_FLAGS",
98 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1" },
99 { "CPU_SSE4_2_FLAGS",
100 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2" },
101 { "CPU_VMX_FLAGS",
102 "CpuVMX" },
103 { "CPU_SMX_FLAGS",
104 "CpuSMX" },
105 { "CPU_XSAVE_FLAGS",
106 "CpuXsave" },
107 { "CPU_AES_FLAGS",
108 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAES" },
109 { "CPU_PCLMUL_FLAGS",
110 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuPCLMUL" },
111 { "CPU_FMA_FLAGS",
112 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA" },
113 { "CPU_MOVBE_FLAGS",
114 "CpuMovbe" },
115 { "CPU_RDTSCP_FLAGS",
116 "CpuRdtscp" },
117 { "CPU_EPT_FLAGS",
118 "CpuEPT" },
119 { "CPU_3DNOW_FLAGS",
120 "CpuMMX|Cpu3dnow" },
121 { "CPU_3DNOWA_FLAGS",
122 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
123 { "CPU_PADLOCK_FLAGS",
124 "CpuPadLock" },
125 { "CPU_SVME_FLAGS",
126 "CpuSVME" },
127 { "CPU_SSE4A_FLAGS",
128 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
129 { "CPU_ABM_FLAGS",
130 "CpuABM" },
131 { "CPU_SSE5_FLAGS",
132 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuSSE5"},
133 { "CPU_AVX_FLAGS",
134 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
137 static initializer operand_type_init [] =
139 { "OPERAND_TYPE_NONE",
140 "0" },
141 { "OPERAND_TYPE_REG8",
142 "Reg8" },
143 { "OPERAND_TYPE_REG16",
144 "Reg16" },
145 { "OPERAND_TYPE_REG32",
146 "Reg32" },
147 { "OPERAND_TYPE_REG64",
148 "Reg64" },
149 { "OPERAND_TYPE_IMM1",
150 "Imm1" },
151 { "OPERAND_TYPE_IMM8",
152 "Imm8" },
153 { "OPERAND_TYPE_IMM8S",
154 "Imm8S" },
155 { "OPERAND_TYPE_IMM16",
156 "Imm16" },
157 { "OPERAND_TYPE_IMM32",
158 "Imm32" },
159 { "OPERAND_TYPE_IMM32S",
160 "Imm32S" },
161 { "OPERAND_TYPE_IMM64",
162 "Imm64" },
163 { "OPERAND_TYPE_BASEINDEX",
164 "BaseIndex" },
165 { "OPERAND_TYPE_DISP8",
166 "Disp8" },
167 { "OPERAND_TYPE_DISP16",
168 "Disp16" },
169 { "OPERAND_TYPE_DISP32",
170 "Disp32" },
171 { "OPERAND_TYPE_DISP32S",
172 "Disp32S" },
173 { "OPERAND_TYPE_DISP64",
174 "Disp64" },
175 { "OPERAND_TYPE_INOUTPORTREG",
176 "InOutPortReg" },
177 { "OPERAND_TYPE_SHIFTCOUNT",
178 "ShiftCount" },
179 { "OPERAND_TYPE_CONTROL",
180 "Control" },
181 { "OPERAND_TYPE_TEST",
182 "Test" },
183 { "OPERAND_TYPE_DEBUG",
184 "FloatReg" },
185 { "OPERAND_TYPE_FLOATREG",
186 "FloatReg" },
187 { "OPERAND_TYPE_FLOATACC",
188 "FloatAcc" },
189 { "OPERAND_TYPE_SREG2",
190 "SReg2" },
191 { "OPERAND_TYPE_SREG3",
192 "SReg3" },
193 { "OPERAND_TYPE_ACC",
194 "Acc" },
195 { "OPERAND_TYPE_JUMPABSOLUTE",
196 "JumpAbsolute" },
197 { "OPERAND_TYPE_REGMMX",
198 "RegMMX" },
199 { "OPERAND_TYPE_REGXMM",
200 "RegXMM" },
201 { "OPERAND_TYPE_REGYMM",
202 "RegYMM" },
203 { "OPERAND_TYPE_ESSEG",
204 "EsSeg" },
205 { "OPERAND_TYPE_ACC32",
206 "Reg32|Acc|Dword" },
207 { "OPERAND_TYPE_ACC64",
208 "Reg64|Acc|Qword" },
209 { "OPERAND_TYPE_INOUTPORTREG",
210 "InOutPortReg" },
211 { "OPERAND_TYPE_REG16_INOUTPORTREG",
212 "Reg16|InOutPortReg" },
213 { "OPERAND_TYPE_DISP16_32",
214 "Disp16|Disp32" },
215 { "OPERAND_TYPE_ANYDISP",
216 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
217 { "OPERAND_TYPE_IMM16_32",
218 "Imm16|Imm32" },
219 { "OPERAND_TYPE_IMM16_32S",
220 "Imm16|Imm32S" },
221 { "OPERAND_TYPE_IMM16_32_32S",
222 "Imm16|Imm32|Imm32S" },
223 { "OPERAND_TYPE_IMM32_32S_DISP32",
224 "Imm32|Imm32S|Disp32" },
225 { "OPERAND_TYPE_IMM64_DISP64",
226 "Imm64|Disp64" },
227 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
228 "Imm32|Imm32S|Imm64|Disp32" },
229 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
230 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
231 { "OPERAND_TYPE_VEX_IMM4",
232 "VEX_Imm4" },
235 typedef struct bitfield
237 int position;
238 int value;
239 const char *name;
240 } bitfield;
242 #define BITFIELD(n) { n, 0, #n }
244 static bitfield cpu_flags[] =
246 BITFIELD (Cpu186),
247 BITFIELD (Cpu286),
248 BITFIELD (Cpu386),
249 BITFIELD (Cpu486),
250 BITFIELD (Cpu586),
251 BITFIELD (Cpu686),
252 BITFIELD (CpuP4),
253 BITFIELD (CpuK6),
254 BITFIELD (CpuK8),
255 BITFIELD (CpuMMX),
256 BITFIELD (CpuSSE),
257 BITFIELD (CpuSSE2),
258 BITFIELD (CpuSSE3),
259 BITFIELD (CpuSSSE3),
260 BITFIELD (CpuSSE4_1),
261 BITFIELD (CpuSSE4_2),
262 BITFIELD (CpuAVX),
263 BITFIELD (CpuSSE4a),
264 BITFIELD (CpuSSE5),
265 BITFIELD (Cpu3dnow),
266 BITFIELD (Cpu3dnowA),
267 BITFIELD (CpuPadLock),
268 BITFIELD (CpuSVME),
269 BITFIELD (CpuVMX),
270 BITFIELD (CpuSMX),
271 BITFIELD (CpuABM),
272 BITFIELD (CpuXsave),
273 BITFIELD (CpuAES),
274 BITFIELD (CpuPCLMUL),
275 BITFIELD (CpuFMA),
276 BITFIELD (CpuLM),
277 BITFIELD (CpuMovbe),
278 BITFIELD (CpuEPT),
279 BITFIELD (CpuRdtscp),
280 BITFIELD (Cpu64),
281 BITFIELD (CpuNo64),
282 #ifdef CpuUnused
283 BITFIELD (CpuUnused),
284 #endif
287 static bitfield opcode_modifiers[] =
289 BITFIELD (D),
290 BITFIELD (W),
291 BITFIELD (S),
292 BITFIELD (Modrm),
293 BITFIELD (ShortForm),
294 BITFIELD (Jump),
295 BITFIELD (JumpDword),
296 BITFIELD (JumpByte),
297 BITFIELD (JumpInterSegment),
298 BITFIELD (FloatMF),
299 BITFIELD (FloatR),
300 BITFIELD (FloatD),
301 BITFIELD (Size16),
302 BITFIELD (Size32),
303 BITFIELD (Size64),
304 BITFIELD (IgnoreSize),
305 BITFIELD (DefaultSize),
306 BITFIELD (No_bSuf),
307 BITFIELD (No_wSuf),
308 BITFIELD (No_lSuf),
309 BITFIELD (No_sSuf),
310 BITFIELD (No_qSuf),
311 BITFIELD (No_ldSuf),
312 BITFIELD (FWait),
313 BITFIELD (IsString),
314 BITFIELD (RegKludge),
315 BITFIELD (FirstXmm0),
316 BITFIELD (Implicit1stXmm0),
317 BITFIELD (ByteOkIntel),
318 BITFIELD (ToDword),
319 BITFIELD (ToQword),
320 BITFIELD (AddrPrefixOp0),
321 BITFIELD (IsPrefix),
322 BITFIELD (ImmExt),
323 BITFIELD (NoRex64),
324 BITFIELD (Rex64),
325 BITFIELD (Ugh),
326 BITFIELD (Drex),
327 BITFIELD (Drexv),
328 BITFIELD (Drexc),
329 BITFIELD (Vex),
330 BITFIELD (Vex256),
331 BITFIELD (VexNDS),
332 BITFIELD (VexNDD),
333 BITFIELD (VexW0),
334 BITFIELD (VexW1),
335 BITFIELD (Vex0F),
336 BITFIELD (Vex0F38),
337 BITFIELD (Vex0F3A),
338 BITFIELD (Vex3Sources),
339 BITFIELD (VexImmExt),
340 BITFIELD (SSE2AVX),
341 BITFIELD (NoAVX),
342 BITFIELD (OldGcc),
343 BITFIELD (ATTMnemonic),
344 BITFIELD (ATTSyntax),
345 BITFIELD (IntelSyntax),
348 static bitfield operand_types[] =
350 BITFIELD (Reg8),
351 BITFIELD (Reg16),
352 BITFIELD (Reg32),
353 BITFIELD (Reg64),
354 BITFIELD (FloatReg),
355 BITFIELD (RegMMX),
356 BITFIELD (RegXMM),
357 BITFIELD (RegYMM),
358 BITFIELD (Imm8),
359 BITFIELD (Imm8S),
360 BITFIELD (Imm16),
361 BITFIELD (Imm32),
362 BITFIELD (Imm32S),
363 BITFIELD (Imm64),
364 BITFIELD (Imm1),
365 BITFIELD (BaseIndex),
366 BITFIELD (Disp8),
367 BITFIELD (Disp16),
368 BITFIELD (Disp32),
369 BITFIELD (Disp32S),
370 BITFIELD (Disp64),
371 BITFIELD (InOutPortReg),
372 BITFIELD (ShiftCount),
373 BITFIELD (Control),
374 BITFIELD (Debug),
375 BITFIELD (Test),
376 BITFIELD (SReg2),
377 BITFIELD (SReg3),
378 BITFIELD (Acc),
379 BITFIELD (FloatAcc),
380 BITFIELD (JumpAbsolute),
381 BITFIELD (EsSeg),
382 BITFIELD (RegMem),
383 BITFIELD (Mem),
384 BITFIELD (Byte),
385 BITFIELD (Word),
386 BITFIELD (Dword),
387 BITFIELD (Fword),
388 BITFIELD (Qword),
389 BITFIELD (Tbyte),
390 BITFIELD (Xmmword),
391 BITFIELD (Ymmword),
392 BITFIELD (Unspecified),
393 BITFIELD (Anysize),
394 BITFIELD (Vex_Imm4),
395 #ifdef OTUnused
396 BITFIELD (OTUnused),
397 #endif
400 static int lineno;
401 static const char *filename;
403 static int
404 compare (const void *x, const void *y)
406 const bitfield *xp = (const bitfield *) x;
407 const bitfield *yp = (const bitfield *) y;
408 return xp->position - yp->position;
411 static void
412 fail (const char *message, ...)
414 va_list args;
416 va_start (args, message);
417 fprintf (stderr, _("%s: Error: "), program_name);
418 vfprintf (stderr, message, args);
419 va_end (args);
420 xexit (1);
423 static void
424 process_copyright (FILE *fp)
426 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
427 /* Copyright 2007, 2008, 2009\n\
428 Free Software Foundation, Inc.\n\
430 This file is part of the GNU opcodes library.\n\
432 This library is free software; you can redistribute it and/or modify\n\
433 it under the terms of the GNU General Public License as published by\n\
434 the Free Software Foundation; either version 3, or (at your option)\n\
435 any later version.\n\
437 It is distributed in the hope that it will be useful, but WITHOUT\n\
438 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
439 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
440 License for more details.\n\
442 You should have received a copy of the GNU General Public License\n\
443 along with this program; if not, write to the Free Software\n\
444 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
445 MA 02110-1301, USA. */\n");
448 /* Remove leading white spaces. */
450 static char *
451 remove_leading_whitespaces (char *str)
453 while (ISSPACE (*str))
454 str++;
455 return str;
458 /* Remove trailing white spaces. */
460 static void
461 remove_trailing_whitespaces (char *str)
463 size_t last = strlen (str);
465 if (last == 0)
466 return;
470 last--;
471 if (ISSPACE (str [last]))
472 str[last] = '\0';
473 else
474 break;
476 while (last != 0);
479 /* Find next field separated by SEP and terminate it. Return a
480 pointer to the one after it. */
482 static char *
483 next_field (char *str, char sep, char **next, char *last)
485 char *p;
487 p = remove_leading_whitespaces (str);
488 for (str = p; *str != sep && *str != '\0'; str++);
490 *str = '\0';
491 remove_trailing_whitespaces (p);
493 *next = str + 1;
495 if (p >= last)
496 abort ();
498 return p;
501 static void
502 set_bitfield (const char *f, bitfield *array, unsigned int size)
504 unsigned int i;
506 if (strcmp (f, "Mmword") == 0)
507 f= "Qword";
508 else if (strcmp (f, "Oword") == 0)
509 f= "Xmmword";
511 for (i = 0; i < size; i++)
512 if (strcasecmp (array[i].name, f) == 0)
514 array[i].value = 1;
515 return;
518 fail (_("%s: %d: Unknown bitfield: %s\n"), filename, lineno, f);
521 static void
522 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
523 int macro, const char *comma, const char *indent)
525 unsigned int i;
527 fprintf (table, "%s{ { ", indent);
529 for (i = 0; i < size - 1; i++)
531 fprintf (table, "%d, ", flags[i].value);
532 if (((i + 1) % 20) == 0)
534 /* We need \\ for macro. */
535 if (macro)
536 fprintf (table, " \\\n %s", indent);
537 else
538 fprintf (table, "\n %s", indent);
542 fprintf (table, "%d } }%s\n", flags[i].value, comma);
545 static void
546 process_i386_cpu_flag (FILE *table, char *flag, int macro,
547 const char *comma, const char *indent)
549 char *str, *next, *last;
550 bitfield flags [ARRAY_SIZE (cpu_flags)];
552 /* Copy the default cpu flags. */
553 memcpy (flags, cpu_flags, sizeof (cpu_flags));
555 if (strcasecmp (flag, "unknown") == 0)
557 unsigned int i;
559 /* We turn on everything except for cpu64 in case of
560 CPU_UNKNOWN_FLAGS. */
561 for (i = 0; i < ARRAY_SIZE (flags); i++)
562 if (flags[i].position != Cpu64)
563 flags[i].value = 1;
565 else if (strcmp (flag, "0"))
567 last = flag + strlen (flag);
568 for (next = flag; next && next < last; )
570 str = next_field (next, '|', &next, last);
571 if (str)
572 set_bitfield (str, flags, ARRAY_SIZE (flags));
576 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
577 comma, indent);
580 static void
581 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
583 unsigned int i;
585 fprintf (table, " { ");
587 for (i = 0; i < size - 1; i++)
589 fprintf (table, "%d, ", modifier[i].value);
590 if (((i + 1) % 20) == 0)
591 fprintf (table, "\n ");
594 fprintf (table, "%d },\n", modifier[i].value);
597 static void
598 process_i386_opcode_modifier (FILE *table, char *mod)
600 char *str, *next, *last;
601 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
603 /* Copy the default opcode modifier. */
604 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
606 if (strcmp (mod, "0"))
608 last = mod + strlen (mod);
609 for (next = mod; next && next < last; )
611 str = next_field (next, '|', &next, last);
612 if (str)
613 set_bitfield (str, modifiers, ARRAY_SIZE (modifiers));
616 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
619 static void
620 output_operand_type (FILE *table, bitfield *types, unsigned int size,
621 int macro, const char *indent)
623 unsigned int i;
625 fprintf (table, "{ { ");
627 for (i = 0; i < size - 1; i++)
629 fprintf (table, "%d, ", types[i].value);
630 if (((i + 1) % 20) == 0)
632 /* We need \\ for macro. */
633 if (macro)
634 fprintf (table, "\\\n%s", indent);
635 else
636 fprintf (table, "\n%s", indent);
640 fprintf (table, "%d } }", types[i].value);
643 static void
644 process_i386_operand_type (FILE *table, char *op, int macro,
645 const char *indent)
647 char *str, *next, *last;
648 bitfield types [ARRAY_SIZE (operand_types)];
650 /* Copy the default operand type. */
651 memcpy (types, operand_types, sizeof (types));
653 if (strcmp (op, "0"))
655 last = op + strlen (op);
656 for (next = op; next && next < last; )
658 str = next_field (next, '|', &next, last);
659 if (str)
660 set_bitfield (str, types, ARRAY_SIZE (types));
663 output_operand_type (table, types, ARRAY_SIZE (types), macro,
664 indent);
667 static void
668 output_i386_opcode (FILE *table, const char *name, char *str,
669 char *last)
671 unsigned int i;
672 char *operands, *base_opcode, *extension_opcode, *opcode_length;
673 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
675 /* Find number of operands. */
676 operands = next_field (str, ',', &str, last);
678 /* Find base_opcode. */
679 base_opcode = next_field (str, ',', &str, last);
681 /* Find extension_opcode. */
682 extension_opcode = next_field (str, ',', &str, last);
684 /* Find opcode_length. */
685 opcode_length = next_field (str, ',', &str, last);
687 /* Find cpu_flags. */
688 cpu_flags = next_field (str, ',', &str, last);
690 /* Find opcode_modifier. */
691 opcode_modifier = next_field (str, ',', &str, last);
693 /* Remove the first {. */
694 str = remove_leading_whitespaces (str);
695 if (*str != '{')
696 abort ();
697 str = remove_leading_whitespaces (str + 1);
699 i = strlen (str);
701 /* There are at least "X}". */
702 if (i < 2)
703 abort ();
705 /* Remove trailing white spaces and }. */
708 i--;
709 if (ISSPACE (str[i]) || str[i] == '}')
710 str[i] = '\0';
711 else
712 break;
714 while (i != 0);
716 last = str + i;
718 /* Find operand_types. */
719 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
721 if (str >= last)
723 operand_types [i] = NULL;
724 break;
727 operand_types [i] = next_field (str, ',', &str, last);
728 if (*operand_types[i] == '0')
730 if (i != 0)
731 operand_types[i] = NULL;
732 break;
736 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
737 name, operands, base_opcode, extension_opcode,
738 opcode_length);
740 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ");
742 process_i386_opcode_modifier (table, opcode_modifier);
744 fprintf (table, " { ");
746 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
748 if (operand_types[i] == NULL || *operand_types[i] == '0')
750 if (i == 0)
751 process_i386_operand_type (table, "0", 0, "\t ");
752 break;
755 if (i != 0)
756 fprintf (table, ",\n ");
758 process_i386_operand_type (table, operand_types[i], 0,
759 "\t ");
761 fprintf (table, " } },\n");
764 struct opcode_hash_entry
766 struct opcode_hash_entry *next;
767 char *name;
768 char *opcode;
771 /* Calculate the hash value of an opcode hash entry P. */
773 static hashval_t
774 opcode_hash_hash (const void *p)
776 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
777 return htab_hash_string (entry->name);
780 /* Compare a string Q against an opcode hash entry P. */
782 static int
783 opcode_hash_eq (const void *p, const void *q)
785 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
786 const char *name = (const char *) q;
787 return strcmp (name, entry->name) == 0;
790 static void
791 process_i386_opcodes (FILE *table)
793 FILE *fp;
794 char buf[2048];
795 unsigned int i, j;
796 char *str, *p, *last, *name;
797 struct opcode_hash_entry **hash_slot, **entry, *next;
798 htab_t opcode_hash_table;
799 struct opcode_hash_entry **opcode_array;
800 unsigned int opcode_array_size = 1024;
802 filename = "i386-opc.tbl";
803 fp = fopen (filename, "r");
805 if (fp == NULL)
806 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
807 xstrerror (errno));
809 i = 0;
810 opcode_array = (struct opcode_hash_entry **)
811 xmalloc (sizeof (*opcode_array) * opcode_array_size);
813 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
814 opcode_hash_eq, NULL,
815 xcalloc, free);
817 fprintf (table, "\n/* i386 opcode table. */\n\n");
818 fprintf (table, "const template i386_optab[] =\n{\n");
820 /* Put everything on opcode array. */
821 while (!feof (fp))
823 if (fgets (buf, sizeof (buf), fp) == NULL)
824 break;
826 lineno++;
828 p = remove_leading_whitespaces (buf);
830 /* Skip comments. */
831 str = strstr (p, "//");
832 if (str != NULL)
833 str[0] = '\0';
835 /* Remove trailing white spaces. */
836 remove_trailing_whitespaces (p);
838 switch (p[0])
840 case '#':
841 /* Ignore comments. */
842 case '\0':
843 continue;
844 break;
845 default:
846 break;
849 last = p + strlen (p);
851 /* Find name. */
852 name = next_field (p, ',', &str, last);
854 /* Get the slot in hash table. */
855 hash_slot = (struct opcode_hash_entry **)
856 htab_find_slot_with_hash (opcode_hash_table, name,
857 htab_hash_string (name),
858 INSERT);
860 if (*hash_slot == NULL)
862 /* It is the new one. Put it on opcode array. */
863 if (i >= opcode_array_size)
865 /* Grow the opcode array when needed. */
866 opcode_array_size += 1024;
867 opcode_array = (struct opcode_hash_entry **)
868 xrealloc (opcode_array,
869 sizeof (*opcode_array) * opcode_array_size);
872 opcode_array[i] = (struct opcode_hash_entry *)
873 xmalloc (sizeof (struct opcode_hash_entry));
874 opcode_array[i]->next = NULL;
875 opcode_array[i]->name = xstrdup (name);
876 opcode_array[i]->opcode = xstrdup (str);
877 *hash_slot = opcode_array[i];
878 i++;
880 else
882 /* Append it to the existing one. */
883 entry = hash_slot;
884 while ((*entry) != NULL)
885 entry = &(*entry)->next;
886 *entry = (struct opcode_hash_entry *)
887 xmalloc (sizeof (struct opcode_hash_entry));
888 (*entry)->next = NULL;
889 (*entry)->name = (*hash_slot)->name;
890 (*entry)->opcode = xstrdup (str);
894 /* Process opcode array. */
895 for (j = 0; j < i; j++)
897 for (next = opcode_array[j]; next; next = next->next)
899 name = next->name;
900 str = next->opcode;
901 last = str + strlen (str);
902 output_i386_opcode (table, name, str, last);
906 fclose (fp);
908 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
910 process_i386_cpu_flag (table, "0", 0, ",", " ");
912 process_i386_opcode_modifier (table, "0");
914 fprintf (table, " { ");
915 process_i386_operand_type (table, "0", 0, "\t ");
916 fprintf (table, " } }\n");
918 fprintf (table, "};\n");
921 static void
922 process_i386_registers (FILE *table)
924 FILE *fp;
925 char buf[2048];
926 char *str, *p, *last;
927 char *reg_name, *reg_type, *reg_flags, *reg_num;
928 char *dw2_32_num, *dw2_64_num;
930 filename = "i386-reg.tbl";
931 fp = fopen (filename, "r");
932 if (fp == NULL)
933 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
934 xstrerror (errno));
936 fprintf (table, "\n/* i386 register table. */\n\n");
937 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
939 while (!feof (fp))
941 if (fgets (buf, sizeof (buf), fp) == NULL)
942 break;
944 lineno++;
946 p = remove_leading_whitespaces (buf);
948 /* Skip comments. */
949 str = strstr (p, "//");
950 if (str != NULL)
951 str[0] = '\0';
953 /* Remove trailing white spaces. */
954 remove_trailing_whitespaces (p);
956 switch (p[0])
958 case '#':
959 fprintf (table, "%s\n", p);
960 case '\0':
961 continue;
962 break;
963 default:
964 break;
967 last = p + strlen (p);
969 /* Find reg_name. */
970 reg_name = next_field (p, ',', &str, last);
972 /* Find reg_type. */
973 reg_type = next_field (str, ',', &str, last);
975 /* Find reg_flags. */
976 reg_flags = next_field (str, ',', &str, last);
978 /* Find reg_num. */
979 reg_num = next_field (str, ',', &str, last);
981 fprintf (table, " { \"%s\",\n ", reg_name);
983 process_i386_operand_type (table, reg_type, 0, "\t");
985 /* Find 32-bit Dwarf2 register number. */
986 dw2_32_num = next_field (str, ',', &str, last);
988 /* Find 64-bit Dwarf2 register number. */
989 dw2_64_num = next_field (str, ',', &str, last);
991 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
992 reg_flags, reg_num, dw2_32_num, dw2_64_num);
995 fclose (fp);
997 fprintf (table, "};\n");
999 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1002 static void
1003 process_i386_initializers (void)
1005 unsigned int i;
1006 FILE *fp = fopen ("i386-init.h", "w");
1007 char *init;
1009 if (fp == NULL)
1010 fail (_("can't create i386-init.h, errno = %s\n"),
1011 xstrerror (errno));
1013 process_copyright (fp);
1015 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1017 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1018 init = xstrdup (cpu_flag_init[i].init);
1019 process_i386_cpu_flag (fp, init, 1, "", " ");
1020 free (init);
1023 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1025 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1026 init = xstrdup (operand_type_init[i].init);
1027 process_i386_operand_type (fp, init, 1, " ");
1028 free (init);
1030 fprintf (fp, "\n");
1032 fclose (fp);
1035 /* Program options. */
1036 #define OPTION_SRCDIR 200
1038 struct option long_options[] =
1040 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1041 {"debug", no_argument, NULL, 'd'},
1042 {"version", no_argument, NULL, 'V'},
1043 {"help", no_argument, NULL, 'h'},
1044 {0, no_argument, NULL, 0}
1047 static void
1048 print_version (void)
1050 printf ("%s: version 1.0\n", program_name);
1051 xexit (0);
1054 static void
1055 usage (FILE * stream, int status)
1057 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1058 program_name);
1059 xexit (status);
1063 main (int argc, char **argv)
1065 extern int chdir (char *);
1066 char *srcdir = NULL;
1067 int c;
1068 FILE *table;
1070 program_name = *argv;
1071 xmalloc_set_program_name (program_name);
1073 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1074 switch (c)
1076 case OPTION_SRCDIR:
1077 srcdir = optarg;
1078 break;
1079 case 'V':
1080 case 'v':
1081 print_version ();
1082 break;
1083 case 'd':
1084 debug = 1;
1085 break;
1086 case 'h':
1087 case '?':
1088 usage (stderr, 0);
1089 default:
1090 case 0:
1091 break;
1094 if (optind != argc)
1095 usage (stdout, 1);
1097 if (srcdir != NULL)
1098 if (chdir (srcdir) != 0)
1099 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1100 srcdir, xstrerror (errno));
1102 /* Check the unused bitfield in i386_cpu_flags. */
1103 #ifndef CpuUnused
1104 c = CpuNumOfBits - CpuMax - 1;
1105 if (c)
1106 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1107 #endif
1109 /* Check the unused bitfield in i386_operand_type. */
1110 #ifndef OTUnused
1111 c = OTNumOfBits - OTMax - 1;
1112 if (c)
1113 fail (_("%d unused bits in i386_operand_type.\n"), c);
1114 #endif
1116 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1117 compare);
1119 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1120 sizeof (opcode_modifiers [0]), compare);
1122 qsort (operand_types, ARRAY_SIZE (operand_types),
1123 sizeof (operand_types [0]), compare);
1125 table = fopen ("i386-tbl.h", "w");
1126 if (table == NULL)
1127 fail (_("can't create i386-tbl.h, errno = %s\n"),
1128 xstrerror (errno));
1130 process_copyright (table);
1132 process_i386_opcodes (table);
1133 process_i386_registers (table);
1134 process_i386_initializers ();
1136 fclose (table);
1138 exit (0);