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