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