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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [opcodes/] [i386-gen.c] - Blame information for rev 862

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

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

powered by: WebSVN 2.1.0

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