1 /* Copyright 2007, 2008 Free Software Foundation, Inc.
3 This file is part of the GNU opcodes library.
5 This library is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3, or (at your option)
10 It is distributed in the hope that it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
13 License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
18 MA 02110-1301, USA. */
24 #include "libiberty.h"
25 #include "safe-ctype.h"
30 #define _(String) gettext (String)
32 static const char *program_name
= NULL
;
35 typedef struct initializer
41 static initializer cpu_flag_init
[] =
43 { "CPU_UNKNOWN_FLAGS",
45 { "CPU_GENERIC32_FLAGS",
46 "Cpu186|Cpu286|Cpu386" },
47 { "CPU_GENERIC64_FLAGS",
48 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2|CpuLM" },
56 "Cpu186|Cpu286|Cpu386" },
58 "Cpu186|Cpu286|Cpu386|Cpu486" },
60 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
62 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686" },
64 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuMMX" },
66 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuMMX|CpuSSE" },
68 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2" },
70 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuLM" },
72 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
74 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuLM" },
76 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuK6|CpuMMX" },
78 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuK6|CpuMMX|Cpu3dnow" },
80 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuK6|CpuMMX|Cpu3dnow|Cpu3dnowA" },
82 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuK6|CpuK8|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuLM" },
83 { "CPU_AMDFAM10_FLAGS",
84 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuK6|CpuK8|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM" },
90 "CpuMMX|CpuSSE|CpuSSE2" },
92 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
94 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3" },
96 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1" },
98 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2" },
107 { "CPU_3DNOWA_FLAGS",
108 "CpuMMX|Cpu3dnow|Cpu3dnowA" },
109 { "CPU_PADLOCK_FLAGS",
114 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
118 "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuSSE5"},
121 static initializer operand_type_init
[] =
123 { "OPERAND_TYPE_NONE",
125 { "OPERAND_TYPE_REG8",
127 { "OPERAND_TYPE_REG16",
129 { "OPERAND_TYPE_REG32",
131 { "OPERAND_TYPE_REG64",
133 { "OPERAND_TYPE_IMM1",
135 { "OPERAND_TYPE_IMM8",
137 { "OPERAND_TYPE_IMM8S",
139 { "OPERAND_TYPE_IMM16",
141 { "OPERAND_TYPE_IMM32",
143 { "OPERAND_TYPE_IMM32S",
145 { "OPERAND_TYPE_IMM64",
147 { "OPERAND_TYPE_BASEINDEX",
149 { "OPERAND_TYPE_DISP8",
151 { "OPERAND_TYPE_DISP16",
153 { "OPERAND_TYPE_DISP32",
155 { "OPERAND_TYPE_DISP32S",
157 { "OPERAND_TYPE_DISP64",
159 { "OPERAND_TYPE_INOUTPORTREG",
161 { "OPERAND_TYPE_SHIFTCOUNT",
163 { "OPERAND_TYPE_CONTROL",
165 { "OPERAND_TYPE_TEST",
167 { "OPERAND_TYPE_DEBUG",
169 { "OPERAND_TYPE_FLOATREG",
171 { "OPERAND_TYPE_FLOATACC",
173 { "OPERAND_TYPE_SREG2",
175 { "OPERAND_TYPE_SREG3",
177 { "OPERAND_TYPE_ACC",
179 { "OPERAND_TYPE_JUMPABSOLUTE",
181 { "OPERAND_TYPE_REGMMX",
183 { "OPERAND_TYPE_REGXMM",
185 { "OPERAND_TYPE_ESSEG",
187 { "OPERAND_TYPE_ACC32",
189 { "OPERAND_TYPE_ACC64",
191 { "OPERAND_TYPE_INOUTPORTREG",
193 { "OPERAND_TYPE_REG16_INOUTPORTREG",
194 "Reg16|InOutPortReg" },
195 { "OPERAND_TYPE_DISP16_32",
197 { "OPERAND_TYPE_ANYDISP",
198 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
199 { "OPERAND_TYPE_IMM16_32",
201 { "OPERAND_TYPE_IMM16_32S",
203 { "OPERAND_TYPE_IMM16_32_32S",
204 "Imm16|Imm32|Imm32S" },
205 { "OPERAND_TYPE_IMM32_32S_DISP32",
206 "Imm32|Imm32S|Disp32" },
207 { "OPERAND_TYPE_IMM64_DISP64",
209 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
210 "Imm32|Imm32S|Imm64|Disp32" },
211 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
212 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
215 typedef struct bitfield
222 #define BITFIELD(n) { n, 0, #n }
224 static bitfield cpu_flags
[] =
240 BITFIELD (CpuSSE4_1
),
241 BITFIELD (CpuSSE4_2
),
245 BITFIELD (Cpu3dnowA
),
246 BITFIELD (CpuPadLock
),
256 BITFIELD (CpuUnused
),
260 static bitfield opcode_modifiers
[] =
265 BITFIELD (ShortForm
),
267 BITFIELD (JumpDword
),
269 BITFIELD (JumpInterSegment
),
276 BITFIELD (IgnoreSize
),
277 BITFIELD (DefaultSize
),
286 BITFIELD (RegKludge
),
287 BITFIELD (FirstXmm0
),
288 BITFIELD (ByteOkIntel
),
291 BITFIELD (AddrPrefixOp0
),
301 BITFIELD (ATTMnemonic
),
302 BITFIELD (ATTSyntax
),
303 BITFIELD (IntelSyntax
),
306 static bitfield operand_types
[] =
322 BITFIELD (BaseIndex
),
328 BITFIELD (InOutPortReg
),
329 BITFIELD (ShiftCount
),
337 BITFIELD (JumpAbsolute
),
348 BITFIELD (Unspecified
),
356 static const char *filename
;
359 compare (const void *x
, const void *y
)
361 const bitfield
*xp
= (const bitfield
*) x
;
362 const bitfield
*yp
= (const bitfield
*) y
;
363 return xp
->position
- yp
->position
;
367 fail (const char *message
, ...)
371 va_start (args
, message
);
372 fprintf (stderr
, _("%s: Error: "), program_name
);
373 vfprintf (stderr
, message
, args
);
379 process_copyright (FILE *fp
)
381 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
382 /* Copyright 2007, 2008 Free Software Foundation, Inc.\n\
384 This file is part of the GNU opcodes library.\n\
386 This library is free software; you can redistribute it and/or modify\n\
387 it under the terms of the GNU General Public License as published by\n\
388 the Free Software Foundation; either version 3, or (at your option)\n\
389 any later version.\n\
391 It is distributed in the hope that it will be useful, but WITHOUT\n\
392 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
393 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
394 License for more details.\n\
396 You should have received a copy of the GNU General Public License\n\
397 along with this program; if not, write to the Free Software\n\
398 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
399 MA 02110-1301, USA. */\n");
402 /* Remove leading white spaces. */
405 remove_leading_whitespaces (char *str
)
407 while (ISSPACE (*str
))
412 /* Remove trailing white spaces. */
415 remove_trailing_whitespaces (char *str
)
417 size_t last
= strlen (str
);
425 if (ISSPACE (str
[last
]))
433 /* Find next field separated by SEP and terminate it. Return a
434 pointer to the one after it. */
437 next_field (char *str
, char sep
, char **next
)
441 p
= remove_leading_whitespaces (str
);
442 for (str
= p
; *str
!= sep
&& *str
!= '\0'; str
++);
445 remove_trailing_whitespaces (p
);
453 set_bitfield (const char *f
, bitfield
*array
, unsigned int size
)
457 if (strcmp (f
, "CpuSledgehammer") == 0)
459 else if (strcmp (f
, "Mmword") == 0)
461 else if (strcmp (f
, "Oword") == 0)
464 for (i
= 0; i
< size
; i
++)
465 if (strcasecmp (array
[i
].name
, f
) == 0)
471 fail (_("%s: %d: Unknown bitfield: %s\n"), filename
, lineno
, f
);
475 output_cpu_flags (FILE *table
, bitfield
*flags
, unsigned int size
,
476 int macro
, const char *comma
, const char *indent
)
480 fprintf (table
, "%s{ { ", indent
);
482 for (i
= 0; i
< size
- 1; i
++)
484 fprintf (table
, "%d, ", flags
[i
].value
);
485 if (((i
+ 1) % 20) == 0)
487 /* We need \\ for macro. */
489 fprintf (table
, " \\\n %s", indent
);
491 fprintf (table
, "\n %s", indent
);
495 fprintf (table
, "%d } }%s\n", flags
[i
].value
, comma
);
499 process_i386_cpu_flag (FILE *table
, char *flag
, int macro
,
500 const char *comma
, const char *indent
)
502 char *str
, *next
, *last
;
503 bitfield flags
[ARRAY_SIZE (cpu_flags
)];
505 /* Copy the default cpu flags. */
506 memcpy (flags
, cpu_flags
, sizeof (cpu_flags
));
508 if (strcasecmp (flag
, "unknown") == 0)
512 /* We turn on everything except for cpu64 in case of
513 CPU_UNKNOWN_FLAGS. */
514 for (i
= 0; i
< ARRAY_SIZE (flags
); i
++)
515 if (flags
[i
].position
!= Cpu64
)
518 else if (strcmp (flag
, "0"))
520 last
= flag
+ strlen (flag
);
521 for (next
= flag
; next
&& next
< last
; )
523 str
= next_field (next
, '|', &next
);
525 set_bitfield (str
, flags
, ARRAY_SIZE (flags
));
529 output_cpu_flags (table
, flags
, ARRAY_SIZE (flags
), macro
,
534 output_opcode_modifier (FILE *table
, bitfield
*modifier
, unsigned int size
)
538 fprintf (table
, " { ");
540 for (i
= 0; i
< size
- 1; i
++)
542 fprintf (table
, "%d, ", modifier
[i
].value
);
543 if (((i
+ 1) % 20) == 0)
544 fprintf (table
, "\n ");
547 fprintf (table
, "%d },\n", modifier
[i
].value
);
551 process_i386_opcode_modifier (FILE *table
, char *mod
)
553 char *str
, *next
, *last
;
554 bitfield modifiers
[ARRAY_SIZE (opcode_modifiers
)];
556 /* Copy the default opcode modifier. */
557 memcpy (modifiers
, opcode_modifiers
, sizeof (modifiers
));
559 if (strcmp (mod
, "0"))
561 last
= mod
+ strlen (mod
);
562 for (next
= mod
; next
&& next
< last
; )
564 str
= next_field (next
, '|', &next
);
566 set_bitfield (str
, modifiers
, ARRAY_SIZE (modifiers
));
569 output_opcode_modifier (table
, modifiers
, ARRAY_SIZE (modifiers
));
573 output_operand_type (FILE *table
, bitfield
*types
, unsigned int size
,
574 int macro
, const char *indent
)
578 fprintf (table
, "{ { ");
580 for (i
= 0; i
< size
- 1; i
++)
582 fprintf (table
, "%d, ", types
[i
].value
);
583 if (((i
+ 1) % 20) == 0)
585 /* We need \\ for macro. */
587 fprintf (table
, "\\\n%s", indent
);
589 fprintf (table
, "\n%s", indent
);
593 fprintf (table
, "%d } }", types
[i
].value
);
597 process_i386_operand_type (FILE *table
, char *op
, int macro
,
600 char *str
, *next
, *last
;
601 bitfield types
[ARRAY_SIZE (operand_types
)];
603 /* Copy the default operand type. */
604 memcpy (types
, operand_types
, sizeof (types
));
606 if (strcmp (op
, "0"))
608 last
= op
+ strlen (op
);
609 for (next
= op
; next
&& next
< last
; )
611 str
= next_field (next
, '|', &next
);
613 set_bitfield (str
, types
, ARRAY_SIZE (types
));
616 output_operand_type (table
, types
, ARRAY_SIZE (types
), macro
,
621 process_i386_opcodes (FILE *table
)
626 char *str
, *p
, *last
;
627 char *name
, *operands
, *base_opcode
, *extension_opcode
;
629 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
631 filename
= "i386-opc.tbl";
632 fp
= fopen (filename
, "r");
635 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
638 fprintf (table
, "\n/* i386 opcode table. */\n\n");
639 fprintf (table
, "const template i386_optab[] =\n{\n");
643 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
648 p
= remove_leading_whitespaces (buf
);
651 str
= strstr (p
, "//");
655 /* Remove trailing white spaces. */
656 remove_trailing_whitespaces (p
);
661 fprintf (table
, "%s\n", p
);
669 last
= p
+ strlen (p
);
672 name
= next_field (p
, ',', &str
);
677 /* Find number of operands. */
678 operands
= next_field (str
, ',', &str
);
683 /* Find base_opcode. */
684 base_opcode
= next_field (str
, ',', &str
);
689 /* Find extension_opcode. */
690 extension_opcode
= next_field (str
, ',', &str
);
695 /* Find opcode_length. */
696 opcode_length
= next_field (str
, ',', &str
);
701 /* Find cpu_flags. */
702 cpu_flags
= next_field (str
, ',', &str
);
707 /* Find opcode_modifier. */
708 opcode_modifier
= next_field (str
, ',', &str
);
713 /* Remove the first {. */
714 str
= remove_leading_whitespaces (str
);
717 str
= remove_leading_whitespaces (str
+ 1);
721 /* There are at least "X}". */
725 /* Remove trailing white spaces and }. */
729 if (ISSPACE (str
[i
]) || str
[i
] == '}')
738 /* Find operand_types. */
739 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
743 operand_types
[i
] = NULL
;
747 operand_types
[i
] = next_field (str
, ',', &str
);
748 if (*operand_types
[i
] == '0')
751 operand_types
[i
] = NULL
;
756 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
757 name
, operands
, base_opcode
, extension_opcode
,
760 process_i386_cpu_flag (table
, cpu_flags
, 0, ",", " ");
762 process_i386_opcode_modifier (table
, opcode_modifier
);
764 fprintf (table
, " { ");
766 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
768 if (operand_types
[i
] == NULL
769 || *operand_types
[i
] == '0')
772 process_i386_operand_type (table
, "0", 0, "\t ");
777 fprintf (table
, ",\n ");
779 process_i386_operand_type (table
, operand_types
[i
], 0,
782 fprintf (table
, " } },\n");
787 fprintf (table
, " { NULL, 0, 0, 0, 0,\n");
789 process_i386_cpu_flag (table
, "0", 0, ",", " ");
791 process_i386_opcode_modifier (table
, "0");
793 fprintf (table
, " { ");
794 process_i386_operand_type (table
, "0", 0, "\t ");
795 fprintf (table
, " } }\n");
797 fprintf (table
, "};\n");
801 process_i386_registers (FILE *table
)
805 char *str
, *p
, *last
;
806 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
807 char *dw2_32_num
, *dw2_64_num
;
809 filename
= "i386-reg.tbl";
810 fp
= fopen (filename
, "r");
812 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
815 fprintf (table
, "\n/* i386 register table. */\n\n");
816 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
820 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
825 p
= remove_leading_whitespaces (buf
);
828 str
= strstr (p
, "//");
832 /* Remove trailing white spaces. */
833 remove_trailing_whitespaces (p
);
838 fprintf (table
, "%s\n", p
);
846 last
= p
+ strlen (p
);
849 reg_name
= next_field (p
, ',', &str
);
855 reg_type
= next_field (str
, ',', &str
);
860 /* Find reg_flags. */
861 reg_flags
= next_field (str
, ',', &str
);
867 reg_num
= next_field (str
, ',', &str
);
872 fprintf (table
, " { \"%s\",\n ", reg_name
);
874 process_i386_operand_type (table
, reg_type
, 0, "\t");
876 /* Find 32-bit Dwarf2 register number. */
877 dw2_32_num
= next_field (str
, ',', &str
);
882 /* Find 64-bit Dwarf2 register number. */
883 dw2_64_num
= next_field (str
, ',', &str
);
885 fprintf (table
, ",\n %s, %s, { %s, %s } },\n",
886 reg_flags
, reg_num
, dw2_32_num
, dw2_64_num
);
891 fprintf (table
, "};\n");
893 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
897 process_i386_initializers (void)
900 FILE *fp
= fopen ("i386-init.h", "w");
904 fail (_("can't create i386-init.h, errno = %s\n"),
907 process_copyright (fp
);
909 for (i
= 0; i
< ARRAY_SIZE (cpu_flag_init
); i
++)
911 fprintf (fp
, "\n#define %s \\\n", cpu_flag_init
[i
].name
);
912 init
= xstrdup (cpu_flag_init
[i
].init
);
913 process_i386_cpu_flag (fp
, init
, 1, "", " ");
917 for (i
= 0; i
< ARRAY_SIZE (operand_type_init
); i
++)
919 fprintf (fp
, "\n\n#define %s \\\n ", operand_type_init
[i
].name
);
920 init
= xstrdup (operand_type_init
[i
].init
);
921 process_i386_operand_type (fp
, init
, 1, " ");
929 /* Program options. */
930 #define OPTION_SRCDIR 200
932 struct option long_options
[] =
934 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
935 {"debug", no_argument
, NULL
, 'd'},
936 {"version", no_argument
, NULL
, 'V'},
937 {"help", no_argument
, NULL
, 'h'},
938 {0, no_argument
, NULL
, 0}
944 printf ("%s: version 1.0\n", program_name
);
949 usage (FILE * stream
, int status
)
951 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
957 main (int argc
, char **argv
)
959 extern int chdir (char *);
964 program_name
= *argv
;
965 xmalloc_set_program_name (program_name
);
967 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
992 if (chdir (srcdir
) != 0)
993 fail (_("unable to change directory to \"%s\", errno = %s\n"),
994 srcdir
, xstrerror (errno
));
996 /* Check the unused bitfield in i386_cpu_flags. */
998 c
= CpuNumOfBits
- CpuMax
- 1;
1000 fail (_("%d unused bits in i386_cpu_flags.\n"), c
);
1003 /* Check the unused bitfield in i386_operand_type. */
1005 c
= OTNumOfBits
- OTMax
- 1;
1007 fail (_("%d unused bits in i386_operand_type.\n"), c
);
1010 qsort (cpu_flags
, ARRAY_SIZE (cpu_flags
), sizeof (cpu_flags
[0]),
1013 qsort (opcode_modifiers
, ARRAY_SIZE (opcode_modifiers
),
1014 sizeof (opcode_modifiers
[0]), compare
);
1016 qsort (operand_types
, ARRAY_SIZE (operand_types
),
1017 sizeof (operand_types
[0]), compare
);
1019 table
= fopen ("i386-tbl.h", "w");
1021 fail (_("can't create i386-tbl.h, errno = %s\n"),
1024 process_copyright (table
);
1026 process_i386_opcodes (table
);
1027 process_i386_registers (table
);
1028 process_i386_initializers ();