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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [opcodes/] [i386-gen.c] - Blame information for rev 841

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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