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