OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [opcodes/] [i386-gen.c] - Blame information for rev 178

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.