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