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