gas/
[deliverable/binutils-gdb.git] / opcodes / i386-gen.c
1 /* Copyright 2007, 2008 Free Software Foundation, Inc.
2
3 This file is part of the GNU opcodes library.
4
5 This library is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3, or (at your option)
8 any later version.
9
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.
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
17 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
18 MA 02110-1301, USA. */
19
20 #include "sysdep.h"
21 #include <stdio.h>
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
32 static const char *program_name = NULL;
33 static int debug = 0;
34
35 typedef struct initializer
36 {
37 const char *name;
38 const char *init;
39 } initializer;
40
41 static initializer cpu_flag_init [] =
42 {
43 { "CPU_UNKNOWN_FLAGS",
44 "unknown" },
45 { "CPU_GENERIC32_FLAGS",
46 "Cpu186|Cpu286|Cpu386" },
47 { "CPU_GENERIC64_FLAGS",
48 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2|CpuLM" },
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",
66 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuMMX|CpuSSE" },
67 { "CPU_P4_FLAGS",
68 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2" },
69 { "CPU_NOCONA_FLAGS",
70 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuLM" },
71 { "CPU_CORE_FLAGS",
72 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
73 { "CPU_CORE2_FLAGS",
74 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuLM" },
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",
80 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuK6|CpuMMX|Cpu3dnow|Cpu3dnowA" },
81 { "CPU_K8_FLAGS",
82 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuK6|CpuK8|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuLM" },
83 { "CPU_AMDFAM10_FLAGS",
84 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuK6|CpuK8|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM" },
85 { "CPU_MMX_FLAGS",
86 "CpuMMX" },
87 { "CPU_SSE_FLAGS",
88 "CpuMMX|CpuSSE" },
89 { "CPU_SSE2_FLAGS",
90 "CpuMMX|CpuSSE|CpuSSE2" },
91 { "CPU_SSE3_FLAGS",
92 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
93 { "CPU_SSSE3_FLAGS",
94 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3" },
95 { "CPU_SSE4_1_FLAGS",
96 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1" },
97 { "CPU_SSE4_2_FLAGS",
98 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2" },
99 { "CPU_VMX_FLAGS",
100 "CpuVMX" },
101 { "CPU_SMX_FLAGS",
102 "CpuSMX" },
103 { "CPU_XSAVE_FLAGS",
104 "CpuXsave" },
105 { "CPU_AES_FLAGS",
106 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAES" },
107 { "CPU_PCLMUL_FLAGS",
108 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuPCLMUL" },
109 { "CPU_FMA_FLAGS",
110 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA" },
111 { "CPU_MOVBE_FLAGS",
112 "CpuMovbe" },
113 { "CPU_EPT_FLAGS",
114 "CpuEPT" },
115 { "CPU_3DNOW_FLAGS",
116 "CpuMMX|Cpu3dnow" },
117 { "CPU_3DNOWA_FLAGS",
118 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
119 { "CPU_PADLOCK_FLAGS",
120 "CpuPadLock" },
121 { "CPU_SVME_FLAGS",
122 "CpuSVME" },
123 { "CPU_SSE4A_FLAGS",
124 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
125 { "CPU_ABM_FLAGS",
126 "CpuABM" },
127 { "CPU_SSE5_FLAGS",
128 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuSSE5"},
129 { "CPU_AVX_FLAGS",
130 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
131 };
132
133 static 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" },
197 { "OPERAND_TYPE_REGYMM",
198 "RegYMM" },
199 { "OPERAND_TYPE_ESSEG",
200 "EsSeg" },
201 { "OPERAND_TYPE_ACC32",
202 "Reg32|Acc|Dword" },
203 { "OPERAND_TYPE_ACC64",
204 "Reg64|Acc|Qword" },
205 { "OPERAND_TYPE_INOUTPORTREG",
206 "InOutPortReg" },
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" },
227 { "OPERAND_TYPE_VEX_IMM4",
228 "VEX_Imm4" },
229 };
230
231 typedef struct bitfield
232 {
233 int position;
234 int value;
235 const char *name;
236 } bitfield;
237
238 #define BITFIELD(n) { n, 0, #n }
239
240 static 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),
252 BITFIELD (CpuSSE),
253 BITFIELD (CpuSSE2),
254 BITFIELD (CpuSSE3),
255 BITFIELD (CpuSSSE3),
256 BITFIELD (CpuSSE4_1),
257 BITFIELD (CpuSSE4_2),
258 BITFIELD (CpuAVX),
259 BITFIELD (CpuSSE4a),
260 BITFIELD (CpuSSE5),
261 BITFIELD (Cpu3dnow),
262 BITFIELD (Cpu3dnowA),
263 BITFIELD (CpuPadLock),
264 BITFIELD (CpuSVME),
265 BITFIELD (CpuVMX),
266 BITFIELD (CpuSMX),
267 BITFIELD (CpuABM),
268 BITFIELD (CpuXsave),
269 BITFIELD (CpuAES),
270 BITFIELD (CpuPCLMUL),
271 BITFIELD (CpuFMA),
272 BITFIELD (CpuLM),
273 BITFIELD (CpuMovbe),
274 BITFIELD (CpuEPT),
275 BITFIELD (Cpu64),
276 BITFIELD (CpuNo64),
277 #ifdef CpuUnused
278 BITFIELD (CpuUnused),
279 #endif
280 };
281
282 static 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),
305 BITFIELD (No_ldSuf),
306 BITFIELD (FWait),
307 BITFIELD (IsString),
308 BITFIELD (RegKludge),
309 BITFIELD (FirstXmm0),
310 BITFIELD (Implicit1stXmm0),
311 BITFIELD (ByteOkIntel),
312 BITFIELD (ToDword),
313 BITFIELD (ToQword),
314 BITFIELD (AddrPrefixOp0),
315 BITFIELD (IsPrefix),
316 BITFIELD (ImmExt),
317 BITFIELD (NoRex64),
318 BITFIELD (Rex64),
319 BITFIELD (Ugh),
320 BITFIELD (Drex),
321 BITFIELD (Drexv),
322 BITFIELD (Drexc),
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),
335 BITFIELD (NoAVX),
336 BITFIELD (OldGcc),
337 BITFIELD (ATTMnemonic),
338 BITFIELD (ATTSyntax),
339 BITFIELD (IntelSyntax),
340 };
341
342 static 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),
351 BITFIELD (RegYMM),
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),
377 BITFIELD (Mem),
378 BITFIELD (Byte),
379 BITFIELD (Word),
380 BITFIELD (Dword),
381 BITFIELD (Fword),
382 BITFIELD (Qword),
383 BITFIELD (Tbyte),
384 BITFIELD (Xmmword),
385 BITFIELD (Ymmword),
386 BITFIELD (Unspecified),
387 BITFIELD (Anysize),
388 BITFIELD (Vex_Imm4),
389 #ifdef OTUnused
390 BITFIELD (OTUnused),
391 #endif
392 };
393
394 static int lineno;
395 static const char *filename;
396
397 static int
398 compare (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
405 static void
406 fail (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
417 static void
418 process_copyright (FILE *fp)
419 {
420 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
421 /* Copyright 2007, 2008 Free Software Foundation, Inc.\n\
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
441 /* Remove leading white spaces. */
442
443 static char *
444 remove_leading_whitespaces (char *str)
445 {
446 while (ISSPACE (*str))
447 str++;
448 return str;
449 }
450
451 /* Remove trailing white spaces. */
452
453 static void
454 remove_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
472 /* Find next field separated by SEP and terminate it. Return a
473 pointer to the one after it. */
474
475 static char *
476 next_field (char *str, char sep, char **next)
477 {
478 char *p;
479
480 p = remove_leading_whitespaces (str);
481 for (str = p; *str != sep && *str != '\0'; str++);
482
483 *str = '\0';
484 remove_trailing_whitespaces (p);
485
486 *next = str + 1;
487
488 return p;
489 }
490
491 static void
492 set_bitfield (const char *f, bitfield *array, unsigned int size)
493 {
494 unsigned int i;
495
496 if (strcmp (f, "CpuSledgehammer") == 0)
497 f= "CpuK8";
498 else if (strcmp (f, "Mmword") == 0)
499 f= "Qword";
500 else if (strcmp (f, "Oword") == 0)
501 f= "Xmmword";
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
510 fail (_("%s: %d: Unknown bitfield: %s\n"), filename, lineno, f);
511 }
512
513 static void
514 output_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
537 static void
538 process_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
572 static void
573 output_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
589 static void
590 process_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
611 static void
612 output_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
635 static void
636 process_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
659 static void
660 process_i386_opcodes (FILE *table)
661 {
662 FILE *fp;
663 char buf[2048];
664 unsigned int i;
665 char *str, *p, *last;
666 char *name, *operands, *base_opcode, *extension_opcode;
667 char *opcode_length;
668 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
669
670 filename = "i386-opc.tbl";
671 fp = fopen (filename, "r");
672
673 if (fp == NULL)
674 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
675 xstrerror (errno));
676
677 fprintf (table, "\n/* i386 opcode table. */\n\n");
678 fprintf (table, "const template i386_optab[] =\n{\n");
679
680 while (!feof (fp))
681 {
682 if (fgets (buf, sizeof (buf), fp) == NULL)
683 break;
684
685 lineno++;
686
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 '#':
700 fprintf (table, "%s\n", p);
701 case '\0':
702 continue;
703 break;
704 default:
705 break;
706 }
707
708 last = p + strlen (p);
709
710 /* Find name. */
711 name = next_field (p, ',', &str);
712
713 if (str >= last)
714 abort ();
715
716 /* Find number of operands. */
717 operands = next_field (str, ',', &str);
718
719 if (str >= last)
720 abort ();
721
722 /* Find base_opcode. */
723 base_opcode = next_field (str, ',', &str);
724
725 if (str >= last)
726 abort ();
727
728 /* Find extension_opcode. */
729 extension_opcode = next_field (str, ',', &str);
730
731 if (str >= last)
732 abort ();
733
734 /* Find opcode_length. */
735 opcode_length = next_field (str, ',', &str);
736
737 if (str >= last)
738 abort ();
739
740 /* Find cpu_flags. */
741 cpu_flags = next_field (str, ',', &str);
742
743 if (str >= last)
744 abort ();
745
746 /* Find opcode_modifier. */
747 opcode_modifier = next_field (str, ',', &str);
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
786 operand_types [i] = next_field (str, ',', &str);
787 if (*operand_types[i] == '0')
788 {
789 if (i != 0)
790 operand_types[i] = NULL;
791 break;
792 }
793 }
794
795 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
796 name, operands, base_opcode, extension_opcode,
797 opcode_length);
798
799 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ");
800
801 process_i386_opcode_modifier (table, opcode_modifier);
802
803 fprintf (table, " { ");
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)
811 process_i386_operand_type (table, "0", 0, "\t ");
812 break;
813 }
814
815 if (i != 0)
816 fprintf (table, ",\n ");
817
818 process_i386_operand_type (table, operand_types[i], 0,
819 "\t ");
820 }
821 fprintf (table, " } },\n");
822 }
823
824 fclose (fp);
825
826 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
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
836 fprintf (table, "};\n");
837 }
838
839 static void
840 process_i386_registers (FILE *table)
841 {
842 FILE *fp;
843 char buf[2048];
844 char *str, *p, *last;
845 char *reg_name, *reg_type, *reg_flags, *reg_num;
846 char *dw2_32_num, *dw2_64_num;
847
848 filename = "i386-reg.tbl";
849 fp = fopen (filename, "r");
850 if (fp == NULL)
851 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
852 xstrerror (errno));
853
854 fprintf (table, "\n/* i386 register table. */\n\n");
855 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
856
857 while (!feof (fp))
858 {
859 if (fgets (buf, sizeof (buf), fp) == NULL)
860 break;
861
862 lineno++;
863
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 '#':
877 fprintf (table, "%s\n", p);
878 case '\0':
879 continue;
880 break;
881 default:
882 break;
883 }
884
885 last = p + strlen (p);
886
887 /* Find reg_name. */
888 reg_name = next_field (p, ',', &str);
889
890 if (str >= last)
891 abort ();
892
893 /* Find reg_type. */
894 reg_type = next_field (str, ',', &str);
895
896 if (str >= last)
897 abort ();
898
899 /* Find reg_flags. */
900 reg_flags = next_field (str, ',', &str);
901
902 if (str >= last)
903 abort ();
904
905 /* Find reg_num. */
906 reg_num = next_field (str, ',', &str);
907
908 if (str >= last)
909 abort ();
910
911 fprintf (table, " { \"%s\",\n ", reg_name);
912
913 process_i386_operand_type (table, reg_type, 0, "\t");
914
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);
926 }
927
928 fclose (fp);
929
930 fprintf (table, "};\n");
931
932 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
933 }
934
935 static void
936 process_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
968 /* Program options. */
969 #define OPTION_SRCDIR 200
970
971 struct 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
980 static void
981 print_version (void)
982 {
983 printf ("%s: version 1.0\n", program_name);
984 xexit (0);
985 }
986
987 static void
988 usage (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
995 int
996 main (int argc, char **argv)
997 {
998 extern int chdir (char *);
999 char *srcdir = NULL;
1000 int c;
1001 FILE *table;
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"),
1033 srcdir, xstrerror (errno));
1034
1035 /* Check the unused bitfield in i386_cpu_flags. */
1036 #ifndef CpuUnused
1037 c = CpuNumOfBits - CpuMax - 1;
1038 if (c)
1039 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1040 #endif
1041
1042 /* Check the unused bitfield in i386_operand_type. */
1043 #ifndef OTUnused
1044 c = OTNumOfBits - OTMax - 1;
1045 if (c)
1046 fail (_("%d unused bits in i386_operand_type.\n"), c);
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);
1057
1058 table = fopen ("i386-tbl.h", "w");
1059 if (table == NULL)
1060 fail (_("can't create i386-tbl.h, errno = %s\n"),
1061 xstrerror (errno));
1062
1063 process_copyright (table);
1064
1065 process_i386_opcodes (table);
1066 process_i386_registers (table);
1067 process_i386_initializers ();
1068
1069 fclose (table);
1070
1071 exit (0);
1072 }
This page took 0.054364 seconds and 4 git commands to generate.