OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.20.1/] [opcodes/] [i386-gen.c] - Blame information for rev 220

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

Line No. Rev Author Line
1 205 julius
/* Copyright 2007, 2008, 2009
2
   Free Software Foundation, Inc.
3
 
4
   This file is part of the GNU opcodes library.
5
 
6
   This library is free software; you can redistribute it and/or modify
7
   it under the terms of the GNU General Public License as published by
8
   the Free Software Foundation; either version 3, or (at your option)
9
   any later version.
10
 
11
   It is distributed in the hope that it will be useful, but WITHOUT
12
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
14
   License for more details.
15
 
16
   You should have received a copy of the GNU General Public License
17
   along with this program; if not, write to the Free Software
18
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19
   MA 02110-1301, USA.  */
20
 
21
#include "sysdep.h"
22
#include <stdio.h>
23
#include <errno.h>
24
#include "getopt.h"
25
#include "libiberty.h"
26
#include "hashtab.h"
27
#include "safe-ctype.h"
28
 
29
#include "i386-opc.h"
30
 
31
#include <libintl.h>
32
#define _(String) gettext (String)
33
 
34
static const char *program_name = NULL;
35
static int debug = 0;
36
 
37
typedef struct initializer
38
{
39
  const char *name;
40
  const char *init;
41
} initializer;
42
 
43
static initializer cpu_flag_init[] =
44
{
45
  { "CPU_UNKNOWN_FLAGS",
46
    "~CpuL1OM" },
47
  { "CPU_GENERIC32_FLAGS",
48
    "Cpu186|Cpu286|Cpu386" },
49
  { "CPU_GENERIC64_FLAGS",
50
    "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuMMX|CpuSSE|CpuSSE2|CpuLM" },
51
  { "CPU_NONE_FLAGS",
52
   "0" },
53
  { "CPU_I186_FLAGS",
54
    "Cpu186" },
55
  { "CPU_I286_FLAGS",
56
    "Cpu186|Cpu286" },
57
  { "CPU_I386_FLAGS",
58
    "Cpu186|Cpu286|Cpu386" },
59
  { "CPU_I486_FLAGS",
60
    "Cpu186|Cpu286|Cpu386|Cpu486" },
61
  { "CPU_I586_FLAGS",
62
    "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu387" },
63
  { "CPU_I686_FLAGS",
64
    "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687" },
65
  { "CPU_P2_FLAGS",
66
    "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuMMX" },
67
  { "CPU_P3_FLAGS",
68
    "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|Cpu387|Cpu687|CpuMMX|CpuSSE" },
69
  { "CPU_P4_FLAGS",
70
    "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuMMX|CpuSSE|CpuSSE2" },
71
  { "CPU_NOCONA_FLAGS",
72
    "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuLM" },
73
  { "CPU_CORE_FLAGS",
74
    "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
75
  { "CPU_CORE2_FLAGS",
76
    "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuLM" },
77
  { "CPU_COREI7_FLAGS",
78
    "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuClflush|Cpu387|Cpu687|CpuFISTTP|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuRdtscp|CpuLM" },
79
  { "CPU_K6_FLAGS",
80
    "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CpuMMX" },
81
  { "CPU_K6_2_FLAGS",
82
    "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CpuMMX|Cpu3dnow" },
83
  { "CPU_ATHLON_FLAGS",
84
    "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|Cpu387|Cpu687|CpuMMX|Cpu3dnow|Cpu3dnowA" },
85
  { "CPU_K8_FLAGS",
86
    "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuLM" },
87
  { "CPU_AMDFAM10_FLAGS",
88
    "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuMMX|Cpu3dnow|Cpu3dnowA|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM" },
89
  { "CPU_8087_FLAGS",
90
    "Cpu8087" },
91
  { "CPU_287_FLAGS",
92
    "Cpu287" },
93
  { "CPU_387_FLAGS",
94
    "Cpu387" },
95
  { "CPU_ANY87_FLAGS",
96
    "Cpu8087|Cpu287|Cpu387|Cpu687|CpuFISTTP" },
97
  { "CPU_CLFLUSH_FLAGS",
98
    "CpuClflush" },
99
  { "CPU_SYSCALL_FLAGS",
100
    "CpuSYSCALL" },
101
  { "CPU_MMX_FLAGS",
102
    "CpuMMX" },
103
  { "CPU_SSE_FLAGS",
104
    "CpuMMX|CpuSSE" },
105
  { "CPU_SSE2_FLAGS",
106
    "CpuMMX|CpuSSE|CpuSSE2" },
107
  { "CPU_SSE3_FLAGS",
108
    "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3" },
109
  { "CPU_SSSE3_FLAGS",
110
    "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3" },
111
  { "CPU_SSE4_1_FLAGS",
112
    "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1" },
113
  { "CPU_SSE4_2_FLAGS",
114
    "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2" },
115
  { "CPU_ANY_SSE_FLAGS",
116
    "CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuSSE4a|CpuAVX" },
117
  { "CPU_VMX_FLAGS",
118
    "CpuVMX" },
119
  { "CPU_SMX_FLAGS",
120
    "CpuSMX" },
121
  { "CPU_XSAVE_FLAGS",
122
    "CpuXsave" },
123
  { "CPU_AES_FLAGS",
124
    "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAES" },
125
  { "CPU_PCLMUL_FLAGS",
126
    "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuPCLMUL" },
127
  { "CPU_FMA_FLAGS",
128
    "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA" },
129
  { "CPU_FMA4_FLAGS",
130
    "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX|CpuFMA4" },
131
  { "CPU_MOVBE_FLAGS",
132
    "CpuMovbe" },
133
  { "CPU_RDTSCP_FLAGS",
134
    "CpuRdtscp" },
135
  { "CPU_EPT_FLAGS",
136
    "CpuEPT" },
137
  { "CPU_3DNOW_FLAGS",
138
    "CpuMMX|Cpu3dnow" },
139
  { "CPU_3DNOWA_FLAGS",
140
    "CpuMMX|Cpu3dnow|Cpu3dnowA" },
141
  { "CPU_PADLOCK_FLAGS",
142
    "CpuPadLock" },
143
  { "CPU_SVME_FLAGS",
144
    "CpuSVME" },
145
  { "CPU_SSE4A_FLAGS",
146
    "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a" },
147
  { "CPU_ABM_FLAGS",
148
    "CpuABM" },
149
  { "CPU_AVX_FLAGS",
150
    "CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1|CpuSSE4_2|CpuAVX" },
151
  { "CPU_ANY_AVX_FLAGS",
152
    "CpuAVX" },
153
  { "CPU_L1OM_FLAGS",
154
    "unknown" },
155
};
156
 
157
static initializer operand_type_init[] =
158
{
159
  { "OPERAND_TYPE_NONE",
160
    "0" },
161
  { "OPERAND_TYPE_REG8",
162
    "Reg8" },
163
  { "OPERAND_TYPE_REG16",
164
    "Reg16" },
165
  { "OPERAND_TYPE_REG32",
166
    "Reg32" },
167
  { "OPERAND_TYPE_REG64",
168
    "Reg64" },
169
  { "OPERAND_TYPE_IMM1",
170
    "Imm1" },
171
  { "OPERAND_TYPE_IMM8",
172
    "Imm8" },
173
  { "OPERAND_TYPE_IMM8S",
174
    "Imm8S" },
175
  { "OPERAND_TYPE_IMM16",
176
    "Imm16" },
177
  { "OPERAND_TYPE_IMM32",
178
    "Imm32" },
179
  { "OPERAND_TYPE_IMM32S",
180
    "Imm32S" },
181
  { "OPERAND_TYPE_IMM64",
182
    "Imm64" },
183
  { "OPERAND_TYPE_BASEINDEX",
184
    "BaseIndex" },
185
  { "OPERAND_TYPE_DISP8",
186
    "Disp8" },
187
  { "OPERAND_TYPE_DISP16",
188
    "Disp16" },
189
  { "OPERAND_TYPE_DISP32",
190
    "Disp32" },
191
  { "OPERAND_TYPE_DISP32S",
192
    "Disp32S" },
193
  { "OPERAND_TYPE_DISP64",
194
    "Disp64" },
195
  { "OPERAND_TYPE_INOUTPORTREG",
196
    "InOutPortReg" },
197
  { "OPERAND_TYPE_SHIFTCOUNT",
198
    "ShiftCount" },
199
  { "OPERAND_TYPE_CONTROL",
200
    "Control" },
201
  { "OPERAND_TYPE_TEST",
202
    "Test" },
203
  { "OPERAND_TYPE_DEBUG",
204
    "FloatReg" },
205
  { "OPERAND_TYPE_FLOATREG",
206
    "FloatReg" },
207
  { "OPERAND_TYPE_FLOATACC",
208
    "FloatAcc" },
209
  { "OPERAND_TYPE_SREG2",
210
    "SReg2" },
211
  { "OPERAND_TYPE_SREG3",
212
    "SReg3" },
213
  { "OPERAND_TYPE_ACC",
214
    "Acc" },
215
  { "OPERAND_TYPE_JUMPABSOLUTE",
216
    "JumpAbsolute" },
217
  { "OPERAND_TYPE_REGMMX",
218
    "RegMMX" },
219
  { "OPERAND_TYPE_REGXMM",
220
    "RegXMM" },
221
  { "OPERAND_TYPE_REGYMM",
222
    "RegYMM" },
223
  { "OPERAND_TYPE_ESSEG",
224
    "EsSeg" },
225
  { "OPERAND_TYPE_ACC32",
226
    "Reg32|Acc|Dword" },
227
  { "OPERAND_TYPE_ACC64",
228
    "Reg64|Acc|Qword" },
229
  { "OPERAND_TYPE_INOUTPORTREG",
230
    "InOutPortReg" },
231
  { "OPERAND_TYPE_REG16_INOUTPORTREG",
232
    "Reg16|InOutPortReg" },
233
  { "OPERAND_TYPE_DISP16_32",
234
    "Disp16|Disp32" },
235
  { "OPERAND_TYPE_ANYDISP",
236
    "Disp8|Disp16|Disp32|Disp32S|Disp64" },
237
  { "OPERAND_TYPE_IMM16_32",
238
    "Imm16|Imm32" },
239
  { "OPERAND_TYPE_IMM16_32S",
240
    "Imm16|Imm32S" },
241
  { "OPERAND_TYPE_IMM16_32_32S",
242
    "Imm16|Imm32|Imm32S" },
243
  { "OPERAND_TYPE_IMM32_32S_DISP32",
244
    "Imm32|Imm32S|Disp32" },
245
  { "OPERAND_TYPE_IMM64_DISP64",
246
    "Imm64|Disp64" },
247
  { "OPERAND_TYPE_IMM32_32S_64_DISP32",
248
    "Imm32|Imm32S|Imm64|Disp32" },
249
  { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
250
    "Imm32|Imm32S|Imm64|Disp32|Disp64" },
251
};
252
 
253
typedef struct bitfield
254
{
255
  int position;
256
  int value;
257
  const char *name;
258
} bitfield;
259
 
260
#define BITFIELD(n) { n, 0, #n }
261
 
262
static bitfield cpu_flags[] =
263
{
264
  BITFIELD (Cpu186),
265
  BITFIELD (Cpu286),
266
  BITFIELD (Cpu386),
267
  BITFIELD (Cpu486),
268
  BITFIELD (Cpu586),
269
  BITFIELD (Cpu686),
270
  BITFIELD (CpuClflush),
271
  BITFIELD (CpuSYSCALL),
272
  BITFIELD (Cpu8087),
273
  BITFIELD (Cpu287),
274
  BITFIELD (Cpu387),
275
  BITFIELD (Cpu687),
276
  BITFIELD (CpuFISTTP),
277
  BITFIELD (CpuMMX),
278
  BITFIELD (CpuSSE),
279
  BITFIELD (CpuSSE2),
280
  BITFIELD (CpuSSE3),
281
  BITFIELD (CpuSSSE3),
282
  BITFIELD (CpuSSE4_1),
283
  BITFIELD (CpuSSE4_2),
284
  BITFIELD (CpuAVX),
285
  BITFIELD (CpuL1OM),
286
  BITFIELD (CpuSSE4a),
287
  BITFIELD (Cpu3dnow),
288
  BITFIELD (Cpu3dnowA),
289
  BITFIELD (CpuPadLock),
290
  BITFIELD (CpuSVME),
291
  BITFIELD (CpuVMX),
292
  BITFIELD (CpuSMX),
293
  BITFIELD (CpuABM),
294
  BITFIELD (CpuXsave),
295
  BITFIELD (CpuAES),
296
  BITFIELD (CpuPCLMUL),
297
  BITFIELD (CpuFMA),
298
  BITFIELD (CpuFMA4),
299
  BITFIELD (CpuLM),
300
  BITFIELD (CpuMovbe),
301
  BITFIELD (CpuEPT),
302
  BITFIELD (CpuRdtscp),
303
  BITFIELD (Cpu64),
304
  BITFIELD (CpuNo64),
305
#ifdef CpuUnused
306
  BITFIELD (CpuUnused),
307
#endif
308
};
309
 
310
static bitfield opcode_modifiers[] =
311
{
312
  BITFIELD (D),
313
  BITFIELD (W),
314
  BITFIELD (S),
315
  BITFIELD (Modrm),
316
  BITFIELD (ShortForm),
317
  BITFIELD (Jump),
318
  BITFIELD (JumpDword),
319
  BITFIELD (JumpByte),
320
  BITFIELD (JumpInterSegment),
321
  BITFIELD (FloatMF),
322
  BITFIELD (FloatR),
323
  BITFIELD (FloatD),
324
  BITFIELD (Size16),
325
  BITFIELD (Size32),
326
  BITFIELD (Size64),
327
  BITFIELD (IgnoreSize),
328
  BITFIELD (DefaultSize),
329
  BITFIELD (No_bSuf),
330
  BITFIELD (No_wSuf),
331
  BITFIELD (No_lSuf),
332
  BITFIELD (No_sSuf),
333
  BITFIELD (No_qSuf),
334
  BITFIELD (No_ldSuf),
335
  BITFIELD (FWait),
336
  BITFIELD (IsString),
337
  BITFIELD (RegKludge),
338
  BITFIELD (FirstXmm0),
339
  BITFIELD (Implicit1stXmm0),
340
  BITFIELD (ByteOkIntel),
341
  BITFIELD (ToDword),
342
  BITFIELD (ToQword),
343
  BITFIELD (AddrPrefixOp0),
344
  BITFIELD (IsPrefix),
345
  BITFIELD (ImmExt),
346
  BITFIELD (NoRex64),
347
  BITFIELD (Rex64),
348
  BITFIELD (Ugh),
349
  BITFIELD (Vex),
350
  BITFIELD (Vex256),
351
  BITFIELD (VexNDS),
352
  BITFIELD (VexNDD),
353
  BITFIELD (VexW0),
354
  BITFIELD (VexW1),
355
  BITFIELD (Vex0F),
356
  BITFIELD (Vex0F38),
357
  BITFIELD (Vex0F3A),
358
  BITFIELD (Vex3Sources),
359
  BITFIELD (VexImmExt),
360
  BITFIELD (SSE2AVX),
361
  BITFIELD (NoAVX),
362
  BITFIELD (OldGcc),
363
  BITFIELD (ATTMnemonic),
364
  BITFIELD (ATTSyntax),
365
  BITFIELD (IntelSyntax),
366
};
367
 
368
static bitfield operand_types[] =
369
{
370
  BITFIELD (Reg8),
371
  BITFIELD (Reg16),
372
  BITFIELD (Reg32),
373
  BITFIELD (Reg64),
374
  BITFIELD (FloatReg),
375
  BITFIELD (RegMMX),
376
  BITFIELD (RegXMM),
377
  BITFIELD (RegYMM),
378
  BITFIELD (Imm8),
379
  BITFIELD (Imm8S),
380
  BITFIELD (Imm16),
381
  BITFIELD (Imm32),
382
  BITFIELD (Imm32S),
383
  BITFIELD (Imm64),
384
  BITFIELD (Imm1),
385
  BITFIELD (BaseIndex),
386
  BITFIELD (Disp8),
387
  BITFIELD (Disp16),
388
  BITFIELD (Disp32),
389
  BITFIELD (Disp32S),
390
  BITFIELD (Disp64),
391
  BITFIELD (InOutPortReg),
392
  BITFIELD (ShiftCount),
393
  BITFIELD (Control),
394
  BITFIELD (Debug),
395
  BITFIELD (Test),
396
  BITFIELD (SReg2),
397
  BITFIELD (SReg3),
398
  BITFIELD (Acc),
399
  BITFIELD (FloatAcc),
400
  BITFIELD (JumpAbsolute),
401
  BITFIELD (EsSeg),
402
  BITFIELD (RegMem),
403
  BITFIELD (Mem),
404
  BITFIELD (Byte),
405
  BITFIELD (Word),
406
  BITFIELD (Dword),
407
  BITFIELD (Fword),
408
  BITFIELD (Qword),
409
  BITFIELD (Tbyte),
410
  BITFIELD (Xmmword),
411
  BITFIELD (Ymmword),
412
  BITFIELD (Unspecified),
413
  BITFIELD (Anysize),
414
#ifdef OTUnused
415
  BITFIELD (OTUnused),
416
#endif
417
};
418
 
419
static const char *filename;
420
 
421
static int
422
compare (const void *x, const void *y)
423
{
424
  const bitfield *xp = (const bitfield *) x;
425
  const bitfield *yp = (const bitfield *) y;
426
  return xp->position - yp->position;
427
}
428
 
429
static void
430
fail (const char *message, ...)
431
{
432
  va_list args;
433
 
434
  va_start (args, message);
435
  fprintf (stderr, _("%s: Error: "), program_name);
436
  vfprintf (stderr, message, args);
437
  va_end (args);
438
  xexit (1);
439
}
440
 
441
static void
442
process_copyright (FILE *fp)
443
{
444
  fprintf (fp, "/* This file is automatically generated by i386-gen.  Do not edit!  */\n\
445
/* Copyright 2007, 2008, 2009\n\
446
   Free Software Foundation, Inc.\n\
447
\n\
448
   This file is part of the GNU opcodes library.\n\
449
\n\
450
   This library is free software; you can redistribute it and/or modify\n\
451
   it under the terms of the GNU General Public License as published by\n\
452
   the Free Software Foundation; either version 3, or (at your option)\n\
453
   any later version.\n\
454
\n\
455
   It is distributed in the hope that it will be useful, but WITHOUT\n\
456
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
457
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public\n\
458
   License for more details.\n\
459
\n\
460
   You should have received a copy of the GNU General Public License\n\
461
   along with this program; if not, write to the Free Software\n\
462
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
463
   MA 02110-1301, USA.  */\n");
464
}
465
 
466
/* Remove leading white spaces.  */
467
 
468
static char *
469
remove_leading_whitespaces (char *str)
470
{
471
  while (ISSPACE (*str))
472
    str++;
473
  return str;
474
}
475
 
476
/* Remove trailing white spaces.  */
477
 
478
static void
479
remove_trailing_whitespaces (char *str)
480
{
481
  size_t last = strlen (str);
482
 
483
  if (last == 0)
484
    return;
485
 
486
  do
487
    {
488
      last--;
489
      if (ISSPACE (str [last]))
490
        str[last] = '\0';
491
      else
492
        break;
493
    }
494
  while (last != 0);
495
}
496
 
497
/* Find next field separated by SEP and terminate it. Return a
498
   pointer to the one after it.  */
499
 
500
static char *
501
next_field (char *str, char sep, char **next, char *last)
502
{
503
  char *p;
504
 
505
  p = remove_leading_whitespaces (str);
506
  for (str = p; *str != sep && *str != '\0'; str++);
507
 
508
  *str = '\0';
509
  remove_trailing_whitespaces (p);
510
 
511
  *next = str + 1;
512
 
513
  if (p >= last)
514
    abort ();
515
 
516
  return p;
517
}
518
 
519
static void
520
set_bitfield (const char *f, bitfield *array, int value,
521
              unsigned int size, int lineno)
522
{
523
  unsigned int i;
524
 
525
  if (strcmp (f, "CpuFP") == 0)
526
    {
527
      set_bitfield("Cpu387", array, value, size, lineno);
528
      set_bitfield("Cpu287", array, value, size, lineno);
529
      f = "Cpu8087";
530
    }
531
  else if (strcmp (f, "Mmword") == 0)
532
    f= "Qword";
533
  else if (strcmp (f, "Oword") == 0)
534
    f= "Xmmword";
535
 
536
  for (i = 0; i < size; i++)
537
    if (strcasecmp (array[i].name, f) == 0)
538
      {
539
        array[i].value = value;
540
        return;
541
      }
542
 
543
  if (lineno != -1)
544
    fail (_("%s: %d: Unknown bitfield: %s\n"), filename, lineno, f);
545
  else
546
    fail (_("Unknown bitfield: %s\n"), f);
547
}
548
 
549
static void
550
output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
551
                  int macro, const char *comma, const char *indent)
552
{
553
  unsigned int i;
554
 
555
  fprintf (table, "%s{ { ", indent);
556
 
557
  for (i = 0; i < size - 1; i++)
558
    {
559
      fprintf (table, "%d, ", flags[i].value);
560
      if (((i + 1) % 20) == 0)
561
        {
562
          /* We need \\ for macro.  */
563
          if (macro)
564
            fprintf (table, " \\\n    %s", indent);
565
          else
566
            fprintf (table, "\n    %s", indent);
567
        }
568
    }
569
 
570
  fprintf (table, "%d } }%s\n", flags[i].value, comma);
571
}
572
 
573
static void
574
process_i386_cpu_flag (FILE *table, char *flag, int macro,
575
                       const char *comma, const char *indent,
576
                       int lineno)
577
{
578
  char *str, *next, *last;
579
  unsigned int i;
580
  bitfield flags [ARRAY_SIZE (cpu_flags)];
581
 
582
  /* Copy the default cpu flags.  */
583
  memcpy (flags, cpu_flags, sizeof (cpu_flags));
584
 
585
  if (strcasecmp (flag, "unknown") == 0)
586
    {
587
      /* We turn on everything except for cpu64 in case of
588
         CPU_UNKNOWN_FLAGS.  */
589
      for (i = 0; i < ARRAY_SIZE (flags); i++)
590
        if (flags[i].position != Cpu64)
591
          flags[i].value = 1;
592
    }
593
  else if (flag[0] == '~')
594
    {
595
      last = flag + strlen (flag);
596
 
597
      if (flag[1] == '(')
598
        {
599
          last -= 1;
600
          next = flag + 2;
601
          if (*last != ')')
602
            fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename,
603
                  lineno, flag);
604
          *last = '\0';
605
        }
606
      else
607
        next = flag + 1;
608
 
609
      /* First we turn on everything except for cpu64.  */
610
      for (i = 0; i < ARRAY_SIZE (flags); i++)
611
        if (flags[i].position != Cpu64)
612
          flags[i].value = 1;
613
 
614
      /* Turn off selective bits.  */
615
      for (; next && next < last; )
616
        {
617
          str = next_field (next, '|', &next, last);
618
          if (str)
619
            set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
620
        }
621
    }
622
  else if (strcmp (flag, "0"))
623
    {
624
      /* Turn on selective bits.  */
625
      last = flag + strlen (flag);
626
      for (next = flag; next && next < last; )
627
        {
628
          str = next_field (next, '|', &next, last);
629
          if (str)
630
            set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
631
        }
632
    }
633
 
634
  output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
635
                    comma, indent);
636
}
637
 
638
static void
639
output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
640
{
641
  unsigned int i;
642
 
643
  fprintf (table, "    { ");
644
 
645
  for (i = 0; i < size - 1; i++)
646
    {
647
      fprintf (table, "%d, ", modifier[i].value);
648
      if (((i + 1) % 20) == 0)
649
        fprintf (table, "\n      ");
650
    }
651
 
652
  fprintf (table, "%d },\n", modifier[i].value);
653
}
654
 
655
static void
656
process_i386_opcode_modifier (FILE *table, char *mod, int lineno)
657
{
658
  char *str, *next, *last;
659
  bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
660
 
661
  /* Copy the default opcode modifier.  */
662
  memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
663
 
664
  if (strcmp (mod, "0"))
665
    {
666
      last = mod + strlen (mod);
667
      for (next = mod; next && next < last; )
668
        {
669
          str = next_field (next, '|', &next, last);
670
          if (str)
671
            set_bitfield (str, modifiers, 1, ARRAY_SIZE (modifiers),
672
                          lineno);
673
        }
674
    }
675
  output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
676
}
677
 
678
static void
679
output_operand_type (FILE *table, bitfield *types, unsigned int size,
680
                     int macro, const char *indent)
681
{
682
  unsigned int i;
683
 
684
  fprintf (table, "{ { ");
685
 
686
  for (i = 0; i < size - 1; i++)
687
    {
688
      fprintf (table, "%d, ", types[i].value);
689
      if (((i + 1) % 20) == 0)
690
        {
691
          /* We need \\ for macro.  */
692
          if (macro)
693
            fprintf (table, "\\\n%s", indent);
694
          else
695
            fprintf (table, "\n%s", indent);
696
        }
697
    }
698
 
699
  fprintf (table, "%d } }", types[i].value);
700
}
701
 
702
static void
703
process_i386_operand_type (FILE *table, char *op, int macro,
704
                           const char *indent, int lineno)
705
{
706
  char *str, *next, *last;
707
  bitfield types [ARRAY_SIZE (operand_types)];
708
 
709
  /* Copy the default operand type.  */
710
  memcpy (types, operand_types, sizeof (types));
711
 
712
  if (strcmp (op, "0"))
713
    {
714
      last = op + strlen (op);
715
      for (next = op; next && next < last; )
716
        {
717
          str = next_field (next, '|', &next, last);
718
          if (str)
719
            set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
720
        }
721
    }
722
  output_operand_type (table, types, ARRAY_SIZE (types), macro,
723
                       indent);
724
}
725
 
726
static void
727
output_i386_opcode (FILE *table, const char *name, char *str,
728
                    char *last, int lineno)
729
{
730
  unsigned int i;
731
  char *operands, *base_opcode, *extension_opcode, *opcode_length;
732
  char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
733
 
734
  /* Find number of operands.  */
735
  operands = next_field (str, ',', &str, last);
736
 
737
  /* Find base_opcode.  */
738
  base_opcode = next_field (str, ',', &str, last);
739
 
740
  /* Find extension_opcode.  */
741
  extension_opcode = next_field (str, ',', &str, last);
742
 
743
  /* Find opcode_length.  */
744
  opcode_length = next_field (str, ',', &str, last);
745
 
746
  /* Find cpu_flags.  */
747
  cpu_flags = next_field (str, ',', &str, last);
748
 
749
  /* Find opcode_modifier.  */
750
  opcode_modifier = next_field (str, ',', &str, last);
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, last);
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, ",", "    ", lineno);
800
 
801
  process_i386_opcode_modifier (table, opcode_modifier, lineno);
802
 
803
  fprintf (table, "    { ");
804
 
805
  for (i = 0; i < ARRAY_SIZE (operand_types); i++)
806
    {
807
      if (operand_types[i] == NULL || *operand_types[i] == '0')
808
        {
809
          if (i == 0)
810
            process_i386_operand_type (table, "0", 0, "\t  ", lineno);
811
          break;
812
        }
813
 
814
      if (i != 0)
815
        fprintf (table, ",\n      ");
816
 
817
      process_i386_operand_type (table, operand_types[i], 0,
818
                                 "\t  ", lineno);
819
    }
820
  fprintf (table, " } },\n");
821
}
822
 
823
struct opcode_hash_entry
824
{
825
  struct opcode_hash_entry *next;
826
  char *name;
827
  char *opcode;
828
  int lineno;
829
};
830
 
831
/* Calculate the hash value of an opcode hash entry P.  */
832
 
833
static hashval_t
834
opcode_hash_hash (const void *p)
835
{
836
  struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
837
  return htab_hash_string (entry->name);
838
}
839
 
840
/* Compare a string Q against an opcode hash entry P.  */
841
 
842
static int
843
opcode_hash_eq (const void *p, const void *q)
844
{
845
  struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
846
  const char *name = (const char *) q;
847
  return strcmp (name, entry->name) == 0;
848
}
849
 
850
static void
851
process_i386_opcodes (FILE *table)
852
{
853
  FILE *fp;
854
  char buf[2048];
855
  unsigned int i, j;
856
  char *str, *p, *last, *name;
857
  struct opcode_hash_entry **hash_slot, **entry, *next;
858
  htab_t opcode_hash_table;
859
  struct opcode_hash_entry **opcode_array;
860
  unsigned int opcode_array_size = 1024;
861
  int lineno = 0;
862
 
863
  filename = "i386-opc.tbl";
864
  fp = fopen (filename, "r");
865
 
866
  if (fp == NULL)
867
    fail (_("can't find i386-opc.tbl for reading, errno = %s\n"),
868
          xstrerror (errno));
869
 
870
  i = 0;
871
  opcode_array = (struct opcode_hash_entry **)
872
    xmalloc (sizeof (*opcode_array) * opcode_array_size);
873
 
874
  opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
875
                                         opcode_hash_eq, NULL,
876
                                         xcalloc, free);
877
 
878
  fprintf (table, "\n/* i386 opcode table.  */\n\n");
879
  fprintf (table, "const insn_template i386_optab[] =\n{\n");
880
 
881
  /* Put everything on opcode array.  */
882
  while (!feof (fp))
883
    {
884
      if (fgets (buf, sizeof (buf), fp) == NULL)
885
        break;
886
 
887
      lineno++;
888
 
889
      p = remove_leading_whitespaces (buf);
890
 
891
      /* Skip comments.  */
892
      str = strstr (p, "//");
893
      if (str != NULL)
894
        str[0] = '\0';
895
 
896
      /* Remove trailing white spaces.  */
897
      remove_trailing_whitespaces (p);
898
 
899
      switch (p[0])
900
        {
901
        case '#':
902
          /* Ignore comments.  */
903
        case '\0':
904
          continue;
905
          break;
906
        default:
907
          break;
908
        }
909
 
910
      last = p + strlen (p);
911
 
912
      /* Find name.  */
913
      name = next_field (p, ',', &str, last);
914
 
915
      /* Get the slot in hash table.  */
916
      hash_slot = (struct opcode_hash_entry **)
917
        htab_find_slot_with_hash (opcode_hash_table, name,
918
                                  htab_hash_string (name),
919
                                  INSERT);
920
 
921
      if (*hash_slot == NULL)
922
        {
923
          /* It is the new one.  Put it on opcode array.  */
924
          if (i >= opcode_array_size)
925
            {
926
              /* Grow the opcode array when needed.  */
927
              opcode_array_size += 1024;
928
              opcode_array = (struct opcode_hash_entry **)
929
                xrealloc (opcode_array,
930
                          sizeof (*opcode_array) * opcode_array_size);
931
            }
932
 
933
          opcode_array[i] = (struct opcode_hash_entry *)
934
            xmalloc (sizeof (struct opcode_hash_entry));
935
          opcode_array[i]->next = NULL;
936
          opcode_array[i]->name = xstrdup (name);
937
          opcode_array[i]->opcode = xstrdup (str);
938
          opcode_array[i]->lineno = lineno;
939
          *hash_slot = opcode_array[i];
940
          i++;
941
        }
942
      else
943
        {
944
          /* Append it to the existing one.  */
945
          entry = hash_slot;
946
          while ((*entry) != NULL)
947
            entry = &(*entry)->next;
948
          *entry = (struct opcode_hash_entry *)
949
            xmalloc (sizeof (struct opcode_hash_entry));
950
          (*entry)->next = NULL;
951
          (*entry)->name = (*hash_slot)->name;
952
          (*entry)->opcode = xstrdup (str);
953
          (*entry)->lineno = lineno;
954
        }
955
    }
956
 
957
  /* Process opcode array.  */
958
  for (j = 0; j < i; j++)
959
    {
960
      for (next = opcode_array[j]; next; next = next->next)
961
        {
962
          name = next->name;
963
          str = next->opcode;
964
          lineno = next->lineno;
965
          last = str + strlen (str);
966
          output_i386_opcode (table, name, str, last, lineno);
967
        }
968
    }
969
 
970
  fclose (fp);
971
 
972
  fprintf (table, "  { NULL, 0, 0, 0, 0,\n");
973
 
974
  process_i386_cpu_flag (table, "0", 0, ",", "    ", -1);
975
 
976
  process_i386_opcode_modifier (table, "0", -1);
977
 
978
  fprintf (table, "    { ");
979
  process_i386_operand_type (table, "0", 0, "\t  ", -1);
980
  fprintf (table, " } }\n");
981
 
982
  fprintf (table, "};\n");
983
}
984
 
985
static void
986
process_i386_registers (FILE *table)
987
{
988
  FILE *fp;
989
  char buf[2048];
990
  char *str, *p, *last;
991
  char *reg_name, *reg_type, *reg_flags, *reg_num;
992
  char *dw2_32_num, *dw2_64_num;
993
  int lineno = 0;
994
 
995
  filename = "i386-reg.tbl";
996
  fp = fopen (filename, "r");
997
  if (fp == NULL)
998
    fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
999
          xstrerror (errno));
1000
 
1001
  fprintf (table, "\n/* i386 register table.  */\n\n");
1002
  fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
1003
 
1004
  while (!feof (fp))
1005
    {
1006
      if (fgets (buf, sizeof (buf), fp) == NULL)
1007
        break;
1008
 
1009
      lineno++;
1010
 
1011
      p = remove_leading_whitespaces (buf);
1012
 
1013
      /* Skip comments.  */
1014
      str = strstr (p, "//");
1015
      if (str != NULL)
1016
        str[0] = '\0';
1017
 
1018
      /* Remove trailing white spaces.  */
1019
      remove_trailing_whitespaces (p);
1020
 
1021
      switch (p[0])
1022
        {
1023
        case '#':
1024
          fprintf (table, "%s\n", p);
1025
        case '\0':
1026
          continue;
1027
          break;
1028
        default:
1029
          break;
1030
        }
1031
 
1032
      last = p + strlen (p);
1033
 
1034
      /* Find reg_name.  */
1035
      reg_name = next_field (p, ',', &str, last);
1036
 
1037
      /* Find reg_type.  */
1038
      reg_type = next_field (str, ',', &str, last);
1039
 
1040
      /* Find reg_flags.  */
1041
      reg_flags = next_field (str, ',', &str, last);
1042
 
1043
      /* Find reg_num.  */
1044
      reg_num = next_field (str, ',', &str, last);
1045
 
1046
      fprintf (table, "  { \"%s\",\n    ", reg_name);
1047
 
1048
      process_i386_operand_type (table, reg_type, 0, "\t", lineno);
1049
 
1050
      /* Find 32-bit Dwarf2 register number.  */
1051
      dw2_32_num = next_field (str, ',', &str, last);
1052
 
1053
      /* Find 64-bit Dwarf2 register number.  */
1054
      dw2_64_num = next_field (str, ',', &str, last);
1055
 
1056
      fprintf (table, ",\n    %s, %s, { %s, %s } },\n",
1057
               reg_flags, reg_num, dw2_32_num, dw2_64_num);
1058
    }
1059
 
1060
  fclose (fp);
1061
 
1062
  fprintf (table, "};\n");
1063
 
1064
  fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
1065
}
1066
 
1067
static void
1068
process_i386_initializers (void)
1069
{
1070
  unsigned int i;
1071
  FILE *fp = fopen ("i386-init.h", "w");
1072
  char *init;
1073
 
1074
  if (fp == NULL)
1075
    fail (_("can't create i386-init.h, errno = %s\n"),
1076
          xstrerror (errno));
1077
 
1078
  process_copyright (fp);
1079
 
1080
  for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1081
    {
1082
      fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1083
      init = xstrdup (cpu_flag_init[i].init);
1084
      process_i386_cpu_flag (fp, init, 1, "", "  ", -1);
1085
      free (init);
1086
    }
1087
 
1088
  for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
1089
    {
1090
      fprintf (fp, "\n\n#define %s \\\n  ", operand_type_init[i].name);
1091
      init = xstrdup (operand_type_init[i].init);
1092
      process_i386_operand_type (fp, init, 1, "      ", -1);
1093
      free (init);
1094
    }
1095
  fprintf (fp, "\n");
1096
 
1097
  fclose (fp);
1098
}
1099
 
1100
/* Program options.  */
1101
#define OPTION_SRCDIR   200
1102
 
1103
struct option long_options[] =
1104
{
1105
  {"srcdir",  required_argument, NULL, OPTION_SRCDIR},
1106
  {"debug",   no_argument,       NULL, 'd'},
1107
  {"version", no_argument,       NULL, 'V'},
1108
  {"help",    no_argument,       NULL, 'h'},
1109
  {0,         no_argument,       NULL, 0}
1110
};
1111
 
1112
static void
1113
print_version (void)
1114
{
1115
  printf ("%s: version 1.0\n", program_name);
1116
  xexit (0);
1117
}
1118
 
1119
static void
1120
usage (FILE * stream, int status)
1121
{
1122
  fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1123
           program_name);
1124
  xexit (status);
1125
}
1126
 
1127
int
1128
main (int argc, char **argv)
1129
{
1130
  extern int chdir (char *);
1131
  char *srcdir = NULL;
1132
  int c;
1133
  FILE *table;
1134
 
1135
  program_name = *argv;
1136
  xmalloc_set_program_name (program_name);
1137
 
1138
  while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1139
    switch (c)
1140
      {
1141
      case OPTION_SRCDIR:
1142
        srcdir = optarg;
1143
        break;
1144
      case 'V':
1145
      case 'v':
1146
        print_version ();
1147
        break;
1148
      case 'd':
1149
        debug = 1;
1150
        break;
1151
      case 'h':
1152
      case '?':
1153
        usage (stderr, 0);
1154
      default:
1155
      case 0:
1156
        break;
1157
      }
1158
 
1159
  if (optind != argc)
1160
    usage (stdout, 1);
1161
 
1162
  if (srcdir != NULL)
1163
    if (chdir (srcdir) != 0)
1164
      fail (_("unable to change directory to \"%s\", errno = %s\n"),
1165
            srcdir, xstrerror (errno));
1166
 
1167
  /* Check the unused bitfield in i386_cpu_flags.  */
1168
#ifndef CpuUnused
1169
  c = CpuNumOfBits - CpuMax - 1;
1170
  if (c)
1171
    fail (_("%d unused bits in i386_cpu_flags.\n"), c);
1172
#endif
1173
 
1174
  /* Check the unused bitfield in i386_operand_type.  */
1175
#ifndef OTUnused
1176
  c = OTNumOfBits - OTMax - 1;
1177
  if (c)
1178
    fail (_("%d unused bits in i386_operand_type.\n"), c);
1179
#endif
1180
 
1181
  qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
1182
         compare);
1183
 
1184
  qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
1185
         sizeof (opcode_modifiers [0]), compare);
1186
 
1187
  qsort (operand_types, ARRAY_SIZE (operand_types),
1188
         sizeof (operand_types [0]), compare);
1189
 
1190
  table = fopen ("i386-tbl.h", "w");
1191
  if (table == NULL)
1192
    fail (_("can't create i386-tbl.h, errno = %s\n"),
1193
          xstrerror (errno));
1194
 
1195
  process_copyright (table);
1196
 
1197
  process_i386_opcodes (table);
1198
  process_i386_registers (table);
1199
  process_i386_initializers ();
1200
 
1201
  fclose (table);
1202
 
1203
  exit (0);
1204
}

powered by: WebSVN 2.1.0

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