1 /* Copyright 2007, 2008, 2009, 2010, 2011
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",
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|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM|CpuFMA4|CpuXOP|CpuLWP" },
100 "Cpu8087|Cpu287|Cpu387|Cpu687|CpuFISTTP" },
101 { "CPU_CLFLUSH_FLAGS",
105 { "CPU_SYSCALL_FLAGS",
112 "CpuMMX|CpuSSE|CpuSSE2" },
114 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
116 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3" },
117 { "CPU_SSE4_1_FLAGS",
118 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1" },
119 { "CPU_SSE4_2_FLAGS",
120 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2" },
121 { "CPU_ANY_SSE_FLAGS",
122 "CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuAVX" },
129 { "CPU_XSAVEOPT_FLAGS",
132 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAES" },
133 { "CPU_PCLMUL_FLAGS",
134 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuPCLMUL" },
136 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA" },
138 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA4" },
140 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuABM|CpuAVX|CpuFMA4|CpuXOP" },
149 { "CPU_RDTSCP_FLAGS",
153 { "CPU_FSGSBASE_FLAGS",
161 { "CPU_3DNOWA_FLAGS",
162 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
163 { "CPU_PADLOCK_FLAGS",
168 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
172 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
173 { "CPU_ANY_AVX_FLAGS",
179 static initializer operand_type_init
[] =
181 { "OPERAND_TYPE_NONE",
183 { "OPERAND_TYPE_REG8",
185 { "OPERAND_TYPE_REG16",
187 { "OPERAND_TYPE_REG32",
189 { "OPERAND_TYPE_REG64",
191 { "OPERAND_TYPE_IMM1",
193 { "OPERAND_TYPE_IMM8",
195 { "OPERAND_TYPE_IMM8S",
197 { "OPERAND_TYPE_IMM16",
199 { "OPERAND_TYPE_IMM32",
201 { "OPERAND_TYPE_IMM32S",
203 { "OPERAND_TYPE_IMM64",
205 { "OPERAND_TYPE_BASEINDEX",
207 { "OPERAND_TYPE_DISP8",
209 { "OPERAND_TYPE_DISP16",
211 { "OPERAND_TYPE_DISP32",
213 { "OPERAND_TYPE_DISP32S",
215 { "OPERAND_TYPE_DISP64",
217 { "OPERAND_TYPE_INOUTPORTREG",
219 { "OPERAND_TYPE_SHIFTCOUNT",
221 { "OPERAND_TYPE_CONTROL",
223 { "OPERAND_TYPE_TEST",
225 { "OPERAND_TYPE_DEBUG",
227 { "OPERAND_TYPE_FLOATREG",
229 { "OPERAND_TYPE_FLOATACC",
231 { "OPERAND_TYPE_SREG2",
233 { "OPERAND_TYPE_SREG3",
235 { "OPERAND_TYPE_ACC",
237 { "OPERAND_TYPE_JUMPABSOLUTE",
239 { "OPERAND_TYPE_REGMMX",
241 { "OPERAND_TYPE_REGXMM",
243 { "OPERAND_TYPE_REGYMM",
245 { "OPERAND_TYPE_ESSEG",
247 { "OPERAND_TYPE_ACC32",
249 { "OPERAND_TYPE_ACC64",
251 { "OPERAND_TYPE_INOUTPORTREG",
253 { "OPERAND_TYPE_REG16_INOUTPORTREG",
254 "Reg16|InOutPortReg" },
255 { "OPERAND_TYPE_DISP16_32",
257 { "OPERAND_TYPE_ANYDISP",
258 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
259 { "OPERAND_TYPE_IMM16_32",
261 { "OPERAND_TYPE_IMM16_32S",
263 { "OPERAND_TYPE_IMM16_32_32S",
264 "Imm16|Imm32|Imm32S" },
265 { "OPERAND_TYPE_IMM32_32S_DISP32",
266 "Imm32|Imm32S|Disp32" },
267 { "OPERAND_TYPE_IMM64_DISP64",
269 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
270 "Imm32|Imm32S|Imm64|Disp32" },
271 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
272 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
273 { "OPERAND_TYPE_VEC_IMM4",
277 typedef struct bitfield
284 #define BITFIELD(n) { n, 0, #n }
286 static bitfield cpu_flags
[] =
294 BITFIELD (CpuClflush
),
296 BITFIELD (CpuSYSCALL
),
301 BITFIELD (CpuFISTTP
),
307 BITFIELD (CpuSSE4_1
),
308 BITFIELD (CpuSSE4_2
),
313 BITFIELD (Cpu3dnowA
),
314 BITFIELD (CpuPadLock
),
320 BITFIELD (CpuXsaveopt
),
322 BITFIELD (CpuPCLMUL
),
332 BITFIELD (CpuRdtscp
),
333 BITFIELD (CpuFSGSBase
),
339 BITFIELD (CpuUnused
),
343 static bitfield opcode_modifiers
[] =
349 BITFIELD (ShortForm
),
351 BITFIELD (JumpDword
),
353 BITFIELD (JumpInterSegment
),
360 BITFIELD (CheckRegSize
),
361 BITFIELD (IgnoreSize
),
362 BITFIELD (DefaultSize
),
371 BITFIELD (IsLockable
),
372 BITFIELD (RegKludge
),
373 BITFIELD (FirstXmm0
),
374 BITFIELD (Implicit1stXmm0
),
377 BITFIELD (AddrPrefixOp0
),
386 BITFIELD (VexOpcode
),
387 BITFIELD (VexSources
),
388 BITFIELD (VexImmExt
),
392 BITFIELD (ATTMnemonic
),
393 BITFIELD (ATTSyntax
),
394 BITFIELD (IntelSyntax
),
397 static bitfield operand_types
[] =
414 BITFIELD (BaseIndex
),
420 BITFIELD (InOutPortReg
),
421 BITFIELD (ShiftCount
),
429 BITFIELD (JumpAbsolute
),
441 BITFIELD (Unspecified
),
449 static const char *filename
;
452 compare (const void *x
, const void *y
)
454 const bitfield
*xp
= (const bitfield
*) x
;
455 const bitfield
*yp
= (const bitfield
*) y
;
456 return xp
->position
- yp
->position
;
460 fail (const char *message
, ...)
464 va_start (args
, message
);
465 fprintf (stderr
, _("%s: Error: "), program_name
);
466 vfprintf (stderr
, message
, args
);
472 process_copyright (FILE *fp
)
474 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
475 /* Copyright 2007, 2008, 2009, 2010, 2011\n\
476 Free Software Foundation, Inc.\n\
478 This file is part of the GNU opcodes library.\n\
480 This library is free software; you can redistribute it and/or modify\n\
481 it under the terms of the GNU General Public License as published by\n\
482 the Free Software Foundation; either version 3, or (at your option)\n\
483 any later version.\n\
485 It is distributed in the hope that it will be useful, but WITHOUT\n\
486 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
487 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
488 License for more details.\n\
490 You should have received a copy of the GNU General Public License\n\
491 along with this program; if not, write to the Free Software\n\
492 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
493 MA 02110-1301, USA. */\n");
496 /* Remove leading white spaces. */
499 remove_leading_whitespaces (char *str
)
501 while (ISSPACE (*str
))
506 /* Remove trailing white spaces. */
509 remove_trailing_whitespaces (char *str
)
511 size_t last
= strlen (str
);
519 if (ISSPACE (str
[last
]))
527 /* Find next field separated by SEP and terminate it. Return a
528 pointer to the one after it. */
531 next_field (char *str
, char sep
, char **next
, char *last
)
535 p
= remove_leading_whitespaces (str
);
536 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
539 remove_trailing_whitespaces (p
);
550 set_bitfield (const char *f
, bitfield
*array
, int value
,
551 unsigned int size
, int lineno
)
555 if (strcmp (f
, "CpuFP") == 0)
557 set_bitfield("Cpu387", array
, value
, size
, lineno
);
558 set_bitfield("Cpu287", array
, value
, size
, lineno
);
561 else if (strcmp (f
, "Mmword") == 0)
563 else if (strcmp (f
, "Oword") == 0)
566 for (i
= 0; i
< size
; i
++)
567 if (strcasecmp (array
[i
].name
, f
) == 0)
569 array
[i
].value
= value
;
575 const char *v
= strchr (f
, '=');
582 for (i
= 0; i
< size
; i
++)
583 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
585 value
= strtol (v
+ 1, &end
, 0);
588 array
[i
].value
= value
;
597 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
599 fail (_("Unknown bitfield: %s\n"), f
);
603 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
604 int macro
, const char *comma
, const char *indent
)
608 fprintf (table
, "%s{ { ", indent
);
610 for (i
= 0; i
< size
- 1; i
++)
612 fprintf (table
, "%d, ", flags
[i
].value
);
613 if (((i
+ 1) % 20) == 0)
615 /* We need \\ for macro. */
617 fprintf (table
, " \\\n %s", indent
);
619 fprintf (table
, "\n %s", indent
);
623 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
627 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
628 const char *comma
, const char *indent
,
631 char *str
, *next
, *last
;
633 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
635 /* Copy the default cpu flags. */
636 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
638 if (strcasecmp (flag
, "unknown") == 0)
640 /* We turn on everything except for cpu64 in case of
641 CPU_UNKNOWN_FLAGS. */
642 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
643 if (flags
[i
].position
!= Cpu64
)
646 else if (flag
[0] == '~')
648 last
= flag
+ strlen (flag
);
655 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename
,
662 /* First we turn on everything except for cpu64. */
663 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
664 if (flags
[i
].position
!= Cpu64
)
667 /* Turn off selective bits. */
668 for (; next
&& next
< last
; )
670 str
= next_field (next
, '|', &next
, last
);
672 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
675 else if (strcmp (flag
, "0"))
677 /* Turn on selective bits. */
678 last
= flag
+ strlen (flag
);
679 for (next
= flag
; next
&& next
< last
; )
681 str
= next_field (next
, '|', &next
, last
);
683 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
687 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
692 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
696 fprintf (table
, " { ");
698 for (i
= 0; i
< size
- 1; i
++)
700 fprintf (table
, "%d, ", modifier
[i
].value
);
701 if (((i
+ 1) % 20) == 0)
702 fprintf (table
, "\n ");
705 fprintf (table
, "%d },\n", modifier
[i
].value
);
709 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
711 char *str
, *next
, *last
;
712 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
714 /* Copy the default opcode modifier. */
715 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
717 if (strcmp (mod
, "0"))
719 last
= mod
+ strlen (mod
);
720 for (next
= mod
; next
&& next
< last
; )
722 str
= next_field (next
, '|', &next
, last
);
724 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
728 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
732 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
733 int macro
, const char *indent
)
737 fprintf (table
, "{ { ");
739 for (i
= 0; i
< size
- 1; i
++)
741 fprintf (table
, "%d, ", types
[i
].value
);
742 if (((i
+ 1) % 20) == 0)
744 /* We need \\ for macro. */
746 fprintf (table
, "\\\n%s", indent
);
748 fprintf (table
, "\n%s", indent
);
752 fprintf (table
, "%d } }", types
[i
].value
);
756 process_i386_operand_type (FILE *table
, char *op
, int macro
,
757 const char *indent
, int lineno
)
759 char *str
, *next
, *last
;
760 bitfield types
[ARRAY_SIZE (operand_types
)];
762 /* Copy the default operand type. */
763 memcpy (types
, operand_types
, sizeof (types
));
765 if (strcmp (op
, "0"))
767 last
= op
+ strlen (op
);
768 for (next
= op
; next
&& next
< last
; )
770 str
= next_field (next
, '|', &next
, last
);
772 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
775 output_operand_type (table
, types
, ARRAY_SIZE (types
), macro
,
780 output_i386_opcode (FILE *table
, const char *name
, char *str
,
781 char *last
, int lineno
)
784 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
785 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
787 /* Find number of operands. */
788 operands
= next_field (str
, ',', &str
, last
);
790 /* Find base_opcode. */
791 base_opcode
= next_field (str
, ',', &str
, last
);
793 /* Find extension_opcode. */
794 extension_opcode
= next_field (str
, ',', &str
, last
);
796 /* Find opcode_length. */
797 opcode_length
= next_field (str
, ',', &str
, last
);
799 /* Find cpu_flags. */
800 cpu_flags
= next_field (str
, ',', &str
, last
);
802 /* Find opcode_modifier. */
803 opcode_modifier
= next_field (str
, ',', &str
, last
);
805 /* Remove the first {. */
806 str
= remove_leading_whitespaces (str
);
809 str
= remove_leading_whitespaces (str
+ 1);
813 /* There are at least "X}". */
817 /* Remove trailing white spaces and }. */
821 if (ISSPACE (str
[i
]) || str
[i
] == '}')
830 /* Find operand_types. */
831 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
835 operand_types
[i
] = NULL
;
839 operand_types
[i
] = next_field (str
, ',', &str
, last
);
840 if (*operand_types
[i
] == '0')
843 operand_types
[i
] = NULL
;
848 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
849 name
, operands
, base_opcode
, extension_opcode
,
852 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
854 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
856 fprintf (table
, " { ");
858 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
860 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
863 process_i386_operand_type (table
, "0", 0, "\t ", lineno
);
868 fprintf (table
, ",\n ");
870 process_i386_operand_type (table
, operand_types
[i
], 0,
873 fprintf (table
, " } },\n");
876 struct opcode_hash_entry
878 struct opcode_hash_entry
*next
;
884 /* Calculate the hash value of an opcode hash entry P. */
887 opcode_hash_hash (const void *p
)
889 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
890 return htab_hash_string (entry
->name
);
893 /* Compare a string Q against an opcode hash entry P. */
896 opcode_hash_eq (const void *p
, const void *q
)
898 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
899 const char *name
= (const char *) q
;
900 return strcmp (name
, entry
->name
) == 0;
904 process_i386_opcodes (FILE *table
)
909 char *str
, *p
, *last
, *name
;
910 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
911 htab_t opcode_hash_table
;
912 struct opcode_hash_entry
**opcode_array
;
913 unsigned int opcode_array_size
= 1024;
916 filename
= "i386-opc.tbl";
917 fp
= fopen (filename
, "r");
920 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
924 opcode_array
= (struct opcode_hash_entry
**)
925 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
927 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
928 opcode_hash_eq
, NULL
,
931 fprintf (table
, "\n/* i386 opcode table. */\n\n");
932 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
934 /* Put everything on opcode array. */
937 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
942 p
= remove_leading_whitespaces (buf
);
945 str
= strstr (p
, "//");
949 /* Remove trailing white spaces. */
950 remove_trailing_whitespaces (p
);
955 /* Ignore comments. */
963 last
= p
+ strlen (p
);
966 name
= next_field (p
, ',', &str
, last
);
968 /* Get the slot in hash table. */
969 hash_slot
= (struct opcode_hash_entry
**)
970 htab_find_slot_with_hash (opcode_hash_table
, name
,
971 htab_hash_string (name
),
974 if (*hash_slot
== NULL
)
976 /* It is the new one. Put it on opcode array. */
977 if (i
>= opcode_array_size
)
979 /* Grow the opcode array when needed. */
980 opcode_array_size
+= 1024;
981 opcode_array
= (struct opcode_hash_entry
**)
982 xrealloc (opcode_array
,
983 sizeof (*opcode_array
) * opcode_array_size
);
986 opcode_array
[i
] = (struct opcode_hash_entry
*)
987 xmalloc (sizeof (struct opcode_hash_entry
));
988 opcode_array
[i
]->next
= NULL
;
989 opcode_array
[i
]->name
= xstrdup (name
);
990 opcode_array
[i
]->opcode
= xstrdup (str
);
991 opcode_array
[i
]->lineno
= lineno
;
992 *hash_slot
= opcode_array
[i
];
997 /* Append it to the existing one. */
999 while ((*entry
) != NULL
)
1000 entry
= &(*entry
)->next
;
1001 *entry
= (struct opcode_hash_entry
*)
1002 xmalloc (sizeof (struct opcode_hash_entry
));
1003 (*entry
)->next
= NULL
;
1004 (*entry
)->name
= (*hash_slot
)->name
;
1005 (*entry
)->opcode
= xstrdup (str
);
1006 (*entry
)->lineno
= lineno
;
1010 /* Process opcode array. */
1011 for (j
= 0; j
< i
; j
++)
1013 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1017 lineno
= next
->lineno
;
1018 last
= str
+ strlen (str
);
1019 output_i386_opcode (table
, name
, str
, last
, lineno
);
1025 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1027 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1029 process_i386_opcode_modifier (table
, "0", -1);
1031 fprintf (table
, " { ");
1032 process_i386_operand_type (table
, "0", 0, "\t ", -1);
1033 fprintf (table
, " } }\n");
1035 fprintf (table
, "};\n");
1039 process_i386_registers (FILE *table
)
1043 char *str
, *p
, *last
;
1044 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1045 char *dw2_32_num
, *dw2_64_num
;
1048 filename
= "i386-reg.tbl";
1049 fp
= fopen (filename
, "r");
1051 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1054 fprintf (table
, "\n/* i386 register table. */\n\n");
1055 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1059 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1064 p
= remove_leading_whitespaces (buf
);
1066 /* Skip comments. */
1067 str
= strstr (p
, "//");
1071 /* Remove trailing white spaces. */
1072 remove_trailing_whitespaces (p
);
1077 fprintf (table
, "%s\n", p
);
1085 last
= p
+ strlen (p
);
1087 /* Find reg_name. */
1088 reg_name
= next_field (p
, ',', &str
, last
);
1090 /* Find reg_type. */
1091 reg_type
= next_field (str
, ',', &str
, last
);
1093 /* Find reg_flags. */
1094 reg_flags
= next_field (str
, ',', &str
, last
);
1097 reg_num
= next_field (str
, ',', &str
, last
);
1099 fprintf (table
, " { \"%s\",\n ", reg_name
);
1101 process_i386_operand_type (table
, reg_type
, 0, "\t", lineno
);
1103 /* Find 32-bit Dwarf2 register number. */
1104 dw2_32_num
= next_field (str
, ',', &str
, last
);
1106 /* Find 64-bit Dwarf2 register number. */
1107 dw2_64_num
= next_field (str
, ',', &str
, last
);
1109 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1110 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1115 fprintf (table
, "};\n");
1117 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1121 process_i386_initializers (void)
1124 FILE *fp
= fopen ("i386-init.h", "w");
1128 fail (_("can't create i386-init.h, errno = %s\n"),
1131 process_copyright (fp
);
1133 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1135 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1136 init
= xstrdup (cpu_flag_init
[i
].init
);
1137 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1141 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1143 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1144 init
= xstrdup (operand_type_init
[i
].init
);
1145 process_i386_operand_type (fp
, init
, 1, " ", -1);
1153 /* Program options. */
1154 #define OPTION_SRCDIR 200
1156 struct option long_options
[] =
1158 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1159 {"debug", no_argument
, NULL
, 'd'},
1160 {"version", no_argument
, NULL
, 'V'},
1161 {"help", no_argument
, NULL
, 'h'},
1162 {0, no_argument
, NULL
, 0}
1166 print_version (void)
1168 printf ("%s: version 1.0\n", program_name
);
1173 usage (FILE * stream
, int status
)
1175 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1181 main (int argc
, char **argv
)
1183 extern int chdir (char *);
1184 char *srcdir
= NULL
;
1188 program_name
= *argv
;
1189 xmalloc_set_program_name (program_name
);
1191 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1216 if (chdir (srcdir
) != 0)
1217 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1218 srcdir
, xstrerror (errno
));
1220 /* Check the unused bitfield in i386_cpu_flags. */
1222 c
= CpuNumOfBits
- CpuMax
- 1;
1224 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1227 /* Check the unused bitfield in i386_operand_type. */
1229 c
= OTNumOfBits
- OTMax
- 1;
1231 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1234 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1237 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1238 sizeof (opcode_modifiers
[0]), compare
);
1240 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1241 sizeof (operand_types
[0]), compare
);
1243 table
= fopen ("i386-tbl.h", "w");
1245 fail (_("can't create i386-tbl.h, errno = %s\n"),
1248 process_copyright (table
);
1250 process_i386_opcodes (table
);
1251 process_i386_registers (table
);
1252 process_i386_initializers ();