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