* breakpoint.c (break_command_really): New parameter
[deliverable/binutils-gdb.git] / opcodes / i386-gen.c
CommitLineData
6f143e4d 1/* Copyright 2007, 2008 Free Software Foundation, Inc.
40b8e679 2
9b201bb5 3 This file is part of the GNU opcodes library.
40b8e679 4
9b201bb5 5 This library is free software; you can redistribute it and/or modify
40b8e679 6 it under the terms of the GNU General Public License as published by
9b201bb5
NC
7 the Free Software Foundation; either version 3, or (at your option)
8 any later version.
40b8e679 9
9b201bb5
NC
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.
40b8e679
L
14
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
9b201bb5
NC
17 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
18 MA 02110-1301, USA. */
40b8e679 19
40fb9820 20#include "sysdep.h"
40b8e679 21#include <stdio.h>
40b8e679
L
22#include <errno.h>
23#include "getopt.h"
24#include "libiberty.h"
25#include "safe-ctype.h"
26
27#include "i386-opc.h"
28
29#include <libintl.h>
30#define _(String) gettext (String)
31
32static const char *program_name = NULL;
33static int debug = 0;
34
40fb9820
L
35typedef struct initializer
36{
37 const char *name;
38 const char *init;
39} initializer;
40
41static initializer cpu_flag_init [] =
42{
43 { "CPU_UNKNOWN_FLAGS",
44 "unknown" },
45 { "CPU_GENERIC32_FLAGS",
46 "Cpu186|Cpu286|Cpu386" },
47 { "CPU_GENERIC64_FLAGS",
48 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuMMX2|CpuSSE|CpuSSE2" },
49 { "CPU_NONE_FLAGS",
50 "0" },
51 { "CPU_I186_FLAGS",
52 "Cpu186" },
53 { "CPU_I286_FLAGS",
54 "Cpu186|Cpu286" },
55 { "CPU_I386_FLAGS",
56 "Cpu186|Cpu286|Cpu386" },
57 { "CPU_I486_FLAGS",
58 "Cpu186|Cpu286|Cpu386|Cpu486" },
59 { "CPU_I586_FLAGS",
60 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
61 { "CPU_I686_FLAGS",
62 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686" },
63 { "CPU_P2_FLAGS",
64 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuMMX" },
65 { "CPU_P3_FLAGS",
66 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuMMX|CpuMMX2|CpuSSE" },
67 { "CPU_P4_FLAGS",
68 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuMMX2|CpuSSE|CpuSSE2" },
69 { "CPU_NOCONA_FLAGS",
70 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuMMX2|CpuSSE|CpuSSE2|CpuSSE3|CpuLM" },
71 { "CPU_CORE_FLAGS",
72 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuMMX2|CpuSSE|CpuSSE2|CpuSSE3" },
73 { "CPU_CORE2_FLAGS",
74 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuMMX|CpuMMX2|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuLM" },
75 { "CPU_K6_FLAGS",
76 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuK6|CpuMMX" },
77 { "CPU_K6_2_FLAGS",
78 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuK6|CpuMMX|Cpu3dnow" },
79 { "CPU_ATHLON_FLAGS",
80 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuK6|CpuMMX|CpuMMX2|Cpu3dnow|Cpu3dnowA" },
81 { "CPU_K8_FLAGS",
82 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuK6|CpuK8|CpuMMX|CpuMMX2|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuLM" },
83 { "CPU_AMDFAM10_FLAGS",
3629bb00 84 "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuK6|CpuK8|CpuMMX|CpuMMX2|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM" },
40fb9820
L
85 { "CPU_MMX_FLAGS",
86 "CpuMMX" },
87 { "CPU_SSE_FLAGS",
88 "CpuMMX|CpuMMX2|CpuSSE" },
89 { "CPU_SSE2_FLAGS",
90 "CpuMMX|CpuMMX2|CpuSSE|CpuSSE2" },
91 { "CPU_SSE3_FLAGS",
92 "CpuMMX|CpuMMX2|CpuSSE|CpuSSE2|CpuSSE3" },
93 { "CPU_SSSE3_FLAGS",
94 "CpuMMX|CpuMMX2|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3" },
95 { "CPU_SSE4_1_FLAGS",
3629bb00 96 "CpuMMX|CpuMMX2|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1" },
40fb9820 97 { "CPU_SSE4_2_FLAGS",
3629bb00 98 "CpuMMX|CpuMMX2|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2" },
6305a203
L
99 { "CPU_VMX_FLAGS",
100 "CpuVMX" },
101 { "CPU_SMX_FLAGS",
102 "CpuSMX" },
40fb9820
L
103 { "CPU_3DNOW_FLAGS",
104 "CpuMMX|Cpu3dnow" },
105 { "CPU_3DNOWA_FLAGS",
106 "CpuMMX|CpuMMX2|Cpu3dnow|Cpu3dnowA" },
107 { "CPU_PADLOCK_FLAGS",
108 "CpuPadLock" },
109 { "CPU_SVME_FLAGS",
110 "CpuSVME" },
111 { "CPU_SSE4A_FLAGS",
112 "CpuMMX|CpuMMX2|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
113 { "CPU_ABM_FLAGS",
3629bb00 114 "CpuABM" },
85f10a01 115 { "CPU_SSE5_FLAGS",
3629bb00 116 "CpuMMX|CpuMMX2|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuSSE5"},
40fb9820
L
117};
118
119static initializer operand_type_init [] =
120{
121 { "OPERAND_TYPE_NONE",
122 "0" },
123 { "OPERAND_TYPE_REG8",
124 "Reg8" },
125 { "OPERAND_TYPE_REG16",
126 "Reg16" },
127 { "OPERAND_TYPE_REG32",
128 "Reg32" },
129 { "OPERAND_TYPE_REG64",
130 "Reg64" },
131 { "OPERAND_TYPE_IMM1",
132 "Imm1" },
133 { "OPERAND_TYPE_IMM8",
134 "Imm8" },
135 { "OPERAND_TYPE_IMM8S",
136 "Imm8S" },
137 { "OPERAND_TYPE_IMM16",
138 "Imm16" },
139 { "OPERAND_TYPE_IMM32",
140 "Imm32" },
141 { "OPERAND_TYPE_IMM32S",
142 "Imm32S" },
143 { "OPERAND_TYPE_IMM64",
144 "Imm64" },
145 { "OPERAND_TYPE_BASEINDEX",
146 "BaseIndex" },
147 { "OPERAND_TYPE_DISP8",
148 "Disp8" },
149 { "OPERAND_TYPE_DISP16",
150 "Disp16" },
151 { "OPERAND_TYPE_DISP32",
152 "Disp32" },
153 { "OPERAND_TYPE_DISP32S",
154 "Disp32S" },
155 { "OPERAND_TYPE_DISP64",
156 "Disp64" },
157 { "OPERAND_TYPE_INOUTPORTREG",
158 "InOutPortReg" },
159 { "OPERAND_TYPE_SHIFTCOUNT",
160 "ShiftCount" },
161 { "OPERAND_TYPE_CONTROL",
162 "Control" },
163 { "OPERAND_TYPE_TEST",
164 "Test" },
165 { "OPERAND_TYPE_DEBUG",
166 "FloatReg" },
167 { "OPERAND_TYPE_FLOATREG",
168 "FloatReg" },
169 { "OPERAND_TYPE_FLOATACC",
170 "FloatAcc" },
171 { "OPERAND_TYPE_SREG2",
172 "SReg2" },
173 { "OPERAND_TYPE_SREG3",
174 "SReg3" },
175 { "OPERAND_TYPE_ACC",
176 "Acc" },
177 { "OPERAND_TYPE_JUMPABSOLUTE",
178 "JumpAbsolute" },
179 { "OPERAND_TYPE_REGMMX",
180 "RegMMX" },
181 { "OPERAND_TYPE_REGXMM",
182 "RegXMM" },
183 { "OPERAND_TYPE_ESSEG",
184 "EsSeg" },
185 { "OPERAND_TYPE_ACC32",
7d5e4556 186 "Reg32|Acc|Dword" },
40fb9820 187 { "OPERAND_TYPE_ACC64",
7d5e4556 188 "Reg64|Acc|Qword" },
40fb9820
L
189 { "OPERAND_TYPE_REG16_INOUTPORTREG",
190 "Reg16|InOutPortReg" },
191 { "OPERAND_TYPE_DISP16_32",
192 "Disp16|Disp32" },
193 { "OPERAND_TYPE_ANYDISP",
194 "Disp8|Disp16|Disp32|Disp32S|Disp64" },
195 { "OPERAND_TYPE_IMM16_32",
196 "Imm16|Imm32" },
197 { "OPERAND_TYPE_IMM16_32S",
198 "Imm16|Imm32S" },
199 { "OPERAND_TYPE_IMM16_32_32S",
200 "Imm16|Imm32|Imm32S" },
201 { "OPERAND_TYPE_IMM32_32S_DISP32",
202 "Imm32|Imm32S|Disp32" },
203 { "OPERAND_TYPE_IMM64_DISP64",
204 "Imm64|Disp64" },
205 { "OPERAND_TYPE_IMM32_32S_64_DISP32",
206 "Imm32|Imm32S|Imm64|Disp32" },
207 { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
208 "Imm32|Imm32S|Imm64|Disp32|Disp64" },
209};
210
211typedef struct bitfield
212{
213 int position;
214 int value;
215 const char *name;
216} bitfield;
217
218#define BITFIELD(n) { n, 0, #n }
219
220static bitfield cpu_flags[] =
221{
222 BITFIELD (Cpu186),
223 BITFIELD (Cpu286),
224 BITFIELD (Cpu386),
225 BITFIELD (Cpu486),
226 BITFIELD (Cpu586),
227 BITFIELD (Cpu686),
228 BITFIELD (CpuP4),
229 BITFIELD (CpuK6),
230 BITFIELD (CpuK8),
231 BITFIELD (CpuMMX),
232 BITFIELD (CpuMMX2),
233 BITFIELD (CpuSSE),
234 BITFIELD (CpuSSE2),
235 BITFIELD (CpuSSE3),
236 BITFIELD (CpuSSSE3),
237 BITFIELD (CpuSSE4_1),
238 BITFIELD (CpuSSE4_2),
239 BITFIELD (CpuSSE4a),
85f10a01 240 BITFIELD (CpuSSE5),
40fb9820
L
241 BITFIELD (Cpu3dnow),
242 BITFIELD (Cpu3dnowA),
243 BITFIELD (CpuPadLock),
244 BITFIELD (CpuSVME),
245 BITFIELD (CpuVMX),
47dd174c 246 BITFIELD (CpuSMX),
40fb9820
L
247 BITFIELD (CpuABM),
248 BITFIELD (CpuLM),
249 BITFIELD (Cpu64),
250 BITFIELD (CpuNo64),
251#ifdef CpuUnused
252 BITFIELD (CpuUnused),
253#endif
254};
255
256static bitfield opcode_modifiers[] =
257{
258 BITFIELD (D),
259 BITFIELD (W),
260 BITFIELD (Modrm),
261 BITFIELD (ShortForm),
262 BITFIELD (Jump),
263 BITFIELD (JumpDword),
264 BITFIELD (JumpByte),
265 BITFIELD (JumpInterSegment),
266 BITFIELD (FloatMF),
267 BITFIELD (FloatR),
268 BITFIELD (FloatD),
269 BITFIELD (Size16),
270 BITFIELD (Size32),
271 BITFIELD (Size64),
272 BITFIELD (IgnoreSize),
273 BITFIELD (DefaultSize),
274 BITFIELD (No_bSuf),
275 BITFIELD (No_wSuf),
276 BITFIELD (No_lSuf),
277 BITFIELD (No_sSuf),
278 BITFIELD (No_qSuf),
7ce189b3 279 BITFIELD (No_ldSuf),
40fb9820
L
280 BITFIELD (FWait),
281 BITFIELD (IsString),
282 BITFIELD (RegKludge),
e2ec9d29 283 BITFIELD (FirstXmm0),
ca61edf2
L
284 BITFIELD (ByteOkIntel),
285 BITFIELD (ToDword),
286 BITFIELD (ToQword),
287 BITFIELD (AddrPrefixOp0),
40fb9820
L
288 BITFIELD (IsPrefix),
289 BITFIELD (ImmExt),
290 BITFIELD (NoRex64),
291 BITFIELD (Rex64),
292 BITFIELD (Ugh),
85f10a01
MM
293 BITFIELD (Drex),
294 BITFIELD (Drexv),
295 BITFIELD (Drexc),
1efbbeb4
L
296 BITFIELD (OldGcc),
297 BITFIELD (ATTMnemonic),
e1d4d893 298 BITFIELD (ATTSyntax),
5c07affc 299 BITFIELD (IntelSyntax),
40fb9820
L
300};
301
302static bitfield operand_types[] =
303{
304 BITFIELD (Reg8),
305 BITFIELD (Reg16),
306 BITFIELD (Reg32),
307 BITFIELD (Reg64),
308 BITFIELD (FloatReg),
309 BITFIELD (RegMMX),
310 BITFIELD (RegXMM),
311 BITFIELD (Imm8),
312 BITFIELD (Imm8S),
313 BITFIELD (Imm16),
314 BITFIELD (Imm32),
315 BITFIELD (Imm32S),
316 BITFIELD (Imm64),
317 BITFIELD (Imm1),
318 BITFIELD (BaseIndex),
319 BITFIELD (Disp8),
320 BITFIELD (Disp16),
321 BITFIELD (Disp32),
322 BITFIELD (Disp32S),
323 BITFIELD (Disp64),
324 BITFIELD (InOutPortReg),
325 BITFIELD (ShiftCount),
326 BITFIELD (Control),
327 BITFIELD (Debug),
328 BITFIELD (Test),
329 BITFIELD (SReg2),
330 BITFIELD (SReg3),
331 BITFIELD (Acc),
332 BITFIELD (FloatAcc),
333 BITFIELD (JumpAbsolute),
334 BITFIELD (EsSeg),
335 BITFIELD (RegMem),
5c07affc 336 BITFIELD (Mem),
7d5e4556
L
337 BITFIELD (Byte),
338 BITFIELD (Word),
339 BITFIELD (Dword),
340 BITFIELD (Fword),
341 BITFIELD (Qword),
342 BITFIELD (Tbyte),
343 BITFIELD (Xmmword),
344 BITFIELD (Unspecified),
345 BITFIELD (Anysize),
40fb9820
L
346#ifdef OTUnused
347 BITFIELD (OTUnused),
348#endif
349};
350
3d4d5afa
L
351static int lineno;
352static const char *filename;
353
40fb9820
L
354static int
355compare (const void *x, const void *y)
356{
357 const bitfield *xp = (const bitfield *) x;
358 const bitfield *yp = (const bitfield *) y;
359 return xp->position - yp->position;
360}
361
40b8e679
L
362static void
363fail (const char *message, ...)
364{
365 va_list args;
366
367 va_start (args, message);
368 fprintf (stderr, _("%s: Error: "), program_name);
369 vfprintf (stderr, message, args);
370 va_end (args);
371 xexit (1);
372}
373
72ffa0fb
L
374static void
375process_copyright (FILE *fp)
376{
377 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
6f143e4d 378/* Copyright 2007, 2008 Free Software Foundation, Inc.\n\
72ffa0fb
L
379\n\
380 This file is part of the GNU opcodes library.\n\
381\n\
382 This library is free software; you can redistribute it and/or modify\n\
383 it under the terms of the GNU General Public License as published by\n\
384 the Free Software Foundation; either version 3, or (at your option)\n\
385 any later version.\n\
386\n\
387 It is distributed in the hope that it will be useful, but WITHOUT\n\
388 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
389 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
390 License for more details.\n\
391\n\
392 You should have received a copy of the GNU General Public License\n\
393 along with this program; if not, write to the Free Software\n\
394 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
395 MA 02110-1301, USA. */\n");
396}
397
40b8e679
L
398/* Remove leading white spaces. */
399
400static char *
401remove_leading_whitespaces (char *str)
402{
403 while (ISSPACE (*str))
404 str++;
405 return str;
406}
407
408/* Remove trailing white spaces. */
409
410static void
411remove_trailing_whitespaces (char *str)
412{
413 size_t last = strlen (str);
414
415 if (last == 0)
416 return;
417
418 do
419 {
420 last--;
421 if (ISSPACE (str [last]))
422 str[last] = '\0';
423 else
424 break;
425 }
426 while (last != 0);
427}
428
93b1ec2c 429/* Find next field separated by SEP and terminate it. Return a
40b8e679
L
430 pointer to the one after it. */
431
432static char *
93b1ec2c 433next_field (char *str, char sep, char **next)
40b8e679
L
434{
435 char *p;
436
437 p = remove_leading_whitespaces (str);
93b1ec2c 438 for (str = p; *str != sep && *str != '\0'; str++);
40b8e679
L
439
440 *str = '\0';
441 remove_trailing_whitespaces (p);
442
443 *next = str + 1;
444
445 return p;
446}
447
40fb9820
L
448static void
449set_bitfield (const char *f, bitfield *array, unsigned int size)
450{
451 unsigned int i;
452
453 if (strcmp (f, "CpuSledgehammer") == 0)
454 f= "CpuK8";
7d5e4556
L
455 else if (strcmp (f, "Mmword") == 0)
456 f= "Qword";
457 else if (strcmp (f, "Oword") == 0)
458 f= "Xmmword";
40fb9820
L
459
460 for (i = 0; i < size; i++)
461 if (strcasecmp (array[i].name, f) == 0)
462 {
463 array[i].value = 1;
464 return;
465 }
466
50e8458f 467 fail (_("%s: %d: Unknown bitfield: %s\n"), filename, lineno, f);
40fb9820
L
468}
469
470static void
471output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
472 int macro, const char *comma, const char *indent)
473{
474 unsigned int i;
475
476 fprintf (table, "%s{ { ", indent);
477
478 for (i = 0; i < size - 1; i++)
479 {
480 fprintf (table, "%d, ", flags[i].value);
481 if (((i + 1) % 20) == 0)
482 {
483 /* We need \\ for macro. */
484 if (macro)
485 fprintf (table, " \\\n %s", indent);
486 else
487 fprintf (table, "\n %s", indent);
488 }
489 }
490
491 fprintf (table, "%d } }%s\n", flags[i].value, comma);
492}
493
494static void
495process_i386_cpu_flag (FILE *table, char *flag, int macro,
496 const char *comma, const char *indent)
497{
498 char *str, *next, *last;
499 bitfield flags [ARRAY_SIZE (cpu_flags)];
500
501 /* Copy the default cpu flags. */
502 memcpy (flags, cpu_flags, sizeof (cpu_flags));
503
504 if (strcasecmp (flag, "unknown") == 0)
505 {
506 unsigned int i;
507
508 /* We turn on everything except for cpu64 in case of
509 CPU_UNKNOWN_FLAGS. */
510 for (i = 0; i < ARRAY_SIZE (flags); i++)
511 if (flags[i].position != Cpu64)
512 flags[i].value = 1;
513 }
514 else if (strcmp (flag, "0"))
515 {
516 last = flag + strlen (flag);
517 for (next = flag; next && next < last; )
518 {
519 str = next_field (next, '|', &next);
520 if (str)
521 set_bitfield (str, flags, ARRAY_SIZE (flags));
522 }
523 }
524
525 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
526 comma, indent);
527}
528
529static void
530output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
531{
532 unsigned int i;
533
534 fprintf (table, " { ");
535
536 for (i = 0; i < size - 1; i++)
537 {
538 fprintf (table, "%d, ", modifier[i].value);
539 if (((i + 1) % 20) == 0)
540 fprintf (table, "\n ");
541 }
542
543 fprintf (table, "%d },\n", modifier[i].value);
544}
545
546static void
547process_i386_opcode_modifier (FILE *table, char *mod)
548{
549 char *str, *next, *last;
550 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
551
552 /* Copy the default opcode modifier. */
553 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
554
555 if (strcmp (mod, "0"))
556 {
557 last = mod + strlen (mod);
558 for (next = mod; next && next < last; )
559 {
560 str = next_field (next, '|', &next);
561 if (str)
562 set_bitfield (str, modifiers, ARRAY_SIZE (modifiers));
563 }
564 }
565 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
566}
567
568static void
569output_operand_type (FILE *table, bitfield *types, unsigned int size,
570 int macro, const char *indent)
571{
572 unsigned int i;
573
574 fprintf (table, "{ { ");
575
576 for (i = 0; i < size - 1; i++)
577 {
578 fprintf (table, "%d, ", types[i].value);
579 if (((i + 1) % 20) == 0)
580 {
581 /* We need \\ for macro. */
582 if (macro)
583 fprintf (table, "\\\n%s", indent);
584 else
585 fprintf (table, "\n%s", indent);
586 }
587 }
588
589 fprintf (table, "%d } }", types[i].value);
590}
591
592static void
593process_i386_operand_type (FILE *table, char *op, int macro,
594 const char *indent)
595{
596 char *str, *next, *last;
597 bitfield types [ARRAY_SIZE (operand_types)];
598
599 /* Copy the default operand type. */
600 memcpy (types, operand_types, sizeof (types));
601
602 if (strcmp (op, "0"))
603 {
604 last = op + strlen (op);
605 for (next = op; next && next < last; )
606 {
607 str = next_field (next, '|', &next);
608 if (str)
609 set_bitfield (str, types, ARRAY_SIZE (types));
610 }
611 }
612 output_operand_type (table, types, ARRAY_SIZE (types), macro,
613 indent);
614}
615
40b8e679 616static void
72ffa0fb 617process_i386_opcodes (FILE *table)
40b8e679 618{
3d4d5afa 619 FILE *fp;
40b8e679
L
620 char buf[2048];
621 unsigned int i;
622 char *str, *p, *last;
623 char *name, *operands, *base_opcode, *extension_opcode;
4dffcebc 624 char *opcode_length;
40b8e679
L
625 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
626
3d4d5afa
L
627 filename = "i386-opc.tbl";
628 fp = fopen (filename, "r");
629
40b8e679 630 if (fp == NULL)
34edb9ad 631 fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
40fb9820 632 xstrerror (errno));
40b8e679 633
34edb9ad
L
634 fprintf (table, "\n/* i386 opcode table. */\n\n");
635 fprintf (table, "const template i386_optab[] =\n{\n");
40b8e679
L
636
637 while (!feof (fp))
638 {
639 if (fgets (buf, sizeof (buf), fp) == NULL)
640 break;
641
3d4d5afa
L
642 lineno++;
643
40b8e679
L
644 p = remove_leading_whitespaces (buf);
645
646 /* Skip comments. */
647 str = strstr (p, "//");
648 if (str != NULL)
649 str[0] = '\0';
650
651 /* Remove trailing white spaces. */
652 remove_trailing_whitespaces (p);
653
654 switch (p[0])
655 {
656 case '#':
34edb9ad 657 fprintf (table, "%s\n", p);
40b8e679
L
658 case '\0':
659 continue;
660 break;
661 default:
662 break;
663 }
664
665 last = p + strlen (p);
666
667 /* Find name. */
93b1ec2c 668 name = next_field (p, ',', &str);
40b8e679
L
669
670 if (str >= last)
671 abort ();
672
673 /* Find number of operands. */
93b1ec2c 674 operands = next_field (str, ',', &str);
40b8e679
L
675
676 if (str >= last)
677 abort ();
678
679 /* Find base_opcode. */
93b1ec2c 680 base_opcode = next_field (str, ',', &str);
40b8e679
L
681
682 if (str >= last)
683 abort ();
684
685 /* Find extension_opcode. */
93b1ec2c 686 extension_opcode = next_field (str, ',', &str);
40b8e679 687
4dffcebc
L
688 if (str >= last)
689 abort ();
690
691 /* Find opcode_length. */
692 opcode_length = next_field (str, ',', &str);
693
40b8e679
L
694 if (str >= last)
695 abort ();
696
697 /* Find cpu_flags. */
93b1ec2c 698 cpu_flags = next_field (str, ',', &str);
40b8e679
L
699
700 if (str >= last)
701 abort ();
702
703 /* Find opcode_modifier. */
93b1ec2c 704 opcode_modifier = next_field (str, ',', &str);
40b8e679
L
705
706 if (str >= last)
707 abort ();
708
709 /* Remove the first {. */
710 str = remove_leading_whitespaces (str);
711 if (*str != '{')
712 abort ();
713 str = remove_leading_whitespaces (str + 1);
714
715 i = strlen (str);
716
717 /* There are at least "X}". */
718 if (i < 2)
719 abort ();
720
721 /* Remove trailing white spaces and }. */
722 do
723 {
724 i--;
725 if (ISSPACE (str[i]) || str[i] == '}')
726 str[i] = '\0';
727 else
728 break;
729 }
730 while (i != 0);
731
732 last = str + i;
733
734 /* Find operand_types. */
735 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
736 {
737 if (str >= last)
738 {
739 operand_types [i] = NULL;
740 break;
741 }
742
93b1ec2c 743 operand_types [i] = next_field (str, ',', &str);
40b8e679
L
744 if (*operand_types[i] == '0')
745 {
746 if (i != 0)
747 operand_types[i] = NULL;
748 break;
749 }
750 }
751
4dffcebc
L
752 fprintf (table, " { \"%s\", %s, %s, %s, %s,\n",
753 name, operands, base_opcode, extension_opcode,
754 opcode_length);
40fb9820
L
755
756 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ");
40b8e679 757
40fb9820 758 process_i386_opcode_modifier (table, opcode_modifier);
40b8e679 759
34edb9ad 760 fprintf (table, " { ");
40b8e679
L
761
762 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
763 {
764 if (operand_types[i] == NULL
765 || *operand_types[i] == '0')
766 {
767 if (i == 0)
40fb9820 768 process_i386_operand_type (table, "0", 0, "\t ");
40b8e679
L
769 break;
770 }
771
772 if (i != 0)
34edb9ad 773 fprintf (table, ",\n ");
40b8e679 774
40fb9820
L
775 process_i386_operand_type (table, operand_types[i], 0,
776 "\t ");
40b8e679 777 }
34edb9ad 778 fprintf (table, " } },\n");
40b8e679
L
779 }
780
34edb9ad
L
781 fclose (fp);
782
4dffcebc 783 fprintf (table, " { NULL, 0, 0, 0, 0,\n");
40fb9820
L
784
785 process_i386_cpu_flag (table, "0", 0, ",", " ");
786
787 process_i386_opcode_modifier (table, "0");
788
789 fprintf (table, " { ");
790 process_i386_operand_type (table, "0", 0, "\t ");
791 fprintf (table, " } }\n");
792
34edb9ad 793 fprintf (table, "};\n");
40b8e679
L
794}
795
796static void
72ffa0fb 797process_i386_registers (FILE *table)
40b8e679 798{
3d4d5afa 799 FILE *fp;
40b8e679
L
800 char buf[2048];
801 char *str, *p, *last;
802 char *reg_name, *reg_type, *reg_flags, *reg_num;
803
3d4d5afa
L
804 filename = "i386-reg.tbl";
805 fp = fopen (filename, "r");
40b8e679 806 if (fp == NULL)
34edb9ad 807 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
40fb9820 808 xstrerror (errno));
40b8e679 809
34edb9ad
L
810 fprintf (table, "\n/* i386 register table. */\n\n");
811 fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
40b8e679
L
812
813 while (!feof (fp))
814 {
815 if (fgets (buf, sizeof (buf), fp) == NULL)
816 break;
817
3d4d5afa
L
818 lineno++;
819
40b8e679
L
820 p = remove_leading_whitespaces (buf);
821
822 /* Skip comments. */
823 str = strstr (p, "//");
824 if (str != NULL)
825 str[0] = '\0';
826
827 /* Remove trailing white spaces. */
828 remove_trailing_whitespaces (p);
829
830 switch (p[0])
831 {
832 case '#':
34edb9ad 833 fprintf (table, "%s\n", p);
40b8e679
L
834 case '\0':
835 continue;
836 break;
837 default:
838 break;
839 }
840
841 last = p + strlen (p);
842
843 /* Find reg_name. */
93b1ec2c 844 reg_name = next_field (p, ',', &str);
40b8e679
L
845
846 if (str >= last)
847 abort ();
848
849 /* Find reg_type. */
93b1ec2c 850 reg_type = next_field (str, ',', &str);
40b8e679
L
851
852 if (str >= last)
853 abort ();
854
855 /* Find reg_flags. */
93b1ec2c 856 reg_flags = next_field (str, ',', &str);
40b8e679
L
857
858 if (str >= last)
859 abort ();
860
861 /* Find reg_num. */
93b1ec2c 862 reg_num = next_field (str, ',', &str);
40b8e679 863
40fb9820
L
864 fprintf (table, " { \"%s\",\n ", reg_name);
865
866 process_i386_operand_type (table, reg_type, 0, "\t");
867
868 fprintf (table, ",\n %s, %s },\n", reg_flags, reg_num);
40b8e679
L
869 }
870
34edb9ad
L
871 fclose (fp);
872
873 fprintf (table, "};\n");
40b8e679 874
34edb9ad 875 fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
40b8e679
L
876}
877
40fb9820
L
878static void
879process_i386_initializers (void)
880{
881 unsigned int i;
882 FILE *fp = fopen ("i386-init.h", "w");
883 char *init;
884
885 if (fp == NULL)
886 fail (_("can't create i386-init.h, errno = %s\n"),
887 xstrerror (errno));
888
889 process_copyright (fp);
890
891 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
892 {
893 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
894 init = xstrdup (cpu_flag_init[i].init);
895 process_i386_cpu_flag (fp, init, 1, "", " ");
896 free (init);
897 }
898
899 for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
900 {
901 fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name);
902 init = xstrdup (operand_type_init[i].init);
903 process_i386_operand_type (fp, init, 1, " ");
904 free (init);
905 }
906 fprintf (fp, "\n");
907
908 fclose (fp);
909}
910
40b8e679
L
911/* Program options. */
912#define OPTION_SRCDIR 200
913
914struct option long_options[] =
915{
916 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
917 {"debug", no_argument, NULL, 'd'},
918 {"version", no_argument, NULL, 'V'},
919 {"help", no_argument, NULL, 'h'},
920 {0, no_argument, NULL, 0}
921};
922
923static void
924print_version (void)
925{
926 printf ("%s: version 1.0\n", program_name);
927 xexit (0);
928}
929
930static void
931usage (FILE * stream, int status)
932{
933 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
934 program_name);
935 xexit (status);
936}
937
938int
939main (int argc, char **argv)
940{
941 extern int chdir (char *);
942 char *srcdir = NULL;
8b40d594 943 int c;
72ffa0fb 944 FILE *table;
40b8e679
L
945
946 program_name = *argv;
947 xmalloc_set_program_name (program_name);
948
949 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
950 switch (c)
951 {
952 case OPTION_SRCDIR:
953 srcdir = optarg;
954 break;
955 case 'V':
956 case 'v':
957 print_version ();
958 break;
959 case 'd':
960 debug = 1;
961 break;
962 case 'h':
963 case '?':
964 usage (stderr, 0);
965 default:
966 case 0:
967 break;
968 }
969
970 if (optind != argc)
971 usage (stdout, 1);
972
973 if (srcdir != NULL)
974 if (chdir (srcdir) != 0)
975 fail (_("unable to change directory to \"%s\", errno = %s\n"),
40fb9820
L
976 srcdir, xstrerror (errno));
977
978 /* Check the unused bitfield in i386_cpu_flags. */
979#ifndef CpuUnused
8b40d594
L
980 c = CpuNumOfBits - CpuMax - 1;
981 if (c)
982 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
40fb9820
L
983#endif
984
985 /* Check the unused bitfield in i386_operand_type. */
986#ifndef OTUnused
8b40d594
L
987 c = OTNumOfBits - OTMax - 1;
988 if (c)
989 fail (_("%d unused bits in i386_operand_type.\n"), c);
40fb9820
L
990#endif
991
992 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
993 compare);
994
995 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
996 sizeof (opcode_modifiers [0]), compare);
997
998 qsort (operand_types, ARRAY_SIZE (operand_types),
999 sizeof (operand_types [0]), compare);
40b8e679 1000
34edb9ad
L
1001 table = fopen ("i386-tbl.h", "w");
1002 if (table == NULL)
40fb9820
L
1003 fail (_("can't create i386-tbl.h, errno = %s\n"),
1004 xstrerror (errno));
34edb9ad 1005
72ffa0fb 1006 process_copyright (table);
40b8e679 1007
72ffa0fb
L
1008 process_i386_opcodes (table);
1009 process_i386_registers (table);
40fb9820 1010 process_i386_initializers ();
40b8e679 1011
34edb9ad
L
1012 fclose (table);
1013
40b8e679
L
1014 exit (0);
1015}
This page took 0.091156 seconds and 4 git commands to generate.