1 /* Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013
2 Free Software Foundation, Inc.
4 This file is part of the GNU opcodes library.
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)
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.
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. */
25 #include "libiberty.h"
27 #include "safe-ctype.h"
32 #define _(String) gettext (String)
34 static const char *program_name
= NULL
;
37 typedef struct initializer
43 static initializer cpu_flag_init
[] =
45 { "CPU_UNKNOWN_FLAGS",
46 "~(CpuL1OM|CpuK1OM)" },
47 { "CPU_GENERIC32_FLAGS",
48 "Cpu186|Cpu286|Cpu386" },
49 { "CPU_GENERIC64_FLAGS",
50 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuLM" },
58 "Cpu186|Cpu286|Cpu386" },
60 "Cpu186|Cpu286|Cpu386|Cpu486" },
62 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu387" },
64 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687" },
65 { "CPU_PENTIUMPRO_FLAGS",
66 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuNop" },
68 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuNop|CpuMMX" },
70 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE" },
72 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE|CpuSSE2" },
74 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuLM|CpuCX16" },
76 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuCX16" },
78 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuLM|CpuCX16" },
80 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuRdtscp|CpuLM|CpuCX16" },
82 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CpuMMX" },
84 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CpuNop|CpuMMX|Cpu3dnow" },
86 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|Cpu387|Cpu687|CpuNop|CpuMMX|Cpu3dnow|Cpu3dnowA" },
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" },
92 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM|CpuFMA4|CpuXOP|CpuLWP|CpuCX16|CpuClflush|CpuSSSE3|CpuSVME|CpuSSE4_1|CpuSSE4_2|CpuXsave|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW" },
94 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM|CpuFMA|CpuFMA4|CpuXOP|CpuLWP|CpuBMI|CpuTBM|CpuF16C|CpuCX16|CpuClflush|CpuSSSE3|CpuSVME|CpuSSE4_1|CpuSSE4_2|CpuXsave|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW" },
96 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM|CpuFMA|CpuFMA4|CpuXOP|CpuLWP|CpuBMI|CpuTBM|CpuF16C|CpuCX16|CpuClflush|CpuSSSE3|CpuSVME|CpuSSE4_1|CpuSSE4_2|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW|CpuXsave|CpuXsaveopt" },
98 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4a|CpuABM|CpuLM|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME|CpuLZCNT" },
100 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4a|CpuSSE4_1|CpuSSE4_2|CpuABM|CpuLM|CpuBMI|CpuF16C|CpuAES|CpuPCLMUL|CpuAVX|CpuMovbe|CpuXsave|CpuXsaveopt|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME|CpuLZCNT" },
108 "Cpu8087|Cpu287|Cpu387|Cpu687|CpuFISTTP" },
109 { "CPU_CLFLUSH_FLAGS",
113 { "CPU_SYSCALL_FLAGS",
120 "CpuMMX|CpuSSE|CpuSSE2" },
122 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
124 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3" },
125 { "CPU_SSE4_1_FLAGS",
126 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1" },
127 { "CPU_SSE4_2_FLAGS",
128 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2" },
129 { "CPU_ANY_SSE_FLAGS",
130 "CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuAVX|CpuAVX2" },
137 { "CPU_XSAVEOPT_FLAGS",
140 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAES" },
141 { "CPU_PCLMUL_FLAGS",
142 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuPCLMUL" },
144 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA" },
146 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA4" },
148 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuABM|CpuAVX|CpuFMA4|CpuXOP" },
159 { "CPU_RDTSCP_FLAGS",
163 { "CPU_FSGSBASE_FLAGS",
177 { "CPU_INVPCID_FLAGS",
179 { "CPU_VMFUNC_FLAGS",
183 { "CPU_3DNOWA_FLAGS",
184 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
185 { "CPU_PADLOCK_FLAGS",
190 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
194 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
196 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2" },
197 { "CPU_ANY_AVX_FLAGS",
205 { "CPU_RDSEED_FLAGS",
207 { "CPU_PRFCHW_FLAGS",
211 static initializer operand_type_init
[] =
213 { "OPERAND_TYPE_NONE",
215 { "OPERAND_TYPE_REG8",
217 { "OPERAND_TYPE_REG16",
219 { "OPERAND_TYPE_REG32",
221 { "OPERAND_TYPE_REG64",
223 { "OPERAND_TYPE_IMM1",
225 { "OPERAND_TYPE_IMM8",
227 { "OPERAND_TYPE_IMM8S",
229 { "OPERAND_TYPE_IMM16",
231 { "OPERAND_TYPE_IMM32",
233 { "OPERAND_TYPE_IMM32S",
235 { "OPERAND_TYPE_IMM64",
237 { "OPERAND_TYPE_BASEINDEX",
239 { "OPERAND_TYPE_DISP8",
241 { "OPERAND_TYPE_DISP16",
243 { "OPERAND_TYPE_DISP32",
245 { "OPERAND_TYPE_DISP32S",
247 { "OPERAND_TYPE_DISP64",
249 { "OPERAND_TYPE_INOUTPORTREG",
251 { "OPERAND_TYPE_SHIFTCOUNT",
253 { "OPERAND_TYPE_CONTROL",
255 { "OPERAND_TYPE_TEST",
257 { "OPERAND_TYPE_DEBUG",
259 { "OPERAND_TYPE_FLOATREG",
261 { "OPERAND_TYPE_FLOATACC",
263 { "OPERAND_TYPE_SREG2",
265 { "OPERAND_TYPE_SREG3",
267 { "OPERAND_TYPE_ACC",
269 { "OPERAND_TYPE_JUMPABSOLUTE",
271 { "OPERAND_TYPE_REGMMX",
273 { "OPERAND_TYPE_REGXMM",
275 { "OPERAND_TYPE_REGYMM",
277 { "OPERAND_TYPE_ESSEG",
279 { "OPERAND_TYPE_ACC32",
281 { "OPERAND_TYPE_ACC64",
283 { "OPERAND_TYPE_INOUTPORTREG",
285 { "OPERAND_TYPE_REG16_INOUTPORTREG",
286 "Reg16|InOutPortReg" },
287 { "OPERAND_TYPE_DISP16_32",
289 { "OPERAND_TYPE_ANYDISP",
290 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
291 { "OPERAND_TYPE_IMM16_32",
293 { "OPERAND_TYPE_IMM16_32S",
295 { "OPERAND_TYPE_IMM16_32_32S",
296 "Imm16|Imm32|Imm32S" },
297 { "OPERAND_TYPE_IMM32_64",
299 { "OPERAND_TYPE_IMM32_32S_DISP32",
300 "Imm32|Imm32S|Disp32" },
301 { "OPERAND_TYPE_IMM64_DISP64",
303 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
304 "Imm32|Imm32S|Imm64|Disp32" },
305 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
306 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
307 { "OPERAND_TYPE_VEC_IMM4",
311 typedef struct bitfield
318 #define BITFIELD(n) { n, 0, #n }
320 static bitfield cpu_flags
[] =
328 BITFIELD (CpuClflush
),
330 BITFIELD (CpuSYSCALL
),
335 BITFIELD (CpuFISTTP
),
341 BITFIELD (CpuSSE4_1
),
342 BITFIELD (CpuSSE4_2
),
349 BITFIELD (Cpu3dnowA
),
350 BITFIELD (CpuPadLock
),
356 BITFIELD (CpuXsaveopt
),
358 BITFIELD (CpuPCLMUL
),
369 BITFIELD (CpuRdtscp
),
370 BITFIELD (CpuFSGSBase
),
377 BITFIELD (CpuINVPCID
),
378 BITFIELD (CpuVMFUNC
),
379 BITFIELD (CpuRDSEED
),
381 BITFIELD (CpuPRFCHW
),
385 BITFIELD (CpuUnused
),
389 static bitfield opcode_modifiers
[] =
395 BITFIELD (ShortForm
),
397 BITFIELD (JumpDword
),
399 BITFIELD (JumpInterSegment
),
406 BITFIELD (CheckRegSize
),
407 BITFIELD (IgnoreSize
),
408 BITFIELD (DefaultSize
),
417 BITFIELD (IsLockable
),
418 BITFIELD (RegKludge
),
419 BITFIELD (FirstXmm0
),
420 BITFIELD (Implicit1stXmm0
),
421 BITFIELD (RepPrefixOk
),
422 BITFIELD (HLEPrefixOk
),
425 BITFIELD (AddrPrefixOp0
),
434 BITFIELD (VexOpcode
),
435 BITFIELD (VexSources
),
436 BITFIELD (VexImmExt
),
441 BITFIELD (ATTMnemonic
),
442 BITFIELD (ATTSyntax
),
443 BITFIELD (IntelSyntax
),
446 static bitfield operand_types
[] =
463 BITFIELD (BaseIndex
),
469 BITFIELD (InOutPortReg
),
470 BITFIELD (ShiftCount
),
478 BITFIELD (JumpAbsolute
),
490 BITFIELD (Unspecified
),
498 static const char *filename
;
501 compare (const void *x
, const void *y
)
503 const bitfield
*xp
= (const bitfield
*) x
;
504 const bitfield
*yp
= (const bitfield
*) y
;
505 return xp
->position
- yp
->position
;
509 fail (const char *message
, ...)
513 va_start (args
, message
);
514 fprintf (stderr
, _("%s: Error: "), program_name
);
515 vfprintf (stderr
, message
, args
);
521 process_copyright (FILE *fp
)
523 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
524 /* Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013\n\
525 Free Software Foundation, Inc.\n\
527 This file is part of the GNU opcodes library.\n\
529 This library is free software; you can redistribute it and/or modify\n\
530 it under the terms of the GNU General Public License as published by\n\
531 the Free Software Foundation; either version 3, or (at your option)\n\
532 any later version.\n\
534 It is distributed in the hope that it will be useful, but WITHOUT\n\
535 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
536 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
537 License for more details.\n\
539 You should have received a copy of the GNU General Public License\n\
540 along with this program; if not, write to the Free Software\n\
541 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
542 MA 02110-1301, USA. */\n");
545 /* Remove leading white spaces. */
548 remove_leading_whitespaces (char *str
)
550 while (ISSPACE (*str
))
555 /* Remove trailing white spaces. */
558 remove_trailing_whitespaces (char *str
)
560 size_t last
= strlen (str
);
568 if (ISSPACE (str
[last
]))
576 /* Find next field separated by SEP and terminate it. Return a
577 pointer to the one after it. */
580 next_field (char *str
, char sep
, char **next
, char *last
)
584 p
= remove_leading_whitespaces (str
);
585 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
588 remove_trailing_whitespaces (p
);
599 set_bitfield (const char *f
, bitfield
*array
, int value
,
600 unsigned int size
, int lineno
)
604 if (strcmp (f
, "CpuFP") == 0)
606 set_bitfield("Cpu387", array
, value
, size
, lineno
);
607 set_bitfield("Cpu287", array
, value
, size
, lineno
);
610 else if (strcmp (f
, "Mmword") == 0)
612 else if (strcmp (f
, "Oword") == 0)
615 for (i
= 0; i
< size
; i
++)
616 if (strcasecmp (array
[i
].name
, f
) == 0)
618 array
[i
].value
= value
;
624 const char *v
= strchr (f
, '=');
631 for (i
= 0; i
< size
; i
++)
632 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
634 value
= strtol (v
+ 1, &end
, 0);
637 array
[i
].value
= value
;
646 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
648 fail (_("Unknown bitfield: %s\n"), f
);
652 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
653 int macro
, const char *comma
, const char *indent
)
657 fprintf (table
, "%s{ { ", indent
);
659 for (i
= 0; i
< size
- 1; i
++)
661 fprintf (table
, "%d, ", flags
[i
].value
);
662 if (((i
+ 1) % 20) == 0)
664 /* We need \\ for macro. */
666 fprintf (table
, " \\\n %s", indent
);
668 fprintf (table
, "\n %s", indent
);
672 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
676 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
677 const char *comma
, const char *indent
,
680 char *str
, *next
, *last
;
682 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
684 /* Copy the default cpu flags. */
685 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
687 if (strcasecmp (flag
, "unknown") == 0)
689 /* We turn on everything except for cpu64 in case of
690 CPU_UNKNOWN_FLAGS. */
691 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
692 if (flags
[i
].position
!= Cpu64
)
695 else if (flag
[0] == '~')
697 last
= flag
+ strlen (flag
);
704 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename
,
711 /* First we turn on everything except for cpu64. */
712 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
713 if (flags
[i
].position
!= Cpu64
)
716 /* Turn off selective bits. */
717 for (; next
&& next
< last
; )
719 str
= next_field (next
, '|', &next
, last
);
721 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
724 else if (strcmp (flag
, "0"))
726 /* Turn on selective bits. */
727 last
= flag
+ strlen (flag
);
728 for (next
= flag
; next
&& next
< last
; )
730 str
= next_field (next
, '|', &next
, last
);
732 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
736 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
741 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
745 fprintf (table
, " { ");
747 for (i
= 0; i
< size
- 1; i
++)
749 fprintf (table
, "%d, ", modifier
[i
].value
);
750 if (((i
+ 1) % 20) == 0)
751 fprintf (table
, "\n ");
754 fprintf (table
, "%d },\n", modifier
[i
].value
);
758 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
760 char *str
, *next
, *last
;
761 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
763 /* Copy the default opcode modifier. */
764 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
766 if (strcmp (mod
, "0"))
768 last
= mod
+ strlen (mod
);
769 for (next
= mod
; next
&& next
< last
; )
771 str
= next_field (next
, '|', &next
, last
);
773 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
777 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
781 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
782 int macro
, const char *indent
)
786 fprintf (table
, "{ { ");
788 for (i
= 0; i
< size
- 1; i
++)
790 fprintf (table
, "%d, ", types
[i
].value
);
791 if (((i
+ 1) % 20) == 0)
793 /* We need \\ for macro. */
795 fprintf (table
, "\\\n%s", indent
);
797 fprintf (table
, "\n%s", indent
);
801 fprintf (table
, "%d } }", types
[i
].value
);
805 process_i386_operand_type (FILE *table
, char *op
, int macro
,
806 const char *indent
, int lineno
)
808 char *str
, *next
, *last
;
809 bitfield types
[ARRAY_SIZE (operand_types
)];
811 /* Copy the default operand type. */
812 memcpy (types
, operand_types
, sizeof (types
));
814 if (strcmp (op
, "0"))
816 last
= op
+ strlen (op
);
817 for (next
= op
; next
&& next
< last
; )
819 str
= next_field (next
, '|', &next
, last
);
821 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
824 output_operand_type (table
, types
, ARRAY_SIZE (types
), macro
,
829 output_i386_opcode (FILE *table
, const char *name
, char *str
,
830 char *last
, int lineno
)
833 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
834 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
836 /* Find number of operands. */
837 operands
= next_field (str
, ',', &str
, last
);
839 /* Find base_opcode. */
840 base_opcode
= next_field (str
, ',', &str
, last
);
842 /* Find extension_opcode. */
843 extension_opcode
= next_field (str
, ',', &str
, last
);
845 /* Find opcode_length. */
846 opcode_length
= next_field (str
, ',', &str
, last
);
848 /* Find cpu_flags. */
849 cpu_flags
= next_field (str
, ',', &str
, last
);
851 /* Find opcode_modifier. */
852 opcode_modifier
= next_field (str
, ',', &str
, last
);
854 /* Remove the first {. */
855 str
= remove_leading_whitespaces (str
);
858 str
= remove_leading_whitespaces (str
+ 1);
862 /* There are at least "X}". */
866 /* Remove trailing white spaces and }. */
870 if (ISSPACE (str
[i
]) || str
[i
] == '}')
879 /* Find operand_types. */
880 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
884 operand_types
[i
] = NULL
;
888 operand_types
[i
] = next_field (str
, ',', &str
, last
);
889 if (*operand_types
[i
] == '0')
892 operand_types
[i
] = NULL
;
897 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
898 name
, operands
, base_opcode
, extension_opcode
,
901 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
903 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
905 fprintf (table
, " { ");
907 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
909 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
912 process_i386_operand_type (table
, "0", 0, "\t ", lineno
);
917 fprintf (table
, ",\n ");
919 process_i386_operand_type (table
, operand_types
[i
], 0,
922 fprintf (table
, " } },\n");
925 struct opcode_hash_entry
927 struct opcode_hash_entry
*next
;
933 /* Calculate the hash value of an opcode hash entry P. */
936 opcode_hash_hash (const void *p
)
938 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
939 return htab_hash_string (entry
->name
);
942 /* Compare a string Q against an opcode hash entry P. */
945 opcode_hash_eq (const void *p
, const void *q
)
947 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
948 const char *name
= (const char *) q
;
949 return strcmp (name
, entry
->name
) == 0;
953 process_i386_opcodes (FILE *table
)
958 char *str
, *p
, *last
, *name
;
959 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
960 htab_t opcode_hash_table
;
961 struct opcode_hash_entry
**opcode_array
;
962 unsigned int opcode_array_size
= 1024;
965 filename
= "i386-opc.tbl";
966 fp
= fopen (filename
, "r");
969 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
973 opcode_array
= (struct opcode_hash_entry
**)
974 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
976 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
977 opcode_hash_eq
, NULL
,
980 fprintf (table
, "\n/* i386 opcode table. */\n\n");
981 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
983 /* Put everything on opcode array. */
986 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
991 p
= remove_leading_whitespaces (buf
);
994 str
= strstr (p
, "//");
998 /* Remove trailing white spaces. */
999 remove_trailing_whitespaces (p
);
1004 /* Ignore comments. */
1012 last
= p
+ strlen (p
);
1015 name
= next_field (p
, ',', &str
, last
);
1017 /* Get the slot in hash table. */
1018 hash_slot
= (struct opcode_hash_entry
**)
1019 htab_find_slot_with_hash (opcode_hash_table
, name
,
1020 htab_hash_string (name
),
1023 if (*hash_slot
== NULL
)
1025 /* It is the new one. Put it on opcode array. */
1026 if (i
>= opcode_array_size
)
1028 /* Grow the opcode array when needed. */
1029 opcode_array_size
+= 1024;
1030 opcode_array
= (struct opcode_hash_entry
**)
1031 xrealloc (opcode_array
,
1032 sizeof (*opcode_array
) * opcode_array_size
);
1035 opcode_array
[i
] = (struct opcode_hash_entry
*)
1036 xmalloc (sizeof (struct opcode_hash_entry
));
1037 opcode_array
[i
]->next
= NULL
;
1038 opcode_array
[i
]->name
= xstrdup (name
);
1039 opcode_array
[i
]->opcode
= xstrdup (str
);
1040 opcode_array
[i
]->lineno
= lineno
;
1041 *hash_slot
= opcode_array
[i
];
1046 /* Append it to the existing one. */
1048 while ((*entry
) != NULL
)
1049 entry
= &(*entry
)->next
;
1050 *entry
= (struct opcode_hash_entry
*)
1051 xmalloc (sizeof (struct opcode_hash_entry
));
1052 (*entry
)->next
= NULL
;
1053 (*entry
)->name
= (*hash_slot
)->name
;
1054 (*entry
)->opcode
= xstrdup (str
);
1055 (*entry
)->lineno
= lineno
;
1059 /* Process opcode array. */
1060 for (j
= 0; j
< i
; j
++)
1062 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1066 lineno
= next
->lineno
;
1067 last
= str
+ strlen (str
);
1068 output_i386_opcode (table
, name
, str
, last
, lineno
);
1074 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1076 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1078 process_i386_opcode_modifier (table
, "0", -1);
1080 fprintf (table
, " { ");
1081 process_i386_operand_type (table
, "0", 0, "\t ", -1);
1082 fprintf (table
, " } }\n");
1084 fprintf (table
, "};\n");
1088 process_i386_registers (FILE *table
)
1092 char *str
, *p
, *last
;
1093 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1094 char *dw2_32_num
, *dw2_64_num
;
1097 filename
= "i386-reg.tbl";
1098 fp
= fopen (filename
, "r");
1100 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1103 fprintf (table
, "\n/* i386 register table. */\n\n");
1104 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1108 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1113 p
= remove_leading_whitespaces (buf
);
1115 /* Skip comments. */
1116 str
= strstr (p
, "//");
1120 /* Remove trailing white spaces. */
1121 remove_trailing_whitespaces (p
);
1126 fprintf (table
, "%s\n", p
);
1134 last
= p
+ strlen (p
);
1136 /* Find reg_name. */
1137 reg_name
= next_field (p
, ',', &str
, last
);
1139 /* Find reg_type. */
1140 reg_type
= next_field (str
, ',', &str
, last
);
1142 /* Find reg_flags. */
1143 reg_flags
= next_field (str
, ',', &str
, last
);
1146 reg_num
= next_field (str
, ',', &str
, last
);
1148 fprintf (table
, " { \"%s\",\n ", reg_name
);
1150 process_i386_operand_type (table
, reg_type
, 0, "\t", lineno
);
1152 /* Find 32-bit Dwarf2 register number. */
1153 dw2_32_num
= next_field (str
, ',', &str
, last
);
1155 /* Find 64-bit Dwarf2 register number. */
1156 dw2_64_num
= next_field (str
, ',', &str
, last
);
1158 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1159 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1164 fprintf (table
, "};\n");
1166 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1170 process_i386_initializers (void)
1173 FILE *fp
= fopen ("i386-init.h", "w");
1177 fail (_("can't create i386-init.h, errno = %s\n"),
1180 process_copyright (fp
);
1182 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1184 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1185 init
= xstrdup (cpu_flag_init
[i
].init
);
1186 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1190 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1192 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1193 init
= xstrdup (operand_type_init
[i
].init
);
1194 process_i386_operand_type (fp
, init
, 1, " ", -1);
1202 /* Program options. */
1203 #define OPTION_SRCDIR 200
1205 struct option long_options
[] =
1207 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1208 {"debug", no_argument
, NULL
, 'd'},
1209 {"version", no_argument
, NULL
, 'V'},
1210 {"help", no_argument
, NULL
, 'h'},
1211 {0, no_argument
, NULL
, 0}
1215 print_version (void)
1217 printf ("%s: version 1.0\n", program_name
);
1222 usage (FILE * stream
, int status
)
1224 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1230 main (int argc
, char **argv
)
1232 extern int chdir (char *);
1233 char *srcdir
= NULL
;
1237 program_name
= *argv
;
1238 xmalloc_set_program_name (program_name
);
1240 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1265 if (chdir (srcdir
) != 0)
1266 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1267 srcdir
, xstrerror (errno
));
1269 /* Check the unused bitfield in i386_cpu_flags. */
1271 c
= CpuNumOfBits
- CpuMax
- 1;
1273 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1276 /* Check the unused bitfield in i386_operand_type. */
1278 c
= OTNumOfBits
- OTMax
- 1;
1280 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1283 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1286 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1287 sizeof (opcode_modifiers
[0]), compare
);
1289 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1290 sizeof (operand_types
[0]), compare
);
1292 table
= fopen ("i386-tbl.h", "w");
1294 fail (_("can't create i386-tbl.h, errno = %s\n"),
1297 process_copyright (table
);
1299 process_i386_opcodes (table
);
1300 process_i386_registers (table
);
1301 process_i386_initializers ();