* binutils-all/objcopy.exp: Move XFAIL from objcopy_test to copy_executable.
[binutils.git] / opcodes / i386-gen.c
blob8c59a02c3c1eb3122f452cf0f359afc0a04cfa82
1 /* Copyright 2007, 2008, 2009
2 Free Software Foundation, Inc.
4 This file is part of the GNU opcodes library.
6 This library is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
11 It is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
21 #include "sysdep.h"
22 #include <stdio.h>
23 #include <errno.h>
24 #include "getopt.h"
25 #include "libiberty.h"
26 #include "hashtab.h"
27 #include "safe-ctype.h"
29 #include "i386-opc.h"
31 #include <libintl.h>
32 #define _(String) gettext (String)
34 static const char *program_name = NULL;
35 static int debug = 0;
37 typedef struct initializer
39 const char *name;
40 const char *init;
41 } initializer;
43 static initializer cpu_flag_init[] =
45 { "CPU_UNKNOWN_FLAGS",
46 "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" },
141 static initializer operand_type_init[] =
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" },
237 typedef struct bitfield
239 int position;
240 int value;
241 const char *name;
242 } bitfield;
244 #define BITFIELD(n) { n, 0, #n }
246 static bitfield cpu_flags[] =
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
287 static bitfield opcode_modifiers[] =
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),
345 static bitfield operand_types[] =
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
396 static const char *filename;
398 static int
399 compare (const void *x, const void *y)
401 const bitfield *xp = (const bitfield *) x;
402 const bitfield *yp = (const bitfield *) y;
403 return xp->position - yp->position;
406 static void
407 fail (const char *message, ...)
409 va_list args;
411 va_start (args, message);
412 fprintf (stderr, _("%s: Error: "), program_name);
413 vfprintf (stderr, message, args);
414 va_end (args);
415 xexit (1);
418 static void
419 process_copyright (FILE *fp)
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\
425 This file is part of the GNU opcodes library.\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\
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\
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");
443 /* Remove leading white spaces. */
445 static char *
446 remove_leading_whitespaces (char *str)
448 while (ISSPACE (*str))
449 str++;
450 return str;
453 /* Remove trailing white spaces. */
455 static void
456 remove_trailing_whitespaces (char *str)
458 size_t last = strlen (str);
460 if (last == 0)
461 return;
465 last--;
466 if (ISSPACE (str [last]))
467 str[last] = '\0';
468 else
469 break;
471 while (last != 0);
474 /* Find next field separated by SEP and terminate it. Return a
475 pointer to the one after it. */
477 static char *
478 next_field (char *str, char sep, char **next, char *last)
480 char *p;
482 p = remove_leading_whitespaces (str);
483 for (str = p; *str != sep && *str != '\0'; str++);
485 *str = '\0';
486 remove_trailing_whitespaces (p);
488 *next = str + 1;
490 if (p >= last)
491 abort ();
493 return p;
496 static void
497 set_bitfield (const char *f, bitfield *array, unsigned int size, int lineno)
499 unsigned int i;
501 if (strcmp (f, "Mmword") == 0)
502 f= "Qword";
503 else if (strcmp (f, "Oword") == 0)
504 f= "Xmmword";
506 for (i = 0; i < size; i++)
507 if (strcasecmp (array[i].name, f) == 0)
509 array[i].value = 1;
510 return;
513 if (lineno != -1)
514 fail (_("%s: %d: Unknown bitfield: %s\n"), filename, lineno, f);
515 else
516 fail (_("Unknown bitfield: %s\n"), f);
519 static void
520 output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
521 int macro, const char *comma, const char *indent)
523 unsigned int i;
525 fprintf (table, "%s{ { ", indent);
527 for (i = 0; i < size - 1; i++)
529 fprintf (table, "%d, ", flags[i].value);
530 if (((i + 1) % 20) == 0)
532 /* We need \\ for macro. */
533 if (macro)
534 fprintf (table, " \\\n %s", indent);
535 else
536 fprintf (table, "\n %s", indent);
540 fprintf (table, "%d } }%s\n", flags[i].value, comma);
543 static void
544 process_i386_cpu_flag (FILE *table, char *flag, int macro,
545 const char *comma, const char *indent,
546 int lineno)
548 char *str, *next, *last;
549 bitfield flags [ARRAY_SIZE (cpu_flags)];
551 /* Copy the default cpu flags. */
552 memcpy (flags, cpu_flags, sizeof (cpu_flags));
554 if (strcasecmp (flag, "unknown") == 0)
556 unsigned int i;
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;
564 else if (strcmp (flag, "0"))
566 last = flag + strlen (flag);
567 for (next = flag; next && next < last; )
569 str = next_field (next, '|', &next, last);
570 if (str)
571 set_bitfield (str, flags, ARRAY_SIZE (flags), lineno);
575 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
576 comma, indent);
579 static void
580 output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
582 unsigned int i;
584 fprintf (table, " { ");
586 for (i = 0; i < size - 1; i++)
588 fprintf (table, "%d, ", modifier[i].value);
589 if (((i + 1) % 20) == 0)
590 fprintf (table, "\n ");
593 fprintf (table, "%d },\n", modifier[i].value);
596 static void
597 process_i386_opcode_modifier (FILE *table, char *mod, int lineno)
599 char *str, *next, *last;
600 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
602 /* Copy the default opcode modifier. */
603 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
605 if (strcmp (mod, "0"))
607 last = mod + strlen (mod);
608 for (next = mod; next && next < last; )
610 str = next_field (next, '|', &next, last);
611 if (str)
612 set_bitfield (str, modifiers, ARRAY_SIZE (modifiers), lineno);
615 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
618 static void
619 output_operand_type (FILE *table, bitfield *types, unsigned int size,
620 int macro, const char *indent)
622 unsigned int i;
624 fprintf (table, "{ { ");
626 for (i = 0; i < size - 1; i++)
628 fprintf (table, "%d, ", types[i].value);
629 if (((i + 1) % 20) == 0)
631 /* We need \\ for macro. */
632 if (macro)
633 fprintf (table, "\\\n%s", indent);
634 else
635 fprintf (table, "\n%s", indent);
639 fprintf (table, "%d } }", types[i].value);
642 static void
643 process_i386_operand_type (FILE *table, char *op, int macro,
644 const char *indent, int lineno)
646 char *str, *next, *last;
647 bitfield types [ARRAY_SIZE (operand_types)];
649 /* Copy the default operand type. */
650 memcpy (types, operand_types, sizeof (types));
652 if (strcmp (op, "0"))
654 last = op + strlen (op);
655 for (next = op; next && next < last; )
657 str = next_field (next, '|', &next, last);
658 if (str)
659 set_bitfield (str, types, ARRAY_SIZE (types), lineno);
662 output_operand_type (table, types, ARRAY_SIZE (types), macro,
663 indent);
666 static void
667 output_i386_opcode (FILE *table, const char *name, char *str,
668 char *last, int lineno)
670 unsigned int i;
671 char *operands, *base_opcode, *extension_opcode, *opcode_length;
672 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
674 /* Find number of operands. */
675 operands = next_field (str, ',', &str, last);
677 /* Find base_opcode. */
678 base_opcode = next_field (str, ',', &str, last);
680 /* Find extension_opcode. */
681 extension_opcode = next_field (str, ',', &str, last);
683 /* Find opcode_length. */
684 opcode_length = next_field (str, ',', &str, last);
686 /* Find cpu_flags. */
687 cpu_flags = next_field (str, ',', &str, last);
689 /* Find opcode_modifier. */
690 opcode_modifier = next_field (str, ',', &str, last);
692 /* Remove the first {. */
693 str = remove_leading_whitespaces (str);
694 if (*str != '{')
695 abort ();
696 str = remove_leading_whitespaces (str + 1);
698 i = strlen (str);
700 /* There are at least "X}". */
701 if (i < 2)
702 abort ();
704 /* Remove trailing white spaces and }. */
707 i--;
708 if (ISSPACE (str[i]) || str[i] == '}')
709 str[i] = '\0';
710 else
711 break;
713 while (i != 0);
715 last = str + i;
717 /* Find operand_types. */
718 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
720 if (str >= last)
722 operand_types [i] = NULL;
723 break;
726 operand_types [i] = next_field (str, ',', &str, last);
727 if (*operand_types[i] == '0')
729 if (i != 0)
730 operand_types[i] = NULL;
731 break;
735 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
736 name, operands, base_opcode, extension_opcode,
737 opcode_length);
739 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
741 process_i386_opcode_modifier (table, opcode_modifier, lineno);
743 fprintf (table, " { ");
745 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
747 if (operand_types[i] == NULL || *operand_types[i] == '0')
749 if (i == 0)
750 process_i386_operand_type (table, "0", 0, "\t ", lineno);
751 break;
754 if (i != 0)
755 fprintf (table, ",\n ");
757 process_i386_operand_type (table, operand_types[i], 0,
758 "\t ", lineno);
760 fprintf (table, " } },\n");
763 struct opcode_hash_entry
765 struct opcode_hash_entry *next;
766 char *name;
767 char *opcode;
768 int lineno;
771 /* Calculate the hash value of an opcode hash entry P. */
773 static hashval_t
774 opcode_hash_hash (const void *p)
776 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
777 return htab_hash_string (entry->name);
780 /* Compare a string Q against an opcode hash entry P. */
782 static int
783 opcode_hash_eq (const void *p, const void *q)
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;
790 static void
791 process_i386_opcodes (FILE *table)
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;
803 filename = "i386-opc.tbl";
804 fp = fopen (filename, "r");
806 if (fp == NULL)
807 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
808 xstrerror (errno));
810 i = 0;
811 opcode_array = (struct opcode_hash_entry **)
812 xmalloc (sizeof (*opcode_array) * opcode_array_size);
814 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
815 opcode_hash_eq, NULL,
816 xcalloc, free);
818 fprintf (table, "\n/* i386 opcode table. */\n\n");
819 fprintf (table, "const template i386_optab[] =\n{\n");
821 /* Put everything on opcode array. */
822 while (!feof (fp))
824 if (fgets (buf, sizeof (buf), fp) == NULL)
825 break;
827 lineno++;
829 p = remove_leading_whitespaces (buf);
831 /* Skip comments. */
832 str = strstr (p, "//");
833 if (str != NULL)
834 str[0] = '\0';
836 /* Remove trailing white spaces. */
837 remove_trailing_whitespaces (p);
839 switch (p[0])
841 case '#':
842 /* Ignore comments. */
843 case '\0':
844 continue;
845 break;
846 default:
847 break;
850 last = p + strlen (p);
852 /* Find name. */
853 name = next_field (p, ',', &str, last);
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);
861 if (*hash_slot == NULL)
863 /* It is the new one. Put it on opcode array. */
864 if (i >= opcode_array_size)
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);
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++;
882 else
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;
897 /* Process opcode array. */
898 for (j = 0; j < i; j++)
900 for (next = opcode_array[j]; next; next = next->next)
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);
910 fclose (fp);
912 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
914 process_i386_cpu_flag (table, "0", 0, ",", " ", -1);
916 process_i386_opcode_modifier (table, "0", -1);
918 fprintf (table, " { ");
919 process_i386_operand_type (table, "0", 0, "\t ", -1);
920 fprintf (table, " } }\n");
922 fprintf (table, "};\n");
925 static void
926 process_i386_registers (FILE *table)
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;
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));
941 fprintf (table, "\n/* i386 register table. */\n\n");
942 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
944 while (!feof (fp))
946 if (fgets (buf, sizeof (buf), fp) == NULL)
947 break;
949 lineno++;
951 p = remove_leading_whitespaces (buf);
953 /* Skip comments. */
954 str = strstr (p, "//");
955 if (str != NULL)
956 str[0] = '\0';
958 /* Remove trailing white spaces. */
959 remove_trailing_whitespaces (p);
961 switch (p[0])
963 case '#':
964 fprintf (table, "%s\n", p);
965 case '\0':
966 continue;
967 break;
968 default:
969 break;
972 last = p + strlen (p);
974 /* Find reg_name. */
975 reg_name = next_field (p, ',', &str, last);
977 /* Find reg_type. */
978 reg_type = next_field (str, ',', &str, last);
980 /* Find reg_flags. */
981 reg_flags = next_field (str, ',', &str, last);
983 /* Find reg_num. */
984 reg_num = next_field (str, ',', &str, last);
986 fprintf (table, " { \"%s\",\n ", reg_name);
988 process_i386_operand_type (table, reg_type, 0, "\t", lineno);
990 /* Find 32-bit Dwarf2 register number. */
991 dw2_32_num = next_field (str, ',', &str, last);
993 /* Find 64-bit Dwarf2 register number. */
994 dw2_64_num = next_field (str, ',', &str, last);
996 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
997 reg_flags, reg_num, dw2_32_num, dw2_64_num);
1000 fclose (fp);
1002 fprintf (table, "};\n");
1004 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1007 static void
1008 process_i386_initializers (void)
1010 unsigned int i;
1011 FILE *fp = fopen ("i386-init.h", "w");
1012 char *init;
1014 if (fp == NULL)
1015 fail (_("can't create i386-init.h, errno = %s\n"),
1016 xstrerror (errno));
1018 process_copyright (fp);
1020 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
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);
1028 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
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);
1035 fprintf (fp, "\n");
1037 fclose (fp);
1040 /* Program options. */
1041 #define OPTION_SRCDIR 200
1043 struct option long_options[] =
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}
1052 static void
1053 print_version (void)
1055 printf ("%s: version 1.0\n", program_name);
1056 xexit (0);
1059 static void
1060 usage (FILE * stream, int status)
1062 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1063 program_name);
1064 xexit (status);
1068 main (int argc, char **argv)
1070 extern int chdir (char *);
1071 char *srcdir = NULL;
1072 int c;
1073 FILE *table;
1075 program_name = *argv;
1076 xmalloc_set_program_name (program_name);
1078 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1079 switch (c)
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;
1099 if (optind != argc)
1100 usage (stdout, 1);
1102 if (srcdir != NULL)
1103 if (chdir (srcdir) != 0)
1104 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1105 srcdir, xstrerror (errno));
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
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
1121 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1122 compare);
1124 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1125 sizeof (opcode_modifiers [0]), compare);
1127 qsort (operand_types, ARRAY_SIZE (operand_types),
1128 sizeof (operand_types [0]), compare);
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));
1135 process_copyright (table);
1137 process_i386_opcodes (table);
1138 process_i386_registers (table);
1139 process_i386_initializers ();
1141 fclose (table);
1143 exit (0);