1 /* Copyright 2007, 2008, 2009
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|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" },
66 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuMMX" },
68 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuMMX|CpuSSE" },
70 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuMMX|CpuSSE|CpuSSE2" },
72 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuLM" },
74 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
76 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuLM" },
78 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuRdtscp|CpuLM" },
80 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CpuMMX" },
82 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CpuMMX|Cpu3dnow" },
84 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|Cpu387|Cpu687|CpuMMX|Cpu3dnow|Cpu3dnowA" },
86 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuLM" },
87 { "CPU_AMDFAM10_FLAGS",
88 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM" },
96 "Cpu8087|Cpu287|Cpu387|Cpu687|CpuFISTTP" },
97 { "CPU_CLFLUSH_FLAGS",
99 { "CPU_SYSCALL_FLAGS",
106 "CpuMMX|CpuSSE|CpuSSE2" },
108 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
110 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3" },
111 { "CPU_SSE4_1_FLAGS",
112 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1" },
113 { "CPU_SSE4_2_FLAGS",
114 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2" },
115 { "CPU_ANY_SSE_FLAGS",
116 "CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuAVX" },
124 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAES" },
125 { "CPU_PCLMUL_FLAGS",
126 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuPCLMUL" },
128 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA" },
130 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA4" },
132 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuABM|CpuAVX|CpuFMA4|CpuXOP" },
137 { "CPU_RDTSCP_FLAGS",
143 { "CPU_3DNOWA_FLAGS",
144 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
145 { "CPU_PADLOCK_FLAGS",
150 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
154 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
155 { "CPU_ANY_AVX_FLAGS",
161 static initializer operand_type_init
[] =
163 { "OPERAND_TYPE_NONE",
165 { "OPERAND_TYPE_REG8",
167 { "OPERAND_TYPE_REG16",
169 { "OPERAND_TYPE_REG32",
171 { "OPERAND_TYPE_REG64",
173 { "OPERAND_TYPE_IMM1",
175 { "OPERAND_TYPE_IMM8",
177 { "OPERAND_TYPE_IMM8S",
179 { "OPERAND_TYPE_IMM16",
181 { "OPERAND_TYPE_IMM32",
183 { "OPERAND_TYPE_IMM32S",
185 { "OPERAND_TYPE_IMM64",
187 { "OPERAND_TYPE_BASEINDEX",
189 { "OPERAND_TYPE_DISP8",
191 { "OPERAND_TYPE_DISP16",
193 { "OPERAND_TYPE_DISP32",
195 { "OPERAND_TYPE_DISP32S",
197 { "OPERAND_TYPE_DISP64",
199 { "OPERAND_TYPE_INOUTPORTREG",
201 { "OPERAND_TYPE_SHIFTCOUNT",
203 { "OPERAND_TYPE_CONTROL",
205 { "OPERAND_TYPE_TEST",
207 { "OPERAND_TYPE_DEBUG",
209 { "OPERAND_TYPE_FLOATREG",
211 { "OPERAND_TYPE_FLOATACC",
213 { "OPERAND_TYPE_SREG2",
215 { "OPERAND_TYPE_SREG3",
217 { "OPERAND_TYPE_ACC",
219 { "OPERAND_TYPE_JUMPABSOLUTE",
221 { "OPERAND_TYPE_REGMMX",
223 { "OPERAND_TYPE_REGXMM",
225 { "OPERAND_TYPE_REGYMM",
227 { "OPERAND_TYPE_ESSEG",
229 { "OPERAND_TYPE_ACC32",
231 { "OPERAND_TYPE_ACC64",
233 { "OPERAND_TYPE_INOUTPORTREG",
235 { "OPERAND_TYPE_REG16_INOUTPORTREG",
236 "Reg16|InOutPortReg" },
237 { "OPERAND_TYPE_DISP16_32",
239 { "OPERAND_TYPE_ANYDISP",
240 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
241 { "OPERAND_TYPE_IMM16_32",
243 { "OPERAND_TYPE_IMM16_32S",
245 { "OPERAND_TYPE_IMM16_32_32S",
246 "Imm16|Imm32|Imm32S" },
247 { "OPERAND_TYPE_IMM32_32S_DISP32",
248 "Imm32|Imm32S|Disp32" },
249 { "OPERAND_TYPE_IMM64_DISP64",
251 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
252 "Imm32|Imm32S|Imm64|Disp32" },
253 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
254 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
257 typedef struct bitfield
264 #define BITFIELD(n) { n, 0, #n }
266 static bitfield cpu_flags
[] =
274 BITFIELD (CpuClflush
),
275 BITFIELD (CpuSYSCALL
),
280 BITFIELD (CpuFISTTP
),
286 BITFIELD (CpuSSE4_1
),
287 BITFIELD (CpuSSE4_2
),
292 BITFIELD (Cpu3dnowA
),
293 BITFIELD (CpuPadLock
),
300 BITFIELD (CpuPCLMUL
),
308 BITFIELD (CpuRdtscp
),
312 BITFIELD (CpuUnused
),
316 static bitfield opcode_modifiers
[] =
322 BITFIELD (ShortForm
),
324 BITFIELD (JumpDword
),
326 BITFIELD (JumpInterSegment
),
333 BITFIELD (IgnoreSize
),
334 BITFIELD (DefaultSize
),
343 BITFIELD (IsLockable
),
344 BITFIELD (RegKludge
),
345 BITFIELD (FirstXmm0
),
346 BITFIELD (Implicit1stXmm0
),
347 BITFIELD (ByteOkIntel
),
350 BITFIELD (AddrPrefixOp0
),
368 BITFIELD (Vex3Sources
),
369 BITFIELD (Vex2Sources
),
370 BITFIELD (VexImmExt
),
374 BITFIELD (ATTMnemonic
),
375 BITFIELD (ATTSyntax
),
376 BITFIELD (IntelSyntax
),
379 static bitfield operand_types
[] =
396 BITFIELD (BaseIndex
),
402 BITFIELD (InOutPortReg
),
403 BITFIELD (ShiftCount
),
411 BITFIELD (JumpAbsolute
),
423 BITFIELD (Unspecified
),
430 static const char *filename
;
433 compare (const void *x
, const void *y
)
435 const bitfield
*xp
= (const bitfield
*) x
;
436 const bitfield
*yp
= (const bitfield
*) y
;
437 return xp
->position
- yp
->position
;
441 fail (const char *message
, ...)
445 va_start (args
, message
);
446 fprintf (stderr
, _("%s: Error: "), program_name
);
447 vfprintf (stderr
, message
, args
);
453 process_copyright (FILE *fp
)
455 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
456 /* Copyright 2007, 2008, 2009\n\
457 Free Software Foundation, Inc.\n\
459 This file is part of the GNU opcodes library.\n\
461 This library is free software; you can redistribute it and/or modify\n\
462 it under the terms of the GNU General Public License as published by\n\
463 the Free Software Foundation; either version 3, or (at your option)\n\
464 any later version.\n\
466 It is distributed in the hope that it will be useful, but WITHOUT\n\
467 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
468 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
469 License for more details.\n\
471 You should have received a copy of the GNU General Public License\n\
472 along with this program; if not, write to the Free Software\n\
473 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
474 MA 02110-1301, USA. */\n");
477 /* Remove leading white spaces. */
480 remove_leading_whitespaces (char *str
)
482 while (ISSPACE (*str
))
487 /* Remove trailing white spaces. */
490 remove_trailing_whitespaces (char *str
)
492 size_t last
= strlen (str
);
500 if (ISSPACE (str
[last
]))
508 /* Find next field separated by SEP and terminate it. Return a
509 pointer to the one after it. */
512 next_field (char *str
, char sep
, char **next
, char *last
)
516 p
= remove_leading_whitespaces (str
);
517 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
520 remove_trailing_whitespaces (p
);
531 set_bitfield (const char *f
, bitfield
*array
, int value
,
532 unsigned int size
, int lineno
)
536 if (strcmp (f
, "CpuFP") == 0)
538 set_bitfield("Cpu387", array
, value
, size
, lineno
);
539 set_bitfield("Cpu287", array
, value
, size
, lineno
);
542 else if (strcmp (f
, "Mmword") == 0)
544 else if (strcmp (f
, "Oword") == 0)
547 for (i
= 0; i
< size
; i
++)
548 if (strcasecmp (array
[i
].name
, f
) == 0)
550 array
[i
].value
= value
;
556 const char *v
= strchr (f
, '=');
563 for (i
= 0; i
< size
; i
++)
564 if (strncasecmp (array
[i
].name
, f
, n
) == 0)
566 value
= strtol (v
+ 1, &end
, 0);
569 array
[i
].value
= value
;
578 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
580 fail (_("Unknown bitfield: %s\n"), f
);
584 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
585 int macro
, const char *comma
, const char *indent
)
589 fprintf (table
, "%s{ { ", indent
);
591 for (i
= 0; i
< size
- 1; i
++)
593 fprintf (table
, "%d, ", flags
[i
].value
);
594 if (((i
+ 1) % 20) == 0)
596 /* We need \\ for macro. */
598 fprintf (table
, " \\\n %s", indent
);
600 fprintf (table
, "\n %s", indent
);
604 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
608 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
609 const char *comma
, const char *indent
,
612 char *str
, *next
, *last
;
614 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
616 /* Copy the default cpu flags. */
617 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
619 if (strcasecmp (flag
, "unknown") == 0)
621 /* We turn on everything except for cpu64 in case of
622 CPU_UNKNOWN_FLAGS. */
623 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
624 if (flags
[i
].position
!= Cpu64
)
627 else if (flag
[0] == '~')
629 last
= flag
+ strlen (flag
);
636 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename
,
643 /* First we turn on everything except for cpu64. */
644 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
645 if (flags
[i
].position
!= Cpu64
)
648 /* Turn off selective bits. */
649 for (; next
&& next
< last
; )
651 str
= next_field (next
, '|', &next
, last
);
653 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
656 else if (strcmp (flag
, "0"))
658 /* Turn on selective bits. */
659 last
= flag
+ strlen (flag
);
660 for (next
= flag
; next
&& next
< last
; )
662 str
= next_field (next
, '|', &next
, last
);
664 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
668 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
673 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
677 fprintf (table
, " { ");
679 for (i
= 0; i
< size
- 1; i
++)
681 fprintf (table
, "%d, ", modifier
[i
].value
);
682 if (((i
+ 1) % 20) == 0)
683 fprintf (table
, "\n ");
686 fprintf (table
, "%d },\n", modifier
[i
].value
);
690 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
692 char *str
, *next
, *last
;
693 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
695 /* Copy the default opcode modifier. */
696 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
698 if (strcmp (mod
, "0"))
700 last
= mod
+ strlen (mod
);
701 for (next
= mod
; next
&& next
< last
; )
703 str
= next_field (next
, '|', &next
, last
);
705 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
709 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
713 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
714 int macro
, const char *indent
)
718 fprintf (table
, "{ { ");
720 for (i
= 0; i
< size
- 1; i
++)
722 fprintf (table
, "%d, ", types
[i
].value
);
723 if (((i
+ 1) % 20) == 0)
725 /* We need \\ for macro. */
727 fprintf (table
, "\\\n%s", indent
);
729 fprintf (table
, "\n%s", indent
);
733 fprintf (table
, "%d } }", types
[i
].value
);
737 process_i386_operand_type (FILE *table
, char *op
, int macro
,
738 const char *indent
, int lineno
)
740 char *str
, *next
, *last
;
741 bitfield types
[ARRAY_SIZE (operand_types
)];
743 /* Copy the default operand type. */
744 memcpy (types
, operand_types
, sizeof (types
));
746 if (strcmp (op
, "0"))
748 last
= op
+ strlen (op
);
749 for (next
= op
; next
&& next
< last
; )
751 str
= next_field (next
, '|', &next
, last
);
753 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
756 output_operand_type (table
, types
, ARRAY_SIZE (types
), macro
,
761 output_i386_opcode (FILE *table
, const char *name
, char *str
,
762 char *last
, int lineno
)
765 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
766 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
768 /* Find number of operands. */
769 operands
= next_field (str
, ',', &str
, last
);
771 /* Find base_opcode. */
772 base_opcode
= next_field (str
, ',', &str
, last
);
774 /* Find extension_opcode. */
775 extension_opcode
= next_field (str
, ',', &str
, last
);
777 /* Find opcode_length. */
778 opcode_length
= next_field (str
, ',', &str
, last
);
780 /* Find cpu_flags. */
781 cpu_flags
= next_field (str
, ',', &str
, last
);
783 /* Find opcode_modifier. */
784 opcode_modifier
= next_field (str
, ',', &str
, last
);
786 /* Remove the first {. */
787 str
= remove_leading_whitespaces (str
);
790 str
= remove_leading_whitespaces (str
+ 1);
794 /* There are at least "X}". */
798 /* Remove trailing white spaces and }. */
802 if (ISSPACE (str
[i
]) || str
[i
] == '}')
811 /* Find operand_types. */
812 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
816 operand_types
[i
] = NULL
;
820 operand_types
[i
] = next_field (str
, ',', &str
, last
);
821 if (*operand_types
[i
] == '0')
824 operand_types
[i
] = NULL
;
829 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
830 name
, operands
, base_opcode
, extension_opcode
,
833 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
835 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
837 fprintf (table
, " { ");
839 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
841 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
844 process_i386_operand_type (table
, "0", 0, "\t ", lineno
);
849 fprintf (table
, ",\n ");
851 process_i386_operand_type (table
, operand_types
[i
], 0,
854 fprintf (table
, " } },\n");
857 struct opcode_hash_entry
859 struct opcode_hash_entry
*next
;
865 /* Calculate the hash value of an opcode hash entry P. */
868 opcode_hash_hash (const void *p
)
870 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
871 return htab_hash_string (entry
->name
);
874 /* Compare a string Q against an opcode hash entry P. */
877 opcode_hash_eq (const void *p
, const void *q
)
879 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
880 const char *name
= (const char *) q
;
881 return strcmp (name
, entry
->name
) == 0;
885 process_i386_opcodes (FILE *table
)
890 char *str
, *p
, *last
, *name
;
891 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
892 htab_t opcode_hash_table
;
893 struct opcode_hash_entry
**opcode_array
;
894 unsigned int opcode_array_size
= 1024;
897 filename
= "i386-opc.tbl";
898 fp
= fopen (filename
, "r");
901 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
905 opcode_array
= (struct opcode_hash_entry
**)
906 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
908 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
909 opcode_hash_eq
, NULL
,
912 fprintf (table
, "\n/* i386 opcode table. */\n\n");
913 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
915 /* Put everything on opcode array. */
918 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
923 p
= remove_leading_whitespaces (buf
);
926 str
= strstr (p
, "//");
930 /* Remove trailing white spaces. */
931 remove_trailing_whitespaces (p
);
936 /* Ignore comments. */
944 last
= p
+ strlen (p
);
947 name
= next_field (p
, ',', &str
, last
);
949 /* Get the slot in hash table. */
950 hash_slot
= (struct opcode_hash_entry
**)
951 htab_find_slot_with_hash (opcode_hash_table
, name
,
952 htab_hash_string (name
),
955 if (*hash_slot
== NULL
)
957 /* It is the new one. Put it on opcode array. */
958 if (i
>= opcode_array_size
)
960 /* Grow the opcode array when needed. */
961 opcode_array_size
+= 1024;
962 opcode_array
= (struct opcode_hash_entry
**)
963 xrealloc (opcode_array
,
964 sizeof (*opcode_array
) * opcode_array_size
);
967 opcode_array
[i
] = (struct opcode_hash_entry
*)
968 xmalloc (sizeof (struct opcode_hash_entry
));
969 opcode_array
[i
]->next
= NULL
;
970 opcode_array
[i
]->name
= xstrdup (name
);
971 opcode_array
[i
]->opcode
= xstrdup (str
);
972 opcode_array
[i
]->lineno
= lineno
;
973 *hash_slot
= opcode_array
[i
];
978 /* Append it to the existing one. */
980 while ((*entry
) != NULL
)
981 entry
= &(*entry
)->next
;
982 *entry
= (struct opcode_hash_entry
*)
983 xmalloc (sizeof (struct opcode_hash_entry
));
984 (*entry
)->next
= NULL
;
985 (*entry
)->name
= (*hash_slot
)->name
;
986 (*entry
)->opcode
= xstrdup (str
);
987 (*entry
)->lineno
= lineno
;
991 /* Process opcode array. */
992 for (j
= 0; j
< i
; j
++)
994 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
998 lineno
= next
->lineno
;
999 last
= str
+ strlen (str
);
1000 output_i386_opcode (table
, name
, str
, last
, lineno
);
1006 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
1008 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
1010 process_i386_opcode_modifier (table
, "0", -1);
1012 fprintf (table
, " { ");
1013 process_i386_operand_type (table
, "0", 0, "\t ", -1);
1014 fprintf (table
, " } }\n");
1016 fprintf (table
, "};\n");
1020 process_i386_registers (FILE *table
)
1024 char *str
, *p
, *last
;
1025 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
1026 char *dw2_32_num
, *dw2_64_num
;
1029 filename
= "i386-reg.tbl";
1030 fp
= fopen (filename
, "r");
1032 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1035 fprintf (table
, "\n/* i386 register table. */\n\n");
1036 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1040 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1045 p
= remove_leading_whitespaces (buf
);
1047 /* Skip comments. */
1048 str
= strstr (p
, "//");
1052 /* Remove trailing white spaces. */
1053 remove_trailing_whitespaces (p
);
1058 fprintf (table
, "%s\n", p
);
1066 last
= p
+ strlen (p
);
1068 /* Find reg_name. */
1069 reg_name
= next_field (p
, ',', &str
, last
);
1071 /* Find reg_type. */
1072 reg_type
= next_field (str
, ',', &str
, last
);
1074 /* Find reg_flags. */
1075 reg_flags
= next_field (str
, ',', &str
, last
);
1078 reg_num
= next_field (str
, ',', &str
, last
);
1080 fprintf (table
, " { \"%s\",\n ", reg_name
);
1082 process_i386_operand_type (table
, reg_type
, 0, "\t", lineno
);
1084 /* Find 32-bit Dwarf2 register number. */
1085 dw2_32_num
= next_field (str
, ',', &str
, last
);
1087 /* Find 64-bit Dwarf2 register number. */
1088 dw2_64_num
= next_field (str
, ',', &str
, last
);
1090 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1091 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1096 fprintf (table
, "};\n");
1098 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1102 process_i386_initializers (void)
1105 FILE *fp
= fopen ("i386-init.h", "w");
1109 fail (_("can't create i386-init.h, errno = %s\n"),
1112 process_copyright (fp
);
1114 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1116 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1117 init
= xstrdup (cpu_flag_init
[i
].init
);
1118 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1122 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1124 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1125 init
= xstrdup (operand_type_init
[i
].init
);
1126 process_i386_operand_type (fp
, init
, 1, " ", -1);
1134 /* Program options. */
1135 #define OPTION_SRCDIR 200
1137 struct option long_options
[] =
1139 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1140 {"debug", no_argument
, NULL
, 'd'},
1141 {"version", no_argument
, NULL
, 'V'},
1142 {"help", no_argument
, NULL
, 'h'},
1143 {0, no_argument
, NULL
, 0}
1147 print_version (void)
1149 printf ("%s: version 1.0\n", program_name
);
1154 usage (FILE * stream
, int status
)
1156 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1162 main (int argc
, char **argv
)
1164 extern int chdir (char *);
1165 char *srcdir
= NULL
;
1169 program_name
= *argv
;
1170 xmalloc_set_program_name (program_name
);
1172 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1197 if (chdir (srcdir
) != 0)
1198 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1199 srcdir
, xstrerror (errno
));
1201 /* Check the unused bitfield in i386_cpu_flags. */
1203 c
= CpuNumOfBits
- CpuMax
- 1;
1205 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1208 /* Check the unused bitfield in i386_operand_type. */
1210 c
= OTNumOfBits
- OTMax
- 1;
1212 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1215 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1218 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1219 sizeof (opcode_modifiers
[0]), compare
);
1221 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1222 sizeof (operand_types
[0]), compare
);
1224 table
= fopen ("i386-tbl.h", "w");
1226 fail (_("can't create i386-tbl.h, errno = %s\n"),
1229 process_copyright (table
);
1231 process_i386_opcodes (table
);
1232 process_i386_registers (table
);
1233 process_i386_initializers ();