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