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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-binutils/] [binutils-2.19.1/] [opcodes/] [i386-gen.c] - Blame information for rev 7

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

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

powered by: WebSVN 2.1.0

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