1 /* Copyright 2007 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. */
25 #include "libiberty.h"
26 #include "safe-ctype.h"
31 #define _(String) gettext (String)
33 static const char *program_name
= NULL
;
37 fail (const char *message
, ...)
41 va_start (args
, message
);
42 fprintf (stderr
, _("%s: Error: "), program_name
);
43 vfprintf (stderr
, message
, args
);
49 process_copyright (FILE *fp
)
51 fprintf (fp
, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
52 /* Copyright 2007 Free Software Foundation, Inc.\n\
54 This file is part of the GNU opcodes library.\n\
56 This library is free software; you can redistribute it and/or modify\n\
57 it under the terms of the GNU General Public License as published by\n\
58 the Free Software Foundation; either version 3, or (at your option)\n\
61 It is distributed in the hope that it will be useful, but WITHOUT\n\
62 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
63 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
64 License for more details.\n\
66 You should have received a copy of the GNU General Public License\n\
67 along with this program; if not, write to the Free Software\n\
68 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
69 MA 02110-1301, USA. */\n");
72 /* Remove leading white spaces. */
75 remove_leading_whitespaces (char *str
)
77 while (ISSPACE (*str
))
82 /* Remove trailing white spaces. */
85 remove_trailing_whitespaces (char *str
)
87 size_t last
= strlen (str
);
95 if (ISSPACE (str
[last
]))
103 /* Find next field separated by '.' and terminate it. Return a
104 pointer to the one after it. */
107 next_field (char *str
, char **next
)
111 p
= remove_leading_whitespaces (str
);
112 for (str
= p
; *str
!= ',' && *str
!= '\0'; str
++);
115 remove_trailing_whitespaces (p
);
123 process_i386_opcodes (FILE *table
)
125 FILE *fp
= fopen ("i386-opc.tbl", "r");
128 char *str
, *p
, *last
;
129 char *name
, *operands
, *base_opcode
, *extension_opcode
;
130 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
133 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
136 fprintf (table
, "\n/* i386 opcode table. */\n\n");
137 fprintf (table
, "const template i386_optab[] =\n{\n");
141 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
144 p
= remove_leading_whitespaces (buf
);
147 str
= strstr (p
, "//");
151 /* Remove trailing white spaces. */
152 remove_trailing_whitespaces (p
);
157 fprintf (table
, "%s\n", p
);
165 last
= p
+ strlen (p
);
168 name
= next_field (p
, &str
);
173 /* Find number of operands. */
174 operands
= next_field (str
, &str
);
179 /* Find base_opcode. */
180 base_opcode
= next_field (str
, &str
);
185 /* Find extension_opcode. */
186 extension_opcode
= next_field (str
, &str
);
191 /* Find cpu_flags. */
192 cpu_flags
= next_field (str
, &str
);
197 /* Find opcode_modifier. */
198 opcode_modifier
= next_field (str
, &str
);
203 /* Remove the first {. */
204 str
= remove_leading_whitespaces (str
);
207 str
= remove_leading_whitespaces (str
+ 1);
211 /* There are at least "X}". */
215 /* Remove trailing white spaces and }. */
219 if (ISSPACE (str
[i
]) || str
[i
] == '}')
228 /* Find operand_types. */
229 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
233 operand_types
[i
] = NULL
;
237 operand_types
[i
] = next_field (str
, &str
);
238 if (*operand_types
[i
] == '0')
241 operand_types
[i
] = NULL
;
246 fprintf (table
, " { \"%s\", %s, %s, %s, %s,\n",
247 name
, operands
, base_opcode
, extension_opcode
,
250 fprintf (table
, " %s,\n", opcode_modifier
);
252 fprintf (table
, " { ");
254 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
256 if (operand_types
[i
] == NULL
257 || *operand_types
[i
] == '0')
260 fprintf (table
, "0");
265 fprintf (table
, ",\n ");
267 fprintf (table
, "%s", operand_types
[i
]);
269 fprintf (table
, " } },\n");
274 fprintf (table
, " { NULL, 0, 0, 0, 0, 0, { 0 } }\n");
275 fprintf (table
, "};\n");
279 process_i386_registers (FILE *table
)
281 FILE *fp
= fopen ("i386-reg.tbl", "r");
283 char *str
, *p
, *last
;
284 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
287 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
290 fprintf (table
, "\n/* i386 register table. */\n\n");
291 fprintf (table
, "const reg_entry i386_regtab[] =\n{\n");
295 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
298 p
= remove_leading_whitespaces (buf
);
301 str
= strstr (p
, "//");
305 /* Remove trailing white spaces. */
306 remove_trailing_whitespaces (p
);
311 fprintf (table
, "%s\n", p
);
319 last
= p
+ strlen (p
);
322 reg_name
= next_field (p
, &str
);
328 reg_type
= next_field (str
, &str
);
333 /* Find reg_flags. */
334 reg_flags
= next_field (str
, &str
);
340 reg_num
= next_field (str
, &str
);
342 fprintf (table
, " { \"%s\", %s, %s, %s },\n",
343 reg_name
, reg_type
, reg_flags
, reg_num
);
348 fprintf (table
, "};\n");
350 fprintf (table
, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
353 /* Program options. */
354 #define OPTION_SRCDIR 200
356 struct option long_options
[] =
358 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
359 {"debug", no_argument
, NULL
, 'd'},
360 {"version", no_argument
, NULL
, 'V'},
361 {"help", no_argument
, NULL
, 'h'},
362 {0, no_argument
, NULL
, 0}
368 printf ("%s: version 1.0\n", program_name
);
373 usage (FILE * stream
, int status
)
375 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
381 main (int argc
, char **argv
)
383 extern int chdir (char *);
388 program_name
= *argv
;
389 xmalloc_set_program_name (program_name
);
391 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
416 if (chdir (srcdir
) != 0)
417 fail (_("unable to change directory to \"%s\", errno = %s\n"),
418 srcdir
, strerror (errno
));
420 table
= fopen ("i386-tbl.h", "w");
422 fail (_("can't create i386-tbl.h, errno = %s\n"), strerror (errno
));
424 process_copyright (table
);
426 process_i386_opcodes (table
);
427 process_i386_registers (table
);