1 /* Copyright 2007, 2008, 2009, 2010, 2011, 2012
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|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4a|CpuABM|CpuLM|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME|CpuLZCNT" },
98 "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" },
106 "Cpu8087|Cpu287|Cpu387|Cpu687|CpuFISTTP" },
107 { "CPU_CLFLUSH_FLAGS",
111 { "CPU_SYSCALL_FLAGS",
118 "CpuMMX|CpuSSE|CpuSSE2" },
120 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
122 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3" },
123 { "CPU_SSE4_1_FLAGS",
124 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1" },
125 { "CPU_SSE4_2_FLAGS",
126 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2" },
127 { "CPU_ANY_SSE_FLAGS",
128 "CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuAVX|CpuAVX2" },
135 { "CPU_XSAVEOPT_FLAGS",
138 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAES" },
139 { "CPU_PCLMUL_FLAGS",
140 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuPCLMUL" },
142 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA" },
144 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA4" },
146 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuABM|CpuAVX|CpuFMA4|CpuXOP" },
157 { "CPU_RDTSCP_FLAGS",
161 { "CPU_FSGSBASE_FLAGS",
175 { "CPU_INVPCID_FLAGS",
177 { "CPU_VMFUNC_FLAGS",
181 { "CPU_3DNOWA_FLAGS",
182 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
183 { "CPU_PADLOCK_FLAGS",
188 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
192 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
194 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2" },
195 { "CPU_ANY_AVX_FLAGS",
203 { "CPU_RDSEED_FLAGS",
205 { "CPU_PRFCHW_FLAGS",
209 static initializer operand_type_init
[] =
211 { "OPERAND_TYPE_NONE",
213 { "OPERAND_TYPE_REG8",
215 { "OPERAND_TYPE_REG16",
217 { "OPERAND_TYPE_REG32",
219 { "OPERAND_TYPE_REG64",
221 { "OPERAND_TYPE_IMM1",
223 { "OPERAND_TYPE_IMM8",
225 { "OPERAND_TYPE_IMM8S",
227 { "OPERAND_TYPE_IMM16",
229 { "OPERAND_TYPE_IMM32",
231 { "OPERAND_TYPE_IMM32S",
233 { "OPERAND_TYPE_IMM64",
235 { "OPERAND_TYPE_BASEINDEX",
237 { "OPERAND_TYPE_DISP8",
239 { "OPERAND_TYPE_DISP16",
241 { "OPERAND_TYPE_DISP32",
243 { "OPERAND_TYPE_DISP32S",
245 { "OPERAND_TYPE_DISP64",
247 { "OPERAND_TYPE_INOUTPORTREG",
249 { "OPERAND_TYPE_SHIFTCOUNT",
251 { "OPERAND_TYPE_CONTROL",
253 { "OPERAND_TYPE_TEST",
255 { "OPERAND_TYPE_DEBUG",
257 { "OPERAND_TYPE_FLOATREG",
259 { "OPERAND_TYPE_FLOATACC",
261 { "OPERAND_TYPE_SREG2",
263 { "OPERAND_TYPE_SREG3",
265 { "OPERAND_TYPE_ACC",
267 { "OPERAND_TYPE_JUMPABSOLUTE",
269 { "OPERAND_TYPE_REGMMX",
271 { "OPERAND_TYPE_REGXMM",
273 { "OPERAND_TYPE_REGYMM",
275 { "OPERAND_TYPE_ESSEG",
277 { "OPERAND_TYPE_ACC32",
279 { "OPERAND_TYPE_ACC64",
281 { "OPERAND_TYPE_INOUTPORTREG",
283 { "OPERAND_TYPE_REG16_INOUTPORTREG",
284 "Reg16|InOutPortReg" },
285 { "OPERAND_TYPE_DISP16_32",
287 { "OPERAND_TYPE_ANYDISP",
288 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
289 { "OPERAND_TYPE_IMM16_32",
291 { "OPERAND_TYPE_IMM16_32S",
293 { "OPERAND_TYPE_IMM16_32_32S",
294 "Imm16|Imm32|Imm32S" },
295 { "OPERAND_TYPE_IMM32_32S_DISP32",
296 "Imm32|Imm32S|Disp32" },
297 { "OPERAND_TYPE_IMM64_DISP64",
299 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
300 "Imm32|Imm32S|Imm64|Disp32" },
301 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
302 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
303 { "OPERAND_TYPE_VEC_IMM4",
307 typedef struct bitfield
314 #define BITFIELD(n) { n, 0, #n }
316 static bitfield cpu_flags
[] =
324 BITFIELD (CpuClflush
),
326 BITFIELD (CpuSYSCALL
),
331 BITFIELD (CpuFISTTP
),
337 BITFIELD (CpuSSE4_1
),
338 BITFIELD (CpuSSE4_2
),
345 BITFIELD (Cpu3dnowA
),
346 BITFIELD (CpuPadLock
),
352 BITFIELD (CpuXsaveopt
),
354 BITFIELD (CpuPCLMUL
),
365 BITFIELD (CpuRdtscp
),
366 BITFIELD (CpuFSGSBase
),
373 BITFIELD (CpuINVPCID
),
374 BITFIELD (CpuVMFUNC
),
375 BITFIELD (CpuRDSEED
),
377 BITFIELD (CpuPRFCHW
),
381 BITFIELD (CpuUnused
),
385 static bitfield opcode_modifiers
[] =
391 BITFIELD (ShortForm
),
393 BITFIELD (JumpDword
),
395 BITFIELD (JumpInterSegment
),
402 BITFIELD (CheckRegSize
),
403 BITFIELD (IgnoreSize
),
404 BITFIELD (DefaultSize
),
413 BITFIELD (IsLockable
),
414 BITFIELD (RegKludge
),
415 BITFIELD (FirstXmm0
),
416 BITFIELD (Implicit1stXmm0
),
417 BITFIELD (RepPrefixOk
),
418 BITFIELD (HLEPrefixOk
),
421 BITFIELD (AddrPrefixOp0
),
430 BITFIELD (VexOpcode
),
431 BITFIELD (VexSources
),
432 BITFIELD (VexImmExt
),
437 BITFIELD (ATTMnemonic
),
438 BITFIELD (ATTSyntax
),
439 BITFIELD (IntelSyntax
),
442 static bitfield operand_types
[] =
459 BITFIELD (BaseIndex
),
465 BITFIELD (InOutPortReg
),
466 BITFIELD (ShiftCount
),
474 BITFIELD (JumpAbsolute
),
486 BITFIELD (Unspecified
),
494 static const char *filename
;
497 compare (const void *x
, const void *y
)
499 const bitfield
*xp
= (const bitfield
*) x
;
500 const bitfield
*yp
= (const bitfield
*) y
;
501 return xp
->position
- yp
->position
;
505 fail (const char *message
, ...)
509 va_start (args
, message
);
510 fprintf (stderr
, _("%s: Error: "), program_name
);
511 vfprintf (stderr
, message
, args
);
517 process_copyright (FILE *fp
)
519 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
520 /* Copyright 2007, 2008, 2009, 2010, 2011\n\
521 Free Software Foundation, Inc.\n\
523 This file is part of the GNU opcodes library.\n\
525 This library is free software; you can redistribute it and/or modify\n\
526 it under the terms of the GNU General Public License as published by\n\
527 the Free Software Foundation; either version 3, or (at your option)\n\
528 any later version.\n\
530 It is distributed in the hope that it will be useful, but WITHOUT\n\
531 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
532 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
533 License for more details.\n\
535 You should have received a copy of the GNU General Public License\n\
536 along with this program; if not, write to the Free Software\n\
537 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
538 MA 02110-1301, USA. */\n");
541 /* Remove leading white spaces. */
544 remove_leading_whitespaces (char *str
)
546 while (ISSPACE (*str
))
551 /* Remove trailing white spaces. */
554 remove_trailing_whitespaces (char *str
)
556 size_t last
= strlen (str
);
564 if (ISSPACE (str
[last
]))
572 /* Find next field separated by SEP and terminate it. Return a
573 pointer to the one after it. */
576 next_field (char *str
, char sep
, char **next
, char *last
)
580 p
= remove_leading_whitespaces (str
);
581 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
584 remove_trailing_whitespaces (p
);
595 set_bitfield (const char *f
, bitfield
*array
, int value
,
596 unsigned int size
, int lineno
)
600 if (strcmp (f
, "CpuFP") == 0)
602 set_bitfield("Cpu387", array
, value
, size
, lineno
);
603 set_bitfield("Cpu287", array
, value
, size
, lineno
);
606 else if (strcmp (f
, "Mmword") == 0)
608 else if (strcmp (f
, "Oword") == 0)
611 for (i
= 0; i
< size
; i
++)
612 if (strcasecmp (array
[i
].name
, f
) == 0)
614 array
[i
].value
= value
;
620 const char *v
= strchr (f
, '=');
627 for (i
= 0; i
< size
; i
++)
628 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
630 value
= strtol (v
+ 1, &end
, 0);
633 array
[i
].value
= value
;
642 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
644 fail (_("Unknown bitfield: %s\n"), f
);
648 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
649 int macro
, const char *comma
, const char *indent
)
653 fprintf (table
, "%s{ { ", indent
);
655 for (i
= 0; i
< size
- 1; i
++)
657 fprintf (table
, "%d, ", flags
[i
].value
);
658 if (((i
+ 1) % 20) == 0)
660 /* We need \\ for macro. */
662 fprintf (table
, " \\\n %s", indent
);
664 fprintf (table
, "\n %s", indent
);
668 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
672 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
673 const char *comma
, const char *indent
,
676 char *str
, *next
, *last
;
678 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
680 /* Copy the default cpu flags. */
681 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
683 if (strcasecmp (flag
, "unknown") == 0)
685 /* We turn on everything except for cpu64 in case of
686 CPU_UNKNOWN_FLAGS. */
687 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
688 if (flags
[i
].position
!= Cpu64
)
691 else if (flag
[0] == '~')
693 last
= flag
+ strlen (flag
);
700 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename
,
707 /* First we turn on everything except for cpu64. */
708 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
709 if (flags
[i
].position
!= Cpu64
)
712 /* Turn off selective bits. */
713 for (; next
&& next
< last
; )
715 str
= next_field (next
, '|', &next
, last
);
717 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
720 else if (strcmp (flag
, "0"))
722 /* Turn on selective bits. */
723 last
= flag
+ strlen (flag
);
724 for (next
= flag
; next
&& next
< last
; )
726 str
= next_field (next
, '|', &next
, last
);
728 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
732 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
737 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
741 fprintf (table
, " { ");
743 for (i
= 0; i
< size
- 1; i
++)
745 fprintf (table
, "%d, ", modifier
[i
].value
);
746 if (((i
+ 1) % 20) == 0)
747 fprintf (table
, "\n ");
750 fprintf (table
, "%d },\n", modifier
[i
].value
);
754 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
756 char *str
, *next
, *last
;
757 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
759 /* Copy the default opcode modifier. */
760 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
762 if (strcmp (mod
, "0"))
764 last
= mod
+ strlen (mod
);
765 for (next
= mod
; next
&& next
< last
; )
767 str
= next_field (next
, '|', &next
, last
);
769 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
773 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
777 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
778 int macro
, const char *indent
)
782 fprintf (table
, "{ { ");
784 for (i
= 0; i
< size
- 1; i
++)
786 fprintf (table
, "%d, ", types
[i
].value
);
787 if (((i
+ 1) % 20) == 0)
789 /* We need \\ for macro. */
791 fprintf (table
, "\\\n%s", indent
);
793 fprintf (table
, "\n%s", indent
);
797 fprintf (table
, "%d } }", types
[i
].value
);
801 process_i386_operand_type (FILE *table
, char *op
, int macro
,
802 const char *indent
, int lineno
)
804 char *str
, *next
, *last
;
805 bitfield types
[ARRAY_SIZE (operand_types
)];
807 /* Copy the default operand type. */
808 memcpy (types
, operand_types
, sizeof (types
));
810 if (strcmp (op
, "0"))
812 last
= op
+ strlen (op
);
813 for (next
= op
; next
&& next
< last
; )
815 str
= next_field (next
, '|', &next
, last
);
817 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
820 output_operand_type (table
, types
, ARRAY_SIZE (types
), macro
,
825 output_i386_opcode (FILE *table
, const char *name
, char *str
,
826 char *last
, int lineno
)
829 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
830 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
832 /* Find number of operands. */
833 operands
= next_field (str
, ',', &str
, last
);
835 /* Find base_opcode. */
836 base_opcode
= next_field (str
, ',', &str
, last
);
838 /* Find extension_opcode. */
839 extension_opcode
= next_field (str
, ',', &str
, last
);
841 /* Find opcode_length. */
842 opcode_length
= next_field (str
, ',', &str
, last
);
844 /* Find cpu_flags. */
845 cpu_flags
= next_field (str
, ',', &str
, last
);
847 /* Find opcode_modifier. */
848 opcode_modifier
= next_field (str
, ',', &str
, last
);
850 /* Remove the first {. */
851 str
= remove_leading_whitespaces (str
);
854 str
= remove_leading_whitespaces (str
+ 1);
858 /* There are at least "X}". */
862 /* Remove trailing white spaces and }. */
866 if (ISSPACE (str
[i
]) || str
[i
] == '}')
875 /* Find operand_types. */
876 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
880 operand_types
[i
] = NULL
;
884 operand_types
[i
] = next_field (str
, ',', &str
, last
);
885 if (*operand_types
[i
] == '0')
888 operand_types
[i
] = NULL
;
893 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
894 name
, operands
, base_opcode
, extension_opcode
,
897 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
899 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
901 fprintf (table
, " { ");
903 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
905 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
908 process_i386_operand_type (table
, "0", 0, "\t ", lineno
);
913 fprintf (table
, ",\n ");
915 process_i386_operand_type (table
, operand_types
[i
], 0,
918 fprintf (table
, " } },\n");
921 struct opcode_hash_entry
923 struct opcode_hash_entry
*next
;
929 /* Calculate the hash value of an opcode hash entry P. */
932 opcode_hash_hash (const void *p
)
934 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
935 return htab_hash_string (entry
->name
);
938 /* Compare a string Q against an opcode hash entry P. */
941 opcode_hash_eq (const void *p
, const void *q
)
943 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
944 const char *name
= (const char *) q
;
945 return strcmp (name
, entry
->name
) == 0;
949 process_i386_opcodes (FILE *table
)
954 char *str
, *p
, *last
, *name
;
955 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
956 htab_t opcode_hash_table
;
957 struct opcode_hash_entry
**opcode_array
;
958 unsigned int opcode_array_size
= 1024;
961 filename
= "i386-opc.tbl";
962 fp
= fopen (filename
, "r");
965 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
969 opcode_array
= (struct opcode_hash_entry
**)
970 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
972 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
973 opcode_hash_eq
, NULL
,
976 fprintf (table
, "\n/* i386 opcode table. */\n\n");
977 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
979 /* Put everything on opcode array. */
982 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
987 p
= remove_leading_whitespaces (buf
);
990 str
= strstr (p
, "//");
994 /* Remove trailing white spaces. */
995 remove_trailing_whitespaces (p
);
1000 /* Ignore comments. */
1008 last
= p
+ strlen (p
);
1011 name
= next_field (p
, ',', &str
, last
);
1013 /* Get the slot in hash table. */
1014 hash_slot
= (struct opcode_hash_entry
**)
1015 htab_find_slot_with_hash (opcode_hash_table
, name
,
1016 htab_hash_string (name
),
1019 if (*hash_slot
== NULL
)
1021 /* It is the new one. Put it on opcode array. */
1022 if (i
>= opcode_array_size
)
1024 /* Grow the opcode array when needed. */
1025 opcode_array_size
+= 1024;
1026 opcode_array
= (struct opcode_hash_entry
**)
1027 xrealloc (opcode_array
,
1028 sizeof (*opcode_array
) * opcode_array_size
);
1031 opcode_array
[i
] = (struct opcode_hash_entry
*)
1032 xmalloc (sizeof (struct opcode_hash_entry
));
1033 opcode_array
[i
]->next
= NULL
;
1034 opcode_array
[i
]->name
= xstrdup (name
);
1035 opcode_array
[i
]->opcode
= xstrdup (str
);
1036 opcode_array
[i
]->lineno
= lineno
;
1037 *hash_slot
= opcode_array
[i
];
1042 /* Append it to the existing one. */
1044 while ((*entry
) != NULL
)
1045 entry
= &(*entry
)->next
;
1046 *entry
= (struct opcode_hash_entry
*)
1047 xmalloc (sizeof (struct opcode_hash_entry
));
1048 (*entry
)->next
= NULL
;
1049 (*entry
)->name
= (*hash_slot
)->name
;
1050 (*entry
)->opcode
= xstrdup (str
);
1051 (*entry
)->lineno
= lineno
;
1055 /* Process opcode array. */
1056 for (j
= 0; j
< i
; j
++)
1058 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1062 lineno
= next
->lineno
;
1063 last
= str
+ strlen (str
);
1064 output_i386_opcode (table
, name
, str
, last
, lineno
);
1070 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1072 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1074 process_i386_opcode_modifier (table
, "0", -1);
1076 fprintf (table
, " { ");
1077 process_i386_operand_type (table
, "0", 0, "\t ", -1);
1078 fprintf (table
, " } }\n");
1080 fprintf (table
, "};\n");
1084 process_i386_registers (FILE *table
)
1088 char *str
, *p
, *last
;
1089 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1090 char *dw2_32_num
, *dw2_64_num
;
1093 filename
= "i386-reg.tbl";
1094 fp
= fopen (filename
, "r");
1096 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1099 fprintf (table
, "\n/* i386 register table. */\n\n");
1100 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1104 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1109 p
= remove_leading_whitespaces (buf
);
1111 /* Skip comments. */
1112 str
= strstr (p
, "//");
1116 /* Remove trailing white spaces. */
1117 remove_trailing_whitespaces (p
);
1122 fprintf (table
, "%s\n", p
);
1130 last
= p
+ strlen (p
);
1132 /* Find reg_name. */
1133 reg_name
= next_field (p
, ',', &str
, last
);
1135 /* Find reg_type. */
1136 reg_type
= next_field (str
, ',', &str
, last
);
1138 /* Find reg_flags. */
1139 reg_flags
= next_field (str
, ',', &str
, last
);
1142 reg_num
= next_field (str
, ',', &str
, last
);
1144 fprintf (table
, " { \"%s\",\n ", reg_name
);
1146 process_i386_operand_type (table
, reg_type
, 0, "\t", lineno
);
1148 /* Find 32-bit Dwarf2 register number. */
1149 dw2_32_num
= next_field (str
, ',', &str
, last
);
1151 /* Find 64-bit Dwarf2 register number. */
1152 dw2_64_num
= next_field (str
, ',', &str
, last
);
1154 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1155 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1160 fprintf (table
, "};\n");
1162 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1166 process_i386_initializers (void)
1169 FILE *fp
= fopen ("i386-init.h", "w");
1173 fail (_("can't create i386-init.h, errno = %s\n"),
1176 process_copyright (fp
);
1178 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1180 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1181 init
= xstrdup (cpu_flag_init
[i
].init
);
1182 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1186 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1188 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1189 init
= xstrdup (operand_type_init
[i
].init
);
1190 process_i386_operand_type (fp
, init
, 1, " ", -1);
1198 /* Program options. */
1199 #define OPTION_SRCDIR 200
1201 struct option long_options
[] =
1203 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1204 {"debug", no_argument
, NULL
, 'd'},
1205 {"version", no_argument
, NULL
, 'V'},
1206 {"help", no_argument
, NULL
, 'h'},
1207 {0, no_argument
, NULL
, 0}
1211 print_version (void)
1213 printf ("%s: version 1.0\n", program_name
);
1218 usage (FILE * stream
, int status
)
1220 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1226 main (int argc
, char **argv
)
1228 extern int chdir (char *);
1229 char *srcdir
= NULL
;
1233 program_name
= *argv
;
1234 xmalloc_set_program_name (program_name
);
1236 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1261 if (chdir (srcdir
) != 0)
1262 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1263 srcdir
, xstrerror (errno
));
1265 /* Check the unused bitfield in i386_cpu_flags. */
1267 c
= CpuNumOfBits
- CpuMax
- 1;
1269 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1272 /* Check the unused bitfield in i386_operand_type. */
1274 c
= OTNumOfBits
- OTMax
- 1;
1276 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1279 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1282 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1283 sizeof (opcode_modifiers
[0]), compare
);
1285 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1286 sizeof (operand_types
[0]), compare
);
1288 table
= fopen ("i386-tbl.h", "w");
1290 fail (_("can't create i386-tbl.h, errno = %s\n"),
1293 process_copyright (table
);
1295 process_i386_opcodes (table
);
1296 process_i386_registers (table
);
1297 process_i386_initializers ();