* objdump.c (disassemble_bytes): Clear aux->reloc before printing
[binutils.git] / opcodes / i386-gen.c
blob08ade93676c861a4d5e52a8be8cecd63fccfdb8b
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 "~CpuL1OM" },
47 { "CPU_GENERIC32_FLAGS",
48 "Cpu186|Cpu286|Cpu386" },
49 { "CPU_GENERIC64_FLAGS",
50 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|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|Cpu387" },
63 { "CPU_I686_FLAGS",
64 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687" },
65 { "CPU_P2_FLAGS",
66 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuMMX" },
67 { "CPU_P3_FLAGS",
68 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuMMX|CpuSSE" },
69 { "CPU_P4_FLAGS",
70 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuMMX|CpuSSE|CpuSSE2" },
71 { "CPU_NOCONA_FLAGS",
72 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuLM" },
73 { "CPU_CORE_FLAGS",
74 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
75 { "CPU_CORE2_FLAGS",
76 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuLM" },
77 { "CPU_COREI7_FLAGS",
78 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuRdtscp|CpuLM" },
79 { "CPU_K6_FLAGS",
80 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CpuMMX" },
81 { "CPU_K6_2_FLAGS",
82 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CpuMMX|Cpu3dnow" },
83 { "CPU_ATHLON_FLAGS",
84 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|Cpu387|Cpu687|CpuMMX|Cpu3dnow|Cpu3dnowA" },
85 { "CPU_K8_FLAGS",
86 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuLM" },
87 { "CPU_AMDFAM10_FLAGS",
88 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM" },
89 { "CPU_BDVER1_FLAGS",
90 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM|CpuFMA4|CpuXOP|CpuLWP" },
91 { "CPU_8087_FLAGS",
92 "Cpu8087" },
93 { "CPU_287_FLAGS",
94 "Cpu287" },
95 { "CPU_387_FLAGS",
96 "Cpu387" },
97 { "CPU_ANY87_FLAGS",
98 "Cpu8087|Cpu287|Cpu387|Cpu687|CpuFISTTP" },
99 { "CPU_CLFLUSH_FLAGS",
100 "CpuClflush" },
101 { "CPU_SYSCALL_FLAGS",
102 "CpuSYSCALL" },
103 { "CPU_MMX_FLAGS",
104 "CpuMMX" },
105 { "CPU_SSE_FLAGS",
106 "CpuMMX|CpuSSE" },
107 { "CPU_SSE2_FLAGS",
108 "CpuMMX|CpuSSE|CpuSSE2" },
109 { "CPU_SSE3_FLAGS",
110 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
111 { "CPU_SSSE3_FLAGS",
112 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3" },
113 { "CPU_SSE4_1_FLAGS",
114 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1" },
115 { "CPU_SSE4_2_FLAGS",
116 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2" },
117 { "CPU_ANY_SSE_FLAGS",
118 "CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuAVX" },
119 { "CPU_VMX_FLAGS",
120 "CpuVMX" },
121 { "CPU_SMX_FLAGS",
122 "CpuSMX" },
123 { "CPU_XSAVE_FLAGS",
124 "CpuXsave" },
125 { "CPU_AES_FLAGS",
126 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAES" },
127 { "CPU_PCLMUL_FLAGS",
128 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuPCLMUL" },
129 { "CPU_FMA_FLAGS",
130 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA" },
131 { "CPU_FMA4_FLAGS",
132 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA4" },
133 { "CPU_XOP_FLAGS",
134 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuABM|CpuAVX|CpuFMA4|CpuXOP" },
135 { "CPU_LWP_FLAGS",
136 "CpuLWP" },
137 { "CPU_MOVBE_FLAGS",
138 "CpuMovbe" },
139 { "CPU_RDTSCP_FLAGS",
140 "CpuRdtscp" },
141 { "CPU_EPT_FLAGS",
142 "CpuEPT" },
143 { "CPU_3DNOW_FLAGS",
144 "CpuMMX|Cpu3dnow" },
145 { "CPU_3DNOWA_FLAGS",
146 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
147 { "CPU_PADLOCK_FLAGS",
148 "CpuPadLock" },
149 { "CPU_SVME_FLAGS",
150 "CpuSVME" },
151 { "CPU_SSE4A_FLAGS",
152 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
153 { "CPU_ABM_FLAGS",
154 "CpuABM" },
155 { "CPU_AVX_FLAGS",
156 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
157 { "CPU_ANY_AVX_FLAGS",
158 "CpuAVX" },
159 { "CPU_L1OM_FLAGS",
160 "unknown" },
163 static initializer operand_type_init[] =
165 { "OPERAND_TYPE_NONE",
166 "0" },
167 { "OPERAND_TYPE_REG8",
168 "Reg8" },
169 { "OPERAND_TYPE_REG16",
170 "Reg16" },
171 { "OPERAND_TYPE_REG32",
172 "Reg32" },
173 { "OPERAND_TYPE_REG64",
174 "Reg64" },
175 { "OPERAND_TYPE_IMM1",
176 "Imm1" },
177 { "OPERAND_TYPE_IMM8",
178 "Imm8" },
179 { "OPERAND_TYPE_IMM8S",
180 "Imm8S" },
181 { "OPERAND_TYPE_IMM16",
182 "Imm16" },
183 { "OPERAND_TYPE_IMM32",
184 "Imm32" },
185 { "OPERAND_TYPE_IMM32S",
186 "Imm32S" },
187 { "OPERAND_TYPE_IMM64",
188 "Imm64" },
189 { "OPERAND_TYPE_BASEINDEX",
190 "BaseIndex" },
191 { "OPERAND_TYPE_DISP8",
192 "Disp8" },
193 { "OPERAND_TYPE_DISP16",
194 "Disp16" },
195 { "OPERAND_TYPE_DISP32",
196 "Disp32" },
197 { "OPERAND_TYPE_DISP32S",
198 "Disp32S" },
199 { "OPERAND_TYPE_DISP64",
200 "Disp64" },
201 { "OPERAND_TYPE_INOUTPORTREG",
202 "InOutPortReg" },
203 { "OPERAND_TYPE_SHIFTCOUNT",
204 "ShiftCount" },
205 { "OPERAND_TYPE_CONTROL",
206 "Control" },
207 { "OPERAND_TYPE_TEST",
208 "Test" },
209 { "OPERAND_TYPE_DEBUG",
210 "FloatReg" },
211 { "OPERAND_TYPE_FLOATREG",
212 "FloatReg" },
213 { "OPERAND_TYPE_FLOATACC",
214 "FloatAcc" },
215 { "OPERAND_TYPE_SREG2",
216 "SReg2" },
217 { "OPERAND_TYPE_SREG3",
218 "SReg3" },
219 { "OPERAND_TYPE_ACC",
220 "Acc" },
221 { "OPERAND_TYPE_JUMPABSOLUTE",
222 "JumpAbsolute" },
223 { "OPERAND_TYPE_REGMMX",
224 "RegMMX" },
225 { "OPERAND_TYPE_REGXMM",
226 "RegXMM" },
227 { "OPERAND_TYPE_REGYMM",
228 "RegYMM" },
229 { "OPERAND_TYPE_ESSEG",
230 "EsSeg" },
231 { "OPERAND_TYPE_ACC32",
232 "Reg32|Acc|Dword" },
233 { "OPERAND_TYPE_ACC64",
234 "Reg64|Acc|Qword" },
235 { "OPERAND_TYPE_INOUTPORTREG",
236 "InOutPortReg" },
237 { "OPERAND_TYPE_REG16_INOUTPORTREG",
238 "Reg16|InOutPortReg" },
239 { "OPERAND_TYPE_DISP16_32",
240 "Disp16|Disp32" },
241 { "OPERAND_TYPE_ANYDISP",
242 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
243 { "OPERAND_TYPE_IMM16_32",
244 "Imm16|Imm32" },
245 { "OPERAND_TYPE_IMM16_32S",
246 "Imm16|Imm32S" },
247 { "OPERAND_TYPE_IMM16_32_32S",
248 "Imm16|Imm32|Imm32S" },
249 { "OPERAND_TYPE_IMM32_32S_DISP32",
250 "Imm32|Imm32S|Disp32" },
251 { "OPERAND_TYPE_IMM64_DISP64",
252 "Imm64|Disp64" },
253 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
254 "Imm32|Imm32S|Imm64|Disp32" },
255 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
256 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
259 typedef struct bitfield
261 int position;
262 int value;
263 const char *name;
264 } bitfield;
266 #define BITFIELD(n) { n, 0, #n }
268 static bitfield cpu_flags[] =
270 BITFIELD (Cpu186),
271 BITFIELD (Cpu286),
272 BITFIELD (Cpu386),
273 BITFIELD (Cpu486),
274 BITFIELD (Cpu586),
275 BITFIELD (Cpu686),
276 BITFIELD (CpuClflush),
277 BITFIELD (CpuSYSCALL),
278 BITFIELD (Cpu8087),
279 BITFIELD (Cpu287),
280 BITFIELD (Cpu387),
281 BITFIELD (Cpu687),
282 BITFIELD (CpuFISTTP),
283 BITFIELD (CpuMMX),
284 BITFIELD (CpuSSE),
285 BITFIELD (CpuSSE2),
286 BITFIELD (CpuSSE3),
287 BITFIELD (CpuSSSE3),
288 BITFIELD (CpuSSE4_1),
289 BITFIELD (CpuSSE4_2),
290 BITFIELD (CpuAVX),
291 BITFIELD (CpuL1OM),
292 BITFIELD (CpuSSE4a),
293 BITFIELD (Cpu3dnow),
294 BITFIELD (Cpu3dnowA),
295 BITFIELD (CpuPadLock),
296 BITFIELD (CpuSVME),
297 BITFIELD (CpuVMX),
298 BITFIELD (CpuSMX),
299 BITFIELD (CpuABM),
300 BITFIELD (CpuXsave),
301 BITFIELD (CpuAES),
302 BITFIELD (CpuPCLMUL),
303 BITFIELD (CpuFMA),
304 BITFIELD (CpuFMA4),
305 BITFIELD (CpuXOP),
306 BITFIELD (CpuLWP),
307 BITFIELD (CpuLM),
308 BITFIELD (CpuMovbe),
309 BITFIELD (CpuEPT),
310 BITFIELD (CpuRdtscp),
311 BITFIELD (Cpu64),
312 BITFIELD (CpuNo64),
313 #ifdef CpuUnused
314 BITFIELD (CpuUnused),
315 #endif
318 static bitfield opcode_modifiers[] =
320 BITFIELD (D),
321 BITFIELD (W),
322 BITFIELD (S),
323 BITFIELD (Modrm),
324 BITFIELD (ShortForm),
325 BITFIELD (Jump),
326 BITFIELD (JumpDword),
327 BITFIELD (JumpByte),
328 BITFIELD (JumpInterSegment),
329 BITFIELD (FloatMF),
330 BITFIELD (FloatR),
331 BITFIELD (FloatD),
332 BITFIELD (Size16),
333 BITFIELD (Size32),
334 BITFIELD (Size64),
335 BITFIELD (IgnoreSize),
336 BITFIELD (DefaultSize),
337 BITFIELD (No_bSuf),
338 BITFIELD (No_wSuf),
339 BITFIELD (No_lSuf),
340 BITFIELD (No_sSuf),
341 BITFIELD (No_qSuf),
342 BITFIELD (No_ldSuf),
343 BITFIELD (FWait),
344 BITFIELD (IsString),
345 BITFIELD (IsLockable),
346 BITFIELD (RegKludge),
347 BITFIELD (FirstXmm0),
348 BITFIELD (Implicit1stXmm0),
349 BITFIELD (ToDword),
350 BITFIELD (ToQword),
351 BITFIELD (AddrPrefixOp0),
352 BITFIELD (IsPrefix),
353 BITFIELD (ImmExt),
354 BITFIELD (NoRex64),
355 BITFIELD (Rex64),
356 BITFIELD (Ugh),
357 BITFIELD (Vex),
358 BITFIELD (VexVVVV),
359 BITFIELD (VexW),
360 BITFIELD (VexOpcode),
361 BITFIELD (VexSources),
362 BITFIELD (VexImmExt),
363 BITFIELD (SSE2AVX),
364 BITFIELD (NoAVX),
365 BITFIELD (OldGcc),
366 BITFIELD (ATTMnemonic),
367 BITFIELD (ATTSyntax),
368 BITFIELD (IntelSyntax),
371 static bitfield operand_types[] =
373 BITFIELD (Reg8),
374 BITFIELD (Reg16),
375 BITFIELD (Reg32),
376 BITFIELD (Reg64),
377 BITFIELD (FloatReg),
378 BITFIELD (RegMMX),
379 BITFIELD (RegXMM),
380 BITFIELD (RegYMM),
381 BITFIELD (Imm1),
382 BITFIELD (Imm8),
383 BITFIELD (Imm8S),
384 BITFIELD (Imm16),
385 BITFIELD (Imm32),
386 BITFIELD (Imm32S),
387 BITFIELD (Imm64),
388 BITFIELD (BaseIndex),
389 BITFIELD (Disp8),
390 BITFIELD (Disp16),
391 BITFIELD (Disp32),
392 BITFIELD (Disp32S),
393 BITFIELD (Disp64),
394 BITFIELD (InOutPortReg),
395 BITFIELD (ShiftCount),
396 BITFIELD (Control),
397 BITFIELD (Debug),
398 BITFIELD (Test),
399 BITFIELD (SReg2),
400 BITFIELD (SReg3),
401 BITFIELD (Acc),
402 BITFIELD (FloatAcc),
403 BITFIELD (JumpAbsolute),
404 BITFIELD (EsSeg),
405 BITFIELD (RegMem),
406 BITFIELD (Mem),
407 BITFIELD (Byte),
408 BITFIELD (Word),
409 BITFIELD (Dword),
410 BITFIELD (Fword),
411 BITFIELD (Qword),
412 BITFIELD (Tbyte),
413 BITFIELD (Xmmword),
414 BITFIELD (Ymmword),
415 BITFIELD (Unspecified),
416 BITFIELD (Anysize),
417 #ifdef OTUnused
418 BITFIELD (OTUnused),
419 #endif
422 static const char *filename;
424 static int
425 compare (const void *x, const void *y)
427 const bitfield *xp = (const bitfield *) x;
428 const bitfield *yp = (const bitfield *) y;
429 return xp->position - yp->position;
432 static void
433 fail (const char *message, ...)
435 va_list args;
437 va_start (args, message);
438 fprintf (stderr, _("%s: Error: "), program_name);
439 vfprintf (stderr, message, args);
440 va_end (args);
441 xexit (1);
444 static void
445 process_copyright (FILE *fp)
447 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
448 /* Copyright 2007, 2008, 2009\n\
449 Free Software Foundation, Inc.\n\
451 This file is part of the GNU opcodes library.\n\
453 This library is free software; you can redistribute it and/or modify\n\
454 it under the terms of the GNU General Public License as published by\n\
455 the Free Software Foundation; either version 3, or (at your option)\n\
456 any later version.\n\
458 It is distributed in the hope that it will be useful, but WITHOUT\n\
459 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
460 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
461 License for more details.\n\
463 You should have received a copy of the GNU General Public License\n\
464 along with this program; if not, write to the Free Software\n\
465 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
466 MA 02110-1301, USA. */\n");
469 /* Remove leading white spaces. */
471 static char *
472 remove_leading_whitespaces (char *str)
474 while (ISSPACE (*str))
475 str++;
476 return str;
479 /* Remove trailing white spaces. */
481 static void
482 remove_trailing_whitespaces (char *str)
484 size_t last = strlen (str);
486 if (last == 0)
487 return;
491 last--;
492 if (ISSPACE (str [last]))
493 str[last] = '\0';
494 else
495 break;
497 while (last != 0);
500 /* Find next field separated by SEP and terminate it. Return a
501 pointer to the one after it. */
503 static char *
504 next_field (char *str, char sep, char **next, char *last)
506 char *p;
508 p = remove_leading_whitespaces (str);
509 for (str = p; *str != sep && *str != '\0'; str++);
511 *str = '\0';
512 remove_trailing_whitespaces (p);
514 *next = str + 1;
516 if (p >= last)
517 abort ();
519 return p;
522 static void
523 set_bitfield (const char *f, bitfield *array, int value,
524 unsigned int size, int lineno)
526 unsigned int i;
528 if (strcmp (f, "CpuFP") == 0)
530 set_bitfield("Cpu387", array, value, size, lineno);
531 set_bitfield("Cpu287", array, value, size, lineno);
532 f = "Cpu8087";
534 else if (strcmp (f, "Mmword") == 0)
535 f= "Qword";
536 else if (strcmp (f, "Oword") == 0)
537 f= "Xmmword";
539 for (i = 0; i < size; i++)
540 if (strcasecmp (array[i].name, f) == 0)
542 array[i].value = value;
543 return;
546 if (value)
548 const char *v = strchr (f, '=');
550 if (v)
552 size_t n = v - f;
553 char *end;
555 for (i = 0; i < size; i++)
556 if (strncasecmp (array[i].name, f, n) == 0)
558 value = strtol (v + 1, &end, 0);
559 if (*end == '\0')
561 array[i].value = value;
562 return;
564 break;
569 if (lineno != -1)
570 fail (_("%s: %d: Unknown bitfield: %s\n"), filename, lineno, f);
571 else
572 fail (_("Unknown bitfield: %s\n"), f);
575 static void
576 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
577 int macro, const char *comma, const char *indent)
579 unsigned int i;
581 fprintf (table, "%s{ { ", indent);
583 for (i = 0; i < size - 1; i++)
585 fprintf (table, "%d, ", flags[i].value);
586 if (((i + 1) % 20) == 0)
588 /* We need \\ for macro. */
589 if (macro)
590 fprintf (table, " \\\n %s", indent);
591 else
592 fprintf (table, "\n %s", indent);
596 fprintf (table, "%d } }%s\n", flags[i].value, comma);
599 static void
600 process_i386_cpu_flag (FILE *table, char *flag, int macro,
601 const char *comma, const char *indent,
602 int lineno)
604 char *str, *next, *last;
605 unsigned int i;
606 bitfield flags [ARRAY_SIZE (cpu_flags)];
608 /* Copy the default cpu flags. */
609 memcpy (flags, cpu_flags, sizeof (cpu_flags));
611 if (strcasecmp (flag, "unknown") == 0)
613 /* We turn on everything except for cpu64 in case of
614 CPU_UNKNOWN_FLAGS. */
615 for (i = 0; i < ARRAY_SIZE (flags); i++)
616 if (flags[i].position != Cpu64)
617 flags[i].value = 1;
619 else if (flag[0] == '~')
621 last = flag + strlen (flag);
623 if (flag[1] == '(')
625 last -= 1;
626 next = flag + 2;
627 if (*last != ')')
628 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename,
629 lineno, flag);
630 *last = '\0';
632 else
633 next = flag + 1;
635 /* First we turn on everything except for cpu64. */
636 for (i = 0; i < ARRAY_SIZE (flags); i++)
637 if (flags[i].position != Cpu64)
638 flags[i].value = 1;
640 /* Turn off selective bits. */
641 for (; next && next < last; )
643 str = next_field (next, '|', &next, last);
644 if (str)
645 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
648 else if (strcmp (flag, "0"))
650 /* Turn on selective bits. */
651 last = flag + strlen (flag);
652 for (next = flag; next && next < last; )
654 str = next_field (next, '|', &next, last);
655 if (str)
656 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
660 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
661 comma, indent);
664 static void
665 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
667 unsigned int i;
669 fprintf (table, " { ");
671 for (i = 0; i < size - 1; i++)
673 fprintf (table, "%d, ", modifier[i].value);
674 if (((i + 1) % 20) == 0)
675 fprintf (table, "\n ");
678 fprintf (table, "%d },\n", modifier[i].value);
681 static void
682 process_i386_opcode_modifier (FILE *table, char *mod, int lineno)
684 char *str, *next, *last;
685 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
687 /* Copy the default opcode modifier. */
688 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
690 if (strcmp (mod, "0"))
692 last = mod + strlen (mod);
693 for (next = mod; next && next < last; )
695 str = next_field (next, '|', &next, last);
696 if (str)
697 set_bitfield (str, modifiers, 1, ARRAY_SIZE (modifiers),
698 lineno);
701 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
704 static void
705 output_operand_type (FILE *table, bitfield *types, unsigned int size,
706 int macro, const char *indent)
708 unsigned int i;
710 fprintf (table, "{ { ");
712 for (i = 0; i < size - 1; i++)
714 fprintf (table, "%d, ", types[i].value);
715 if (((i + 1) % 20) == 0)
717 /* We need \\ for macro. */
718 if (macro)
719 fprintf (table, "\\\n%s", indent);
720 else
721 fprintf (table, "\n%s", indent);
725 fprintf (table, "%d } }", types[i].value);
728 static void
729 process_i386_operand_type (FILE *table, char *op, int macro,
730 const char *indent, int lineno)
732 char *str, *next, *last;
733 bitfield types [ARRAY_SIZE (operand_types)];
735 /* Copy the default operand type. */
736 memcpy (types, operand_types, sizeof (types));
738 if (strcmp (op, "0"))
740 last = op + strlen (op);
741 for (next = op; next && next < last; )
743 str = next_field (next, '|', &next, last);
744 if (str)
745 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
748 output_operand_type (table, types, ARRAY_SIZE (types), macro,
749 indent);
752 static void
753 output_i386_opcode (FILE *table, const char *name, char *str,
754 char *last, int lineno)
756 unsigned int i;
757 char *operands, *base_opcode, *extension_opcode, *opcode_length;
758 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
760 /* Find number of operands. */
761 operands = next_field (str, ',', &str, last);
763 /* Find base_opcode. */
764 base_opcode = next_field (str, ',', &str, last);
766 /* Find extension_opcode. */
767 extension_opcode = next_field (str, ',', &str, last);
769 /* Find opcode_length. */
770 opcode_length = next_field (str, ',', &str, last);
772 /* Find cpu_flags. */
773 cpu_flags = next_field (str, ',', &str, last);
775 /* Find opcode_modifier. */
776 opcode_modifier = next_field (str, ',', &str, last);
778 /* Remove the first {. */
779 str = remove_leading_whitespaces (str);
780 if (*str != '{')
781 abort ();
782 str = remove_leading_whitespaces (str + 1);
784 i = strlen (str);
786 /* There are at least "X}". */
787 if (i < 2)
788 abort ();
790 /* Remove trailing white spaces and }. */
793 i--;
794 if (ISSPACE (str[i]) || str[i] == '}')
795 str[i] = '\0';
796 else
797 break;
799 while (i != 0);
801 last = str + i;
803 /* Find operand_types. */
804 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
806 if (str >= last)
808 operand_types [i] = NULL;
809 break;
812 operand_types [i] = next_field (str, ',', &str, last);
813 if (*operand_types[i] == '0')
815 if (i != 0)
816 operand_types[i] = NULL;
817 break;
821 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
822 name, operands, base_opcode, extension_opcode,
823 opcode_length);
825 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
827 process_i386_opcode_modifier (table, opcode_modifier, lineno);
829 fprintf (table, " { ");
831 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
833 if (operand_types[i] == NULL || *operand_types[i] == '0')
835 if (i == 0)
836 process_i386_operand_type (table, "0", 0, "\t ", lineno);
837 break;
840 if (i != 0)
841 fprintf (table, ",\n ");
843 process_i386_operand_type (table, operand_types[i], 0,
844 "\t ", lineno);
846 fprintf (table, " } },\n");
849 struct opcode_hash_entry
851 struct opcode_hash_entry *next;
852 char *name;
853 char *opcode;
854 int lineno;
857 /* Calculate the hash value of an opcode hash entry P. */
859 static hashval_t
860 opcode_hash_hash (const void *p)
862 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
863 return htab_hash_string (entry->name);
866 /* Compare a string Q against an opcode hash entry P. */
868 static int
869 opcode_hash_eq (const void *p, const void *q)
871 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
872 const char *name = (const char *) q;
873 return strcmp (name, entry->name) == 0;
876 static void
877 process_i386_opcodes (FILE *table)
879 FILE *fp;
880 char buf[2048];
881 unsigned int i, j;
882 char *str, *p, *last, *name;
883 struct opcode_hash_entry **hash_slot, **entry, *next;
884 htab_t opcode_hash_table;
885 struct opcode_hash_entry **opcode_array;
886 unsigned int opcode_array_size = 1024;
887 int lineno = 0;
889 filename = "i386-opc.tbl";
890 fp = fopen (filename, "r");
892 if (fp == NULL)
893 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
894 xstrerror (errno));
896 i = 0;
897 opcode_array = (struct opcode_hash_entry **)
898 xmalloc (sizeof (*opcode_array) * opcode_array_size);
900 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
901 opcode_hash_eq, NULL,
902 xcalloc, free);
904 fprintf (table, "\n/* i386 opcode table. */\n\n");
905 fprintf (table, "const insn_template i386_optab[] =\n{\n");
907 /* Put everything on opcode array. */
908 while (!feof (fp))
910 if (fgets (buf, sizeof (buf), fp) == NULL)
911 break;
913 lineno++;
915 p = remove_leading_whitespaces (buf);
917 /* Skip comments. */
918 str = strstr (p, "//");
919 if (str != NULL)
920 str[0] = '\0';
922 /* Remove trailing white spaces. */
923 remove_trailing_whitespaces (p);
925 switch (p[0])
927 case '#':
928 /* Ignore comments. */
929 case '\0':
930 continue;
931 break;
932 default:
933 break;
936 last = p + strlen (p);
938 /* Find name. */
939 name = next_field (p, ',', &str, last);
941 /* Get the slot in hash table. */
942 hash_slot = (struct opcode_hash_entry **)
943 htab_find_slot_with_hash (opcode_hash_table, name,
944 htab_hash_string (name),
945 INSERT);
947 if (*hash_slot == NULL)
949 /* It is the new one. Put it on opcode array. */
950 if (i >= opcode_array_size)
952 /* Grow the opcode array when needed. */
953 opcode_array_size += 1024;
954 opcode_array = (struct opcode_hash_entry **)
955 xrealloc (opcode_array,
956 sizeof (*opcode_array) * opcode_array_size);
959 opcode_array[i] = (struct opcode_hash_entry *)
960 xmalloc (sizeof (struct opcode_hash_entry));
961 opcode_array[i]->next = NULL;
962 opcode_array[i]->name = xstrdup (name);
963 opcode_array[i]->opcode = xstrdup (str);
964 opcode_array[i]->lineno = lineno;
965 *hash_slot = opcode_array[i];
966 i++;
968 else
970 /* Append it to the existing one. */
971 entry = hash_slot;
972 while ((*entry) != NULL)
973 entry = &(*entry)->next;
974 *entry = (struct opcode_hash_entry *)
975 xmalloc (sizeof (struct opcode_hash_entry));
976 (*entry)->next = NULL;
977 (*entry)->name = (*hash_slot)->name;
978 (*entry)->opcode = xstrdup (str);
979 (*entry)->lineno = lineno;
983 /* Process opcode array. */
984 for (j = 0; j < i; j++)
986 for (next = opcode_array[j]; next; next = next->next)
988 name = next->name;
989 str = next->opcode;
990 lineno = next->lineno;
991 last = str + strlen (str);
992 output_i386_opcode (table, name, str, last, lineno);
996 fclose (fp);
998 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
1000 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1002 process_i386_opcode_modifier (table, "0", -1);
1004 fprintf (table, " { ");
1005 process_i386_operand_type (table, "0", 0, "\t ", -1);
1006 fprintf (table, " } }\n");
1008 fprintf (table, "};\n");
1011 static void
1012 process_i386_registers (FILE *table)
1014 FILE *fp;
1015 char buf[2048];
1016 char *str, *p, *last;
1017 char *reg_name, *reg_type, *reg_flags, *reg_num;
1018 char *dw2_32_num, *dw2_64_num;
1019 int lineno = 0;
1021 filename = "i386-reg.tbl";
1022 fp = fopen (filename, "r");
1023 if (fp == NULL)
1024 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1025 xstrerror (errno));
1027 fprintf (table, "\n/* i386 register table. */\n\n");
1028 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1030 while (!feof (fp))
1032 if (fgets (buf, sizeof (buf), fp) == NULL)
1033 break;
1035 lineno++;
1037 p = remove_leading_whitespaces (buf);
1039 /* Skip comments. */
1040 str = strstr (p, "//");
1041 if (str != NULL)
1042 str[0] = '\0';
1044 /* Remove trailing white spaces. */
1045 remove_trailing_whitespaces (p);
1047 switch (p[0])
1049 case '#':
1050 fprintf (table, "%s\n", p);
1051 case '\0':
1052 continue;
1053 break;
1054 default:
1055 break;
1058 last = p + strlen (p);
1060 /* Find reg_name. */
1061 reg_name = next_field (p, ',', &str, last);
1063 /* Find reg_type. */
1064 reg_type = next_field (str, ',', &str, last);
1066 /* Find reg_flags. */
1067 reg_flags = next_field (str, ',', &str, last);
1069 /* Find reg_num. */
1070 reg_num = next_field (str, ',', &str, last);
1072 fprintf (table, " { \"%s\",\n ", reg_name);
1074 process_i386_operand_type (table, reg_type, 0, "\t", lineno);
1076 /* Find 32-bit Dwarf2 register number. */
1077 dw2_32_num = next_field (str, ',', &str, last);
1079 /* Find 64-bit Dwarf2 register number. */
1080 dw2_64_num = next_field (str, ',', &str, last);
1082 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1083 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1086 fclose (fp);
1088 fprintf (table, "};\n");
1090 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1093 static void
1094 process_i386_initializers (void)
1096 unsigned int i;
1097 FILE *fp = fopen ("i386-init.h", "w");
1098 char *init;
1100 if (fp == NULL)
1101 fail (_("can't create i386-init.h, errno = %s\n"),
1102 xstrerror (errno));
1104 process_copyright (fp);
1106 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1108 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1109 init = xstrdup (cpu_flag_init[i].init);
1110 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1111 free (init);
1114 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1116 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1117 init = xstrdup (operand_type_init[i].init);
1118 process_i386_operand_type (fp, init, 1, " ", -1);
1119 free (init);
1121 fprintf (fp, "\n");
1123 fclose (fp);
1126 /* Program options. */
1127 #define OPTION_SRCDIR 200
1129 struct option long_options[] =
1131 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1132 {"debug", no_argument, NULL, 'd'},
1133 {"version", no_argument, NULL, 'V'},
1134 {"help", no_argument, NULL, 'h'},
1135 {0, no_argument, NULL, 0}
1138 static void
1139 print_version (void)
1141 printf ("%s: version 1.0\n", program_name);
1142 xexit (0);
1145 static void
1146 usage (FILE * stream, int status)
1148 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1149 program_name);
1150 xexit (status);
1154 main (int argc, char **argv)
1156 extern int chdir (char *);
1157 char *srcdir = NULL;
1158 int c;
1159 FILE *table;
1161 program_name = *argv;
1162 xmalloc_set_program_name (program_name);
1164 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1165 switch (c)
1167 case OPTION_SRCDIR:
1168 srcdir = optarg;
1169 break;
1170 case 'V':
1171 case 'v':
1172 print_version ();
1173 break;
1174 case 'd':
1175 debug = 1;
1176 break;
1177 case 'h':
1178 case '?':
1179 usage (stderr, 0);
1180 default:
1181 case 0:
1182 break;
1185 if (optind != argc)
1186 usage (stdout, 1);
1188 if (srcdir != NULL)
1189 if (chdir (srcdir) != 0)
1190 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1191 srcdir, xstrerror (errno));
1193 /* Check the unused bitfield in i386_cpu_flags. */
1194 #ifndef CpuUnused
1195 c = CpuNumOfBits - CpuMax - 1;
1196 if (c)
1197 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1198 #endif
1200 /* Check the unused bitfield in i386_operand_type. */
1201 #ifndef OTUnused
1202 c = OTNumOfBits - OTMax - 1;
1203 if (c)
1204 fail (_("%d unused bits in i386_operand_type.\n"), c);
1205 #endif
1207 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1208 compare);
1210 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1211 sizeof (opcode_modifiers [0]), compare);
1213 qsort (operand_types, ARRAY_SIZE (operand_types),
1214 sizeof (operand_types [0]), compare);
1216 table = fopen ("i386-tbl.h", "w");
1217 if (table == NULL)
1218 fail (_("can't create i386-tbl.h, errno = %s\n"),
1219 xstrerror (errno));
1221 process_copyright (table);
1223 process_i386_opcodes (table);
1224 process_i386_registers (table);
1225 process_i386_initializers ();
1227 fclose (table);
1229 exit (0);