[ia64] small integral parameters and return values
[binutils-gdb.git] / opcodes / i386-gen.c
1 /* Copyright 2007, 2008, 2009, 2010, 2011
2 Free Software Foundation, Inc.
3
4 This file is part of the GNU opcodes library.
5
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.
10
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.
15
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. */
20
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"
28
29 #include "i386-opc.h"
30
31 #include <libintl.h>
32 #define _(String) gettext (String)
33
34 static const char *program_name = NULL;
35 static int debug = 0;
36
37 typedef struct initializer
38 {
39 const char *name;
40 const char *init;
41 } initializer;
42
43 static initializer cpu_flag_init[] =
44 {
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_BMI_FLAGS",
144 "CpuBMI" },
145 { "CPU_MOVBE_FLAGS",
146 "CpuMovbe" },
147 { "CPU_RDTSCP_FLAGS",
148 "CpuRdtscp" },
149 { "CPU_EPT_FLAGS",
150 "CpuEPT" },
151 { "CPU_FSGSBASE_FLAGS",
152 "CpuFSGSBase" },
153 { "CPU_RDRND_FLAGS",
154 "CpuRdRnd" },
155 { "CPU_F16C_FLAGS",
156 "CpuF16C" },
157 { "CPU_3DNOW_FLAGS",
158 "CpuMMX|Cpu3dnow" },
159 { "CPU_3DNOWA_FLAGS",
160 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
161 { "CPU_PADLOCK_FLAGS",
162 "CpuPadLock" },
163 { "CPU_SVME_FLAGS",
164 "CpuSVME" },
165 { "CPU_SSE4A_FLAGS",
166 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
167 { "CPU_ABM_FLAGS",
168 "CpuABM" },
169 { "CPU_AVX_FLAGS",
170 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
171 { "CPU_ANY_AVX_FLAGS",
172 "CpuAVX" },
173 { "CPU_L1OM_FLAGS",
174 "unknown" },
175 };
176
177 static initializer operand_type_init[] =
178 {
179 { "OPERAND_TYPE_NONE",
180 "0" },
181 { "OPERAND_TYPE_REG8",
182 "Reg8" },
183 { "OPERAND_TYPE_REG16",
184 "Reg16" },
185 { "OPERAND_TYPE_REG32",
186 "Reg32" },
187 { "OPERAND_TYPE_REG64",
188 "Reg64" },
189 { "OPERAND_TYPE_IMM1",
190 "Imm1" },
191 { "OPERAND_TYPE_IMM8",
192 "Imm8" },
193 { "OPERAND_TYPE_IMM8S",
194 "Imm8S" },
195 { "OPERAND_TYPE_IMM16",
196 "Imm16" },
197 { "OPERAND_TYPE_IMM32",
198 "Imm32" },
199 { "OPERAND_TYPE_IMM32S",
200 "Imm32S" },
201 { "OPERAND_TYPE_IMM64",
202 "Imm64" },
203 { "OPERAND_TYPE_BASEINDEX",
204 "BaseIndex" },
205 { "OPERAND_TYPE_DISP8",
206 "Disp8" },
207 { "OPERAND_TYPE_DISP16",
208 "Disp16" },
209 { "OPERAND_TYPE_DISP32",
210 "Disp32" },
211 { "OPERAND_TYPE_DISP32S",
212 "Disp32S" },
213 { "OPERAND_TYPE_DISP64",
214 "Disp64" },
215 { "OPERAND_TYPE_INOUTPORTREG",
216 "InOutPortReg" },
217 { "OPERAND_TYPE_SHIFTCOUNT",
218 "ShiftCount" },
219 { "OPERAND_TYPE_CONTROL",
220 "Control" },
221 { "OPERAND_TYPE_TEST",
222 "Test" },
223 { "OPERAND_TYPE_DEBUG",
224 "FloatReg" },
225 { "OPERAND_TYPE_FLOATREG",
226 "FloatReg" },
227 { "OPERAND_TYPE_FLOATACC",
228 "FloatAcc" },
229 { "OPERAND_TYPE_SREG2",
230 "SReg2" },
231 { "OPERAND_TYPE_SREG3",
232 "SReg3" },
233 { "OPERAND_TYPE_ACC",
234 "Acc" },
235 { "OPERAND_TYPE_JUMPABSOLUTE",
236 "JumpAbsolute" },
237 { "OPERAND_TYPE_REGMMX",
238 "RegMMX" },
239 { "OPERAND_TYPE_REGXMM",
240 "RegXMM" },
241 { "OPERAND_TYPE_REGYMM",
242 "RegYMM" },
243 { "OPERAND_TYPE_ESSEG",
244 "EsSeg" },
245 { "OPERAND_TYPE_ACC32",
246 "Reg32|Acc|Dword" },
247 { "OPERAND_TYPE_ACC64",
248 "Reg64|Acc|Qword" },
249 { "OPERAND_TYPE_INOUTPORTREG",
250 "InOutPortReg" },
251 { "OPERAND_TYPE_REG16_INOUTPORTREG",
252 "Reg16|InOutPortReg" },
253 { "OPERAND_TYPE_DISP16_32",
254 "Disp16|Disp32" },
255 { "OPERAND_TYPE_ANYDISP",
256 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
257 { "OPERAND_TYPE_IMM16_32",
258 "Imm16|Imm32" },
259 { "OPERAND_TYPE_IMM16_32S",
260 "Imm16|Imm32S" },
261 { "OPERAND_TYPE_IMM16_32_32S",
262 "Imm16|Imm32|Imm32S" },
263 { "OPERAND_TYPE_IMM32_32S_DISP32",
264 "Imm32|Imm32S|Disp32" },
265 { "OPERAND_TYPE_IMM64_DISP64",
266 "Imm64|Disp64" },
267 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
268 "Imm32|Imm32S|Imm64|Disp32" },
269 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
270 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
271 { "OPERAND_TYPE_VEC_IMM4",
272 "Vec_Imm4" },
273 };
274
275 typedef struct bitfield
276 {
277 int position;
278 int value;
279 const char *name;
280 } bitfield;
281
282 #define BITFIELD(n) { n, 0, #n }
283
284 static bitfield cpu_flags[] =
285 {
286 BITFIELD (Cpu186),
287 BITFIELD (Cpu286),
288 BITFIELD (Cpu386),
289 BITFIELD (Cpu486),
290 BITFIELD (Cpu586),
291 BITFIELD (Cpu686),
292 BITFIELD (CpuClflush),
293 BITFIELD (CpuNop),
294 BITFIELD (CpuSYSCALL),
295 BITFIELD (Cpu8087),
296 BITFIELD (Cpu287),
297 BITFIELD (Cpu387),
298 BITFIELD (Cpu687),
299 BITFIELD (CpuFISTTP),
300 BITFIELD (CpuMMX),
301 BITFIELD (CpuSSE),
302 BITFIELD (CpuSSE2),
303 BITFIELD (CpuSSE3),
304 BITFIELD (CpuSSSE3),
305 BITFIELD (CpuSSE4_1),
306 BITFIELD (CpuSSE4_2),
307 BITFIELD (CpuAVX),
308 BITFIELD (CpuL1OM),
309 BITFIELD (CpuSSE4a),
310 BITFIELD (Cpu3dnow),
311 BITFIELD (Cpu3dnowA),
312 BITFIELD (CpuPadLock),
313 BITFIELD (CpuSVME),
314 BITFIELD (CpuVMX),
315 BITFIELD (CpuSMX),
316 BITFIELD (CpuABM),
317 BITFIELD (CpuXsave),
318 BITFIELD (CpuXsaveopt),
319 BITFIELD (CpuAES),
320 BITFIELD (CpuPCLMUL),
321 BITFIELD (CpuFMA),
322 BITFIELD (CpuFMA4),
323 BITFIELD (CpuXOP),
324 BITFIELD (CpuLWP),
325 BITFIELD (CpuBMI),
326 BITFIELD (CpuLM),
327 BITFIELD (CpuMovbe),
328 BITFIELD (CpuEPT),
329 BITFIELD (CpuRdtscp),
330 BITFIELD (CpuFSGSBase),
331 BITFIELD (CpuRdRnd),
332 BITFIELD (CpuF16C),
333 BITFIELD (Cpu64),
334 BITFIELD (CpuNo64),
335 #ifdef CpuUnused
336 BITFIELD (CpuUnused),
337 #endif
338 };
339
340 static bitfield opcode_modifiers[] =
341 {
342 BITFIELD (D),
343 BITFIELD (W),
344 BITFIELD (S),
345 BITFIELD (Modrm),
346 BITFIELD (ShortForm),
347 BITFIELD (Jump),
348 BITFIELD (JumpDword),
349 BITFIELD (JumpByte),
350 BITFIELD (JumpInterSegment),
351 BITFIELD (FloatMF),
352 BITFIELD (FloatR),
353 BITFIELD (FloatD),
354 BITFIELD (Size16),
355 BITFIELD (Size32),
356 BITFIELD (Size64),
357 BITFIELD (CheckRegSize),
358 BITFIELD (IgnoreSize),
359 BITFIELD (DefaultSize),
360 BITFIELD (No_bSuf),
361 BITFIELD (No_wSuf),
362 BITFIELD (No_lSuf),
363 BITFIELD (No_sSuf),
364 BITFIELD (No_qSuf),
365 BITFIELD (No_ldSuf),
366 BITFIELD (FWait),
367 BITFIELD (IsString),
368 BITFIELD (IsLockable),
369 BITFIELD (RegKludge),
370 BITFIELD (FirstXmm0),
371 BITFIELD (Implicit1stXmm0),
372 BITFIELD (ToDword),
373 BITFIELD (ToQword),
374 BITFIELD (AddrPrefixOp0),
375 BITFIELD (IsPrefix),
376 BITFIELD (ImmExt),
377 BITFIELD (NoRex64),
378 BITFIELD (Rex64),
379 BITFIELD (Ugh),
380 BITFIELD (Vex),
381 BITFIELD (VexVVVV),
382 BITFIELD (VexW),
383 BITFIELD (VexOpcode),
384 BITFIELD (VexSources),
385 BITFIELD (VexImmExt),
386 BITFIELD (SSE2AVX),
387 BITFIELD (NoAVX),
388 BITFIELD (OldGcc),
389 BITFIELD (ATTMnemonic),
390 BITFIELD (ATTSyntax),
391 BITFIELD (IntelSyntax),
392 };
393
394 static bitfield operand_types[] =
395 {
396 BITFIELD (Reg8),
397 BITFIELD (Reg16),
398 BITFIELD (Reg32),
399 BITFIELD (Reg64),
400 BITFIELD (FloatReg),
401 BITFIELD (RegMMX),
402 BITFIELD (RegXMM),
403 BITFIELD (RegYMM),
404 BITFIELD (Imm1),
405 BITFIELD (Imm8),
406 BITFIELD (Imm8S),
407 BITFIELD (Imm16),
408 BITFIELD (Imm32),
409 BITFIELD (Imm32S),
410 BITFIELD (Imm64),
411 BITFIELD (BaseIndex),
412 BITFIELD (Disp8),
413 BITFIELD (Disp16),
414 BITFIELD (Disp32),
415 BITFIELD (Disp32S),
416 BITFIELD (Disp64),
417 BITFIELD (InOutPortReg),
418 BITFIELD (ShiftCount),
419 BITFIELD (Control),
420 BITFIELD (Debug),
421 BITFIELD (Test),
422 BITFIELD (SReg2),
423 BITFIELD (SReg3),
424 BITFIELD (Acc),
425 BITFIELD (FloatAcc),
426 BITFIELD (JumpAbsolute),
427 BITFIELD (EsSeg),
428 BITFIELD (RegMem),
429 BITFIELD (Mem),
430 BITFIELD (Byte),
431 BITFIELD (Word),
432 BITFIELD (Dword),
433 BITFIELD (Fword),
434 BITFIELD (Qword),
435 BITFIELD (Tbyte),
436 BITFIELD (Xmmword),
437 BITFIELD (Ymmword),
438 BITFIELD (Unspecified),
439 BITFIELD (Anysize),
440 BITFIELD (Vec_Imm4),
441 #ifdef OTUnused
442 BITFIELD (OTUnused),
443 #endif
444 };
445
446 static const char *filename;
447
448 static int
449 compare (const void *x, const void *y)
450 {
451 const bitfield *xp = (const bitfield *) x;
452 const bitfield *yp = (const bitfield *) y;
453 return xp->position - yp->position;
454 }
455
456 static void
457 fail (const char *message, ...)
458 {
459 va_list args;
460
461 va_start (args, message);
462 fprintf (stderr, _("%s: Error: "), program_name);
463 vfprintf (stderr, message, args);
464 va_end (args);
465 xexit (1);
466 }
467
468 static void
469 process_copyright (FILE *fp)
470 {
471 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
472 /* Copyright 2007, 2008, 2009, 2010, 2011\n\
473 Free Software Foundation, Inc.\n\
474 \n\
475 This file is part of the GNU opcodes library.\n\
476 \n\
477 This library is free software; you can redistribute it and/or modify\n\
478 it under the terms of the GNU General Public License as published by\n\
479 the Free Software Foundation; either version 3, or (at your option)\n\
480 any later version.\n\
481 \n\
482 It is distributed in the hope that it will be useful, but WITHOUT\n\
483 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
484 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
485 License for more details.\n\
486 \n\
487 You should have received a copy of the GNU General Public License\n\
488 along with this program; if not, write to the Free Software\n\
489 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
490 MA 02110-1301, USA. */\n");
491 }
492
493 /* Remove leading white spaces. */
494
495 static char *
496 remove_leading_whitespaces (char *str)
497 {
498 while (ISSPACE (*str))
499 str++;
500 return str;
501 }
502
503 /* Remove trailing white spaces. */
504
505 static void
506 remove_trailing_whitespaces (char *str)
507 {
508 size_t last = strlen (str);
509
510 if (last == 0)
511 return;
512
513 do
514 {
515 last--;
516 if (ISSPACE (str [last]))
517 str[last] = '\0';
518 else
519 break;
520 }
521 while (last != 0);
522 }
523
524 /* Find next field separated by SEP and terminate it. Return a
525 pointer to the one after it. */
526
527 static char *
528 next_field (char *str, char sep, char **next, char *last)
529 {
530 char *p;
531
532 p = remove_leading_whitespaces (str);
533 for (str = p; *str != sep && *str != '\0'; str++);
534
535 *str = '\0';
536 remove_trailing_whitespaces (p);
537
538 *next = str + 1;
539
540 if (p >= last)
541 abort ();
542
543 return p;
544 }
545
546 static void
547 set_bitfield (const char *f, bitfield *array, int value,
548 unsigned int size, int lineno)
549 {
550 unsigned int i;
551
552 if (strcmp (f, "CpuFP") == 0)
553 {
554 set_bitfield("Cpu387", array, value, size, lineno);
555 set_bitfield("Cpu287", array, value, size, lineno);
556 f = "Cpu8087";
557 }
558 else if (strcmp (f, "Mmword") == 0)
559 f= "Qword";
560 else if (strcmp (f, "Oword") == 0)
561 f= "Xmmword";
562
563 for (i = 0; i < size; i++)
564 if (strcasecmp (array[i].name, f) == 0)
565 {
566 array[i].value = value;
567 return;
568 }
569
570 if (value)
571 {
572 const char *v = strchr (f, '=');
573
574 if (v)
575 {
576 size_t n = v - f;
577 char *end;
578
579 for (i = 0; i < size; i++)
580 if (strncasecmp (array[i].name, f, n) == 0)
581 {
582 value = strtol (v + 1, &end, 0);
583 if (*end == '\0')
584 {
585 array[i].value = value;
586 return;
587 }
588 break;
589 }
590 }
591 }
592
593 if (lineno != -1)
594 fail (_("%s: %d: Unknown bitfield: %s\n"), filename, lineno, f);
595 else
596 fail (_("Unknown bitfield: %s\n"), f);
597 }
598
599 static void
600 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
601 int macro, const char *comma, const char *indent)
602 {
603 unsigned int i;
604
605 fprintf (table, "%s{ { ", indent);
606
607 for (i = 0; i < size - 1; i++)
608 {
609 fprintf (table, "%d, ", flags[i].value);
610 if (((i + 1) % 20) == 0)
611 {
612 /* We need \\ for macro. */
613 if (macro)
614 fprintf (table, " \\\n %s", indent);
615 else
616 fprintf (table, "\n %s", indent);
617 }
618 }
619
620 fprintf (table, "%d } }%s\n", flags[i].value, comma);
621 }
622
623 static void
624 process_i386_cpu_flag (FILE *table, char *flag, int macro,
625 const char *comma, const char *indent,
626 int lineno)
627 {
628 char *str, *next, *last;
629 unsigned int i;
630 bitfield flags [ARRAY_SIZE (cpu_flags)];
631
632 /* Copy the default cpu flags. */
633 memcpy (flags, cpu_flags, sizeof (cpu_flags));
634
635 if (strcasecmp (flag, "unknown") == 0)
636 {
637 /* We turn on everything except for cpu64 in case of
638 CPU_UNKNOWN_FLAGS. */
639 for (i = 0; i < ARRAY_SIZE (flags); i++)
640 if (flags[i].position != Cpu64)
641 flags[i].value = 1;
642 }
643 else if (flag[0] == '~')
644 {
645 last = flag + strlen (flag);
646
647 if (flag[1] == '(')
648 {
649 last -= 1;
650 next = flag + 2;
651 if (*last != ')')
652 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename,
653 lineno, flag);
654 *last = '\0';
655 }
656 else
657 next = flag + 1;
658
659 /* First we turn on everything except for cpu64. */
660 for (i = 0; i < ARRAY_SIZE (flags); i++)
661 if (flags[i].position != Cpu64)
662 flags[i].value = 1;
663
664 /* Turn off selective bits. */
665 for (; next && next < last; )
666 {
667 str = next_field (next, '|', &next, last);
668 if (str)
669 set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
670 }
671 }
672 else if (strcmp (flag, "0"))
673 {
674 /* Turn on selective bits. */
675 last = flag + strlen (flag);
676 for (next = flag; next && next < last; )
677 {
678 str = next_field (next, '|', &next, last);
679 if (str)
680 set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
681 }
682 }
683
684 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
685 comma, indent);
686 }
687
688 static void
689 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
690 {
691 unsigned int i;
692
693 fprintf (table, " { ");
694
695 for (i = 0; i < size - 1; i++)
696 {
697 fprintf (table, "%d, ", modifier[i].value);
698 if (((i + 1) % 20) == 0)
699 fprintf (table, "\n ");
700 }
701
702 fprintf (table, "%d },\n", modifier[i].value);
703 }
704
705 static void
706 process_i386_opcode_modifier (FILE *table, char *mod, int lineno)
707 {
708 char *str, *next, *last;
709 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
710
711 /* Copy the default opcode modifier. */
712 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
713
714 if (strcmp (mod, "0"))
715 {
716 last = mod + strlen (mod);
717 for (next = mod; next && next < last; )
718 {
719 str = next_field (next, '|', &next, last);
720 if (str)
721 set_bitfield (str, modifiers, 1, ARRAY_SIZE (modifiers),
722 lineno);
723 }
724 }
725 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
726 }
727
728 static void
729 output_operand_type (FILE *table, bitfield *types, unsigned int size,
730 int macro, const char *indent)
731 {
732 unsigned int i;
733
734 fprintf (table, "{ { ");
735
736 for (i = 0; i < size - 1; i++)
737 {
738 fprintf (table, "%d, ", types[i].value);
739 if (((i + 1) % 20) == 0)
740 {
741 /* We need \\ for macro. */
742 if (macro)
743 fprintf (table, "\\\n%s", indent);
744 else
745 fprintf (table, "\n%s", indent);
746 }
747 }
748
749 fprintf (table, "%d } }", types[i].value);
750 }
751
752 static void
753 process_i386_operand_type (FILE *table, char *op, int macro,
754 const char *indent, int lineno)
755 {
756 char *str, *next, *last;
757 bitfield types [ARRAY_SIZE (operand_types)];
758
759 /* Copy the default operand type. */
760 memcpy (types, operand_types, sizeof (types));
761
762 if (strcmp (op, "0"))
763 {
764 last = op + strlen (op);
765 for (next = op; next && next < last; )
766 {
767 str = next_field (next, '|', &next, last);
768 if (str)
769 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
770 }
771 }
772 output_operand_type (table, types, ARRAY_SIZE (types), macro,
773 indent);
774 }
775
776 static void
777 output_i386_opcode (FILE *table, const char *name, char *str,
778 char *last, int lineno)
779 {
780 unsigned int i;
781 char *operands, *base_opcode, *extension_opcode, *opcode_length;
782 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
783
784 /* Find number of operands. */
785 operands = next_field (str, ',', &str, last);
786
787 /* Find base_opcode. */
788 base_opcode = next_field (str, ',', &str, last);
789
790 /* Find extension_opcode. */
791 extension_opcode = next_field (str, ',', &str, last);
792
793 /* Find opcode_length. */
794 opcode_length = next_field (str, ',', &str, last);
795
796 /* Find cpu_flags. */
797 cpu_flags = next_field (str, ',', &str, last);
798
799 /* Find opcode_modifier. */
800 opcode_modifier = next_field (str, ',', &str, last);
801
802 /* Remove the first {. */
803 str = remove_leading_whitespaces (str);
804 if (*str != '{')
805 abort ();
806 str = remove_leading_whitespaces (str + 1);
807
808 i = strlen (str);
809
810 /* There are at least "X}". */
811 if (i < 2)
812 abort ();
813
814 /* Remove trailing white spaces and }. */
815 do
816 {
817 i--;
818 if (ISSPACE (str[i]) || str[i] == '}')
819 str[i] = '\0';
820 else
821 break;
822 }
823 while (i != 0);
824
825 last = str + i;
826
827 /* Find operand_types. */
828 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
829 {
830 if (str >= last)
831 {
832 operand_types [i] = NULL;
833 break;
834 }
835
836 operand_types [i] = next_field (str, ',', &str, last);
837 if (*operand_types[i] == '0')
838 {
839 if (i != 0)
840 operand_types[i] = NULL;
841 break;
842 }
843 }
844
845 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
846 name, operands, base_opcode, extension_opcode,
847 opcode_length);
848
849 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
850
851 process_i386_opcode_modifier (table, opcode_modifier, lineno);
852
853 fprintf (table, " { ");
854
855 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
856 {
857 if (operand_types[i] == NULL || *operand_types[i] == '0')
858 {
859 if (i == 0)
860 process_i386_operand_type (table, "0", 0, "\t ", lineno);
861 break;
862 }
863
864 if (i != 0)
865 fprintf (table, ",\n ");
866
867 process_i386_operand_type (table, operand_types[i], 0,
868 "\t ", lineno);
869 }
870 fprintf (table, " } },\n");
871 }
872
873 struct opcode_hash_entry
874 {
875 struct opcode_hash_entry *next;
876 char *name;
877 char *opcode;
878 int lineno;
879 };
880
881 /* Calculate the hash value of an opcode hash entry P. */
882
883 static hashval_t
884 opcode_hash_hash (const void *p)
885 {
886 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
887 return htab_hash_string (entry->name);
888 }
889
890 /* Compare a string Q against an opcode hash entry P. */
891
892 static int
893 opcode_hash_eq (const void *p, const void *q)
894 {
895 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
896 const char *name = (const char *) q;
897 return strcmp (name, entry->name) == 0;
898 }
899
900 static void
901 process_i386_opcodes (FILE *table)
902 {
903 FILE *fp;
904 char buf[2048];
905 unsigned int i, j;
906 char *str, *p, *last, *name;
907 struct opcode_hash_entry **hash_slot, **entry, *next;
908 htab_t opcode_hash_table;
909 struct opcode_hash_entry **opcode_array;
910 unsigned int opcode_array_size = 1024;
911 int lineno = 0;
912
913 filename = "i386-opc.tbl";
914 fp = fopen (filename, "r");
915
916 if (fp == NULL)
917 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
918 xstrerror (errno));
919
920 i = 0;
921 opcode_array = (struct opcode_hash_entry **)
922 xmalloc (sizeof (*opcode_array) * opcode_array_size);
923
924 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
925 opcode_hash_eq, NULL,
926 xcalloc, free);
927
928 fprintf (table, "\n/* i386 opcode table. */\n\n");
929 fprintf (table, "const insn_template i386_optab[] =\n{\n");
930
931 /* Put everything on opcode array. */
932 while (!feof (fp))
933 {
934 if (fgets (buf, sizeof (buf), fp) == NULL)
935 break;
936
937 lineno++;
938
939 p = remove_leading_whitespaces (buf);
940
941 /* Skip comments. */
942 str = strstr (p, "//");
943 if (str != NULL)
944 str[0] = '\0';
945
946 /* Remove trailing white spaces. */
947 remove_trailing_whitespaces (p);
948
949 switch (p[0])
950 {
951 case '#':
952 /* Ignore comments. */
953 case '\0':
954 continue;
955 break;
956 default:
957 break;
958 }
959
960 last = p + strlen (p);
961
962 /* Find name. */
963 name = next_field (p, ',', &str, last);
964
965 /* Get the slot in hash table. */
966 hash_slot = (struct opcode_hash_entry **)
967 htab_find_slot_with_hash (opcode_hash_table, name,
968 htab_hash_string (name),
969 INSERT);
970
971 if (*hash_slot == NULL)
972 {
973 /* It is the new one. Put it on opcode array. */
974 if (i >= opcode_array_size)
975 {
976 /* Grow the opcode array when needed. */
977 opcode_array_size += 1024;
978 opcode_array = (struct opcode_hash_entry **)
979 xrealloc (opcode_array,
980 sizeof (*opcode_array) * opcode_array_size);
981 }
982
983 opcode_array[i] = (struct opcode_hash_entry *)
984 xmalloc (sizeof (struct opcode_hash_entry));
985 opcode_array[i]->next = NULL;
986 opcode_array[i]->name = xstrdup (name);
987 opcode_array[i]->opcode = xstrdup (str);
988 opcode_array[i]->lineno = lineno;
989 *hash_slot = opcode_array[i];
990 i++;
991 }
992 else
993 {
994 /* Append it to the existing one. */
995 entry = hash_slot;
996 while ((*entry) != NULL)
997 entry = &(*entry)->next;
998 *entry = (struct opcode_hash_entry *)
999 xmalloc (sizeof (struct opcode_hash_entry));
1000 (*entry)->next = NULL;
1001 (*entry)->name = (*hash_slot)->name;
1002 (*entry)->opcode = xstrdup (str);
1003 (*entry)->lineno = lineno;
1004 }
1005 }
1006
1007 /* Process opcode array. */
1008 for (j = 0; j < i; j++)
1009 {
1010 for (next = opcode_array[j]; next; next = next->next)
1011 {
1012 name = next->name;
1013 str = next->opcode;
1014 lineno = next->lineno;
1015 last = str + strlen (str);
1016 output_i386_opcode (table, name, str, last, lineno);
1017 }
1018 }
1019
1020 fclose (fp);
1021
1022 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
1023
1024 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
1025
1026 process_i386_opcode_modifier (table, "0", -1);
1027
1028 fprintf (table, " { ");
1029 process_i386_operand_type (table, "0", 0, "\t ", -1);
1030 fprintf (table, " } }\n");
1031
1032 fprintf (table, "};\n");
1033 }
1034
1035 static void
1036 process_i386_registers (FILE *table)
1037 {
1038 FILE *fp;
1039 char buf[2048];
1040 char *str, *p, *last;
1041 char *reg_name, *reg_type, *reg_flags, *reg_num;
1042 char *dw2_32_num, *dw2_64_num;
1043 int lineno = 0;
1044
1045 filename = "i386-reg.tbl";
1046 fp = fopen (filename, "r");
1047 if (fp == NULL)
1048 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1049 xstrerror (errno));
1050
1051 fprintf (table, "\n/* i386 register table. */\n\n");
1052 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1053
1054 while (!feof (fp))
1055 {
1056 if (fgets (buf, sizeof (buf), fp) == NULL)
1057 break;
1058
1059 lineno++;
1060
1061 p = remove_leading_whitespaces (buf);
1062
1063 /* Skip comments. */
1064 str = strstr (p, "//");
1065 if (str != NULL)
1066 str[0] = '\0';
1067
1068 /* Remove trailing white spaces. */
1069 remove_trailing_whitespaces (p);
1070
1071 switch (p[0])
1072 {
1073 case '#':
1074 fprintf (table, "%s\n", p);
1075 case '\0':
1076 continue;
1077 break;
1078 default:
1079 break;
1080 }
1081
1082 last = p + strlen (p);
1083
1084 /* Find reg_name. */
1085 reg_name = next_field (p, ',', &str, last);
1086
1087 /* Find reg_type. */
1088 reg_type = next_field (str, ',', &str, last);
1089
1090 /* Find reg_flags. */
1091 reg_flags = next_field (str, ',', &str, last);
1092
1093 /* Find reg_num. */
1094 reg_num = next_field (str, ',', &str, last);
1095
1096 fprintf (table, " { \"%s\",\n ", reg_name);
1097
1098 process_i386_operand_type (table, reg_type, 0, "\t", lineno);
1099
1100 /* Find 32-bit Dwarf2 register number. */
1101 dw2_32_num = next_field (str, ',', &str, last);
1102
1103 /* Find 64-bit Dwarf2 register number. */
1104 dw2_64_num = next_field (str, ',', &str, last);
1105
1106 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1107 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1108 }
1109
1110 fclose (fp);
1111
1112 fprintf (table, "};\n");
1113
1114 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1115 }
1116
1117 static void
1118 process_i386_initializers (void)
1119 {
1120 unsigned int i;
1121 FILE *fp = fopen ("i386-init.h", "w");
1122 char *init;
1123
1124 if (fp == NULL)
1125 fail (_("can't create i386-init.h, errno = %s\n"),
1126 xstrerror (errno));
1127
1128 process_copyright (fp);
1129
1130 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1131 {
1132 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1133 init = xstrdup (cpu_flag_init[i].init);
1134 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
1135 free (init);
1136 }
1137
1138 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1139 {
1140 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
1141 init = xstrdup (operand_type_init[i].init);
1142 process_i386_operand_type (fp, init, 1, " ", -1);
1143 free (init);
1144 }
1145 fprintf (fp, "\n");
1146
1147 fclose (fp);
1148 }
1149
1150 /* Program options. */
1151 #define OPTION_SRCDIR 200
1152
1153 struct option long_options[] =
1154 {
1155 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1156 {"debug", no_argument, NULL, 'd'},
1157 {"version", no_argument, NULL, 'V'},
1158 {"help", no_argument, NULL, 'h'},
1159 {0, no_argument, NULL, 0}
1160 };
1161
1162 static void
1163 print_version (void)
1164 {
1165 printf ("%s: version 1.0\n", program_name);
1166 xexit (0);
1167 }
1168
1169 static void
1170 usage (FILE * stream, int status)
1171 {
1172 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1173 program_name);
1174 xexit (status);
1175 }
1176
1177 int
1178 main (int argc, char **argv)
1179 {
1180 extern int chdir (char *);
1181 char *srcdir = NULL;
1182 int c;
1183 FILE *table;
1184
1185 program_name = *argv;
1186 xmalloc_set_program_name (program_name);
1187
1188 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1189 switch (c)
1190 {
1191 case OPTION_SRCDIR:
1192 srcdir = optarg;
1193 break;
1194 case 'V':
1195 case 'v':
1196 print_version ();
1197 break;
1198 case 'd':
1199 debug = 1;
1200 break;
1201 case 'h':
1202 case '?':
1203 usage (stderr, 0);
1204 default:
1205 case 0:
1206 break;
1207 }
1208
1209 if (optind != argc)
1210 usage (stdout, 1);
1211
1212 if (srcdir != NULL)
1213 if (chdir (srcdir) != 0)
1214 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1215 srcdir, xstrerror (errno));
1216
1217 /* Check the unused bitfield in i386_cpu_flags. */
1218 #ifndef CpuUnused
1219 c = CpuNumOfBits - CpuMax - 1;
1220 if (c)
1221 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1222 #endif
1223
1224 /* Check the unused bitfield in i386_operand_type. */
1225 #ifndef OTUnused
1226 c = OTNumOfBits - OTMax - 1;
1227 if (c)
1228 fail (_("%d unused bits in i386_operand_type.\n"), c);
1229 #endif
1230
1231 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1232 compare);
1233
1234 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1235 sizeof (opcode_modifiers [0]), compare);
1236
1237 qsort (operand_types, ARRAY_SIZE (operand_types),
1238 sizeof (operand_types [0]), compare);
1239
1240 table = fopen ("i386-tbl.h", "w");
1241 if (table == NULL)
1242 fail (_("can't create i386-tbl.h, errno = %s\n"),
1243 xstrerror (errno));
1244
1245 process_copyright (table);
1246
1247 process_i386_opcodes (table);
1248 process_i386_registers (table);
1249 process_i386_initializers ();
1250
1251 fclose (table);
1252
1253 exit (0);
1254 }