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|CpuFMA4|CpuXOP|CpuLWP|CpuBMI|CpuTBM|CpuF16C" },
102 "Cpu8087|Cpu287|Cpu387|Cpu687|CpuFISTTP" },
103 { "CPU_CLFLUSH_FLAGS",
107 { "CPU_SYSCALL_FLAGS",
114 "CpuMMX|CpuSSE|CpuSSE2" },
116 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
118 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3" },
119 { "CPU_SSE4_1_FLAGS",
120 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1" },
121 { "CPU_SSE4_2_FLAGS",
122 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2" },
123 { "CPU_ANY_SSE_FLAGS",
124 "CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuAVX|CpuAVX2" },
131 { "CPU_XSAVEOPT_FLAGS",
134 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAES" },
135 { "CPU_PCLMUL_FLAGS",
136 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuPCLMUL" },
138 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA" },
140 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA4" },
142 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuABM|CpuAVX|CpuFMA4|CpuXOP" },
151 { "CPU_RDTSCP_FLAGS",
155 { "CPU_FSGSBASE_FLAGS",
169 { "CPU_INVPCID_FLAGS",
171 { "CPU_VMFUNC_FLAGS",
175 { "CPU_3DNOWA_FLAGS",
176 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
177 { "CPU_PADLOCK_FLAGS",
182 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
186 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
188 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuAVX2" },
189 { "CPU_ANY_AVX_FLAGS",
197 static initializer operand_type_init
[] =
199 { "OPERAND_TYPE_NONE",
201 { "OPERAND_TYPE_REG8",
203 { "OPERAND_TYPE_REG16",
205 { "OPERAND_TYPE_REG32",
207 { "OPERAND_TYPE_REG64",
209 { "OPERAND_TYPE_IMM1",
211 { "OPERAND_TYPE_IMM8",
213 { "OPERAND_TYPE_IMM8S",
215 { "OPERAND_TYPE_IMM16",
217 { "OPERAND_TYPE_IMM32",
219 { "OPERAND_TYPE_IMM32S",
221 { "OPERAND_TYPE_IMM64",
223 { "OPERAND_TYPE_BASEINDEX",
225 { "OPERAND_TYPE_DISP8",
227 { "OPERAND_TYPE_DISP16",
229 { "OPERAND_TYPE_DISP32",
231 { "OPERAND_TYPE_DISP32S",
233 { "OPERAND_TYPE_DISP64",
235 { "OPERAND_TYPE_INOUTPORTREG",
237 { "OPERAND_TYPE_SHIFTCOUNT",
239 { "OPERAND_TYPE_CONTROL",
241 { "OPERAND_TYPE_TEST",
243 { "OPERAND_TYPE_DEBUG",
245 { "OPERAND_TYPE_FLOATREG",
247 { "OPERAND_TYPE_FLOATACC",
249 { "OPERAND_TYPE_SREG2",
251 { "OPERAND_TYPE_SREG3",
253 { "OPERAND_TYPE_ACC",
255 { "OPERAND_TYPE_JUMPABSOLUTE",
257 { "OPERAND_TYPE_REGMMX",
259 { "OPERAND_TYPE_REGXMM",
261 { "OPERAND_TYPE_REGYMM",
263 { "OPERAND_TYPE_ESSEG",
265 { "OPERAND_TYPE_ACC32",
267 { "OPERAND_TYPE_ACC64",
269 { "OPERAND_TYPE_INOUTPORTREG",
271 { "OPERAND_TYPE_REG16_INOUTPORTREG",
272 "Reg16|InOutPortReg" },
273 { "OPERAND_TYPE_DISP16_32",
275 { "OPERAND_TYPE_ANYDISP",
276 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
277 { "OPERAND_TYPE_IMM16_32",
279 { "OPERAND_TYPE_IMM16_32S",
281 { "OPERAND_TYPE_IMM16_32_32S",
282 "Imm16|Imm32|Imm32S" },
283 { "OPERAND_TYPE_IMM32_32S_DISP32",
284 "Imm32|Imm32S|Disp32" },
285 { "OPERAND_TYPE_IMM64_DISP64",
287 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
288 "Imm32|Imm32S|Imm64|Disp32" },
289 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
290 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
291 { "OPERAND_TYPE_VEC_IMM4",
295 typedef struct bitfield
302 #define BITFIELD(n) { n, 0, #n }
304 static bitfield cpu_flags
[] =
312 BITFIELD (CpuClflush
),
314 BITFIELD (CpuSYSCALL
),
319 BITFIELD (CpuFISTTP
),
325 BITFIELD (CpuSSE4_1
),
326 BITFIELD (CpuSSE4_2
),
333 BITFIELD (Cpu3dnowA
),
334 BITFIELD (CpuPadLock
),
340 BITFIELD (CpuXsaveopt
),
342 BITFIELD (CpuPCLMUL
),
352 BITFIELD (CpuRdtscp
),
353 BITFIELD (CpuFSGSBase
),
360 BITFIELD (CpuINVPCID
),
361 BITFIELD (CpuVMFUNC
),
365 BITFIELD (CpuUnused
),
369 static bitfield opcode_modifiers
[] =
375 BITFIELD (ShortForm
),
377 BITFIELD (JumpDword
),
379 BITFIELD (JumpInterSegment
),
386 BITFIELD (CheckRegSize
),
387 BITFIELD (IgnoreSize
),
388 BITFIELD (DefaultSize
),
397 BITFIELD (IsLockable
),
398 BITFIELD (RegKludge
),
399 BITFIELD (FirstXmm0
),
400 BITFIELD (Implicit1stXmm0
),
401 BITFIELD (RepPrefixOk
),
402 BITFIELD (HLEPrefixOk
),
405 BITFIELD (AddrPrefixOp0
),
414 BITFIELD (VexOpcode
),
415 BITFIELD (VexSources
),
416 BITFIELD (VexImmExt
),
421 BITFIELD (ATTMnemonic
),
422 BITFIELD (ATTSyntax
),
423 BITFIELD (IntelSyntax
),
426 static bitfield operand_types
[] =
443 BITFIELD (BaseIndex
),
449 BITFIELD (InOutPortReg
),
450 BITFIELD (ShiftCount
),
458 BITFIELD (JumpAbsolute
),
470 BITFIELD (Unspecified
),
478 static const char *filename
;
481 compare (const void *x
, const void *y
)
483 const bitfield
*xp
= (const bitfield
*) x
;
484 const bitfield
*yp
= (const bitfield
*) y
;
485 return xp
->position
- yp
->position
;
489 fail (const char *message
, ...)
493 va_start (args
, message
);
494 fprintf (stderr
, _("%s: Error: "), program_name
);
495 vfprintf (stderr
, message
, args
);
501 process_copyright (FILE *fp
)
503 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
504 /* Copyright 2007, 2008, 2009, 2010, 2011\n\
505 Free Software Foundation, Inc.\n\
507 This file is part of the GNU opcodes library.\n\
509 This library is free software; you can redistribute it and/or modify\n\
510 it under the terms of the GNU General Public License as published by\n\
511 the Free Software Foundation; either version 3, or (at your option)\n\
512 any later version.\n\
514 It is distributed in the hope that it will be useful, but WITHOUT\n\
515 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
516 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
517 License for more details.\n\
519 You should have received a copy of the GNU General Public License\n\
520 along with this program; if not, write to the Free Software\n\
521 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
522 MA 02110-1301, USA. */\n");
525 /* Remove leading white spaces. */
528 remove_leading_whitespaces (char *str
)
530 while (ISSPACE (*str
))
535 /* Remove trailing white spaces. */
538 remove_trailing_whitespaces (char *str
)
540 size_t last
= strlen (str
);
548 if (ISSPACE (str
[last
]))
556 /* Find next field separated by SEP and terminate it. Return a
557 pointer to the one after it. */
560 next_field (char *str
, char sep
, char **next
, char *last
)
564 p
= remove_leading_whitespaces (str
);
565 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
568 remove_trailing_whitespaces (p
);
579 set_bitfield (const char *f
, bitfield
*array
, int value
,
580 unsigned int size
, int lineno
)
584 if (strcmp (f
, "CpuFP") == 0)
586 set_bitfield("Cpu387", array
, value
, size
, lineno
);
587 set_bitfield("Cpu287", array
, value
, size
, lineno
);
590 else if (strcmp (f
, "Mmword") == 0)
592 else if (strcmp (f
, "Oword") == 0)
595 for (i
= 0; i
< size
; i
++)
596 if (strcasecmp (array
[i
].name
, f
) == 0)
598 array
[i
].value
= value
;
604 const char *v
= strchr (f
, '=');
611 for (i
= 0; i
< size
; i
++)
612 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
614 value
= strtol (v
+ 1, &end
, 0);
617 array
[i
].value
= value
;
626 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
628 fail (_("Unknown bitfield: %s\n"), f
);
632 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
633 int macro
, const char *comma
, const char *indent
)
637 fprintf (table
, "%s{ { ", indent
);
639 for (i
= 0; i
< size
- 1; i
++)
641 fprintf (table
, "%d, ", flags
[i
].value
);
642 if (((i
+ 1) % 20) == 0)
644 /* We need \\ for macro. */
646 fprintf (table
, " \\\n %s", indent
);
648 fprintf (table
, "\n %s", indent
);
652 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
656 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
657 const char *comma
, const char *indent
,
660 char *str
, *next
, *last
;
662 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
664 /* Copy the default cpu flags. */
665 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
667 if (strcasecmp (flag
, "unknown") == 0)
669 /* We turn on everything except for cpu64 in case of
670 CPU_UNKNOWN_FLAGS. */
671 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
672 if (flags
[i
].position
!= Cpu64
)
675 else if (flag
[0] == '~')
677 last
= flag
+ strlen (flag
);
684 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename
,
691 /* First we turn on everything except for cpu64. */
692 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
693 if (flags
[i
].position
!= Cpu64
)
696 /* Turn off selective bits. */
697 for (; next
&& next
< last
; )
699 str
= next_field (next
, '|', &next
, last
);
701 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
704 else if (strcmp (flag
, "0"))
706 /* Turn on selective bits. */
707 last
= flag
+ strlen (flag
);
708 for (next
= flag
; next
&& next
< last
; )
710 str
= next_field (next
, '|', &next
, last
);
712 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
716 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
721 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
725 fprintf (table
, " { ");
727 for (i
= 0; i
< size
- 1; i
++)
729 fprintf (table
, "%d, ", modifier
[i
].value
);
730 if (((i
+ 1) % 20) == 0)
731 fprintf (table
, "\n ");
734 fprintf (table
, "%d },\n", modifier
[i
].value
);
738 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
740 char *str
, *next
, *last
;
741 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
743 /* Copy the default opcode modifier. */
744 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
746 if (strcmp (mod
, "0"))
748 last
= mod
+ strlen (mod
);
749 for (next
= mod
; next
&& next
< last
; )
751 str
= next_field (next
, '|', &next
, last
);
753 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
757 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
761 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
762 int macro
, const char *indent
)
766 fprintf (table
, "{ { ");
768 for (i
= 0; i
< size
- 1; i
++)
770 fprintf (table
, "%d, ", types
[i
].value
);
771 if (((i
+ 1) % 20) == 0)
773 /* We need \\ for macro. */
775 fprintf (table
, "\\\n%s", indent
);
777 fprintf (table
, "\n%s", indent
);
781 fprintf (table
, "%d } }", types
[i
].value
);
785 process_i386_operand_type (FILE *table
, char *op
, int macro
,
786 const char *indent
, int lineno
)
788 char *str
, *next
, *last
;
789 bitfield types
[ARRAY_SIZE (operand_types
)];
791 /* Copy the default operand type. */
792 memcpy (types
, operand_types
, sizeof (types
));
794 if (strcmp (op
, "0"))
796 last
= op
+ strlen (op
);
797 for (next
= op
; next
&& next
< last
; )
799 str
= next_field (next
, '|', &next
, last
);
801 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
804 output_operand_type (table
, types
, ARRAY_SIZE (types
), macro
,
809 output_i386_opcode (FILE *table
, const char *name
, char *str
,
810 char *last
, int lineno
)
813 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
814 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
816 /* Find number of operands. */
817 operands
= next_field (str
, ',', &str
, last
);
819 /* Find base_opcode. */
820 base_opcode
= next_field (str
, ',', &str
, last
);
822 /* Find extension_opcode. */
823 extension_opcode
= next_field (str
, ',', &str
, last
);
825 /* Find opcode_length. */
826 opcode_length
= next_field (str
, ',', &str
, last
);
828 /* Find cpu_flags. */
829 cpu_flags
= next_field (str
, ',', &str
, last
);
831 /* Find opcode_modifier. */
832 opcode_modifier
= next_field (str
, ',', &str
, last
);
834 /* Remove the first {. */
835 str
= remove_leading_whitespaces (str
);
838 str
= remove_leading_whitespaces (str
+ 1);
842 /* There are at least "X}". */
846 /* Remove trailing white spaces and }. */
850 if (ISSPACE (str
[i
]) || str
[i
] == '}')
859 /* Find operand_types. */
860 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
864 operand_types
[i
] = NULL
;
868 operand_types
[i
] = next_field (str
, ',', &str
, last
);
869 if (*operand_types
[i
] == '0')
872 operand_types
[i
] = NULL
;
877 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
878 name
, operands
, base_opcode
, extension_opcode
,
881 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
883 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
885 fprintf (table
, " { ");
887 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
889 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
892 process_i386_operand_type (table
, "0", 0, "\t ", lineno
);
897 fprintf (table
, ",\n ");
899 process_i386_operand_type (table
, operand_types
[i
], 0,
902 fprintf (table
, " } },\n");
905 struct opcode_hash_entry
907 struct opcode_hash_entry
*next
;
913 /* Calculate the hash value of an opcode hash entry P. */
916 opcode_hash_hash (const void *p
)
918 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
919 return htab_hash_string (entry
->name
);
922 /* Compare a string Q against an opcode hash entry P. */
925 opcode_hash_eq (const void *p
, const void *q
)
927 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
928 const char *name
= (const char *) q
;
929 return strcmp (name
, entry
->name
) == 0;
933 process_i386_opcodes (FILE *table
)
938 char *str
, *p
, *last
, *name
;
939 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
940 htab_t opcode_hash_table
;
941 struct opcode_hash_entry
**opcode_array
;
942 unsigned int opcode_array_size
= 1024;
945 filename
= "i386-opc.tbl";
946 fp
= fopen (filename
, "r");
949 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
953 opcode_array
= (struct opcode_hash_entry
**)
954 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
956 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
957 opcode_hash_eq
, NULL
,
960 fprintf (table
, "\n/* i386 opcode table. */\n\n");
961 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
963 /* Put everything on opcode array. */
966 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
971 p
= remove_leading_whitespaces (buf
);
974 str
= strstr (p
, "//");
978 /* Remove trailing white spaces. */
979 remove_trailing_whitespaces (p
);
984 /* Ignore comments. */
992 last
= p
+ strlen (p
);
995 name
= next_field (p
, ',', &str
, last
);
997 /* Get the slot in hash table. */
998 hash_slot
= (struct opcode_hash_entry
**)
999 htab_find_slot_with_hash (opcode_hash_table
, name
,
1000 htab_hash_string (name
),
1003 if (*hash_slot
== NULL
)
1005 /* It is the new one. Put it on opcode array. */
1006 if (i
>= opcode_array_size
)
1008 /* Grow the opcode array when needed. */
1009 opcode_array_size
+= 1024;
1010 opcode_array
= (struct opcode_hash_entry
**)
1011 xrealloc (opcode_array
,
1012 sizeof (*opcode_array
) * opcode_array_size
);
1015 opcode_array
[i
] = (struct opcode_hash_entry
*)
1016 xmalloc (sizeof (struct opcode_hash_entry
));
1017 opcode_array
[i
]->next
= NULL
;
1018 opcode_array
[i
]->name
= xstrdup (name
);
1019 opcode_array
[i
]->opcode
= xstrdup (str
);
1020 opcode_array
[i
]->lineno
= lineno
;
1021 *hash_slot
= opcode_array
[i
];
1026 /* Append it to the existing one. */
1028 while ((*entry
) != NULL
)
1029 entry
= &(*entry
)->next
;
1030 *entry
= (struct opcode_hash_entry
*)
1031 xmalloc (sizeof (struct opcode_hash_entry
));
1032 (*entry
)->next
= NULL
;
1033 (*entry
)->name
= (*hash_slot
)->name
;
1034 (*entry
)->opcode
= xstrdup (str
);
1035 (*entry
)->lineno
= lineno
;
1039 /* Process opcode array. */
1040 for (j
= 0; j
< i
; j
++)
1042 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1046 lineno
= next
->lineno
;
1047 last
= str
+ strlen (str
);
1048 output_i386_opcode (table
, name
, str
, last
, lineno
);
1054 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1056 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1058 process_i386_opcode_modifier (table
, "0", -1);
1060 fprintf (table
, " { ");
1061 process_i386_operand_type (table
, "0", 0, "\t ", -1);
1062 fprintf (table
, " } }\n");
1064 fprintf (table
, "};\n");
1068 process_i386_registers (FILE *table
)
1072 char *str
, *p
, *last
;
1073 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1074 char *dw2_32_num
, *dw2_64_num
;
1077 filename
= "i386-reg.tbl";
1078 fp
= fopen (filename
, "r");
1080 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1083 fprintf (table
, "\n/* i386 register table. */\n\n");
1084 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1088 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1093 p
= remove_leading_whitespaces (buf
);
1095 /* Skip comments. */
1096 str
= strstr (p
, "//");
1100 /* Remove trailing white spaces. */
1101 remove_trailing_whitespaces (p
);
1106 fprintf (table
, "%s\n", p
);
1114 last
= p
+ strlen (p
);
1116 /* Find reg_name. */
1117 reg_name
= next_field (p
, ',', &str
, last
);
1119 /* Find reg_type. */
1120 reg_type
= next_field (str
, ',', &str
, last
);
1122 /* Find reg_flags. */
1123 reg_flags
= next_field (str
, ',', &str
, last
);
1126 reg_num
= next_field (str
, ',', &str
, last
);
1128 fprintf (table
, " { \"%s\",\n ", reg_name
);
1130 process_i386_operand_type (table
, reg_type
, 0, "\t", lineno
);
1132 /* Find 32-bit Dwarf2 register number. */
1133 dw2_32_num
= next_field (str
, ',', &str
, last
);
1135 /* Find 64-bit Dwarf2 register number. */
1136 dw2_64_num
= next_field (str
, ',', &str
, last
);
1138 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1139 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1144 fprintf (table
, "};\n");
1146 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1150 process_i386_initializers (void)
1153 FILE *fp
= fopen ("i386-init.h", "w");
1157 fail (_("can't create i386-init.h, errno = %s\n"),
1160 process_copyright (fp
);
1162 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1164 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1165 init
= xstrdup (cpu_flag_init
[i
].init
);
1166 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1170 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1172 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1173 init
= xstrdup (operand_type_init
[i
].init
);
1174 process_i386_operand_type (fp
, init
, 1, " ", -1);
1182 /* Program options. */
1183 #define OPTION_SRCDIR 200
1185 struct option long_options
[] =
1187 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1188 {"debug", no_argument
, NULL
, 'd'},
1189 {"version", no_argument
, NULL
, 'V'},
1190 {"help", no_argument
, NULL
, 'h'},
1191 {0, no_argument
, NULL
, 0}
1195 print_version (void)
1197 printf ("%s: version 1.0\n", program_name
);
1202 usage (FILE * stream
, int status
)
1204 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1210 main (int argc
, char **argv
)
1212 extern int chdir (char *);
1213 char *srcdir
= NULL
;
1217 program_name
= *argv
;
1218 xmalloc_set_program_name (program_name
);
1220 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1245 if (chdir (srcdir
) != 0)
1246 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1247 srcdir
, xstrerror (errno
));
1249 /* Check the unused bitfield in i386_cpu_flags. */
1251 c
= CpuNumOfBits
- CpuMax
- 1;
1253 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1256 /* Check the unused bitfield in i386_operand_type. */
1258 c
= OTNumOfBits
- OTMax
- 1;
1260 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1263 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1266 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1267 sizeof (opcode_modifiers
[0]), compare
);
1269 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1270 sizeof (operand_types
[0]), compare
);
1272 table
= fopen ("i386-tbl.h", "w");
1274 fail (_("can't create i386-tbl.h, errno = %s\n"),
1277 process_copyright (table
);
1279 process_i386_opcodes (table
);
1280 process_i386_registers (table
);
1281 process_i386_initializers ();