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" },
145 { "CPU_RDTSCP_FLAGS",
149 { "CPU_FSGSBASE_FLAGS",
157 { "CPU_3DNOWA_FLAGS",
158 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
159 { "CPU_PADLOCK_FLAGS",
164 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
168 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
169 { "CPU_ANY_AVX_FLAGS",
175 static initializer operand_type_init
[] =
177 { "OPERAND_TYPE_NONE",
179 { "OPERAND_TYPE_REG8",
181 { "OPERAND_TYPE_REG16",
183 { "OPERAND_TYPE_REG32",
185 { "OPERAND_TYPE_REG64",
187 { "OPERAND_TYPE_IMM1",
189 { "OPERAND_TYPE_IMM8",
191 { "OPERAND_TYPE_IMM8S",
193 { "OPERAND_TYPE_IMM16",
195 { "OPERAND_TYPE_IMM32",
197 { "OPERAND_TYPE_IMM32S",
199 { "OPERAND_TYPE_IMM64",
201 { "OPERAND_TYPE_BASEINDEX",
203 { "OPERAND_TYPE_DISP8",
205 { "OPERAND_TYPE_DISP16",
207 { "OPERAND_TYPE_DISP32",
209 { "OPERAND_TYPE_DISP32S",
211 { "OPERAND_TYPE_DISP64",
213 { "OPERAND_TYPE_INOUTPORTREG",
215 { "OPERAND_TYPE_SHIFTCOUNT",
217 { "OPERAND_TYPE_CONTROL",
219 { "OPERAND_TYPE_TEST",
221 { "OPERAND_TYPE_DEBUG",
223 { "OPERAND_TYPE_FLOATREG",
225 { "OPERAND_TYPE_FLOATACC",
227 { "OPERAND_TYPE_SREG2",
229 { "OPERAND_TYPE_SREG3",
231 { "OPERAND_TYPE_ACC",
233 { "OPERAND_TYPE_JUMPABSOLUTE",
235 { "OPERAND_TYPE_REGMMX",
237 { "OPERAND_TYPE_REGXMM",
239 { "OPERAND_TYPE_REGYMM",
241 { "OPERAND_TYPE_ESSEG",
243 { "OPERAND_TYPE_ACC32",
245 { "OPERAND_TYPE_ACC64",
247 { "OPERAND_TYPE_INOUTPORTREG",
249 { "OPERAND_TYPE_REG16_INOUTPORTREG",
250 "Reg16|InOutPortReg" },
251 { "OPERAND_TYPE_DISP16_32",
253 { "OPERAND_TYPE_ANYDISP",
254 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
255 { "OPERAND_TYPE_IMM16_32",
257 { "OPERAND_TYPE_IMM16_32S",
259 { "OPERAND_TYPE_IMM16_32_32S",
260 "Imm16|Imm32|Imm32S" },
261 { "OPERAND_TYPE_IMM32_32S_DISP32",
262 "Imm32|Imm32S|Disp32" },
263 { "OPERAND_TYPE_IMM64_DISP64",
265 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
266 "Imm32|Imm32S|Imm64|Disp32" },
267 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
268 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
269 { "OPERAND_TYPE_VEC_IMM4",
273 typedef struct bitfield
280 #define BITFIELD(n) { n, 0, #n }
282 static bitfield cpu_flags
[] =
290 BITFIELD (CpuClflush
),
292 BITFIELD (CpuSYSCALL
),
297 BITFIELD (CpuFISTTP
),
303 BITFIELD (CpuSSE4_1
),
304 BITFIELD (CpuSSE4_2
),
309 BITFIELD (Cpu3dnowA
),
310 BITFIELD (CpuPadLock
),
316 BITFIELD (CpuXsaveopt
),
318 BITFIELD (CpuPCLMUL
),
326 BITFIELD (CpuRdtscp
),
327 BITFIELD (CpuFSGSBase
),
333 BITFIELD (CpuUnused
),
337 static bitfield opcode_modifiers
[] =
343 BITFIELD (ShortForm
),
345 BITFIELD (JumpDword
),
347 BITFIELD (JumpInterSegment
),
354 BITFIELD (CheckRegSize
),
355 BITFIELD (IgnoreSize
),
356 BITFIELD (DefaultSize
),
365 BITFIELD (IsLockable
),
366 BITFIELD (RegKludge
),
367 BITFIELD (FirstXmm0
),
368 BITFIELD (Implicit1stXmm0
),
371 BITFIELD (AddrPrefixOp0
),
380 BITFIELD (VexOpcode
),
381 BITFIELD (VexSources
),
382 BITFIELD (VexImmExt
),
386 BITFIELD (ATTMnemonic
),
387 BITFIELD (ATTSyntax
),
388 BITFIELD (IntelSyntax
),
391 static bitfield operand_types
[] =
408 BITFIELD (BaseIndex
),
414 BITFIELD (InOutPortReg
),
415 BITFIELD (ShiftCount
),
423 BITFIELD (JumpAbsolute
),
435 BITFIELD (Unspecified
),
443 static const char *filename
;
446 compare (const void *x
, const void *y
)
448 const bitfield
*xp
= (const bitfield
*) x
;
449 const bitfield
*yp
= (const bitfield
*) y
;
450 return xp
->position
- yp
->position
;
454 fail (const char *message
, ...)
458 va_start (args
, message
);
459 fprintf (stderr
, _("%s: Error: "), program_name
);
460 vfprintf (stderr
, message
, args
);
466 process_copyright (FILE *fp
)
468 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
469 /* Copyright 2007, 2008, 2009, 2010, 2011\n\
470 Free Software Foundation, Inc.\n\
472 This file is part of the GNU opcodes library.\n\
474 This library is free software; you can redistribute it and/or modify\n\
475 it under the terms of the GNU General Public License as published by\n\
476 the Free Software Foundation; either version 3, or (at your option)\n\
477 any later version.\n\
479 It is distributed in the hope that it will be useful, but WITHOUT\n\
480 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
481 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
482 License for more details.\n\
484 You should have received a copy of the GNU General Public License\n\
485 along with this program; if not, write to the Free Software\n\
486 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
487 MA 02110-1301, USA. */\n");
490 /* Remove leading white spaces. */
493 remove_leading_whitespaces (char *str
)
495 while (ISSPACE (*str
))
500 /* Remove trailing white spaces. */
503 remove_trailing_whitespaces (char *str
)
505 size_t last
= strlen (str
);
513 if (ISSPACE (str
[last
]))
521 /* Find next field separated by SEP and terminate it. Return a
522 pointer to the one after it. */
525 next_field (char *str
, char sep
, char **next
, char *last
)
529 p
= remove_leading_whitespaces (str
);
530 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
533 remove_trailing_whitespaces (p
);
544 set_bitfield (const char *f
, bitfield
*array
, int value
,
545 unsigned int size
, int lineno
)
549 if (strcmp (f
, "CpuFP") == 0)
551 set_bitfield("Cpu387", array
, value
, size
, lineno
);
552 set_bitfield("Cpu287", array
, value
, size
, lineno
);
555 else if (strcmp (f
, "Mmword") == 0)
557 else if (strcmp (f
, "Oword") == 0)
560 for (i
= 0; i
< size
; i
++)
561 if (strcasecmp (array
[i
].name
, f
) == 0)
563 array
[i
].value
= value
;
569 const char *v
= strchr (f
, '=');
576 for (i
= 0; i
< size
; i
++)
577 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
579 value
= strtol (v
+ 1, &end
, 0);
582 array
[i
].value
= value
;
591 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
593 fail (_("Unknown bitfield: %s\n"), f
);
597 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
598 int macro
, const char *comma
, const char *indent
)
602 fprintf (table
, "%s{ { ", indent
);
604 for (i
= 0; i
< size
- 1; i
++)
606 fprintf (table
, "%d, ", flags
[i
].value
);
607 if (((i
+ 1) % 20) == 0)
609 /* We need \\ for macro. */
611 fprintf (table
, " \\\n %s", indent
);
613 fprintf (table
, "\n %s", indent
);
617 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
621 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
622 const char *comma
, const char *indent
,
625 char *str
, *next
, *last
;
627 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
629 /* Copy the default cpu flags. */
630 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
632 if (strcasecmp (flag
, "unknown") == 0)
634 /* We turn on everything except for cpu64 in case of
635 CPU_UNKNOWN_FLAGS. */
636 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
637 if (flags
[i
].position
!= Cpu64
)
640 else if (flag
[0] == '~')
642 last
= flag
+ strlen (flag
);
649 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename
,
656 /* First we turn on everything except for cpu64. */
657 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
658 if (flags
[i
].position
!= Cpu64
)
661 /* Turn off selective bits. */
662 for (; next
&& next
< last
; )
664 str
= next_field (next
, '|', &next
, last
);
666 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
669 else if (strcmp (flag
, "0"))
671 /* Turn on selective bits. */
672 last
= flag
+ strlen (flag
);
673 for (next
= flag
; next
&& next
< last
; )
675 str
= next_field (next
, '|', &next
, last
);
677 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
681 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
686 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
690 fprintf (table
, " { ");
692 for (i
= 0; i
< size
- 1; i
++)
694 fprintf (table
, "%d, ", modifier
[i
].value
);
695 if (((i
+ 1) % 20) == 0)
696 fprintf (table
, "\n ");
699 fprintf (table
, "%d },\n", modifier
[i
].value
);
703 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
705 char *str
, *next
, *last
;
706 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
708 /* Copy the default opcode modifier. */
709 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
711 if (strcmp (mod
, "0"))
713 last
= mod
+ strlen (mod
);
714 for (next
= mod
; next
&& next
< last
; )
716 str
= next_field (next
, '|', &next
, last
);
718 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
722 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
726 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
727 int macro
, const char *indent
)
731 fprintf (table
, "{ { ");
733 for (i
= 0; i
< size
- 1; i
++)
735 fprintf (table
, "%d, ", types
[i
].value
);
736 if (((i
+ 1) % 20) == 0)
738 /* We need \\ for macro. */
740 fprintf (table
, "\\\n%s", indent
);
742 fprintf (table
, "\n%s", indent
);
746 fprintf (table
, "%d } }", types
[i
].value
);
750 process_i386_operand_type (FILE *table
, char *op
, int macro
,
751 const char *indent
, int lineno
)
753 char *str
, *next
, *last
;
754 bitfield types
[ARRAY_SIZE (operand_types
)];
756 /* Copy the default operand type. */
757 memcpy (types
, operand_types
, sizeof (types
));
759 if (strcmp (op
, "0"))
761 last
= op
+ strlen (op
);
762 for (next
= op
; next
&& next
< last
; )
764 str
= next_field (next
, '|', &next
, last
);
766 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
769 output_operand_type (table
, types
, ARRAY_SIZE (types
), macro
,
774 output_i386_opcode (FILE *table
, const char *name
, char *str
,
775 char *last
, int lineno
)
778 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
779 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
781 /* Find number of operands. */
782 operands
= next_field (str
, ',', &str
, last
);
784 /* Find base_opcode. */
785 base_opcode
= next_field (str
, ',', &str
, last
);
787 /* Find extension_opcode. */
788 extension_opcode
= next_field (str
, ',', &str
, last
);
790 /* Find opcode_length. */
791 opcode_length
= next_field (str
, ',', &str
, last
);
793 /* Find cpu_flags. */
794 cpu_flags
= next_field (str
, ',', &str
, last
);
796 /* Find opcode_modifier. */
797 opcode_modifier
= next_field (str
, ',', &str
, last
);
799 /* Remove the first {. */
800 str
= remove_leading_whitespaces (str
);
803 str
= remove_leading_whitespaces (str
+ 1);
807 /* There are at least "X}". */
811 /* Remove trailing white spaces and }. */
815 if (ISSPACE (str
[i
]) || str
[i
] == '}')
824 /* Find operand_types. */
825 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
829 operand_types
[i
] = NULL
;
833 operand_types
[i
] = next_field (str
, ',', &str
, last
);
834 if (*operand_types
[i
] == '0')
837 operand_types
[i
] = NULL
;
842 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
843 name
, operands
, base_opcode
, extension_opcode
,
846 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
848 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
850 fprintf (table
, " { ");
852 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
854 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
857 process_i386_operand_type (table
, "0", 0, "\t ", lineno
);
862 fprintf (table
, ",\n ");
864 process_i386_operand_type (table
, operand_types
[i
], 0,
867 fprintf (table
, " } },\n");
870 struct opcode_hash_entry
872 struct opcode_hash_entry
*next
;
878 /* Calculate the hash value of an opcode hash entry P. */
881 opcode_hash_hash (const void *p
)
883 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
884 return htab_hash_string (entry
->name
);
887 /* Compare a string Q against an opcode hash entry P. */
890 opcode_hash_eq (const void *p
, const void *q
)
892 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
893 const char *name
= (const char *) q
;
894 return strcmp (name
, entry
->name
) == 0;
898 process_i386_opcodes (FILE *table
)
903 char *str
, *p
, *last
, *name
;
904 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
905 htab_t opcode_hash_table
;
906 struct opcode_hash_entry
**opcode_array
;
907 unsigned int opcode_array_size
= 1024;
910 filename
= "i386-opc.tbl";
911 fp
= fopen (filename
, "r");
914 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
918 opcode_array
= (struct opcode_hash_entry
**)
919 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
921 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
922 opcode_hash_eq
, NULL
,
925 fprintf (table
, "\n/* i386 opcode table. */\n\n");
926 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
928 /* Put everything on opcode array. */
931 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
936 p
= remove_leading_whitespaces (buf
);
939 str
= strstr (p
, "//");
943 /* Remove trailing white spaces. */
944 remove_trailing_whitespaces (p
);
949 /* Ignore comments. */
957 last
= p
+ strlen (p
);
960 name
= next_field (p
, ',', &str
, last
);
962 /* Get the slot in hash table. */
963 hash_slot
= (struct opcode_hash_entry
**)
964 htab_find_slot_with_hash (opcode_hash_table
, name
,
965 htab_hash_string (name
),
968 if (*hash_slot
== NULL
)
970 /* It is the new one. Put it on opcode array. */
971 if (i
>= opcode_array_size
)
973 /* Grow the opcode array when needed. */
974 opcode_array_size
+= 1024;
975 opcode_array
= (struct opcode_hash_entry
**)
976 xrealloc (opcode_array
,
977 sizeof (*opcode_array
) * opcode_array_size
);
980 opcode_array
[i
] = (struct opcode_hash_entry
*)
981 xmalloc (sizeof (struct opcode_hash_entry
));
982 opcode_array
[i
]->next
= NULL
;
983 opcode_array
[i
]->name
= xstrdup (name
);
984 opcode_array
[i
]->opcode
= xstrdup (str
);
985 opcode_array
[i
]->lineno
= lineno
;
986 *hash_slot
= opcode_array
[i
];
991 /* Append it to the existing one. */
993 while ((*entry
) != NULL
)
994 entry
= &(*entry
)->next
;
995 *entry
= (struct opcode_hash_entry
*)
996 xmalloc (sizeof (struct opcode_hash_entry
));
997 (*entry
)->next
= NULL
;
998 (*entry
)->name
= (*hash_slot
)->name
;
999 (*entry
)->opcode
= xstrdup (str
);
1000 (*entry
)->lineno
= lineno
;
1004 /* Process opcode array. */
1005 for (j
= 0; j
< i
; j
++)
1007 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
1011 lineno
= next
->lineno
;
1012 last
= str
+ strlen (str
);
1013 output_i386_opcode (table
, name
, str
, last
, lineno
);
1019 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1021 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1023 process_i386_opcode_modifier (table
, "0", -1);
1025 fprintf (table
, " { ");
1026 process_i386_operand_type (table
, "0", 0, "\t ", -1);
1027 fprintf (table
, " } }\n");
1029 fprintf (table
, "};\n");
1033 process_i386_registers (FILE *table
)
1037 char *str
, *p
, *last
;
1038 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1039 char *dw2_32_num
, *dw2_64_num
;
1042 filename
= "i386-reg.tbl";
1043 fp
= fopen (filename
, "r");
1045 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1048 fprintf (table
, "\n/* i386 register table. */\n\n");
1049 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1053 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1058 p
= remove_leading_whitespaces (buf
);
1060 /* Skip comments. */
1061 str
= strstr (p
, "//");
1065 /* Remove trailing white spaces. */
1066 remove_trailing_whitespaces (p
);
1071 fprintf (table
, "%s\n", p
);
1079 last
= p
+ strlen (p
);
1081 /* Find reg_name. */
1082 reg_name
= next_field (p
, ',', &str
, last
);
1084 /* Find reg_type. */
1085 reg_type
= next_field (str
, ',', &str
, last
);
1087 /* Find reg_flags. */
1088 reg_flags
= next_field (str
, ',', &str
, last
);
1091 reg_num
= next_field (str
, ',', &str
, last
);
1093 fprintf (table
, " { \"%s\",\n ", reg_name
);
1095 process_i386_operand_type (table
, reg_type
, 0, "\t", lineno
);
1097 /* Find 32-bit Dwarf2 register number. */
1098 dw2_32_num
= next_field (str
, ',', &str
, last
);
1100 /* Find 64-bit Dwarf2 register number. */
1101 dw2_64_num
= next_field (str
, ',', &str
, last
);
1103 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1104 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1109 fprintf (table
, "};\n");
1111 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1115 process_i386_initializers (void)
1118 FILE *fp
= fopen ("i386-init.h", "w");
1122 fail (_("can't create i386-init.h, errno = %s\n"),
1125 process_copyright (fp
);
1127 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1129 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1130 init
= xstrdup (cpu_flag_init
[i
].init
);
1131 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1135 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1137 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1138 init
= xstrdup (operand_type_init
[i
].init
);
1139 process_i386_operand_type (fp
, init
, 1, " ", -1);
1147 /* Program options. */
1148 #define OPTION_SRCDIR 200
1150 struct option long_options
[] =
1152 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1153 {"debug", no_argument
, NULL
, 'd'},
1154 {"version", no_argument
, NULL
, 'V'},
1155 {"help", no_argument
, NULL
, 'h'},
1156 {0, no_argument
, NULL
, 0}
1160 print_version (void)
1162 printf ("%s: version 1.0\n", program_name
);
1167 usage (FILE * stream
, int status
)
1169 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1175 main (int argc
, char **argv
)
1177 extern int chdir (char *);
1178 char *srcdir
= NULL
;
1182 program_name
= *argv
;
1183 xmalloc_set_program_name (program_name
);
1185 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1210 if (chdir (srcdir
) != 0)
1211 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1212 srcdir
, xstrerror (errno
));
1214 /* Check the unused bitfield in i386_cpu_flags. */
1216 c
= CpuNumOfBits
- CpuMax
- 1;
1218 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1221 /* Check the unused bitfield in i386_operand_type. */
1223 c
= OTNumOfBits
- OTMax
- 1;
1225 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1228 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1231 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1232 sizeof (opcode_modifiers
[0]), compare
);
1234 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1235 sizeof (operand_types
[0]), compare
);
1237 table
= fopen ("i386-tbl.h", "w");
1239 fail (_("can't create i386-tbl.h, errno = %s\n"),
1242 process_copyright (table
);
1244 process_i386_opcodes (table
);
1245 process_i386_registers (table
);
1246 process_i386_initializers ();