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" },
76 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
78 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuLM" },
80 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuRdtscp|CpuLM" },
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" },
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" },
96 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4a|CpuABM|CpuLM|CpuPRFCHW" },
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" },
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" },
155 { "CPU_RDTSCP_FLAGS",
159 { "CPU_FSGSBASE_FLAGS",
173 { "CPU_INVPCID_FLAGS",
175 { "CPU_VMFUNC_FLAGS",
179 { "CPU_3DNOWA_FLAGS",
180 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
181 { "CPU_PADLOCK_FLAGS",
186 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
190 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
192 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2" },
193 { "CPU_ANY_AVX_FLAGS",
201 { "CPU_RDSEED_FLAGS",
203 { "CPU_PRFCHW_FLAGS",
207 static initializer operand_type_init
[] =
209 { "OPERAND_TYPE_NONE",
211 { "OPERAND_TYPE_REG8",
213 { "OPERAND_TYPE_REG16",
215 { "OPERAND_TYPE_REG32",
217 { "OPERAND_TYPE_REG64",
219 { "OPERAND_TYPE_IMM1",
221 { "OPERAND_TYPE_IMM8",
223 { "OPERAND_TYPE_IMM8S",
225 { "OPERAND_TYPE_IMM16",
227 { "OPERAND_TYPE_IMM32",
229 { "OPERAND_TYPE_IMM32S",
231 { "OPERAND_TYPE_IMM64",
233 { "OPERAND_TYPE_BASEINDEX",
235 { "OPERAND_TYPE_DISP8",
237 { "OPERAND_TYPE_DISP16",
239 { "OPERAND_TYPE_DISP32",
241 { "OPERAND_TYPE_DISP32S",
243 { "OPERAND_TYPE_DISP64",
245 { "OPERAND_TYPE_INOUTPORTREG",
247 { "OPERAND_TYPE_SHIFTCOUNT",
249 { "OPERAND_TYPE_CONTROL",
251 { "OPERAND_TYPE_TEST",
253 { "OPERAND_TYPE_DEBUG",
255 { "OPERAND_TYPE_FLOATREG",
257 { "OPERAND_TYPE_FLOATACC",
259 { "OPERAND_TYPE_SREG2",
261 { "OPERAND_TYPE_SREG3",
263 { "OPERAND_TYPE_ACC",
265 { "OPERAND_TYPE_JUMPABSOLUTE",
267 { "OPERAND_TYPE_REGMMX",
269 { "OPERAND_TYPE_REGXMM",
271 { "OPERAND_TYPE_REGYMM",
273 { "OPERAND_TYPE_ESSEG",
275 { "OPERAND_TYPE_ACC32",
277 { "OPERAND_TYPE_ACC64",
279 { "OPERAND_TYPE_INOUTPORTREG",
281 { "OPERAND_TYPE_REG16_INOUTPORTREG",
282 "Reg16|InOutPortReg" },
283 { "OPERAND_TYPE_DISP16_32",
285 { "OPERAND_TYPE_ANYDISP",
286 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
287 { "OPERAND_TYPE_IMM16_32",
289 { "OPERAND_TYPE_IMM16_32S",
291 { "OPERAND_TYPE_IMM16_32_32S",
292 "Imm16|Imm32|Imm32S" },
293 { "OPERAND_TYPE_IMM32_32S_DISP32",
294 "Imm32|Imm32S|Disp32" },
295 { "OPERAND_TYPE_IMM64_DISP64",
297 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
298 "Imm32|Imm32S|Imm64|Disp32" },
299 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
300 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
301 { "OPERAND_TYPE_VEC_IMM4",
305 typedef struct bitfield
312 #define BITFIELD(n) { n, 0, #n }
314 static bitfield cpu_flags
[] =
322 BITFIELD (CpuClflush
),
324 BITFIELD (CpuSYSCALL
),
329 BITFIELD (CpuFISTTP
),
335 BITFIELD (CpuSSE4_1
),
336 BITFIELD (CpuSSE4_2
),
343 BITFIELD (Cpu3dnowA
),
344 BITFIELD (CpuPadLock
),
350 BITFIELD (CpuXsaveopt
),
352 BITFIELD (CpuPCLMUL
),
362 BITFIELD (CpuRdtscp
),
363 BITFIELD (CpuFSGSBase
),
370 BITFIELD (CpuINVPCID
),
371 BITFIELD (CpuVMFUNC
),
372 BITFIELD (CpuRDSEED
),
374 BITFIELD (CpuPRFCHW
),
378 BITFIELD (CpuUnused
),
382 static bitfield opcode_modifiers
[] =
388 BITFIELD (ShortForm
),
390 BITFIELD (JumpDword
),
392 BITFIELD (JumpInterSegment
),
399 BITFIELD (CheckRegSize
),
400 BITFIELD (IgnoreSize
),
401 BITFIELD (DefaultSize
),
410 BITFIELD (IsLockable
),
411 BITFIELD (RegKludge
),
412 BITFIELD (FirstXmm0
),
413 BITFIELD (Implicit1stXmm0
),
414 BITFIELD (RepPrefixOk
),
415 BITFIELD (HLEPrefixOk
),
418 BITFIELD (AddrPrefixOp0
),
427 BITFIELD (VexOpcode
),
428 BITFIELD (VexSources
),
429 BITFIELD (VexImmExt
),
434 BITFIELD (ATTMnemonic
),
435 BITFIELD (ATTSyntax
),
436 BITFIELD (IntelSyntax
),
439 static bitfield operand_types
[] =
456 BITFIELD (BaseIndex
),
462 BITFIELD (InOutPortReg
),
463 BITFIELD (ShiftCount
),
471 BITFIELD (JumpAbsolute
),
483 BITFIELD (Unspecified
),
491 static const char *filename
;
494 compare (const void *x
, const void *y
)
496 const bitfield
*xp
= (const bitfield
*) x
;
497 const bitfield
*yp
= (const bitfield
*) y
;
498 return xp
->position
- yp
->position
;
502 fail (const char *message
, ...)
506 va_start (args
, message
);
507 fprintf (stderr
, _("%s: Error: "), program_name
);
508 vfprintf (stderr
, message
, args
);
514 process_copyright (FILE *fp
)
516 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
517 /* Copyright 2007, 2008, 2009, 2010, 2011\n\
518 Free Software Foundation, Inc.\n\
520 This file is part of the GNU opcodes library.\n\
522 This library is free software; you can redistribute it and/or modify\n\
523 it under the terms of the GNU General Public License as published by\n\
524 the Free Software Foundation; either version 3, or (at your option)\n\
525 any later version.\n\
527 It is distributed in the hope that it will be useful, but WITHOUT\n\
528 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
529 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
530 License for more details.\n\
532 You should have received a copy of the GNU General Public License\n\
533 along with this program; if not, write to the Free Software\n\
534 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
535 MA 02110-1301, USA. */\n");
538 /* Remove leading white spaces. */
541 remove_leading_whitespaces (char *str
)
543 while (ISSPACE (*str
))
548 /* Remove trailing white spaces. */
551 remove_trailing_whitespaces (char *str
)
553 size_t last
= strlen (str
);
561 if (ISSPACE (str
[last
]))
569 /* Find next field separated by SEP and terminate it. Return a
570 pointer to the one after it. */
573 next_field (char *str
, char sep
, char **next
, char *last
)
577 p
= remove_leading_whitespaces (str
);
578 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
581 remove_trailing_whitespaces (p
);
592 set_bitfield (const char *f
, bitfield
*array
, int value
,
593 unsigned int size
, int lineno
)
597 if (strcmp (f
, "CpuFP") == 0)
599 set_bitfield("Cpu387", array
, value
, size
, lineno
);
600 set_bitfield("Cpu287", array
, value
, size
, lineno
);
603 else if (strcmp (f
, "Mmword") == 0)
605 else if (strcmp (f
, "Oword") == 0)
608 for (i
= 0; i
< size
; i
++)
609 if (strcasecmp (array
[i
].name
, f
) == 0)
611 array
[i
].value
= value
;
617 const char *v
= strchr (f
, '=');
624 for (i
= 0; i
< size
; i
++)
625 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
627 value
= strtol (v
+ 1, &end
, 0);
630 array
[i
].value
= value
;
639 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
641 fail (_("Unknown bitfield: %s\n"), f
);
645 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
646 int macro
, const char *comma
, const char *indent
)
650 fprintf (table
, "%s{ { ", indent
);
652 for (i
= 0; i
< size
- 1; i
++)
654 fprintf (table
, "%d, ", flags
[i
].value
);
655 if (((i
+ 1) % 20) == 0)
657 /* We need \\ for macro. */
659 fprintf (table
, " \\\n %s", indent
);
661 fprintf (table
, "\n %s", indent
);
665 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
669 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
670 const char *comma
, const char *indent
,
673 char *str
, *next
, *last
;
675 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
677 /* Copy the default cpu flags. */
678 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
680 if (strcasecmp (flag
, "unknown") == 0)
682 /* We turn on everything except for cpu64 in case of
683 CPU_UNKNOWN_FLAGS. */
684 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
685 if (flags
[i
].position
!= Cpu64
)
688 else if (flag
[0] == '~')
690 last
= flag
+ strlen (flag
);
697 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename
,
704 /* First we turn on everything except for cpu64. */
705 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
706 if (flags
[i
].position
!= Cpu64
)
709 /* Turn off selective bits. */
710 for (; next
&& next
< last
; )
712 str
= next_field (next
, '|', &next
, last
);
714 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
717 else if (strcmp (flag
, "0"))
719 /* Turn on selective bits. */
720 last
= flag
+ strlen (flag
);
721 for (next
= flag
; next
&& next
< last
; )
723 str
= next_field (next
, '|', &next
, last
);
725 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
729 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
734 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
738 fprintf (table
, " { ");
740 for (i
= 0; i
< size
- 1; i
++)
742 fprintf (table
, "%d, ", modifier
[i
].value
);
743 if (((i
+ 1) % 20) == 0)
744 fprintf (table
, "\n ");
747 fprintf (table
, "%d },\n", modifier
[i
].value
);
751 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
753 char *str
, *next
, *last
;
754 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
756 /* Copy the default opcode modifier. */
757 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
759 if (strcmp (mod
, "0"))
761 last
= mod
+ strlen (mod
);
762 for (next
= mod
; next
&& next
< last
; )
764 str
= next_field (next
, '|', &next
, last
);
766 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
770 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
774 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
775 int macro
, const char *indent
)
779 fprintf (table
, "{ { ");
781 for (i
= 0; i
< size
- 1; i
++)
783 fprintf (table
, "%d, ", types
[i
].value
);
784 if (((i
+ 1) % 20) == 0)
786 /* We need \\ for macro. */
788 fprintf (table
, "\\\n%s", indent
);
790 fprintf (table
, "\n%s", indent
);
794 fprintf (table
, "%d } }", types
[i
].value
);
798 process_i386_operand_type (FILE *table
, char *op
, int macro
,
799 const char *indent
, int lineno
)
801 char *str
, *next
, *last
;
802 bitfield types
[ARRAY_SIZE (operand_types
)];
804 /* Copy the default operand type. */
805 memcpy (types
, operand_types
, sizeof (types
));
807 if (strcmp (op
, "0"))
809 last
= op
+ strlen (op
);
810 for (next
= op
; next
&& next
< last
; )
812 str
= next_field (next
, '|', &next
, last
);
814 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
817 output_operand_type (table
, types
, ARRAY_SIZE (types
), macro
,
822 output_i386_opcode (FILE *table
, const char *name
, char *str
,
823 char *last
, int lineno
)
826 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
827 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
829 /* Find number of operands. */
830 operands
= next_field (str
, ',', &str
, last
);
832 /* Find base_opcode. */
833 base_opcode
= next_field (str
, ',', &str
, last
);
835 /* Find extension_opcode. */
836 extension_opcode
= next_field (str
, ',', &str
, last
);
838 /* Find opcode_length. */
839 opcode_length
= next_field (str
, ',', &str
, last
);
841 /* Find cpu_flags. */
842 cpu_flags
= next_field (str
, ',', &str
, last
);
844 /* Find opcode_modifier. */
845 opcode_modifier
= next_field (str
, ',', &str
, last
);
847 /* Remove the first {. */
848 str
= remove_leading_whitespaces (str
);
851 str
= remove_leading_whitespaces (str
+ 1);
855 /* There are at least "X}". */
859 /* Remove trailing white spaces and }. */
863 if (ISSPACE (str
[i
]) || str
[i
] == '}')
872 /* Find operand_types. */
873 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
877 operand_types
[i
] = NULL
;
881 operand_types
[i
] = next_field (str
, ',', &str
, last
);
882 if (*operand_types
[i
] == '0')
885 operand_types
[i
] = NULL
;
890 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
891 name
, operands
, base_opcode
, extension_opcode
,
894 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
896 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
898 fprintf (table
, " { ");
900 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
902 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
905 process_i386_operand_type (table
, "0", 0, "\t ", lineno
);
910 fprintf (table
, ",\n ");
912 process_i386_operand_type (table
, operand_types
[i
], 0,
915 fprintf (table
, " } },\n");
918 struct opcode_hash_entry
920 struct opcode_hash_entry
*next
;
926 /* Calculate the hash value of an opcode hash entry P. */
929 opcode_hash_hash (const void *p
)
931 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
932 return htab_hash_string (entry
->name
);
935 /* Compare a string Q against an opcode hash entry P. */
938 opcode_hash_eq (const void *p
, const void *q
)
940 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
941 const char *name
= (const char *) q
;
942 return strcmp (name
, entry
->name
) == 0;
946 process_i386_opcodes (FILE *table
)
951 char *str
, *p
, *last
, *name
;
952 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
953 htab_t opcode_hash_table
;
954 struct opcode_hash_entry
**opcode_array
;
955 unsigned int opcode_array_size
= 1024;
958 filename
= "i386-opc.tbl";
959 fp
= fopen (filename
, "r");
962 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
966 opcode_array
= (struct opcode_hash_entry
**)
967 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
969 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
970 opcode_hash_eq
, NULL
,
973 fprintf (table
, "\n/* i386 opcode table. */\n\n");
974 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
976 /* Put everything on opcode array. */
979 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
984 p
= remove_leading_whitespaces (buf
);
987 str
= strstr (p
, "//");
991 /* Remove trailing white spaces. */
992 remove_trailing_whitespaces (p
);
997 /* Ignore comments. */
1005 last
= p
+ strlen (p
);
1008 name
= next_field (p
, ',', &str
, last
);
1010 /* Get the slot in hash table. */
1011 hash_slot
= (struct opcode_hash_entry
**)
1012 htab_find_slot_with_hash (opcode_hash_table
, name
,
1013 htab_hash_string (name
),
1016 if (*hash_slot
== NULL
)
1018 /* It is the new one. Put it on opcode array. */
1019 if (i
>= opcode_array_size
)
1021 /* Grow the opcode array when needed. */
1022 opcode_array_size
+= 1024;
1023 opcode_array
= (struct opcode_hash_entry
**)
1024 xrealloc (opcode_array
,
1025 sizeof (*opcode_array
) * opcode_array_size
);
1028 opcode_array
[i
] = (struct opcode_hash_entry
*)
1029 xmalloc (sizeof (struct opcode_hash_entry
));
1030 opcode_array
[i
]->next
= NULL
;
1031 opcode_array
[i
]->name
= xstrdup (name
);
1032 opcode_array
[i
]->opcode
= xstrdup (str
);
1033 opcode_array
[i
]->lineno
= lineno
;
1034 *hash_slot
= opcode_array
[i
];
1039 /* Append it to the existing one. */
1041 while ((*entry
) != NULL
)
1042 entry
= &(*entry
)->next
;
1043 *entry
= (struct opcode_hash_entry
*)
1044 xmalloc (sizeof (struct opcode_hash_entry
));
1045 (*entry
)->next
= NULL
;
1046 (*entry
)->name
= (*hash_slot
)->name
;
1047 (*entry
)->opcode
= xstrdup (str
);
1048 (*entry
)->lineno
= lineno
;
1052 /* Process opcode array. */
1053 for (j
= 0; j
< i
; j
++)
1055 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1059 lineno
= next
->lineno
;
1060 last
= str
+ strlen (str
);
1061 output_i386_opcode (table
, name
, str
, last
, lineno
);
1067 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1069 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1071 process_i386_opcode_modifier (table
, "0", -1);
1073 fprintf (table
, " { ");
1074 process_i386_operand_type (table
, "0", 0, "\t ", -1);
1075 fprintf (table
, " } }\n");
1077 fprintf (table
, "};\n");
1081 process_i386_registers (FILE *table
)
1085 char *str
, *p
, *last
;
1086 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1087 char *dw2_32_num
, *dw2_64_num
;
1090 filename
= "i386-reg.tbl";
1091 fp
= fopen (filename
, "r");
1093 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1096 fprintf (table
, "\n/* i386 register table. */\n\n");
1097 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1101 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1106 p
= remove_leading_whitespaces (buf
);
1108 /* Skip comments. */
1109 str
= strstr (p
, "//");
1113 /* Remove trailing white spaces. */
1114 remove_trailing_whitespaces (p
);
1119 fprintf (table
, "%s\n", p
);
1127 last
= p
+ strlen (p
);
1129 /* Find reg_name. */
1130 reg_name
= next_field (p
, ',', &str
, last
);
1132 /* Find reg_type. */
1133 reg_type
= next_field (str
, ',', &str
, last
);
1135 /* Find reg_flags. */
1136 reg_flags
= next_field (str
, ',', &str
, last
);
1139 reg_num
= next_field (str
, ',', &str
, last
);
1141 fprintf (table
, " { \"%s\",\n ", reg_name
);
1143 process_i386_operand_type (table
, reg_type
, 0, "\t", lineno
);
1145 /* Find 32-bit Dwarf2 register number. */
1146 dw2_32_num
= next_field (str
, ',', &str
, last
);
1148 /* Find 64-bit Dwarf2 register number. */
1149 dw2_64_num
= next_field (str
, ',', &str
, last
);
1151 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1152 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1157 fprintf (table
, "};\n");
1159 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1163 process_i386_initializers (void)
1166 FILE *fp
= fopen ("i386-init.h", "w");
1170 fail (_("can't create i386-init.h, errno = %s\n"),
1173 process_copyright (fp
);
1175 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1177 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1178 init
= xstrdup (cpu_flag_init
[i
].init
);
1179 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1183 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1185 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1186 init
= xstrdup (operand_type_init
[i
].init
);
1187 process_i386_operand_type (fp
, init
, 1, " ", -1);
1195 /* Program options. */
1196 #define OPTION_SRCDIR 200
1198 struct option long_options
[] =
1200 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1201 {"debug", no_argument
, NULL
, 'd'},
1202 {"version", no_argument
, NULL
, 'V'},
1203 {"help", no_argument
, NULL
, 'h'},
1204 {0, no_argument
, NULL
, 0}
1208 print_version (void)
1210 printf ("%s: version 1.0\n", program_name
);
1215 usage (FILE * stream
, int status
)
1217 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1223 main (int argc
, char **argv
)
1225 extern int chdir (char *);
1226 char *srcdir
= NULL
;
1230 program_name
= *argv
;
1231 xmalloc_set_program_name (program_name
);
1233 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1258 if (chdir (srcdir
) != 0)
1259 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1260 srcdir
, xstrerror (errno
));
1262 /* Check the unused bitfield in i386_cpu_flags. */
1264 c
= CpuNumOfBits
- CpuMax
- 1;
1266 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1269 /* Check the unused bitfield in i386_operand_type. */
1271 c
= OTNumOfBits
- OTMax
- 1;
1273 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1276 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1279 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1280 sizeof (opcode_modifiers
[0]), compare
);
1282 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1283 sizeof (operand_types
[0]), compare
);
1285 table
= fopen ("i386-tbl.h", "w");
1287 fail (_("can't create i386-tbl.h, errno = %s\n"),
1290 process_copyright (table
);
1292 process_i386_opcodes (table
);
1293 process_i386_registers (table
);
1294 process_i386_initializers ();