Implement displaced stepping.
[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),
81f8a913 329 BITFIELD (NoAVX),
1efbbeb4
L
330 BITFIELD (OldGcc),
331 BITFIELD (ATTMnemonic),
e1d4d893 332 BITFIELD (ATTSyntax),
5c07affc 333 BITFIELD (IntelSyntax),
40fb9820
L
334};
335
336static bitfield operand_types[] =
337{
338 BITFIELD (Reg8),
339 BITFIELD (Reg16),
340 BITFIELD (Reg32),
341 BITFIELD (Reg64),
342 BITFIELD (FloatReg),
343 BITFIELD (RegMMX),
344 BITFIELD (RegXMM),
c0f3af97 345 BITFIELD (RegYMM),
40fb9820
L
346 BITFIELD (Imm8),
347 BITFIELD (Imm8S),
348 BITFIELD (Imm16),
349 BITFIELD (Imm32),
350 BITFIELD (Imm32S),
351 BITFIELD (Imm64),
352 BITFIELD (Imm1),
353 BITFIELD (BaseIndex),
354 BITFIELD (Disp8),
355 BITFIELD (Disp16),
356 BITFIELD (Disp32),
357 BITFIELD (Disp32S),
358 BITFIELD (Disp64),
359 BITFIELD (InOutPortReg),
360 BITFIELD (ShiftCount),
361 BITFIELD (Control),
362 BITFIELD (Debug),
363 BITFIELD (Test),
364 BITFIELD (SReg2),
365 BITFIELD (SReg3),
366 BITFIELD (Acc),
367 BITFIELD (FloatAcc),
368 BITFIELD (JumpAbsolute),
369 BITFIELD (EsSeg),
370 BITFIELD (RegMem),
5c07affc 371 BITFIELD (Mem),
7d5e4556
L
372 BITFIELD (Byte),
373 BITFIELD (Word),
374 BITFIELD (Dword),
375 BITFIELD (Fword),
376 BITFIELD (Qword),
377 BITFIELD (Tbyte),
378 BITFIELD (Xmmword),
c0f3af97 379 BITFIELD (Ymmword),
7d5e4556
L
380 BITFIELD (Unspecified),
381 BITFIELD (Anysize),
c0f3af97 382 BITFIELD (Vex_Imm4),
40fb9820
L
383#ifdef OTUnused
384 BITFIELD (OTUnused),
385#endif
386};
387
3d4d5afa
L
388static int lineno;
389static const char *filename;
390
40fb9820
L
391static int
392compare (const void *x, const void *y)
393{
394 const bitfield *xp = (const bitfield *) x;
395 const bitfield *yp = (const bitfield *) y;
396 return xp->position - yp->position;
397}
398
40b8e679
L
399static void
400fail (const char *message, ...)
401{
402 va_list args;
403
404 va_start (args, message);
405 fprintf (stderr, _("%s: Error: "), program_name);
406 vfprintf (stderr, message, args);
407 va_end (args);
408 xexit (1);
409}
410
72ffa0fb
L
411static void
412process_copyright (FILE *fp)
413{
414 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
6f143e4d 415/* Copyright 2007, 2008 Free Software Foundation, Inc.\n\
72ffa0fb
L
416\n\
417 This file is part of the GNU opcodes library.\n\
418\n\
419 This library is free software; you can redistribute it and/or modify\n\
420 it under the terms of the GNU General Public License as published by\n\
421 the Free Software Foundation; either version 3, or (at your option)\n\
422 any later version.\n\
423\n\
424 It is distributed in the hope that it will be useful, but WITHOUT\n\
425 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
426 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
427 License for more details.\n\
428\n\
429 You should have received a copy of the GNU General Public License\n\
430 along with this program; if not, write to the Free Software\n\
431 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
432 MA 02110-1301, USA. */\n");
433}
434
40b8e679
L
435/* Remove leading white spaces. */
436
437static char *
438remove_leading_whitespaces (char *str)
439{
440 while (ISSPACE (*str))
441 str++;
442 return str;
443}
444
445/* Remove trailing white spaces. */
446
447static void
448remove_trailing_whitespaces (char *str)
449{
450 size_t last = strlen (str);
451
452 if (last == 0)
453 return;
454
455 do
456 {
457 last--;
458 if (ISSPACE (str [last]))
459 str[last] = '\0';
460 else
461 break;
462 }
463 while (last != 0);
464}
465
93b1ec2c 466/* Find next field separated by SEP and terminate it. Return a
40b8e679
L
467 pointer to the one after it. */
468
469static char *
93b1ec2c 470next_field (char *str, char sep, char **next)
40b8e679
L
471{
472 char *p;
473
474 p = remove_leading_whitespaces (str);
93b1ec2c 475 for (str = p; *str != sep && *str != '\0'; str++);
40b8e679
L
476
477 *str = '\0';
478 remove_trailing_whitespaces (p);
479
480 *next = str + 1;
481
482 return p;
483}
484
40fb9820
L
485static void
486set_bitfield (const char *f, bitfield *array, unsigned int size)
487{
488 unsigned int i;
489
490 if (strcmp (f, "CpuSledgehammer") == 0)
491 f= "CpuK8";
7d5e4556
L
492 else if (strcmp (f, "Mmword") == 0)
493 f= "Qword";
494 else if (strcmp (f, "Oword") == 0)
495 f= "Xmmword";
40fb9820
L
496
497 for (i = 0; i < size; i++)
498 if (strcasecmp (array[i].name, f) == 0)
499 {
500 array[i].value = 1;
501 return;
502 }
503
50e8458f 504 fail (_("%s: %d: Unknown bitfield: %s\n"), filename, lineno, f);
40fb9820
L
505}
506
507static void
508output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
509 int macro, const char *comma, const char *indent)
510{
511 unsigned int i;
512
513 fprintf (table, "%s{ { ", indent);
514
515 for (i = 0; i < size - 1; i++)
516 {
517 fprintf (table, "%d, ", flags[i].value);
518 if (((i + 1) % 20) == 0)
519 {
520 /* We need \\ for macro. */
521 if (macro)
522 fprintf (table, " \\\n %s", indent);
523 else
524 fprintf (table, "\n %s", indent);
525 }
526 }
527
528 fprintf (table, "%d } }%s\n", flags[i].value, comma);
529}
530
531static void
532process_i386_cpu_flag (FILE *table, char *flag, int macro,
533 const char *comma, const char *indent)
534{
535 char *str, *next, *last;
536 bitfield flags [ARRAY_SIZE (cpu_flags)];
537
538 /* Copy the default cpu flags. */
539 memcpy (flags, cpu_flags, sizeof (cpu_flags));
540
541 if (strcasecmp (flag, "unknown") == 0)
542 {
543 unsigned int i;
544
545 /* We turn on everything except for cpu64 in case of
546 CPU_UNKNOWN_FLAGS. */
547 for (i = 0; i < ARRAY_SIZE (flags); i++)
548 if (flags[i].position != Cpu64)
549 flags[i].value = 1;
550 }
551 else if (strcmp (flag, "0"))
552 {
553 last = flag + strlen (flag);
554 for (next = flag; next && next < last; )
555 {
556 str = next_field (next, '|', &next);
557 if (str)
558 set_bitfield (str, flags, ARRAY_SIZE (flags));
559 }
560 }
561
562 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
563 comma, indent);
564}
565
566static void
567output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
568{
569 unsigned int i;
570
571 fprintf (table, " { ");
572
573 for (i = 0; i < size - 1; i++)
574 {
575 fprintf (table, "%d, ", modifier[i].value);
576 if (((i + 1) % 20) == 0)
577 fprintf (table, "\n ");
578 }
579
580 fprintf (table, "%d },\n", modifier[i].value);
581}
582
583static void
584process_i386_opcode_modifier (FILE *table, char *mod)
585{
586 char *str, *next, *last;
587 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
588
589 /* Copy the default opcode modifier. */
590 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
591
592 if (strcmp (mod, "0"))
593 {
594 last = mod + strlen (mod);
595 for (next = mod; next && next < last; )
596 {
597 str = next_field (next, '|', &next);
598 if (str)
599 set_bitfield (str, modifiers, ARRAY_SIZE (modifiers));
600 }
601 }
602 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
603}
604
605static void
606output_operand_type (FILE *table, bitfield *types, unsigned int size,
607 int macro, const char *indent)
608{
609 unsigned int i;
610
611 fprintf (table, "{ { ");
612
613 for (i = 0; i < size - 1; i++)
614 {
615 fprintf (table, "%d, ", types[i].value);
616 if (((i + 1) % 20) == 0)
617 {
618 /* We need \\ for macro. */
619 if (macro)
620 fprintf (table, "\\\n%s", indent);
621 else
622 fprintf (table, "\n%s", indent);
623 }
624 }
625
626 fprintf (table, "%d } }", types[i].value);
627}
628
629static void
630process_i386_operand_type (FILE *table, char *op, int macro,
631 const char *indent)
632{
633 char *str, *next, *last;
634 bitfield types [ARRAY_SIZE (operand_types)];
635
636 /* Copy the default operand type. */
637 memcpy (types, operand_types, sizeof (types));
638
639 if (strcmp (op, "0"))
640 {
641 last = op + strlen (op);
642 for (next = op; next && next < last; )
643 {
644 str = next_field (next, '|', &next);
645 if (str)
646 set_bitfield (str, types, ARRAY_SIZE (types));
647 }
648 }
649 output_operand_type (table, types, ARRAY_SIZE (types), macro,
650 indent);
651}
652
40b8e679 653static void
72ffa0fb 654process_i386_opcodes (FILE *table)
40b8e679 655{
3d4d5afa 656 FILE *fp;
40b8e679
L
657 char buf[2048];
658 unsigned int i;
659 char *str, *p, *last;
660 char *name, *operands, *base_opcode, *extension_opcode;
4dffcebc 661 char *opcode_length;
40b8e679
L
662 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
663
3d4d5afa
L
664 filename = "i386-opc.tbl";
665 fp = fopen (filename, "r");
666
40b8e679 667 if (fp == NULL)
34edb9ad 668 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
40fb9820 669 xstrerror (errno));
40b8e679 670
34edb9ad
L
671 fprintf (table, "\n/* i386 opcode table. */\n\n");
672 fprintf (table, "const template i386_optab[] =\n{\n");
40b8e679
L
673
674 while (!feof (fp))
675 {
676 if (fgets (buf, sizeof (buf), fp) == NULL)
677 break;
678
3d4d5afa
L
679 lineno++;
680
40b8e679
L
681 p = remove_leading_whitespaces (buf);
682
683 /* Skip comments. */
684 str = strstr (p, "//");
685 if (str != NULL)
686 str[0] = '\0';
687
688 /* Remove trailing white spaces. */
689 remove_trailing_whitespaces (p);
690
691 switch (p[0])
692 {
693 case '#':
34edb9ad 694 fprintf (table, "%s\n", p);
40b8e679
L
695 case '\0':
696 continue;
697 break;
698 default:
699 break;
700 }
701
702 last = p + strlen (p);
703
704 /* Find name. */
93b1ec2c 705 name = next_field (p, ',', &str);
40b8e679
L
706
707 if (str >= last)
708 abort ();
709
710 /* Find number of operands. */
93b1ec2c 711 operands = next_field (str, ',', &str);
40b8e679
L
712
713 if (str >= last)
714 abort ();
715
716 /* Find base_opcode. */
93b1ec2c 717 base_opcode = next_field (str, ',', &str);
40b8e679
L
718
719 if (str >= last)
720 abort ();
721
722 /* Find extension_opcode. */
93b1ec2c 723 extension_opcode = next_field (str, ',', &str);
40b8e679 724
4dffcebc
L
725 if (str >= last)
726 abort ();
727
728 /* Find opcode_length. */
729 opcode_length = next_field (str, ',', &str);
730
40b8e679
L
731 if (str >= last)
732 abort ();
733
734 /* Find cpu_flags. */
93b1ec2c 735 cpu_flags = next_field (str, ',', &str);
40b8e679
L
736
737 if (str >= last)
738 abort ();
739
740 /* Find opcode_modifier. */
93b1ec2c 741 opcode_modifier = next_field (str, ',', &str);
40b8e679
L
742
743 if (str >= last)
744 abort ();
745
746 /* Remove the first {. */
747 str = remove_leading_whitespaces (str);
748 if (*str != '{')
749 abort ();
750 str = remove_leading_whitespaces (str + 1);
751
752 i = strlen (str);
753
754 /* There are at least "X}". */
755 if (i < 2)
756 abort ();
757
758 /* Remove trailing white spaces and }. */
759 do
760 {
761 i--;
762 if (ISSPACE (str[i]) || str[i] == '}')
763 str[i] = '\0';
764 else
765 break;
766 }
767 while (i != 0);
768
769 last = str + i;
770
771 /* Find operand_types. */
772 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
773 {
774 if (str >= last)
775 {
776 operand_types [i] = NULL;
777 break;
778 }
779
93b1ec2c 780 operand_types [i] = next_field (str, ',', &str);
40b8e679
L
781 if (*operand_types[i] == '0')
782 {
783 if (i != 0)
784 operand_types[i] = NULL;
785 break;
786 }
787 }
788
4dffcebc
L
789 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
790 name, operands, base_opcode, extension_opcode,
791 opcode_length);
40fb9820
L
792
793 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ");
40b8e679 794
40fb9820 795 process_i386_opcode_modifier (table, opcode_modifier);
40b8e679 796
34edb9ad 797 fprintf (table, " { ");
40b8e679
L
798
799 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
800 {
801 if (operand_types[i] == NULL
802 || *operand_types[i] == '0')
803 {
804 if (i == 0)
40fb9820 805 process_i386_operand_type (table, "0", 0, "\t ");
40b8e679
L
806 break;
807 }
808
809 if (i != 0)
34edb9ad 810 fprintf (table, ",\n ");
40b8e679 811
40fb9820
L
812 process_i386_operand_type (table, operand_types[i], 0,
813 "\t ");
40b8e679 814 }
34edb9ad 815 fprintf (table, " } },\n");
40b8e679
L
816 }
817
34edb9ad
L
818 fclose (fp);
819
4dffcebc 820 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
40fb9820
L
821
822 process_i386_cpu_flag (table, "0", 0, ",", " ");
823
824 process_i386_opcode_modifier (table, "0");
825
826 fprintf (table, " { ");
827 process_i386_operand_type (table, "0", 0, "\t ");
828 fprintf (table, " } }\n");
829
34edb9ad 830 fprintf (table, "};\n");
40b8e679
L
831}
832
833static void
72ffa0fb 834process_i386_registers (FILE *table)
40b8e679 835{
3d4d5afa 836 FILE *fp;
40b8e679
L
837 char buf[2048];
838 char *str, *p, *last;
839 char *reg_name, *reg_type, *reg_flags, *reg_num;
a60de03c 840 char *dw2_32_num, *dw2_64_num;
40b8e679 841
3d4d5afa
L
842 filename = "i386-reg.tbl";
843 fp = fopen (filename, "r");
40b8e679 844 if (fp == NULL)
34edb9ad 845 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
40fb9820 846 xstrerror (errno));
40b8e679 847
34edb9ad
L
848 fprintf (table, "\n/* i386 register table. */\n\n");
849 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
40b8e679
L
850
851 while (!feof (fp))
852 {
853 if (fgets (buf, sizeof (buf), fp) == NULL)
854 break;
855
3d4d5afa
L
856 lineno++;
857
40b8e679
L
858 p = remove_leading_whitespaces (buf);
859
860 /* Skip comments. */
861 str = strstr (p, "//");
862 if (str != NULL)
863 str[0] = '\0';
864
865 /* Remove trailing white spaces. */
866 remove_trailing_whitespaces (p);
867
868 switch (p[0])
869 {
870 case '#':
34edb9ad 871 fprintf (table, "%s\n", p);
40b8e679
L
872 case '\0':
873 continue;
874 break;
875 default:
876 break;
877 }
878
879 last = p + strlen (p);
880
881 /* Find reg_name. */
93b1ec2c 882 reg_name = next_field (p, ',', &str);
40b8e679
L
883
884 if (str >= last)
885 abort ();
886
887 /* Find reg_type. */
93b1ec2c 888 reg_type = next_field (str, ',', &str);
40b8e679
L
889
890 if (str >= last)
891 abort ();
892
893 /* Find reg_flags. */
93b1ec2c 894 reg_flags = next_field (str, ',', &str);
40b8e679
L
895
896 if (str >= last)
897 abort ();
898
899 /* Find reg_num. */
93b1ec2c 900 reg_num = next_field (str, ',', &str);
40b8e679 901
a60de03c
JB
902 if (str >= last)
903 abort ();
904
40fb9820
L
905 fprintf (table, " { \"%s\",\n ", reg_name);
906
907 process_i386_operand_type (table, reg_type, 0, "\t");
908
a60de03c
JB
909 /* Find 32-bit Dwarf2 register number. */
910 dw2_32_num = next_field (str, ',', &str);
911
912 if (str >= last)
913 abort ();
914
915 /* Find 64-bit Dwarf2 register number. */
916 dw2_64_num = next_field (str, ',', &str);
917
918 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
919 reg_flags, reg_num, dw2_32_num, dw2_64_num);
40b8e679
L
920 }
921
34edb9ad
L
922 fclose (fp);
923
924 fprintf (table, "};\n");
40b8e679 925
34edb9ad 926 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
40b8e679
L
927}
928
40fb9820
L
929static void
930process_i386_initializers (void)
931{
932 unsigned int i;
933 FILE *fp = fopen ("i386-init.h", "w");
934 char *init;
935
936 if (fp == NULL)
937 fail (_("can't create i386-init.h, errno = %s\n"),
938 xstrerror (errno));
939
940 process_copyright (fp);
941
942 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
943 {
944 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
945 init = xstrdup (cpu_flag_init[i].init);
946 process_i386_cpu_flag (fp, init, 1, "", " ");
947 free (init);
948 }
949
950 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
951 {
952 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
953 init = xstrdup (operand_type_init[i].init);
954 process_i386_operand_type (fp, init, 1, " ");
955 free (init);
956 }
957 fprintf (fp, "\n");
958
959 fclose (fp);
960}
961
40b8e679
L
962/* Program options. */
963#define OPTION_SRCDIR 200
964
965struct option long_options[] =
966{
967 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
968 {"debug", no_argument, NULL, 'd'},
969 {"version", no_argument, NULL, 'V'},
970 {"help", no_argument, NULL, 'h'},
971 {0, no_argument, NULL, 0}
972};
973
974static void
975print_version (void)
976{
977 printf ("%s: version 1.0\n", program_name);
978 xexit (0);
979}
980
981static void
982usage (FILE * stream, int status)
983{
984 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
985 program_name);
986 xexit (status);
987}
988
989int
990main (int argc, char **argv)
991{
992 extern int chdir (char *);
993 char *srcdir = NULL;
8b40d594 994 int c;
72ffa0fb 995 FILE *table;
40b8e679
L
996
997 program_name = *argv;
998 xmalloc_set_program_name (program_name);
999
1000 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1001 switch (c)
1002 {
1003 case OPTION_SRCDIR:
1004 srcdir = optarg;
1005 break;
1006 case 'V':
1007 case 'v':
1008 print_version ();
1009 break;
1010 case 'd':
1011 debug = 1;
1012 break;
1013 case 'h':
1014 case '?':
1015 usage (stderr, 0);
1016 default:
1017 case 0:
1018 break;
1019 }
1020
1021 if (optind != argc)
1022 usage (stdout, 1);
1023
1024 if (srcdir != NULL)
1025 if (chdir (srcdir) != 0)
1026 fail (_("unable to change directory to \"%s\", errno = %s\n"),
40fb9820
L
1027 srcdir, xstrerror (errno));
1028
1029 /* Check the unused bitfield in i386_cpu_flags. */
1030#ifndef CpuUnused
8b40d594
L
1031 c = CpuNumOfBits - CpuMax - 1;
1032 if (c)
1033 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
40fb9820
L
1034#endif
1035
1036 /* Check the unused bitfield in i386_operand_type. */
1037#ifndef OTUnused
8b40d594
L
1038 c = OTNumOfBits - OTMax - 1;
1039 if (c)
1040 fail (_("%d unused bits in i386_operand_type.\n"), c);
40fb9820
L
1041#endif
1042
1043 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1044 compare);
1045
1046 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1047 sizeof (opcode_modifiers [0]), compare);
1048
1049 qsort (operand_types, ARRAY_SIZE (operand_types),
1050 sizeof (operand_types [0]), compare);
40b8e679 1051
34edb9ad
L
1052 table = fopen ("i386-tbl.h", "w");
1053 if (table == NULL)
40fb9820
L
1054 fail (_("can't create i386-tbl.h, errno = %s\n"),
1055 xstrerror (errno));
34edb9ad 1056
72ffa0fb 1057 process_copyright (table);
40b8e679 1058
72ffa0fb
L
1059 process_i386_opcodes (table);
1060 process_i386_registers (table);
40fb9820 1061 process_i386_initializers ();
40b8e679 1062
34edb9ad
L
1063 fclose (table);
1064
40b8e679
L
1065 exit (0);
1066}
This page took 0.10405 seconds and 4 git commands to generate.