bfd/binutils/gas/gprof/ld/libiberty/opcodes: add .gitignore
[binutils.git] / opcodes / i386-gen.c
blobee0633863d439e977df3a277ee5d986b7b076a5f
1 /* Copyright 2007, 2008, 2009, 2010
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|CpuNop|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_PENTIUMPRO_FLAGS",
66 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuNop" },
67 { "CPU_P2_FLAGS",
68 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuNop|CpuMMX" },
69 { "CPU_P3_FLAGS",
70 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE" },
71 { "CPU_P4_FLAGS",
72 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE|CpuSSE2" },
73 { "CPU_NOCONA_FLAGS",
74 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuLM" },
75 { "CPU_CORE_FLAGS",
76 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
77 { "CPU_CORE2_FLAGS",
78 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuLM" },
79 { "CPU_COREI7_FLAGS",
80 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuRdtscp|CpuLM" },
81 { "CPU_K6_FLAGS",
82 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CpuMMX" },
83 { "CPU_K6_2_FLAGS",
84 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CpuNop|CpuMMX|Cpu3dnow" },
85 { "CPU_ATHLON_FLAGS",
86 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|Cpu387|Cpu687|CpuNop|CpuMMX|Cpu3dnow|Cpu3dnowA" },
87 { "CPU_K8_FLAGS",
88 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuNop|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuLM" },
89 { "CPU_AMDFAM10_FLAGS",
90 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM" },
91 { "CPU_BDVER1_FLAGS",
92 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM|CpuFMA4|CpuXOP|CpuLWP" },
93 { "CPU_8087_FLAGS",
94 "Cpu8087" },
95 { "CPU_287_FLAGS",
96 "Cpu287" },
97 { "CPU_387_FLAGS",
98 "Cpu387" },
99 { "CPU_ANY87_FLAGS",
100 "Cpu8087|Cpu287|Cpu387|Cpu687|CpuFISTTP" },
101 { "CPU_CLFLUSH_FLAGS",
102 "CpuClflush" },
103 { "CPU_NOP_FLAGS",
104 "CpuNop" },
105 { "CPU_SYSCALL_FLAGS",
106 "CpuSYSCALL" },
107 { "CPU_MMX_FLAGS",
108 "CpuMMX" },
109 { "CPU_SSE_FLAGS",
110 "CpuMMX|CpuSSE" },
111 { "CPU_SSE2_FLAGS",
112 "CpuMMX|CpuSSE|CpuSSE2" },
113 { "CPU_SSE3_FLAGS",
114 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
115 { "CPU_SSSE3_FLAGS",
116 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3" },
117 { "CPU_SSE4_1_FLAGS",
118 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1" },
119 { "CPU_SSE4_2_FLAGS",
120 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2" },
121 { "CPU_ANY_SSE_FLAGS",
122 "CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuAVX" },
123 { "CPU_VMX_FLAGS",
124 "CpuVMX" },
125 { "CPU_SMX_FLAGS",
126 "CpuSMX" },
127 { "CPU_XSAVE_FLAGS",
128 "CpuXsave" },
129 { "CPU_XSAVEOPT_FLAGS",
130 "CpuXsaveopt" },
131 { "CPU_AES_FLAGS",
132 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAES" },
133 { "CPU_PCLMUL_FLAGS",
134 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuPCLMUL" },
135 { "CPU_FMA_FLAGS",
136 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA" },
137 { "CPU_FMA4_FLAGS",
138 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA4" },
139 { "CPU_XOP_FLAGS",
140 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuABM|CpuAVX|CpuFMA4|CpuXOP" },
141 { "CPU_LWP_FLAGS",
142 "CpuLWP" },
143 { "CPU_MOVBE_FLAGS",
144 "CpuMovbe" },
145 { "CPU_RDTSCP_FLAGS",
146 "CpuRdtscp" },
147 { "CPU_EPT_FLAGS",
148 "CpuEPT" },
149 { "CPU_FSGSBASE_FLAGS",
150 "CpuFSGSBase" },
151 { "CPU_RDRND_FLAGS",
152 "CpuRdRnd" },
153 { "CPU_F16C_FLAGS",
154 "CpuF16C" },
155 { "CPU_3DNOW_FLAGS",
156 "CpuMMX|Cpu3dnow" },
157 { "CPU_3DNOWA_FLAGS",
158 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
159 { "CPU_PADLOCK_FLAGS",
160 "CpuPadLock" },
161 { "CPU_SVME_FLAGS",
162 "CpuSVME" },
163 { "CPU_SSE4A_FLAGS",
164 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
165 { "CPU_ABM_FLAGS",
166 "CpuABM" },
167 { "CPU_AVX_FLAGS",
168 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
169 { "CPU_ANY_AVX_FLAGS",
170 "CpuAVX" },
171 { "CPU_L1OM_FLAGS",
172 "unknown" },
175 static initializer operand_type_init[] =
177 { "OPERAND_TYPE_NONE",
178 "0" },
179 { "OPERAND_TYPE_REG8",
180 "Reg8" },
181 { "OPERAND_TYPE_REG16",
182 "Reg16" },
183 { "OPERAND_TYPE_REG32",
184 "Reg32" },
185 { "OPERAND_TYPE_REG64",
186 "Reg64" },
187 { "OPERAND_TYPE_IMM1",
188 "Imm1" },
189 { "OPERAND_TYPE_IMM8",
190 "Imm8" },
191 { "OPERAND_TYPE_IMM8S",
192 "Imm8S" },
193 { "OPERAND_TYPE_IMM16",
194 "Imm16" },
195 { "OPERAND_TYPE_IMM32",
196 "Imm32" },
197 { "OPERAND_TYPE_IMM32S",
198 "Imm32S" },
199 { "OPERAND_TYPE_IMM64",
200 "Imm64" },
201 { "OPERAND_TYPE_BASEINDEX",
202 "BaseIndex" },
203 { "OPERAND_TYPE_DISP8",
204 "Disp8" },
205 { "OPERAND_TYPE_DISP16",
206 "Disp16" },
207 { "OPERAND_TYPE_DISP32",
208 "Disp32" },
209 { "OPERAND_TYPE_DISP32S",
210 "Disp32S" },
211 { "OPERAND_TYPE_DISP64",
212 "Disp64" },
213 { "OPERAND_TYPE_INOUTPORTREG",
214 "InOutPortReg" },
215 { "OPERAND_TYPE_SHIFTCOUNT",
216 "ShiftCount" },
217 { "OPERAND_TYPE_CONTROL",
218 "Control" },
219 { "OPERAND_TYPE_TEST",
220 "Test" },
221 { "OPERAND_TYPE_DEBUG",
222 "FloatReg" },
223 { "OPERAND_TYPE_FLOATREG",
224 "FloatReg" },
225 { "OPERAND_TYPE_FLOATACC",
226 "FloatAcc" },
227 { "OPERAND_TYPE_SREG2",
228 "SReg2" },
229 { "OPERAND_TYPE_SREG3",
230 "SReg3" },
231 { "OPERAND_TYPE_ACC",
232 "Acc" },
233 { "OPERAND_TYPE_JUMPABSOLUTE",
234 "JumpAbsolute" },
235 { "OPERAND_TYPE_REGMMX",
236 "RegMMX" },
237 { "OPERAND_TYPE_REGXMM",
238 "RegXMM" },
239 { "OPERAND_TYPE_REGYMM",
240 "RegYMM" },
241 { "OPERAND_TYPE_ESSEG",
242 "EsSeg" },
243 { "OPERAND_TYPE_ACC32",
244 "Reg32|Acc|Dword" },
245 { "OPERAND_TYPE_ACC64",
246 "Reg64|Acc|Qword" },
247 { "OPERAND_TYPE_INOUTPORTREG",
248 "InOutPortReg" },
249 { "OPERAND_TYPE_REG16_INOUTPORTREG",
250 "Reg16|InOutPortReg" },
251 { "OPERAND_TYPE_DISP16_32",
252 "Disp16|Disp32" },
253 { "OPERAND_TYPE_ANYDISP",
254 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
255 { "OPERAND_TYPE_IMM16_32",
256 "Imm16|Imm32" },
257 { "OPERAND_TYPE_IMM16_32S",
258 "Imm16|Imm32S" },
259 { "OPERAND_TYPE_IMM16_32_32S",
260 "Imm16|Imm32|Imm32S" },
261 { "OPERAND_TYPE_IMM32_32S_DISP32",
262 "Imm32|Imm32S|Disp32" },
263 { "OPERAND_TYPE_IMM64_DISP64",
264 "Imm64|Disp64" },
265 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
266 "Imm32|Imm32S|Imm64|Disp32" },
267 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
268 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
269 { "OPERAND_TYPE_VEC_IMM4",
270 "Vec_Imm4" },
273 typedef struct bitfield
275 int position;
276 int value;
277 const char *name;
278 } bitfield;
280 #define BITFIELD(n) { n, 0, #n }
282 static bitfield cpu_flags[] =
284 BITFIELD (Cpu186),
285 BITFIELD (Cpu286),
286 BITFIELD (Cpu386),
287 BITFIELD (Cpu486),
288 BITFIELD (Cpu586),
289 BITFIELD (Cpu686),
290 BITFIELD (CpuClflush),
291 BITFIELD (CpuNop),
292 BITFIELD (CpuSYSCALL),
293 BITFIELD (Cpu8087),
294 BITFIELD (Cpu287),
295 BITFIELD (Cpu387),
296 BITFIELD (Cpu687),
297 BITFIELD (CpuFISTTP),
298 BITFIELD (CpuMMX),
299 BITFIELD (CpuSSE),
300 BITFIELD (CpuSSE2),
301 BITFIELD (CpuSSE3),
302 BITFIELD (CpuSSSE3),
303 BITFIELD (CpuSSE4_1),
304 BITFIELD (CpuSSE4_2),
305 BITFIELD (CpuAVX),
306 BITFIELD (CpuL1OM),
307 BITFIELD (CpuSSE4a),
308 BITFIELD (Cpu3dnow),
309 BITFIELD (Cpu3dnowA),
310 BITFIELD (CpuPadLock),
311 BITFIELD (CpuSVME),
312 BITFIELD (CpuVMX),
313 BITFIELD (CpuSMX),
314 BITFIELD (CpuABM),
315 BITFIELD (CpuXsave),
316 BITFIELD (CpuXsaveopt),
317 BITFIELD (CpuAES),
318 BITFIELD (CpuPCLMUL),
319 BITFIELD (CpuFMA),
320 BITFIELD (CpuFMA4),
321 BITFIELD (CpuXOP),
322 BITFIELD (CpuLWP),
323 BITFIELD (CpuLM),
324 BITFIELD (CpuMovbe),
325 BITFIELD (CpuEPT),
326 BITFIELD (CpuRdtscp),
327 BITFIELD (CpuFSGSBase),
328 BITFIELD (CpuRdRnd),
329 BITFIELD (CpuF16C),
330 BITFIELD (Cpu64),
331 BITFIELD (CpuNo64),
332 #ifdef CpuUnused
333 BITFIELD (CpuUnused),
334 #endif
337 static bitfield opcode_modifiers[] =
339 BITFIELD (D),
340 BITFIELD (W),
341 BITFIELD (S),
342 BITFIELD (Modrm),
343 BITFIELD (ShortForm),
344 BITFIELD (Jump),
345 BITFIELD (JumpDword),
346 BITFIELD (JumpByte),
347 BITFIELD (JumpInterSegment),
348 BITFIELD (FloatMF),
349 BITFIELD (FloatR),
350 BITFIELD (FloatD),
351 BITFIELD (Size16),
352 BITFIELD (Size32),
353 BITFIELD (Size64),
354 BITFIELD (CheckRegSize),
355 BITFIELD (IgnoreSize),
356 BITFIELD (DefaultSize),
357 BITFIELD (No_bSuf),
358 BITFIELD (No_wSuf),
359 BITFIELD (No_lSuf),
360 BITFIELD (No_sSuf),
361 BITFIELD (No_qSuf),
362 BITFIELD (No_ldSuf),
363 BITFIELD (FWait),
364 BITFIELD (IsString),
365 BITFIELD (IsLockable),
366 BITFIELD (RegKludge),
367 BITFIELD (FirstXmm0),
368 BITFIELD (Implicit1stXmm0),
369 BITFIELD (ToDword),
370 BITFIELD (ToQword),
371 BITFIELD (AddrPrefixOp0),
372 BITFIELD (IsPrefix),
373 BITFIELD (ImmExt),
374 BITFIELD (NoRex64),
375 BITFIELD (Rex64),
376 BITFIELD (Ugh),
377 BITFIELD (Vex),
378 BITFIELD (VexVVVV),
379 BITFIELD (VexW),
380 BITFIELD (VexOpcode),
381 BITFIELD (VexSources),
382 BITFIELD (VexImmExt),
383 BITFIELD (SSE2AVX),
384 BITFIELD (NoAVX),
385 BITFIELD (OldGcc),
386 BITFIELD (ATTMnemonic),
387 BITFIELD (ATTSyntax),
388 BITFIELD (IntelSyntax),
391 static bitfield operand_types[] =
393 BITFIELD (Reg8),
394 BITFIELD (Reg16),
395 BITFIELD (Reg32),
396 BITFIELD (Reg64),
397 BITFIELD (FloatReg),
398 BITFIELD (RegMMX),
399 BITFIELD (RegXMM),
400 BITFIELD (RegYMM),
401 BITFIELD (Imm1),
402 BITFIELD (Imm8),
403 BITFIELD (Imm8S),
404 BITFIELD (Imm16),
405 BITFIELD (Imm32),
406 BITFIELD (Imm32S),
407 BITFIELD (Imm64),
408 BITFIELD (BaseIndex),
409 BITFIELD (Disp8),
410 BITFIELD (Disp16),
411 BITFIELD (Disp32),
412 BITFIELD (Disp32S),
413 BITFIELD (Disp64),
414 BITFIELD (InOutPortReg),
415 BITFIELD (ShiftCount),
416 BITFIELD (Control),
417 BITFIELD (Debug),
418 BITFIELD (Test),
419 BITFIELD (SReg2),
420 BITFIELD (SReg3),
421 BITFIELD (Acc),
422 BITFIELD (FloatAcc),
423 BITFIELD (JumpAbsolute),
424 BITFIELD (EsSeg),
425 BITFIELD (RegMem),
426 BITFIELD (Mem),
427 BITFIELD (Byte),
428 BITFIELD (Word),
429 BITFIELD (Dword),
430 BITFIELD (Fword),
431 BITFIELD (Qword),
432 BITFIELD (Tbyte),
433 BITFIELD (Xmmword),
434 BITFIELD (Ymmword),
435 BITFIELD (Unspecified),
436 BITFIELD (Anysize),
437 BITFIELD (Vec_Imm4),
438 #ifdef OTUnused
439 BITFIELD (OTUnused),
440 #endif
443 static const char *filename;
445 static int
446 compare (const void *x, const void *y)
448 const bitfield *xp = (const bitfield *) x;
449 const bitfield *yp = (const bitfield *) y;
450 return xp->position - yp->position;
453 static void
454 fail (const char *message, ...)
456 va_list args;
458 va_start (args, message);
459 fprintf (stderr, _("%s: Error: "), program_name);
460 vfprintf (stderr, message, args);
461 va_end (args);
462 xexit (1);
465 static void
466 process_copyright (FILE *fp)
468 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
469 /* Copyright 2007, 2008, 2009, 2010\n\
470 Free Software Foundation, Inc.\n\
472 This file is part of the GNU opcodes library.\n\
474 This library is free software; you can redistribute it and/or modify\n\
475 it under the terms of the GNU General Public License as published by\n\
476 the Free Software Foundation; either version 3, or (at your option)\n\
477 any later version.\n\
479 It is distributed in the hope that it will be useful, but WITHOUT\n\
480 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
481 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
482 License for more details.\n\
484 You should have received a copy of the GNU General Public License\n\
485 along with this program; if not, write to the Free Software\n\
486 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
487 MA 02110-1301, USA. */\n");
490 /* Remove leading white spaces. */
492 static char *
493 remove_leading_whitespaces (char *str)
495 while (ISSPACE (*str))
496 str++;
497 return str;
500 /* Remove trailing white spaces. */
502 static void
503 remove_trailing_whitespaces (char *str)
505 size_t last = strlen (str);
507 if (last == 0)
508 return;
512 last--;
513 if (ISSPACE (str [last]))
514 str[last] = '\0';
515 else
516 break;
518 while (last != 0);
521 /* Find next field separated by SEP and terminate it. Return a
522 pointer to the one after it. */
524 static char *
525 next_field (char *str, char sep, char **next, char *last)
527 char *p;
529 p = remove_leading_whitespaces (str);
530 for (str = p; *str != sep && *str != '\0'; str++);
532 *str = '\0';
533 remove_trailing_whitespaces (p);
535 *next = str + 1;
537 if (p >= last)
538 abort ();
540 return p;
543 static void
544 set_bitfield (const char *f, bitfield *array, int value,
545 unsigned int size, int lineno)
547 unsigned int i;
549 if (strcmp (f, "CpuFP") == 0)
551 set_bitfield("Cpu387", array, value, size, lineno);
552 set_bitfield("Cpu287", array, value, size, lineno);
553 f = "Cpu8087";
555 else if (strcmp (f, "Mmword") == 0)
556 f= "Qword";
557 else if (strcmp (f, "Oword") == 0)
558 f= "Xmmword";
560 for (i = 0; i < size; i++)
561 if (strcasecmp (array[i].name, f) == 0)
563 array[i].value = value;
564 return;
567 if (value)
569 const char *v = strchr (f, '=');
571 if (v)
573 size_t n = v - f;
574 char *end;
576 for (i = 0; i < size; i++)
577 if (strncasecmp (array[i].name, f, n) == 0)
579 value = strtol (v + 1, &end, 0);
580 if (*end == '\0')
582 array[i].value = value;
583 return;
585 break;
590 if (lineno != -1)
591 fail (_("%s: %d: Unknown bitfield: %s\n"), filename, lineno, f);
592 else
593 fail (_("Unknown bitfield: %s\n"), f);
596 static void
597 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
598 int macro, const char *comma, const char *indent)
600 unsigned int i;
602 fprintf (table, "%s{ { ", indent);
604 for (i = 0; i < size - 1; i++)
606 fprintf (table, "%d, ", flags[i].value);
607 if (((i + 1) % 20) == 0)
609 /* We need \\ for macro. */
610 if (macro)
611 fprintf (table, " \\\n %s", indent);
612 else
613 fprintf (table, "\n %s", indent);
617 fprintf (table, "%d } }%s\n", flags[i].value, comma);
620 static void
621 process_i386_cpu_flag (FILE *table, char *flag, int macro,
622 const char *comma, const char *indent,
623 int lineno)
625 char *str, *next, *last;
626 unsigned int i;
627 bitfield flags [ARRAY_SIZE (cpu_flags)];
629 /* Copy the default cpu flags. */
630 memcpy (flags, cpu_flags, sizeof (cpu_flags));
632 if (strcasecmp (flag, "unknown") == 0)
634 /* We turn on everything except for cpu64 in case of
635 CPU_UNKNOWN_FLAGS. */
636 for (i = 0; i < ARRAY_SIZE (flags); i++)
637 if (flags[i].position != Cpu64)
638 flags[i].value = 1;
640 else if (flag[0] == '~')
642 last = flag + strlen (flag);
644 if (flag[1] == '(')
646 last -= 1;
647 next = flag + 2;
648 if (*last != ')')
649 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename,
650 lineno, flag);
651 *last = '\0';
653 else
654 next = flag + 1;
656 /* First we turn on everything except for cpu64. */
657 for (i = 0; i < ARRAY_SIZE (flags); i++)
658 if (flags[i].position != Cpu64)
659 flags[i].value = 1;
661 /* Turn off selective bits. */
662 for (; next && next < last; )
664 str = next_field (next, '|', &next, last);
665 if (str)
666 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
669 else if (strcmp (flag, "0"))
671 /* Turn on selective bits. */
672 last = flag + strlen (flag);
673 for (next = flag; next && next < last; )
675 str = next_field (next, '|', &next, last);
676 if (str)
677 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
681 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
682 comma, indent);
685 static void
686 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
688 unsigned int i;
690 fprintf (table, " { ");
692 for (i = 0; i < size - 1; i++)
694 fprintf (table, "%d, ", modifier[i].value);
695 if (((i + 1) % 20) == 0)
696 fprintf (table, "\n ");
699 fprintf (table, "%d },\n", modifier[i].value);
702 static void
703 process_i386_opcode_modifier (FILE *table, char *mod, int lineno)
705 char *str, *next, *last;
706 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
708 /* Copy the default opcode modifier. */
709 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
711 if (strcmp (mod, "0"))
713 last = mod + strlen (mod);
714 for (next = mod; next && next < last; )
716 str = next_field (next, '|', &next, last);
717 if (str)
718 set_bitfield (str, modifiers, 1, ARRAY_SIZE (modifiers),
719 lineno);
722 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
725 static void
726 output_operand_type (FILE *table, bitfield *types, unsigned int size,
727 int macro, const char *indent)
729 unsigned int i;
731 fprintf (table, "{ { ");
733 for (i = 0; i < size - 1; i++)
735 fprintf (table, "%d, ", types[i].value);
736 if (((i + 1) % 20) == 0)
738 /* We need \\ for macro. */
739 if (macro)
740 fprintf (table, "\\\n%s", indent);
741 else
742 fprintf (table, "\n%s", indent);
746 fprintf (table, "%d } }", types[i].value);
749 static void
750 process_i386_operand_type (FILE *table, char *op, int macro,
751 const char *indent, int lineno)
753 char *str, *next, *last;
754 bitfield types [ARRAY_SIZE (operand_types)];
756 /* Copy the default operand type. */
757 memcpy (types, operand_types, sizeof (types));
759 if (strcmp (op, "0"))
761 last = op + strlen (op);
762 for (next = op; next && next < last; )
764 str = next_field (next, '|', &next, last);
765 if (str)
766 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
769 output_operand_type (table, types, ARRAY_SIZE (types), macro,
770 indent);
773 static void
774 output_i386_opcode (FILE *table, const char *name, char *str,
775 char *last, int lineno)
777 unsigned int i;
778 char *operands, *base_opcode, *extension_opcode, *opcode_length;
779 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
781 /* Find number of operands. */
782 operands = next_field (str, ',', &str, last);
784 /* Find base_opcode. */
785 base_opcode = next_field (str, ',', &str, last);
787 /* Find extension_opcode. */
788 extension_opcode = next_field (str, ',', &str, last);
790 /* Find opcode_length. */
791 opcode_length = next_field (str, ',', &str, last);
793 /* Find cpu_flags. */
794 cpu_flags = next_field (str, ',', &str, last);
796 /* Find opcode_modifier. */
797 opcode_modifier = next_field (str, ',', &str, last);
799 /* Remove the first {. */
800 str = remove_leading_whitespaces (str);
801 if (*str != '{')
802 abort ();
803 str = remove_leading_whitespaces (str + 1);
805 i = strlen (str);
807 /* There are at least "X}". */
808 if (i < 2)
809 abort ();
811 /* Remove trailing white spaces and }. */
814 i--;
815 if (ISSPACE (str[i]) || str[i] == '}')
816 str[i] = '\0';
817 else
818 break;
820 while (i != 0);
822 last = str + i;
824 /* Find operand_types. */
825 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
827 if (str >= last)
829 operand_types [i] = NULL;
830 break;
833 operand_types [i] = next_field (str, ',', &str, last);
834 if (*operand_types[i] == '0')
836 if (i != 0)
837 operand_types[i] = NULL;
838 break;
842 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
843 name, operands, base_opcode, extension_opcode,
844 opcode_length);
846 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
848 process_i386_opcode_modifier (table, opcode_modifier, lineno);
850 fprintf (table, " { ");
852 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
854 if (operand_types[i] == NULL || *operand_types[i] == '0')
856 if (i == 0)
857 process_i386_operand_type (table, "0", 0, "\t ", lineno);
858 break;
861 if (i != 0)
862 fprintf (table, ",\n ");
864 process_i386_operand_type (table, operand_types[i], 0,
865 "\t ", lineno);
867 fprintf (table, " } },\n");
870 struct opcode_hash_entry
872 struct opcode_hash_entry *next;
873 char *name;
874 char *opcode;
875 int lineno;
878 /* Calculate the hash value of an opcode hash entry P. */
880 static hashval_t
881 opcode_hash_hash (const void *p)
883 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
884 return htab_hash_string (entry->name);
887 /* Compare a string Q against an opcode hash entry P. */
889 static int
890 opcode_hash_eq (const void *p, const void *q)
892 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
893 const char *name = (const char *) q;
894 return strcmp (name, entry->name) == 0;
897 static void
898 process_i386_opcodes (FILE *table)
900 FILE *fp;
901 char buf[2048];
902 unsigned int i, j;
903 char *str, *p, *last, *name;
904 struct opcode_hash_entry **hash_slot, **entry, *next;
905 htab_t opcode_hash_table;
906 struct opcode_hash_entry **opcode_array;
907 unsigned int opcode_array_size = 1024;
908 int lineno = 0;
910 filename = "i386-opc.tbl";
911 fp = fopen (filename, "r");
913 if (fp == NULL)
914 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
915 xstrerror (errno));
917 i = 0;
918 opcode_array = (struct opcode_hash_entry **)
919 xmalloc (sizeof (*opcode_array) * opcode_array_size);
921 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
922 opcode_hash_eq, NULL,
923 xcalloc, free);
925 fprintf (table, "\n/* i386 opcode table. */\n\n");
926 fprintf (table, "const insn_template i386_optab[] =\n{\n");
928 /* Put everything on opcode array. */
929 while (!feof (fp))
931 if (fgets (buf, sizeof (buf), fp) == NULL)
932 break;
934 lineno++;
936 p = remove_leading_whitespaces (buf);
938 /* Skip comments. */
939 str = strstr (p, "//");
940 if (str != NULL)
941 str[0] = '\0';
943 /* Remove trailing white spaces. */
944 remove_trailing_whitespaces (p);
946 switch (p[0])
948 case '#':
949 /* Ignore comments. */
950 case '\0':
951 continue;
952 break;
953 default:
954 break;
957 last = p + strlen (p);
959 /* Find name. */
960 name = next_field (p, ',', &str, last);
962 /* Get the slot in hash table. */
963 hash_slot = (struct opcode_hash_entry **)
964 htab_find_slot_with_hash (opcode_hash_table, name,
965 htab_hash_string (name),
966 INSERT);
968 if (*hash_slot == NULL)
970 /* It is the new one. Put it on opcode array. */
971 if (i >= opcode_array_size)
973 /* Grow the opcode array when needed. */
974 opcode_array_size += 1024;
975 opcode_array = (struct opcode_hash_entry **)
976 xrealloc (opcode_array,
977 sizeof (*opcode_array) * opcode_array_size);
980 opcode_array[i] = (struct opcode_hash_entry *)
981 xmalloc (sizeof (struct opcode_hash_entry));
982 opcode_array[i]->next = NULL;
983 opcode_array[i]->name = xstrdup (name);
984 opcode_array[i]->opcode = xstrdup (str);
985 opcode_array[i]->lineno = lineno;
986 *hash_slot = opcode_array[i];
987 i++;
989 else
991 /* Append it to the existing one. */
992 entry = hash_slot;
993 while ((*entry) != NULL)
994 entry = &(*entry)->next;
995 *entry = (struct opcode_hash_entry *)
996 xmalloc (sizeof (struct opcode_hash_entry));
997 (*entry)->next = NULL;
998 (*entry)->name = (*hash_slot)->name;
999 (*entry)->opcode = xstrdup (str);
1000 (*entry)->lineno = lineno;
1004 /* Process opcode array. */
1005 for (j = 0; j < i; j++)
1007 for (next = opcode_array[j]; next; next = next->next)
1009 name = next->name;
1010 str = next->opcode;
1011 lineno = next->lineno;
1012 last = str + strlen (str);
1013 output_i386_opcode (table, name, str, last, lineno);
1017 fclose (fp);
1019 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
1021 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1023 process_i386_opcode_modifier (table, "0", -1);
1025 fprintf (table, " { ");
1026 process_i386_operand_type (table, "0", 0, "\t ", -1);
1027 fprintf (table, " } }\n");
1029 fprintf (table, "};\n");
1032 static void
1033 process_i386_registers (FILE *table)
1035 FILE *fp;
1036 char buf[2048];
1037 char *str, *p, *last;
1038 char *reg_name, *reg_type, *reg_flags, *reg_num;
1039 char *dw2_32_num, *dw2_64_num;
1040 int lineno = 0;
1042 filename = "i386-reg.tbl";
1043 fp = fopen (filename, "r");
1044 if (fp == NULL)
1045 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1046 xstrerror (errno));
1048 fprintf (table, "\n/* i386 register table. */\n\n");
1049 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1051 while (!feof (fp))
1053 if (fgets (buf, sizeof (buf), fp) == NULL)
1054 break;
1056 lineno++;
1058 p = remove_leading_whitespaces (buf);
1060 /* Skip comments. */
1061 str = strstr (p, "//");
1062 if (str != NULL)
1063 str[0] = '\0';
1065 /* Remove trailing white spaces. */
1066 remove_trailing_whitespaces (p);
1068 switch (p[0])
1070 case '#':
1071 fprintf (table, "%s\n", p);
1072 case '\0':
1073 continue;
1074 break;
1075 default:
1076 break;
1079 last = p + strlen (p);
1081 /* Find reg_name. */
1082 reg_name = next_field (p, ',', &str, last);
1084 /* Find reg_type. */
1085 reg_type = next_field (str, ',', &str, last);
1087 /* Find reg_flags. */
1088 reg_flags = next_field (str, ',', &str, last);
1090 /* Find reg_num. */
1091 reg_num = next_field (str, ',', &str, last);
1093 fprintf (table, " { \"%s\",\n ", reg_name);
1095 process_i386_operand_type (table, reg_type, 0, "\t", lineno);
1097 /* Find 32-bit Dwarf2 register number. */
1098 dw2_32_num = next_field (str, ',', &str, last);
1100 /* Find 64-bit Dwarf2 register number. */
1101 dw2_64_num = next_field (str, ',', &str, last);
1103 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1104 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1107 fclose (fp);
1109 fprintf (table, "};\n");
1111 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1114 static void
1115 process_i386_initializers (void)
1117 unsigned int i;
1118 FILE *fp = fopen ("i386-init.h", "w");
1119 char *init;
1121 if (fp == NULL)
1122 fail (_("can't create i386-init.h, errno = %s\n"),
1123 xstrerror (errno));
1125 process_copyright (fp);
1127 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1129 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1130 init = xstrdup (cpu_flag_init[i].init);
1131 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1132 free (init);
1135 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1137 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1138 init = xstrdup (operand_type_init[i].init);
1139 process_i386_operand_type (fp, init, 1, " ", -1);
1140 free (init);
1142 fprintf (fp, "\n");
1144 fclose (fp);
1147 /* Program options. */
1148 #define OPTION_SRCDIR 200
1150 struct option long_options[] =
1152 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1153 {"debug", no_argument, NULL, 'd'},
1154 {"version", no_argument, NULL, 'V'},
1155 {"help", no_argument, NULL, 'h'},
1156 {0, no_argument, NULL, 0}
1159 static void
1160 print_version (void)
1162 printf ("%s: version 1.0\n", program_name);
1163 xexit (0);
1166 static void
1167 usage (FILE * stream, int status)
1169 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1170 program_name);
1171 xexit (status);
1175 main (int argc, char **argv)
1177 extern int chdir (char *);
1178 char *srcdir = NULL;
1179 int c;
1180 FILE *table;
1182 program_name = *argv;
1183 xmalloc_set_program_name (program_name);
1185 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1186 switch (c)
1188 case OPTION_SRCDIR:
1189 srcdir = optarg;
1190 break;
1191 case 'V':
1192 case 'v':
1193 print_version ();
1194 break;
1195 case 'd':
1196 debug = 1;
1197 break;
1198 case 'h':
1199 case '?':
1200 usage (stderr, 0);
1201 default:
1202 case 0:
1203 break;
1206 if (optind != argc)
1207 usage (stdout, 1);
1209 if (srcdir != NULL)
1210 if (chdir (srcdir) != 0)
1211 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1212 srcdir, xstrerror (errno));
1214 /* Check the unused bitfield in i386_cpu_flags. */
1215 #ifndef CpuUnused
1216 c = CpuNumOfBits - CpuMax - 1;
1217 if (c)
1218 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1219 #endif
1221 /* Check the unused bitfield in i386_operand_type. */
1222 #ifndef OTUnused
1223 c = OTNumOfBits - OTMax - 1;
1224 if (c)
1225 fail (_("%d unused bits in i386_operand_type.\n"), c);
1226 #endif
1228 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1229 compare);
1231 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1232 sizeof (opcode_modifiers [0]), compare);
1234 qsort (operand_types, ARRAY_SIZE (operand_types),
1235 sizeof (operand_types [0]), compare);
1237 table = fopen ("i386-tbl.h", "w");
1238 if (table == NULL)
1239 fail (_("can't create i386-tbl.h, errno = %s\n"),
1240 xstrerror (errno));
1242 process_copyright (table);
1244 process_i386_opcodes (table);
1245 process_i386_registers (table);
1246 process_i386_initializers ();
1248 fclose (table);
1250 exit (0);