PR 7093
[binutils.git] / opcodes / i386-gen.c
blob1e11911240fa27a43e48dcee42ca95ed6887b2c3
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 (S),
288 BITFIELD (Modrm),
289 BITFIELD (ShortForm),
290 BITFIELD (Jump),
291 BITFIELD (JumpDword),
292 BITFIELD (JumpByte),
293 BITFIELD (JumpInterSegment),
294 BITFIELD (FloatMF),
295 BITFIELD (FloatR),
296 BITFIELD (FloatD),
297 BITFIELD (Size16),
298 BITFIELD (Size32),
299 BITFIELD (Size64),
300 BITFIELD (IgnoreSize),
301 BITFIELD (DefaultSize),
302 BITFIELD (No_bSuf),
303 BITFIELD (No_wSuf),
304 BITFIELD (No_lSuf),
305 BITFIELD (No_sSuf),
306 BITFIELD (No_qSuf),
307 BITFIELD (No_ldSuf),
308 BITFIELD (FWait),
309 BITFIELD (IsString),
310 BITFIELD (RegKludge),
311 BITFIELD (FirstXmm0),
312 BITFIELD (Implicit1stXmm0),
313 BITFIELD (ByteOkIntel),
314 BITFIELD (ToDword),
315 BITFIELD (ToQword),
316 BITFIELD (AddrPrefixOp0),
317 BITFIELD (IsPrefix),
318 BITFIELD (ImmExt),
319 BITFIELD (NoRex64),
320 BITFIELD (Rex64),
321 BITFIELD (Ugh),
322 BITFIELD (Drex),
323 BITFIELD (Drexv),
324 BITFIELD (Drexc),
325 BITFIELD (Vex),
326 BITFIELD (Vex256),
327 BITFIELD (VexNDS),
328 BITFIELD (VexNDD),
329 BITFIELD (VexW0),
330 BITFIELD (VexW1),
331 BITFIELD (Vex0F),
332 BITFIELD (Vex0F38),
333 BITFIELD (Vex0F3A),
334 BITFIELD (Vex3Sources),
335 BITFIELD (VexImmExt),
336 BITFIELD (SSE2AVX),
337 BITFIELD (NoAVX),
338 BITFIELD (OldGcc),
339 BITFIELD (ATTMnemonic),
340 BITFIELD (ATTSyntax),
341 BITFIELD (IntelSyntax),
344 static bitfield operand_types[] =
346 BITFIELD (Reg8),
347 BITFIELD (Reg16),
348 BITFIELD (Reg32),
349 BITFIELD (Reg64),
350 BITFIELD (FloatReg),
351 BITFIELD (RegMMX),
352 BITFIELD (RegXMM),
353 BITFIELD (RegYMM),
354 BITFIELD (Imm8),
355 BITFIELD (Imm8S),
356 BITFIELD (Imm16),
357 BITFIELD (Imm32),
358 BITFIELD (Imm32S),
359 BITFIELD (Imm64),
360 BITFIELD (Imm1),
361 BITFIELD (BaseIndex),
362 BITFIELD (Disp8),
363 BITFIELD (Disp16),
364 BITFIELD (Disp32),
365 BITFIELD (Disp32S),
366 BITFIELD (Disp64),
367 BITFIELD (InOutPortReg),
368 BITFIELD (ShiftCount),
369 BITFIELD (Control),
370 BITFIELD (Debug),
371 BITFIELD (Test),
372 BITFIELD (SReg2),
373 BITFIELD (SReg3),
374 BITFIELD (Acc),
375 BITFIELD (FloatAcc),
376 BITFIELD (JumpAbsolute),
377 BITFIELD (EsSeg),
378 BITFIELD (RegMem),
379 BITFIELD (Mem),
380 BITFIELD (Byte),
381 BITFIELD (Word),
382 BITFIELD (Dword),
383 BITFIELD (Fword),
384 BITFIELD (Qword),
385 BITFIELD (Tbyte),
386 BITFIELD (Xmmword),
387 BITFIELD (Ymmword),
388 BITFIELD (Unspecified),
389 BITFIELD (Anysize),
390 BITFIELD (Vex_Imm4),
391 #ifdef OTUnused
392 BITFIELD (OTUnused),
393 #endif
396 static int lineno;
397 static const char *filename;
399 static int
400 compare (const void *x, const void *y)
402 const bitfield *xp = (const bitfield *) x;
403 const bitfield *yp = (const bitfield *) y;
404 return xp->position - yp->position;
407 static void
408 fail (const char *message, ...)
410 va_list args;
412 va_start (args, message);
413 fprintf (stderr, _("%s: Error: "), program_name);
414 vfprintf (stderr, message, args);
415 va_end (args);
416 xexit (1);
419 static void
420 process_copyright (FILE *fp)
422 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
423 /* Copyright 2007, 2008 Free Software Foundation, Inc.\n\
425 This file is part of the GNU opcodes library.\n\
427 This library is free software; you can redistribute it and/or modify\n\
428 it under the terms of the GNU General Public License as published by\n\
429 the Free Software Foundation; either version 3, or (at your option)\n\
430 any later version.\n\
432 It is distributed in the hope that it will be useful, but WITHOUT\n\
433 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
434 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
435 License for more details.\n\
437 You should have received a copy of the GNU General Public License\n\
438 along with this program; if not, write to the Free Software\n\
439 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
440 MA 02110-1301, USA. */\n");
443 /* Remove leading white spaces. */
445 static char *
446 remove_leading_whitespaces (char *str)
448 while (ISSPACE (*str))
449 str++;
450 return str;
453 /* Remove trailing white spaces. */
455 static void
456 remove_trailing_whitespaces (char *str)
458 size_t last = strlen (str);
460 if (last == 0)
461 return;
465 last--;
466 if (ISSPACE (str [last]))
467 str[last] = '\0';
468 else
469 break;
471 while (last != 0);
474 /* Find next field separated by SEP and terminate it. Return a
475 pointer to the one after it. */
477 static char *
478 next_field (char *str, char sep, char **next, char *last)
480 char *p;
482 p = remove_leading_whitespaces (str);
483 for (str = p; *str != sep && *str != '\0'; str++);
485 *str = '\0';
486 remove_trailing_whitespaces (p);
488 *next = str + 1;
490 if (p >= last)
491 abort ();
493 return p;
496 static void
497 set_bitfield (const char *f, bitfield *array, unsigned int size)
499 unsigned int i;
501 if (strcmp (f, "CpuSledgehammer") == 0)
502 f= "CpuK8";
503 else if (strcmp (f, "Mmword") == 0)
504 f= "Qword";
505 else if (strcmp (f, "Oword") == 0)
506 f= "Xmmword";
508 for (i = 0; i < size; i++)
509 if (strcasecmp (array[i].name, f) == 0)
511 array[i].value = 1;
512 return;
515 fail (_("%s: %d: Unknown bitfield: %s\n"), filename, lineno, f);
518 static void
519 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
520 int macro, const char *comma, const char *indent)
522 unsigned int i;
524 fprintf (table, "%s{ { ", indent);
526 for (i = 0; i < size - 1; i++)
528 fprintf (table, "%d, ", flags[i].value);
529 if (((i + 1) % 20) == 0)
531 /* We need \\ for macro. */
532 if (macro)
533 fprintf (table, " \\\n %s", indent);
534 else
535 fprintf (table, "\n %s", indent);
539 fprintf (table, "%d } }%s\n", flags[i].value, comma);
542 static void
543 process_i386_cpu_flag (FILE *table, char *flag, int macro,
544 const char *comma, const char *indent)
546 char *str, *next, *last;
547 bitfield flags [ARRAY_SIZE (cpu_flags)];
549 /* Copy the default cpu flags. */
550 memcpy (flags, cpu_flags, sizeof (cpu_flags));
552 if (strcasecmp (flag, "unknown") == 0)
554 unsigned int i;
556 /* We turn on everything except for cpu64 in case of
557 CPU_UNKNOWN_FLAGS. */
558 for (i = 0; i < ARRAY_SIZE (flags); i++)
559 if (flags[i].position != Cpu64)
560 flags[i].value = 1;
562 else if (strcmp (flag, "0"))
564 last = flag + strlen (flag);
565 for (next = flag; next && next < last; )
567 str = next_field (next, '|', &next, last);
568 if (str)
569 set_bitfield (str, flags, ARRAY_SIZE (flags));
573 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
574 comma, indent);
577 static void
578 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
580 unsigned int i;
582 fprintf (table, " { ");
584 for (i = 0; i < size - 1; i++)
586 fprintf (table, "%d, ", modifier[i].value);
587 if (((i + 1) % 20) == 0)
588 fprintf (table, "\n ");
591 fprintf (table, "%d },\n", modifier[i].value);
594 static void
595 process_i386_opcode_modifier (FILE *table, char *mod)
597 char *str, *next, *last;
598 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
600 /* Copy the default opcode modifier. */
601 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
603 if (strcmp (mod, "0"))
605 last = mod + strlen (mod);
606 for (next = mod; next && next < last; )
608 str = next_field (next, '|', &next, last);
609 if (str)
610 set_bitfield (str, modifiers, ARRAY_SIZE (modifiers));
613 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
616 static void
617 output_operand_type (FILE *table, bitfield *types, unsigned int size,
618 int macro, const char *indent)
620 unsigned int i;
622 fprintf (table, "{ { ");
624 for (i = 0; i < size - 1; i++)
626 fprintf (table, "%d, ", types[i].value);
627 if (((i + 1) % 20) == 0)
629 /* We need \\ for macro. */
630 if (macro)
631 fprintf (table, "\\\n%s", indent);
632 else
633 fprintf (table, "\n%s", indent);
637 fprintf (table, "%d } }", types[i].value);
640 static void
641 process_i386_operand_type (FILE *table, char *op, int macro,
642 const char *indent)
644 char *str, *next, *last;
645 bitfield types [ARRAY_SIZE (operand_types)];
647 /* Copy the default operand type. */
648 memcpy (types, operand_types, sizeof (types));
650 if (strcmp (op, "0"))
652 last = op + strlen (op);
653 for (next = op; next && next < last; )
655 str = next_field (next, '|', &next, last);
656 if (str)
657 set_bitfield (str, types, ARRAY_SIZE (types));
660 output_operand_type (table, types, ARRAY_SIZE (types), macro,
661 indent);
664 static void
665 output_i386_opcode (FILE *table, const char *name, char *str,
666 char *last)
668 unsigned int i;
669 char *operands, *base_opcode, *extension_opcode, *opcode_length;
670 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
672 /* Find number of operands. */
673 operands = next_field (str, ',', &str, last);
675 /* Find base_opcode. */
676 base_opcode = next_field (str, ',', &str, last);
678 /* Find extension_opcode. */
679 extension_opcode = next_field (str, ',', &str, last);
681 /* Find opcode_length. */
682 opcode_length = next_field (str, ',', &str, last);
684 /* Find cpu_flags. */
685 cpu_flags = next_field (str, ',', &str, last);
687 /* Find opcode_modifier. */
688 opcode_modifier = next_field (str, ',', &str, last);
690 /* Remove the first {. */
691 str = remove_leading_whitespaces (str);
692 if (*str != '{')
693 abort ();
694 str = remove_leading_whitespaces (str + 1);
696 i = strlen (str);
698 /* There are at least "X}". */
699 if (i < 2)
700 abort ();
702 /* Remove trailing white spaces and }. */
705 i--;
706 if (ISSPACE (str[i]) || str[i] == '}')
707 str[i] = '\0';
708 else
709 break;
711 while (i != 0);
713 last = str + i;
715 /* Find operand_types. */
716 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
718 if (str >= last)
720 operand_types [i] = NULL;
721 break;
724 operand_types [i] = next_field (str, ',', &str, last);
725 if (*operand_types[i] == '0')
727 if (i != 0)
728 operand_types[i] = NULL;
729 break;
733 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
734 name, operands, base_opcode, extension_opcode,
735 opcode_length);
737 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ");
739 process_i386_opcode_modifier (table, opcode_modifier);
741 fprintf (table, " { ");
743 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
745 if (operand_types[i] == NULL || *operand_types[i] == '0')
747 if (i == 0)
748 process_i386_operand_type (table, "0", 0, "\t ");
749 break;
752 if (i != 0)
753 fprintf (table, ",\n ");
755 process_i386_operand_type (table, operand_types[i], 0,
756 "\t ");
758 fprintf (table, " } },\n");
761 struct opcode_hash_entry
763 struct opcode_hash_entry *next;
764 char *name;
765 char *opcode;
768 /* Calculate the hash value of an opcode hash entry P. */
770 static hashval_t
771 opcode_hash_hash (const void *p)
773 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
774 return htab_hash_string (entry->name);
777 /* Compare a string Q against an opcode hash entry P. */
779 static int
780 opcode_hash_eq (const void *p, const void *q)
782 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
783 const char *name = (const char *) q;
784 return strcmp (name, entry->name) == 0;
787 static void
788 process_i386_opcodes (FILE *table)
790 FILE *fp;
791 char buf[2048];
792 unsigned int i, j;
793 char *str, *p, *last, *name;
794 struct opcode_hash_entry **hash_slot, **entry, *next;
795 htab_t opcode_hash_table;
796 struct opcode_hash_entry **opcode_array;
797 unsigned int opcode_array_size = 1024;
799 filename = "i386-opc.tbl";
800 fp = fopen (filename, "r");
802 if (fp == NULL)
803 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
804 xstrerror (errno));
806 i = 0;
807 opcode_array = (struct opcode_hash_entry **)
808 xmalloc (sizeof (*opcode_array) * opcode_array_size);
810 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
811 opcode_hash_eq, NULL,
812 xcalloc, free);
814 fprintf (table, "\n/* i386 opcode table. */\n\n");
815 fprintf (table, "const template i386_optab[] =\n{\n");
817 /* Put everything on opcode array. */
818 while (!feof (fp))
820 if (fgets (buf, sizeof (buf), fp) == NULL)
821 break;
823 lineno++;
825 p = remove_leading_whitespaces (buf);
827 /* Skip comments. */
828 str = strstr (p, "//");
829 if (str != NULL)
830 str[0] = '\0';
832 /* Remove trailing white spaces. */
833 remove_trailing_whitespaces (p);
835 switch (p[0])
837 case '#':
838 /* Ignore comments. */
839 case '\0':
840 continue;
841 break;
842 default:
843 break;
846 last = p + strlen (p);
848 /* Find name. */
849 name = next_field (p, ',', &str, last);
851 /* Get the slot in hash table. */
852 hash_slot = (struct opcode_hash_entry **)
853 htab_find_slot_with_hash (opcode_hash_table, name,
854 htab_hash_string (name),
855 INSERT);
857 if (*hash_slot == NULL)
859 /* It is the new one. Put it on opcode array. */
860 if (i >= opcode_array_size)
862 /* Grow the opcode array when needed. */
863 opcode_array_size += 1024;
864 opcode_array = (struct opcode_hash_entry **)
865 xrealloc (opcode_array,
866 sizeof (*opcode_array) * opcode_array_size);
869 opcode_array[i] = (struct opcode_hash_entry *)
870 xmalloc (sizeof (struct opcode_hash_entry));
871 opcode_array[i]->next = NULL;
872 opcode_array[i]->name = xstrdup (name);
873 opcode_array[i]->opcode = xstrdup (str);
874 *hash_slot = opcode_array[i];
875 i++;
877 else
879 /* Append it to the existing one. */
880 entry = hash_slot;
881 while ((*entry) != NULL)
882 entry = &(*entry)->next;
883 *entry = (struct opcode_hash_entry *)
884 xmalloc (sizeof (struct opcode_hash_entry));
885 (*entry)->next = NULL;
886 (*entry)->name = (*hash_slot)->name;
887 (*entry)->opcode = xstrdup (str);
891 /* Process opcode array. */
892 for (j = 0; j < i; j++)
894 for (next = opcode_array[j]; next; next = next->next)
896 name = next->name;
897 str = next->opcode;
898 last = str + strlen (str);
899 output_i386_opcode (table, name, str, last);
903 fclose (fp);
905 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
907 process_i386_cpu_flag (table, "0", 0, ",", " ");
909 process_i386_opcode_modifier (table, "0");
911 fprintf (table, " { ");
912 process_i386_operand_type (table, "0", 0, "\t ");
913 fprintf (table, " } }\n");
915 fprintf (table, "};\n");
918 static void
919 process_i386_registers (FILE *table)
921 FILE *fp;
922 char buf[2048];
923 char *str, *p, *last;
924 char *reg_name, *reg_type, *reg_flags, *reg_num;
925 char *dw2_32_num, *dw2_64_num;
927 filename = "i386-reg.tbl";
928 fp = fopen (filename, "r");
929 if (fp == NULL)
930 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
931 xstrerror (errno));
933 fprintf (table, "\n/* i386 register table. */\n\n");
934 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
936 while (!feof (fp))
938 if (fgets (buf, sizeof (buf), fp) == NULL)
939 break;
941 lineno++;
943 p = remove_leading_whitespaces (buf);
945 /* Skip comments. */
946 str = strstr (p, "//");
947 if (str != NULL)
948 str[0] = '\0';
950 /* Remove trailing white spaces. */
951 remove_trailing_whitespaces (p);
953 switch (p[0])
955 case '#':
956 fprintf (table, "%s\n", p);
957 case '\0':
958 continue;
959 break;
960 default:
961 break;
964 last = p + strlen (p);
966 /* Find reg_name. */
967 reg_name = next_field (p, ',', &str, last);
969 /* Find reg_type. */
970 reg_type = next_field (str, ',', &str, last);
972 /* Find reg_flags. */
973 reg_flags = next_field (str, ',', &str, last);
975 /* Find reg_num. */
976 reg_num = next_field (str, ',', &str, last);
978 fprintf (table, " { \"%s\",\n ", reg_name);
980 process_i386_operand_type (table, reg_type, 0, "\t");
982 /* Find 32-bit Dwarf2 register number. */
983 dw2_32_num = next_field (str, ',', &str, last);
985 /* Find 64-bit Dwarf2 register number. */
986 dw2_64_num = next_field (str, ',', &str, last);
988 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
989 reg_flags, reg_num, dw2_32_num, dw2_64_num);
992 fclose (fp);
994 fprintf (table, "};\n");
996 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
999 static void
1000 process_i386_initializers (void)
1002 unsigned int i;
1003 FILE *fp = fopen ("i386-init.h", "w");
1004 char *init;
1006 if (fp == NULL)
1007 fail (_("can't create i386-init.h, errno = %s\n"),
1008 xstrerror (errno));
1010 process_copyright (fp);
1012 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1014 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1015 init = xstrdup (cpu_flag_init[i].init);
1016 process_i386_cpu_flag (fp, init, 1, "", " ");
1017 free (init);
1020 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1022 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1023 init = xstrdup (operand_type_init[i].init);
1024 process_i386_operand_type (fp, init, 1, " ");
1025 free (init);
1027 fprintf (fp, "\n");
1029 fclose (fp);
1032 /* Program options. */
1033 #define OPTION_SRCDIR 200
1035 struct option long_options[] =
1037 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1038 {"debug", no_argument, NULL, 'd'},
1039 {"version", no_argument, NULL, 'V'},
1040 {"help", no_argument, NULL, 'h'},
1041 {0, no_argument, NULL, 0}
1044 static void
1045 print_version (void)
1047 printf ("%s: version 1.0\n", program_name);
1048 xexit (0);
1051 static void
1052 usage (FILE * stream, int status)
1054 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1055 program_name);
1056 xexit (status);
1060 main (int argc, char **argv)
1062 extern int chdir (char *);
1063 char *srcdir = NULL;
1064 int c;
1065 FILE *table;
1067 program_name = *argv;
1068 xmalloc_set_program_name (program_name);
1070 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1071 switch (c)
1073 case OPTION_SRCDIR:
1074 srcdir = optarg;
1075 break;
1076 case 'V':
1077 case 'v':
1078 print_version ();
1079 break;
1080 case 'd':
1081 debug = 1;
1082 break;
1083 case 'h':
1084 case '?':
1085 usage (stderr, 0);
1086 default:
1087 case 0:
1088 break;
1091 if (optind != argc)
1092 usage (stdout, 1);
1094 if (srcdir != NULL)
1095 if (chdir (srcdir) != 0)
1096 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1097 srcdir, xstrerror (errno));
1099 /* Check the unused bitfield in i386_cpu_flags. */
1100 #ifndef CpuUnused
1101 c = CpuNumOfBits - CpuMax - 1;
1102 if (c)
1103 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1104 #endif
1106 /* Check the unused bitfield in i386_operand_type. */
1107 #ifndef OTUnused
1108 c = OTNumOfBits - OTMax - 1;
1109 if (c)
1110 fail (_("%d unused bits in i386_operand_type.\n"), c);
1111 #endif
1113 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1114 compare);
1116 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1117 sizeof (opcode_modifiers [0]), compare);
1119 qsort (operand_types, ARRAY_SIZE (operand_types),
1120 sizeof (operand_types [0]), compare);
1122 table = fopen ("i386-tbl.h", "w");
1123 if (table == NULL)
1124 fail (_("can't create i386-tbl.h, errno = %s\n"),
1125 xstrerror (errno));
1127 process_copyright (table);
1129 process_i386_opcodes (table);
1130 process_i386_registers (table);
1131 process_i386_initializers ();
1133 fclose (table);
1135 exit (0);