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
);
48 /* Remove leading white spaces. */
51 remove_leading_whitespaces (char *str
)
53 while (ISSPACE (*str
))
58 /* Remove trailing white spaces. */
61 remove_trailing_whitespaces (char *str
)
63 size_t last
= strlen (str
);
71 if (ISSPACE (str
[last
]))
79 /* Find next field separated by '.' and terminate it. Return a
80 pointer to the one after it. */
83 next_field (char *str
, char **next
)
87 p
= remove_leading_whitespaces (str
);
88 for (str
= p
; *str
!= ',' && *str
!= '\0'; str
++);
91 remove_trailing_whitespaces (p
);
99 process_i386_opcodes (void)
101 FILE *fp
= fopen ("i386-opc.tbl", "r");
104 char *str
, *p
, *last
;
105 char *name
, *operands
, *base_opcode
, *extension_opcode
;
106 char *cpu_flags
, *opcode_modifier
, *operand_types
[MAX_OPERANDS
];
109 fail (_("can't find i386-opc.tbl for reading\n"));
111 printf ("\n/* i386 opcode table. */\n\n");
112 printf ("const template i386_optab[] =\n{\n");
116 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
119 p
= remove_leading_whitespaces (buf
);
122 str
= strstr (p
, "//");
126 /* Remove trailing white spaces. */
127 remove_trailing_whitespaces (p
);
140 last
= p
+ strlen (p
);
143 name
= next_field (p
, &str
);
148 /* Find number of operands. */
149 operands
= next_field (str
, &str
);
154 /* Find base_opcode. */
155 base_opcode
= next_field (str
, &str
);
160 /* Find extension_opcode. */
161 extension_opcode
= next_field (str
, &str
);
166 /* Find cpu_flags. */
167 cpu_flags
= next_field (str
, &str
);
172 /* Find opcode_modifier. */
173 opcode_modifier
= next_field (str
, &str
);
178 /* Remove the first {. */
179 str
= remove_leading_whitespaces (str
);
182 str
= remove_leading_whitespaces (str
+ 1);
186 /* There are at least "X}". */
190 /* Remove trailing white spaces and }. */
194 if (ISSPACE (str
[i
]) || str
[i
] == '}')
203 /* Find operand_types. */
204 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
208 operand_types
[i
] = NULL
;
212 operand_types
[i
] = next_field (str
, &str
);
213 if (*operand_types
[i
] == '0')
216 operand_types
[i
] = NULL
;
221 printf (" { \"%s\", %s, %s, %s, %s,\n",
222 name
, operands
, base_opcode
, extension_opcode
,
225 printf (" %s,\n", opcode_modifier
);
229 for (i
= 0; i
< ARRAY_SIZE (operand_types
); i
++)
231 if (operand_types
[i
] == NULL
232 || *operand_types
[i
] == '0')
242 printf ("%s", operand_types
[i
]);
247 printf (" { NULL, 0, 0, 0, 0, 0, { 0 } }\n");
252 process_i386_registers (void)
254 FILE *fp
= fopen ("i386-reg.tbl", "r");
256 char *str
, *p
, *last
;
257 char *reg_name
, *reg_type
, *reg_flags
, *reg_num
;
260 fail (_("can't find i386-reg.tbl for reading\n"));
262 printf ("\n/* i386 register table. */\n\n");
263 printf ("const reg_entry i386_regtab[] =\n{\n");
267 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
270 p
= remove_leading_whitespaces (buf
);
273 str
= strstr (p
, "//");
277 /* Remove trailing white spaces. */
278 remove_trailing_whitespaces (p
);
291 last
= p
+ strlen (p
);
294 reg_name
= next_field (p
, &str
);
300 reg_type
= next_field (str
, &str
);
305 /* Find reg_flags. */
306 reg_flags
= next_field (str
, &str
);
312 reg_num
= next_field (str
, &str
);
314 printf (" { \"%s\", %s, %s, %s },\n",
315 reg_name
, reg_type
, reg_flags
, reg_num
);
320 printf ("\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
323 /* Program options. */
324 #define OPTION_SRCDIR 200
326 struct option long_options
[] =
328 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
329 {"debug", no_argument
, NULL
, 'd'},
330 {"version", no_argument
, NULL
, 'V'},
331 {"help", no_argument
, NULL
, 'h'},
332 {0, no_argument
, NULL
, 0}
338 printf ("%s: version 1.0\n", program_name
);
343 usage (FILE * stream
, int status
)
345 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
351 main (int argc
, char **argv
)
353 extern int chdir (char *);
357 program_name
= *argv
;
358 xmalloc_set_program_name (program_name
);
360 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
385 if (chdir (srcdir
) != 0)
386 fail (_("unable to change directory to \"%s\", errno = %s\n"),
387 srcdir
, strerror (errno
));
389 printf ("/* This file is automatically generated by i386-gen. Do not edit! */\n");
390 printf ("/* Copyright 2007 Free Software Foundation, Inc.\n\
392 This file is part of the GNU opcodes library.\n\
394 This library is free software; you can redistribute it and/or modify\n\
395 it under the terms of the GNU General Public License as published by\n\
396 the Free Software Foundation; either version 3, or (at your option)\n\
397 any later version.\n\
399 It is distributed in the hope that it will be useful, but WITHOUT\n\
400 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
401 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
402 License for more details.\n\
404 You should have received a copy of the GNU General Public License\n\
405 along with this program; if not, write to the Free Software\n\
406 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
407 MA 02110-1301, USA. */");
409 process_i386_opcodes ();
410 process_i386_registers ();