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