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|CpuFSGSBase" },
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",
215 static initializer operand_type_init
[] =
217 { "OPERAND_TYPE_NONE",
219 { "OPERAND_TYPE_REG8",
221 { "OPERAND_TYPE_REG16",
223 { "OPERAND_TYPE_REG32",
225 { "OPERAND_TYPE_REG64",
227 { "OPERAND_TYPE_IMM1",
229 { "OPERAND_TYPE_IMM8",
231 { "OPERAND_TYPE_IMM8S",
233 { "OPERAND_TYPE_IMM16",
235 { "OPERAND_TYPE_IMM32",
237 { "OPERAND_TYPE_IMM32S",
239 { "OPERAND_TYPE_IMM64",
241 { "OPERAND_TYPE_BASEINDEX",
243 { "OPERAND_TYPE_DISP8",
245 { "OPERAND_TYPE_DISP16",
247 { "OPERAND_TYPE_DISP32",
249 { "OPERAND_TYPE_DISP32S",
251 { "OPERAND_TYPE_DISP64",
253 { "OPERAND_TYPE_INOUTPORTREG",
255 { "OPERAND_TYPE_SHIFTCOUNT",
257 { "OPERAND_TYPE_CONTROL",
259 { "OPERAND_TYPE_TEST",
261 { "OPERAND_TYPE_DEBUG",
263 { "OPERAND_TYPE_FLOATREG",
265 { "OPERAND_TYPE_FLOATACC",
267 { "OPERAND_TYPE_SREG2",
269 { "OPERAND_TYPE_SREG3",
271 { "OPERAND_TYPE_ACC",
273 { "OPERAND_TYPE_JUMPABSOLUTE",
275 { "OPERAND_TYPE_REGMMX",
277 { "OPERAND_TYPE_REGXMM",
279 { "OPERAND_TYPE_REGYMM",
281 { "OPERAND_TYPE_ESSEG",
283 { "OPERAND_TYPE_ACC32",
285 { "OPERAND_TYPE_ACC64",
287 { "OPERAND_TYPE_INOUTPORTREG",
289 { "OPERAND_TYPE_REG16_INOUTPORTREG",
290 "Reg16|InOutPortReg" },
291 { "OPERAND_TYPE_DISP16_32",
293 { "OPERAND_TYPE_ANYDISP",
294 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
295 { "OPERAND_TYPE_IMM16_32",
297 { "OPERAND_TYPE_IMM16_32S",
299 { "OPERAND_TYPE_IMM16_32_32S",
300 "Imm16|Imm32|Imm32S" },
301 { "OPERAND_TYPE_IMM32_64",
303 { "OPERAND_TYPE_IMM32_32S_DISP32",
304 "Imm32|Imm32S|Disp32" },
305 { "OPERAND_TYPE_IMM64_DISP64",
307 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
308 "Imm32|Imm32S|Imm64|Disp32" },
309 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
310 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
311 { "OPERAND_TYPE_VEC_IMM4",
313 { "OPERAND_TYPE_REGBND",
317 typedef struct bitfield
324 #define BITFIELD(n) { n, 0, #n }
326 static bitfield cpu_flags
[] =
334 BITFIELD (CpuClflush
),
336 BITFIELD (CpuSYSCALL
),
341 BITFIELD (CpuFISTTP
),
347 BITFIELD (CpuSSE4_1
),
348 BITFIELD (CpuSSE4_2
),
355 BITFIELD (Cpu3dnowA
),
356 BITFIELD (CpuPadLock
),
362 BITFIELD (CpuXsaveopt
),
364 BITFIELD (CpuPCLMUL
),
375 BITFIELD (CpuRdtscp
),
376 BITFIELD (CpuFSGSBase
),
383 BITFIELD (CpuINVPCID
),
384 BITFIELD (CpuVMFUNC
),
385 BITFIELD (CpuRDSEED
),
387 BITFIELD (CpuPRFCHW
),
393 BITFIELD (CpuUnused
),
397 static bitfield opcode_modifiers
[] =
403 BITFIELD (ShortForm
),
405 BITFIELD (JumpDword
),
407 BITFIELD (JumpInterSegment
),
414 BITFIELD (CheckRegSize
),
415 BITFIELD (IgnoreSize
),
416 BITFIELD (DefaultSize
),
425 BITFIELD (BNDPrefixOk
),
426 BITFIELD (IsLockable
),
427 BITFIELD (RegKludge
),
428 BITFIELD (FirstXmm0
),
429 BITFIELD (Implicit1stXmm0
),
430 BITFIELD (RepPrefixOk
),
431 BITFIELD (HLEPrefixOk
),
434 BITFIELD (AddrPrefixOp0
),
443 BITFIELD (VexOpcode
),
444 BITFIELD (VexSources
),
445 BITFIELD (VexImmExt
),
450 BITFIELD (ATTMnemonic
),
451 BITFIELD (ATTSyntax
),
452 BITFIELD (IntelSyntax
),
455 static bitfield operand_types
[] =
472 BITFIELD (BaseIndex
),
478 BITFIELD (InOutPortReg
),
479 BITFIELD (ShiftCount
),
487 BITFIELD (JumpAbsolute
),
499 BITFIELD (Unspecified
),
508 static const char *filename
;
511 compare (const void *x
, const void *y
)
513 const bitfield
*xp
= (const bitfield
*) x
;
514 const bitfield
*yp
= (const bitfield
*) y
;
515 return xp
->position
- yp
->position
;
519 fail (const char *message
, ...)
523 va_start (args
, message
);
524 fprintf (stderr
, _("%s: Error: "), program_name
);
525 vfprintf (stderr
, message
, args
);
531 process_copyright (FILE *fp
)
533 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
534 /* Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013\n\
535 Free Software Foundation, Inc.\n\
537 This file is part of the GNU opcodes library.\n\
539 This library is free software; you can redistribute it and/or modify\n\
540 it under the terms of the GNU General Public License as published by\n\
541 the Free Software Foundation; either version 3, or (at your option)\n\
542 any later version.\n\
544 It is distributed in the hope that it will be useful, but WITHOUT\n\
545 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
546 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
547 License for more details.\n\
549 You should have received a copy of the GNU General Public License\n\
550 along with this program; if not, write to the Free Software\n\
551 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
552 MA 02110-1301, USA. */\n");
555 /* Remove leading white spaces. */
558 remove_leading_whitespaces (char *str
)
560 while (ISSPACE (*str
))
565 /* Remove trailing white spaces. */
568 remove_trailing_whitespaces (char *str
)
570 size_t last
= strlen (str
);
578 if (ISSPACE (str
[last
]))
586 /* Find next field separated by SEP and terminate it. Return a
587 pointer to the one after it. */
590 next_field (char *str
, char sep
, char **next
, char *last
)
594 p
= remove_leading_whitespaces (str
);
595 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
598 remove_trailing_whitespaces (p
);
609 set_bitfield (const char *f
, bitfield
*array
, int value
,
610 unsigned int size
, int lineno
)
614 if (strcmp (f
, "CpuFP") == 0)
616 set_bitfield("Cpu387", array
, value
, size
, lineno
);
617 set_bitfield("Cpu287", array
, value
, size
, lineno
);
620 else if (strcmp (f
, "Mmword") == 0)
622 else if (strcmp (f
, "Oword") == 0)
625 for (i
= 0; i
< size
; i
++)
626 if (strcasecmp (array
[i
].name
, f
) == 0)
628 array
[i
].value
= value
;
634 const char *v
= strchr (f
, '=');
641 for (i
= 0; i
< size
; i
++)
642 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
644 value
= strtol (v
+ 1, &end
, 0);
647 array
[i
].value
= value
;
656 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
658 fail (_("Unknown bitfield: %s\n"), f
);
662 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
663 int macro
, const char *comma
, const char *indent
)
667 fprintf (table
, "%s{ { ", indent
);
669 for (i
= 0; i
< size
- 1; i
++)
671 fprintf (table
, "%d, ", flags
[i
].value
);
672 if (((i
+ 1) % 20) == 0)
674 /* We need \\ for macro. */
676 fprintf (table
, " \\\n %s", indent
);
678 fprintf (table
, "\n %s", indent
);
682 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
686 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
687 const char *comma
, const char *indent
,
690 char *str
, *next
, *last
;
692 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
694 /* Copy the default cpu flags. */
695 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
697 if (strcasecmp (flag
, "unknown") == 0)
699 /* We turn on everything except for cpu64 in case of
700 CPU_UNKNOWN_FLAGS. */
701 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
702 if (flags
[i
].position
!= Cpu64
)
705 else if (flag
[0] == '~')
707 last
= flag
+ strlen (flag
);
714 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename
,
721 /* First we turn on everything except for cpu64. */
722 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
723 if (flags
[i
].position
!= Cpu64
)
726 /* Turn off selective bits. */
727 for (; next
&& next
< last
; )
729 str
= next_field (next
, '|', &next
, last
);
731 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
734 else if (strcmp (flag
, "0"))
736 /* Turn on selective bits. */
737 last
= flag
+ strlen (flag
);
738 for (next
= flag
; next
&& next
< last
; )
740 str
= next_field (next
, '|', &next
, last
);
742 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
746 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
751 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
755 fprintf (table
, " { ");
757 for (i
= 0; i
< size
- 1; i
++)
759 fprintf (table
, "%d, ", modifier
[i
].value
);
760 if (((i
+ 1) % 20) == 0)
761 fprintf (table
, "\n ");
764 fprintf (table
, "%d },\n", modifier
[i
].value
);
768 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
770 char *str
, *next
, *last
;
771 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
773 /* Copy the default opcode modifier. */
774 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
776 if (strcmp (mod
, "0"))
778 last
= mod
+ strlen (mod
);
779 for (next
= mod
; next
&& next
< last
; )
781 str
= next_field (next
, '|', &next
, last
);
783 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
787 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
791 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
792 int macro
, const char *indent
)
796 fprintf (table
, "{ { ");
798 for (i
= 0; i
< size
- 1; i
++)
800 fprintf (table
, "%d, ", types
[i
].value
);
801 if (((i
+ 1) % 20) == 0)
803 /* We need \\ for macro. */
805 fprintf (table
, "\\\n%s", indent
);
807 fprintf (table
, "\n%s", indent
);
811 fprintf (table
, "%d } }", types
[i
].value
);
815 process_i386_operand_type (FILE *table
, char *op
, int macro
,
816 const char *indent
, int lineno
)
818 char *str
, *next
, *last
;
819 bitfield types
[ARRAY_SIZE (operand_types
)];
821 /* Copy the default operand type. */
822 memcpy (types
, operand_types
, sizeof (types
));
824 if (strcmp (op
, "0"))
826 last
= op
+ strlen (op
);
827 for (next
= op
; next
&& next
< last
; )
829 str
= next_field (next
, '|', &next
, last
);
831 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
834 output_operand_type (table
, types
, ARRAY_SIZE (types
), macro
,
839 output_i386_opcode (FILE *table
, const char *name
, char *str
,
840 char *last
, int lineno
)
843 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
844 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
846 /* Find number of operands. */
847 operands
= next_field (str
, ',', &str
, last
);
849 /* Find base_opcode. */
850 base_opcode
= next_field (str
, ',', &str
, last
);
852 /* Find extension_opcode. */
853 extension_opcode
= next_field (str
, ',', &str
, last
);
855 /* Find opcode_length. */
856 opcode_length
= next_field (str
, ',', &str
, last
);
858 /* Find cpu_flags. */
859 cpu_flags
= next_field (str
, ',', &str
, last
);
861 /* Find opcode_modifier. */
862 opcode_modifier
= next_field (str
, ',', &str
, last
);
864 /* Remove the first {. */
865 str
= remove_leading_whitespaces (str
);
868 str
= remove_leading_whitespaces (str
+ 1);
872 /* There are at least "X}". */
876 /* Remove trailing white spaces and }. */
880 if (ISSPACE (str
[i
]) || str
[i
] == '}')
889 /* Find operand_types. */
890 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
894 operand_types
[i
] = NULL
;
898 operand_types
[i
] = next_field (str
, ',', &str
, last
);
899 if (*operand_types
[i
] == '0')
902 operand_types
[i
] = NULL
;
907 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
908 name
, operands
, base_opcode
, extension_opcode
,
911 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
913 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
915 fprintf (table
, " { ");
917 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
919 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
922 process_i386_operand_type (table
, "0", 0, "\t ", lineno
);
927 fprintf (table
, ",\n ");
929 process_i386_operand_type (table
, operand_types
[i
], 0,
932 fprintf (table
, " } },\n");
935 struct opcode_hash_entry
937 struct opcode_hash_entry
*next
;
943 /* Calculate the hash value of an opcode hash entry P. */
946 opcode_hash_hash (const void *p
)
948 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
949 return htab_hash_string (entry
->name
);
952 /* Compare a string Q against an opcode hash entry P. */
955 opcode_hash_eq (const void *p
, const void *q
)
957 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
958 const char *name
= (const char *) q
;
959 return strcmp (name
, entry
->name
) == 0;
963 process_i386_opcodes (FILE *table
)
968 char *str
, *p
, *last
, *name
;
969 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
970 htab_t opcode_hash_table
;
971 struct opcode_hash_entry
**opcode_array
;
972 unsigned int opcode_array_size
= 1024;
975 filename
= "i386-opc.tbl";
976 fp
= fopen (filename
, "r");
979 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
983 opcode_array
= (struct opcode_hash_entry
**)
984 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
986 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
987 opcode_hash_eq
, NULL
,
990 fprintf (table
, "\n/* i386 opcode table. */\n\n");
991 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
993 /* Put everything on opcode array. */
996 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1001 p
= remove_leading_whitespaces (buf
);
1003 /* Skip comments. */
1004 str
= strstr (p
, "//");
1008 /* Remove trailing white spaces. */
1009 remove_trailing_whitespaces (p
);
1014 /* Ignore comments. */
1022 last
= p
+ strlen (p
);
1025 name
= next_field (p
, ',', &str
, last
);
1027 /* Get the slot in hash table. */
1028 hash_slot
= (struct opcode_hash_entry
**)
1029 htab_find_slot_with_hash (opcode_hash_table
, name
,
1030 htab_hash_string (name
),
1033 if (*hash_slot
== NULL
)
1035 /* It is the new one. Put it on opcode array. */
1036 if (i
>= opcode_array_size
)
1038 /* Grow the opcode array when needed. */
1039 opcode_array_size
+= 1024;
1040 opcode_array
= (struct opcode_hash_entry
**)
1041 xrealloc (opcode_array
,
1042 sizeof (*opcode_array
) * opcode_array_size
);
1045 opcode_array
[i
] = (struct opcode_hash_entry
*)
1046 xmalloc (sizeof (struct opcode_hash_entry
));
1047 opcode_array
[i
]->next
= NULL
;
1048 opcode_array
[i
]->name
= xstrdup (name
);
1049 opcode_array
[i
]->opcode
= xstrdup (str
);
1050 opcode_array
[i
]->lineno
= lineno
;
1051 *hash_slot
= opcode_array
[i
];
1056 /* Append it to the existing one. */
1058 while ((*entry
) != NULL
)
1059 entry
= &(*entry
)->next
;
1060 *entry
= (struct opcode_hash_entry
*)
1061 xmalloc (sizeof (struct opcode_hash_entry
));
1062 (*entry
)->next
= NULL
;
1063 (*entry
)->name
= (*hash_slot
)->name
;
1064 (*entry
)->opcode
= xstrdup (str
);
1065 (*entry
)->lineno
= lineno
;
1069 /* Process opcode array. */
1070 for (j
= 0; j
< i
; j
++)
1072 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1076 lineno
= next
->lineno
;
1077 last
= str
+ strlen (str
);
1078 output_i386_opcode (table
, name
, str
, last
, lineno
);
1084 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1086 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1088 process_i386_opcode_modifier (table
, "0", -1);
1090 fprintf (table
, " { ");
1091 process_i386_operand_type (table
, "0", 0, "\t ", -1);
1092 fprintf (table
, " } }\n");
1094 fprintf (table
, "};\n");
1098 process_i386_registers (FILE *table
)
1102 char *str
, *p
, *last
;
1103 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1104 char *dw2_32_num
, *dw2_64_num
;
1107 filename
= "i386-reg.tbl";
1108 fp
= fopen (filename
, "r");
1110 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1113 fprintf (table
, "\n/* i386 register table. */\n\n");
1114 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1118 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1123 p
= remove_leading_whitespaces (buf
);
1125 /* Skip comments. */
1126 str
= strstr (p
, "//");
1130 /* Remove trailing white spaces. */
1131 remove_trailing_whitespaces (p
);
1136 fprintf (table
, "%s\n", p
);
1144 last
= p
+ strlen (p
);
1146 /* Find reg_name. */
1147 reg_name
= next_field (p
, ',', &str
, last
);
1149 /* Find reg_type. */
1150 reg_type
= next_field (str
, ',', &str
, last
);
1152 /* Find reg_flags. */
1153 reg_flags
= next_field (str
, ',', &str
, last
);
1156 reg_num
= next_field (str
, ',', &str
, last
);
1158 fprintf (table
, " { \"%s\",\n ", reg_name
);
1160 process_i386_operand_type (table
, reg_type
, 0, "\t", lineno
);
1162 /* Find 32-bit Dwarf2 register number. */
1163 dw2_32_num
= next_field (str
, ',', &str
, last
);
1165 /* Find 64-bit Dwarf2 register number. */
1166 dw2_64_num
= next_field (str
, ',', &str
, last
);
1168 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1169 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1174 fprintf (table
, "};\n");
1176 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1180 process_i386_initializers (void)
1183 FILE *fp
= fopen ("i386-init.h", "w");
1187 fail (_("can't create i386-init.h, errno = %s\n"),
1190 process_copyright (fp
);
1192 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1194 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1195 init
= xstrdup (cpu_flag_init
[i
].init
);
1196 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1200 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1202 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1203 init
= xstrdup (operand_type_init
[i
].init
);
1204 process_i386_operand_type (fp
, init
, 1, " ", -1);
1212 /* Program options. */
1213 #define OPTION_SRCDIR 200
1215 struct option long_options
[] =
1217 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1218 {"debug", no_argument
, NULL
, 'd'},
1219 {"version", no_argument
, NULL
, 'V'},
1220 {"help", no_argument
, NULL
, 'h'},
1221 {0, no_argument
, NULL
, 0}
1225 print_version (void)
1227 printf ("%s: version 1.0\n", program_name
);
1232 usage (FILE * stream
, int status
)
1234 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1240 main (int argc
, char **argv
)
1242 extern int chdir (char *);
1243 char *srcdir
= NULL
;
1247 program_name
= *argv
;
1248 xmalloc_set_program_name (program_name
);
1250 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1275 if (chdir (srcdir
) != 0)
1276 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1277 srcdir
, xstrerror (errno
));
1279 /* Check the unused bitfield in i386_cpu_flags. */
1281 c
= CpuNumOfBits
- CpuMax
- 1;
1283 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1286 /* Check the unused bitfield in i386_operand_type. */
1288 c
= OTNumOfBits
- OTMax
- 1;
1290 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1293 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1296 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1297 sizeof (opcode_modifiers
[0]), compare
);
1299 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1300 sizeof (operand_types
[0]), compare
);
1302 table
= fopen ("i386-tbl.h", "w");
1304 fail (_("can't create i386-tbl.h, errno = %s\n"),
1307 process_copyright (table
);
1309 process_i386_opcodes (table
);
1310 process_i386_registers (table
);
1311 process_i386_initializers ();