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" },
133 { "CPU_RDTSCP_FLAGS",
139 { "CPU_3DNOWA_FLAGS",
140 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
141 { "CPU_PADLOCK_FLAGS",
146 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
150 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
151 { "CPU_ANY_AVX_FLAGS",
157 static initializer operand_type_init
[] =
159 { "OPERAND_TYPE_NONE",
161 { "OPERAND_TYPE_REG8",
163 { "OPERAND_TYPE_REG16",
165 { "OPERAND_TYPE_REG32",
167 { "OPERAND_TYPE_REG64",
169 { "OPERAND_TYPE_IMM1",
171 { "OPERAND_TYPE_IMM8",
173 { "OPERAND_TYPE_IMM8S",
175 { "OPERAND_TYPE_IMM16",
177 { "OPERAND_TYPE_IMM32",
179 { "OPERAND_TYPE_IMM32S",
181 { "OPERAND_TYPE_IMM64",
183 { "OPERAND_TYPE_BASEINDEX",
185 { "OPERAND_TYPE_DISP8",
187 { "OPERAND_TYPE_DISP16",
189 { "OPERAND_TYPE_DISP32",
191 { "OPERAND_TYPE_DISP32S",
193 { "OPERAND_TYPE_DISP64",
195 { "OPERAND_TYPE_INOUTPORTREG",
197 { "OPERAND_TYPE_SHIFTCOUNT",
199 { "OPERAND_TYPE_CONTROL",
201 { "OPERAND_TYPE_TEST",
203 { "OPERAND_TYPE_DEBUG",
205 { "OPERAND_TYPE_FLOATREG",
207 { "OPERAND_TYPE_FLOATACC",
209 { "OPERAND_TYPE_SREG2",
211 { "OPERAND_TYPE_SREG3",
213 { "OPERAND_TYPE_ACC",
215 { "OPERAND_TYPE_JUMPABSOLUTE",
217 { "OPERAND_TYPE_REGMMX",
219 { "OPERAND_TYPE_REGXMM",
221 { "OPERAND_TYPE_REGYMM",
223 { "OPERAND_TYPE_ESSEG",
225 { "OPERAND_TYPE_ACC32",
227 { "OPERAND_TYPE_ACC64",
229 { "OPERAND_TYPE_INOUTPORTREG",
231 { "OPERAND_TYPE_REG16_INOUTPORTREG",
232 "Reg16|InOutPortReg" },
233 { "OPERAND_TYPE_DISP16_32",
235 { "OPERAND_TYPE_ANYDISP",
236 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
237 { "OPERAND_TYPE_IMM16_32",
239 { "OPERAND_TYPE_IMM16_32S",
241 { "OPERAND_TYPE_IMM16_32_32S",
242 "Imm16|Imm32|Imm32S" },
243 { "OPERAND_TYPE_IMM32_32S_DISP32",
244 "Imm32|Imm32S|Disp32" },
245 { "OPERAND_TYPE_IMM64_DISP64",
247 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
248 "Imm32|Imm32S|Imm64|Disp32" },
249 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
250 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
253 typedef struct bitfield
260 #define BITFIELD(n) { n, 0, #n }
262 static bitfield cpu_flags
[] =
270 BITFIELD (CpuClflush
),
271 BITFIELD (CpuSYSCALL
),
276 BITFIELD (CpuFISTTP
),
282 BITFIELD (CpuSSE4_1
),
283 BITFIELD (CpuSSE4_2
),
288 BITFIELD (Cpu3dnowA
),
289 BITFIELD (CpuPadLock
),
296 BITFIELD (CpuPCLMUL
),
302 BITFIELD (CpuRdtscp
),
306 BITFIELD (CpuUnused
),
310 static bitfield opcode_modifiers
[] =
316 BITFIELD (ShortForm
),
318 BITFIELD (JumpDword
),
320 BITFIELD (JumpInterSegment
),
327 BITFIELD (IgnoreSize
),
328 BITFIELD (DefaultSize
),
337 BITFIELD (RegKludge
),
338 BITFIELD (FirstXmm0
),
339 BITFIELD (Implicit1stXmm0
),
340 BITFIELD (ByteOkIntel
),
343 BITFIELD (AddrPrefixOp0
),
358 BITFIELD (Vex3Sources
),
359 BITFIELD (VexImmExt
),
363 BITFIELD (ATTMnemonic
),
364 BITFIELD (ATTSyntax
),
365 BITFIELD (IntelSyntax
),
368 static bitfield operand_types
[] =
385 BITFIELD (BaseIndex
),
391 BITFIELD (InOutPortReg
),
392 BITFIELD (ShiftCount
),
400 BITFIELD (JumpAbsolute
),
412 BITFIELD (Unspecified
),
419 static const char *filename
;
422 compare (const void *x
, const void *y
)
424 const bitfield
*xp
= (const bitfield
*) x
;
425 const bitfield
*yp
= (const bitfield
*) y
;
426 return xp
->position
- yp
->position
;
430 fail (const char *message
, ...)
434 va_start (args
, message
);
435 fprintf (stderr
, _("%s: Error: "), program_name
);
436 vfprintf (stderr
, message
, args
);
442 process_copyright (FILE *fp
)
444 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
445 /* Copyright 2007, 2008, 2009\n\
446 Free Software Foundation, Inc.\n\
448 This file is part of the GNU opcodes library.\n\
450 This library is free software; you can redistribute it and/or modify\n\
451 it under the terms of the GNU General Public License as published by\n\
452 the Free Software Foundation; either version 3, or (at your option)\n\
453 any later version.\n\
455 It is distributed in the hope that it will be useful, but WITHOUT\n\
456 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
457 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
458 License for more details.\n\
460 You should have received a copy of the GNU General Public License\n\
461 along with this program; if not, write to the Free Software\n\
462 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
463 MA 02110-1301, USA. */\n");
466 /* Remove leading white spaces. */
469 remove_leading_whitespaces (char *str
)
471 while (ISSPACE (*str
))
476 /* Remove trailing white spaces. */
479 remove_trailing_whitespaces (char *str
)
481 size_t last
= strlen (str
);
489 if (ISSPACE (str
[last
]))
497 /* Find next field separated by SEP and terminate it. Return a
498 pointer to the one after it. */
501 next_field (char *str
, char sep
, char **next
, char *last
)
505 p
= remove_leading_whitespaces (str
);
506 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
509 remove_trailing_whitespaces (p
);
520 set_bitfield (const char *f
, bitfield
*array
, int value
,
521 unsigned int size
, int lineno
)
525 if (strcmp (f
, "CpuFP") == 0)
527 set_bitfield("Cpu387", array
, value
, size
, lineno
);
528 set_bitfield("Cpu287", array
, value
, size
, lineno
);
531 else if (strcmp (f
, "Mmword") == 0)
533 else if (strcmp (f
, "Oword") == 0)
536 for (i
= 0; i
< size
; i
++)
537 if (strcasecmp (array
[i
].name
, f
) == 0)
539 array
[i
].value
= value
;
544 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
546 fail (_("Unknown bitfield: %s\n"), f
);
550 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
551 int macro
, const char *comma
, const char *indent
)
555 fprintf (table
, "%s{ { ", indent
);
557 for (i
= 0; i
< size
- 1; i
++)
559 fprintf (table
, "%d, ", flags
[i
].value
);
560 if (((i
+ 1) % 20) == 0)
562 /* We need \\ for macro. */
564 fprintf (table
, " \\\n %s", indent
);
566 fprintf (table
, "\n %s", indent
);
570 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
574 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
575 const char *comma
, const char *indent
,
578 char *str
, *next
, *last
;
580 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
582 /* Copy the default cpu flags. */
583 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
585 if (strcasecmp (flag
, "unknown") == 0)
587 /* We turn on everything except for cpu64 in case of
588 CPU_UNKNOWN_FLAGS. */
589 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
590 if (flags
[i
].position
!= Cpu64
)
593 else if (flag
[0] == '~')
595 last
= flag
+ strlen (flag
);
602 fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename
,
609 /* First we turn on everything except for cpu64. */
610 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
611 if (flags
[i
].position
!= Cpu64
)
614 /* Turn off selective bits. */
615 for (; next
&& next
< last
; )
617 str
= next_field (next
, '|', &next
, last
);
619 set_bitfield (str
, flags
, 0, ARRAY_SIZE (flags
), lineno
);
622 else if (strcmp (flag
, "0"))
624 /* Turn on selective bits. */
625 last
= flag
+ strlen (flag
);
626 for (next
= flag
; next
&& next
< last
; )
628 str
= next_field (next
, '|', &next
, last
);
630 set_bitfield (str
, flags
, 1, ARRAY_SIZE (flags
), lineno
);
634 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
639 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
643 fprintf (table
, " { ");
645 for (i
= 0; i
< size
- 1; i
++)
647 fprintf (table
, "%d, ", modifier
[i
].value
);
648 if (((i
+ 1) % 20) == 0)
649 fprintf (table
, "\n ");
652 fprintf (table
, "%d },\n", modifier
[i
].value
);
656 process_i386_opcode_modifier (FILE *table
, char *mod
, int lineno
)
658 char *str
, *next
, *last
;
659 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
661 /* Copy the default opcode modifier. */
662 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
664 if (strcmp (mod
, "0"))
666 last
= mod
+ strlen (mod
);
667 for (next
= mod
; next
&& next
< last
; )
669 str
= next_field (next
, '|', &next
, last
);
671 set_bitfield (str
, modifiers
, 1, ARRAY_SIZE (modifiers
),
675 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
679 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
680 int macro
, const char *indent
)
684 fprintf (table
, "{ { ");
686 for (i
= 0; i
< size
- 1; i
++)
688 fprintf (table
, "%d, ", types
[i
].value
);
689 if (((i
+ 1) % 20) == 0)
691 /* We need \\ for macro. */
693 fprintf (table
, "\\\n%s", indent
);
695 fprintf (table
, "\n%s", indent
);
699 fprintf (table
, "%d } }", types
[i
].value
);
703 process_i386_operand_type (FILE *table
, char *op
, int macro
,
704 const char *indent
, int lineno
)
706 char *str
, *next
, *last
;
707 bitfield types
[ARRAY_SIZE (operand_types
)];
709 /* Copy the default operand type. */
710 memcpy (types
, operand_types
, sizeof (types
));
712 if (strcmp (op
, "0"))
714 last
= op
+ strlen (op
);
715 for (next
= op
; next
&& next
< last
; )
717 str
= next_field (next
, '|', &next
, last
);
719 set_bitfield (str
, types
, 1, ARRAY_SIZE (types
), lineno
);
722 output_operand_type (table
, types
, ARRAY_SIZE (types
), macro
,
727 output_i386_opcode (FILE *table
, const char *name
, char *str
,
728 char *last
, int lineno
)
731 char *operands
, *base_opcode
, *extension_opcode
, *opcode_length
;
732 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
734 /* Find number of operands. */
735 operands
= next_field (str
, ',', &str
, last
);
737 /* Find base_opcode. */
738 base_opcode
= next_field (str
, ',', &str
, last
);
740 /* Find extension_opcode. */
741 extension_opcode
= next_field (str
, ',', &str
, last
);
743 /* Find opcode_length. */
744 opcode_length
= next_field (str
, ',', &str
, last
);
746 /* Find cpu_flags. */
747 cpu_flags
= next_field (str
, ',', &str
, last
);
749 /* Find opcode_modifier. */
750 opcode_modifier
= next_field (str
, ',', &str
, last
);
752 /* Remove the first {. */
753 str
= remove_leading_whitespaces (str
);
756 str
= remove_leading_whitespaces (str
+ 1);
760 /* There are at least "X}". */
764 /* Remove trailing white spaces and }. */
768 if (ISSPACE (str
[i
]) || str
[i
] == '}')
777 /* Find operand_types. */
778 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
782 operand_types
[i
] = NULL
;
786 operand_types
[i
] = next_field (str
, ',', &str
, last
);
787 if (*operand_types
[i
] == '0')
790 operand_types
[i
] = NULL
;
795 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
796 name
, operands
, base_opcode
, extension_opcode
,
799 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ", lineno
);
801 process_i386_opcode_modifier (table
, opcode_modifier
, lineno
);
803 fprintf (table
, " { ");
805 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
807 if (operand_types
[i
] == NULL
|| *operand_types
[i
] == '0')
810 process_i386_operand_type (table
, "0", 0, "\t ", lineno
);
815 fprintf (table
, ",\n ");
817 process_i386_operand_type (table
, operand_types
[i
], 0,
820 fprintf (table
, " } },\n");
823 struct opcode_hash_entry
825 struct opcode_hash_entry
*next
;
831 /* Calculate the hash value of an opcode hash entry P. */
834 opcode_hash_hash (const void *p
)
836 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
837 return htab_hash_string (entry
->name
);
840 /* Compare a string Q against an opcode hash entry P. */
843 opcode_hash_eq (const void *p
, const void *q
)
845 struct opcode_hash_entry
*entry
= (struct opcode_hash_entry
*) p
;
846 const char *name
= (const char *) q
;
847 return strcmp (name
, entry
->name
) == 0;
851 process_i386_opcodes (FILE *table
)
856 char *str
, *p
, *last
, *name
;
857 struct opcode_hash_entry
**hash_slot
, **entry
, *next
;
858 htab_t opcode_hash_table
;
859 struct opcode_hash_entry
**opcode_array
;
860 unsigned int opcode_array_size
= 1024;
863 filename
= "i386-opc.tbl";
864 fp
= fopen (filename
, "r");
867 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
871 opcode_array
= (struct opcode_hash_entry
**)
872 xmalloc (sizeof (*opcode_array
) * opcode_array_size
);
874 opcode_hash_table
= htab_create_alloc (16, opcode_hash_hash
,
875 opcode_hash_eq
, NULL
,
878 fprintf (table
, "\n/* i386 opcode table. */\n\n");
879 fprintf (table
, "const insn_template i386_optab[] =\n{\n");
881 /* Put everything on opcode array. */
884 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
889 p
= remove_leading_whitespaces (buf
);
892 str
= strstr (p
, "//");
896 /* Remove trailing white spaces. */
897 remove_trailing_whitespaces (p
);
902 /* Ignore comments. */
910 last
= p
+ strlen (p
);
913 name
= next_field (p
, ',', &str
, last
);
915 /* Get the slot in hash table. */
916 hash_slot
= (struct opcode_hash_entry
**)
917 htab_find_slot_with_hash (opcode_hash_table
, name
,
918 htab_hash_string (name
),
921 if (*hash_slot
== NULL
)
923 /* It is the new one. Put it on opcode array. */
924 if (i
>= opcode_array_size
)
926 /* Grow the opcode array when needed. */
927 opcode_array_size
+= 1024;
928 opcode_array
= (struct opcode_hash_entry
**)
929 xrealloc (opcode_array
,
930 sizeof (*opcode_array
) * opcode_array_size
);
933 opcode_array
[i
] = (struct opcode_hash_entry
*)
934 xmalloc (sizeof (struct opcode_hash_entry
));
935 opcode_array
[i
]->next
= NULL
;
936 opcode_array
[i
]->name
= xstrdup (name
);
937 opcode_array
[i
]->opcode
= xstrdup (str
);
938 opcode_array
[i
]->lineno
= lineno
;
939 *hash_slot
= opcode_array
[i
];
944 /* Append it to the existing one. */
946 while ((*entry
) != NULL
)
947 entry
= &(*entry
)->next
;
948 *entry
= (struct opcode_hash_entry
*)
949 xmalloc (sizeof (struct opcode_hash_entry
));
950 (*entry
)->next
= NULL
;
951 (*entry
)->name
= (*hash_slot
)->name
;
952 (*entry
)->opcode
= xstrdup (str
);
953 (*entry
)->lineno
= lineno
;
957 /* Process opcode array. */
958 for (j
= 0; j
< i
; j
++)
960 for (next
= opcode_array
[j
]; next
; next
= next
->next
)
964 lineno
= next
->lineno
;
965 last
= str
+ strlen (str
);
966 output_i386_opcode (table
, name
, str
, last
, lineno
);
972 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
974 process_i386_cpu_flag (table
, "0", 0, ",", " ", -1);
976 process_i386_opcode_modifier (table
, "0", -1);
978 fprintf (table
, " { ");
979 process_i386_operand_type (table
, "0", 0, "\t ", -1);
980 fprintf (table
, " } }\n");
982 fprintf (table
, "};\n");
986 process_i386_registers (FILE *table
)
990 char *str
, *p
, *last
;
991 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
992 char *dw2_32_num
, *dw2_64_num
;
995 filename
= "i386-reg.tbl";
996 fp
= fopen (filename
, "r");
998 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
1001 fprintf (table
, "\n/* i386 register table. */\n\n");
1002 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
1006 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
1011 p
= remove_leading_whitespaces (buf
);
1013 /* Skip comments. */
1014 str
= strstr (p
, "//");
1018 /* Remove trailing white spaces. */
1019 remove_trailing_whitespaces (p
);
1024 fprintf (table
, "%s\n", p
);
1032 last
= p
+ strlen (p
);
1034 /* Find reg_name. */
1035 reg_name
= next_field (p
, ',', &str
, last
);
1037 /* Find reg_type. */
1038 reg_type
= next_field (str
, ',', &str
, last
);
1040 /* Find reg_flags. */
1041 reg_flags
= next_field (str
, ',', &str
, last
);
1044 reg_num
= next_field (str
, ',', &str
, last
);
1046 fprintf (table
, " { \"%s\",\n ", reg_name
);
1048 process_i386_operand_type (table
, reg_type
, 0, "\t", lineno
);
1050 /* Find 32-bit Dwarf2 register number. */
1051 dw2_32_num
= next_field (str
, ',', &str
, last
);
1053 /* Find 64-bit Dwarf2 register number. */
1054 dw2_64_num
= next_field (str
, ',', &str
, last
);
1056 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
1057 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
1062 fprintf (table
, "};\n");
1064 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1068 process_i386_initializers (void)
1071 FILE *fp
= fopen ("i386-init.h", "w");
1075 fail (_("can't create i386-init.h, errno = %s\n"),
1078 process_copyright (fp
);
1080 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
1082 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
1083 init
= xstrdup (cpu_flag_init
[i
].init
);
1084 process_i386_cpu_flag (fp
, init
, 1, "", " ", -1);
1088 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
1090 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
1091 init
= xstrdup (operand_type_init
[i
].init
);
1092 process_i386_operand_type (fp
, init
, 1, " ", -1);
1100 /* Program options. */
1101 #define OPTION_SRCDIR 200
1103 struct option long_options
[] =
1105 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
1106 {"debug", no_argument
, NULL
, 'd'},
1107 {"version", no_argument
, NULL
, 'V'},
1108 {"help", no_argument
, NULL
, 'h'},
1109 {0, no_argument
, NULL
, 0}
1113 print_version (void)
1115 printf ("%s: version 1.0\n", program_name
);
1120 usage (FILE * stream
, int status
)
1122 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1128 main (int argc
, char **argv
)
1130 extern int chdir (char *);
1131 char *srcdir
= NULL
;
1135 program_name
= *argv
;
1136 xmalloc_set_program_name (program_name
);
1138 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
1163 if (chdir (srcdir
) != 0)
1164 fail (_("unable to change directory to \"%s\", errno = %s\n"),
1165 srcdir
, xstrerror (errno
));
1167 /* Check the unused bitfield in i386_cpu_flags. */
1169 c
= CpuNumOfBits
- CpuMax
- 1;
1171 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1174 /* Check the unused bitfield in i386_operand_type. */
1176 c
= OTNumOfBits
- OTMax
- 1;
1178 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1181 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1184 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1185 sizeof (opcode_modifiers
[0]), compare
);
1187 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1188 sizeof (operand_types
[0]), compare
);
1190 table
= fopen ("i386-tbl.h", "w");
1192 fail (_("can't create i386-tbl.h, errno = %s\n"),
1195 process_copyright (table
);
1197 process_i386_opcodes (table
);
1198 process_i386_registers (table
);
1199 process_i386_initializers ();