Home | History | Annotate | Line # | Download | only in opcodes
i386-gen.c revision 1.7
      1  1.7  christos /* Copyright (C) 2007-2020 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.7  christos /* Build-time checks are preferrable over runtime ones.  Use this construct
     34  1.7  christos    in preference where possible.  */
     35  1.7  christos #define static_assert(e) ((void)sizeof (struct { int _:1 - 2 * !(e); }))
     36  1.7  christos 
     37  1.1  christos static const char *program_name = NULL;
     38  1.1  christos static int debug = 0;
     39  1.1  christos 
     40  1.1  christos typedef struct initializer
     41  1.1  christos {
     42  1.1  christos   const char *name;
     43  1.1  christos   const char *init;
     44  1.1  christos } initializer;
     45  1.1  christos 
     46  1.1  christos static initializer cpu_flag_init[] =
     47  1.1  christos {
     48  1.1  christos   { "CPU_UNKNOWN_FLAGS",
     49  1.1  christos     "~(CpuL1OM|CpuK1OM)" },
     50  1.1  christos   { "CPU_GENERIC32_FLAGS",
     51  1.1  christos     "Cpu186|Cpu286|Cpu386" },
     52  1.1  christos   { "CPU_GENERIC64_FLAGS",
     53  1.5  christos     "CPU_PENTIUMPRO_FLAGS|CpuClflush|CpuSYSCALL|CPU_MMX_FLAGS|CPU_SSE2_FLAGS|CpuLM" },
     54  1.1  christos   { "CPU_NONE_FLAGS",
     55  1.1  christos    "0" },
     56  1.1  christos   { "CPU_I186_FLAGS",
     57  1.1  christos     "Cpu186" },
     58  1.1  christos   { "CPU_I286_FLAGS",
     59  1.5  christos     "CPU_I186_FLAGS|Cpu286" },
     60  1.1  christos   { "CPU_I386_FLAGS",
     61  1.5  christos     "CPU_I286_FLAGS|Cpu386" },
     62  1.1  christos   { "CPU_I486_FLAGS",
     63  1.5  christos     "CPU_I386_FLAGS|Cpu486" },
     64  1.1  christos   { "CPU_I586_FLAGS",
     65  1.6  christos     "CPU_I486_FLAGS|Cpu387|Cpu586" },
     66  1.1  christos   { "CPU_I686_FLAGS",
     67  1.7  christos     "CPU_I586_FLAGS|Cpu686|Cpu687|CpuCMOV|CpuFXSR" },
     68  1.1  christos   { "CPU_PENTIUMPRO_FLAGS",
     69  1.5  christos     "CPU_I686_FLAGS|CpuNop" },
     70  1.1  christos   { "CPU_P2_FLAGS",
     71  1.5  christos     "CPU_PENTIUMPRO_FLAGS|CPU_MMX_FLAGS" },
     72  1.1  christos   { "CPU_P3_FLAGS",
     73  1.5  christos     "CPU_P2_FLAGS|CPU_SSE_FLAGS" },
     74  1.1  christos   { "CPU_P4_FLAGS",
     75  1.5  christos     "CPU_P3_FLAGS|CpuClflush|CPU_SSE2_FLAGS" },
     76  1.1  christos   { "CPU_NOCONA_FLAGS",
     77  1.5  christos     "CPU_GENERIC64_FLAGS|CpuFISTTP|CPU_SSE3_FLAGS|CpuCX16" },
     78  1.1  christos   { "CPU_CORE_FLAGS",
     79  1.5  christos     "CPU_P4_FLAGS|CpuFISTTP|CPU_SSE3_FLAGS|CpuCX16" },
     80  1.1  christos   { "CPU_CORE2_FLAGS",
     81  1.5  christos     "CPU_NOCONA_FLAGS|CPU_SSSE3_FLAGS" },
     82  1.1  christos   { "CPU_COREI7_FLAGS",
     83  1.5  christos     "CPU_CORE2_FLAGS|CPU_SSE4_2_FLAGS|CpuRdtscp" },
     84  1.1  christos   { "CPU_K6_FLAGS",
     85  1.5  christos     "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|CpuSYSCALL|Cpu387|CPU_MMX_FLAGS" },
     86  1.1  christos   { "CPU_K6_2_FLAGS",
     87  1.5  christos     "CPU_K6_FLAGS|Cpu3dnow" },
     88  1.1  christos   { "CPU_ATHLON_FLAGS",
     89  1.5  christos     "CPU_K6_2_FLAGS|Cpu686|Cpu687|CpuNop|Cpu3dnowA" },
     90  1.1  christos   { "CPU_K8_FLAGS",
     91  1.5  christos     "CPU_ATHLON_FLAGS|CpuRdtscp|CPU_SSE2_FLAGS|CpuLM" },
     92  1.1  christos   { "CPU_AMDFAM10_FLAGS",
     93  1.5  christos     "CPU_K8_FLAGS|CpuFISTTP|CPU_SSE4A_FLAGS|CpuABM" },
     94  1.1  christos   { "CPU_BDVER1_FLAGS",
     95  1.6  christos     "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_XOP_FLAGS|CpuABM|CpuLWP|CpuSVME|CpuAES|CpuPCLMUL|CpuLZCNT|CpuPRFCHW" },
     96  1.1  christos   { "CPU_BDVER2_FLAGS",
     97  1.5  christos     "CPU_BDVER1_FLAGS|CpuFMA|CpuBMI|CpuTBM|CpuF16C" },
     98  1.1  christos   { "CPU_BDVER3_FLAGS",
     99  1.5  christos     "CPU_BDVER2_FLAGS|CpuXsaveopt|CpuFSGSBase" },
    100  1.3  christos   { "CPU_BDVER4_FLAGS",
    101  1.5  christos     "CPU_BDVER3_FLAGS|CpuAVX2|CpuMovbe|CpuBMI2|CpuRdRnd|CpuMWAITX" },
    102  1.3  christos   { "CPU_ZNVER1_FLAGS",
    103  1.6  christos     "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_AVX2_FLAGS|CpuSSE4A|CpuABM|CpuSVME|CpuAES|CpuPCLMUL|CpuLZCNT|CpuPRFCHW|CpuFMA|CpuBMI|CpuF16C|CpuXsaveopt|CpuFSGSBase|CpuMovbe|CpuBMI2|CpuRdRnd|CpuADX|CpuRdSeed|CpuSMAP|CpuSHA|CpuXSAVEC|CpuXSAVES|CpuClflushOpt|CpuCLZERO|CpuMWAITX" },
    104  1.6  christos   { "CPU_ZNVER2_FLAGS",
    105  1.7  christos     "CPU_ZNVER1_FLAGS|CpuCLWB|CpuRDPID|CpuRDPRU|CpuMCOMMIT|CpuWBNOINVD" },
    106  1.1  christos   { "CPU_BTVER1_FLAGS",
    107  1.5  christos     "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuCX16|CpuRdtscp|CPU_SSSE3_FLAGS|CpuSSE4A|CpuABM|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME|CpuLZCNT" },
    108  1.1  christos   { "CPU_BTVER2_FLAGS",
    109  1.6  christos     "CPU_BTVER1_FLAGS|CPU_AVX_FLAGS|CpuBMI|CpuF16C|CpuAES|CpuPCLMUL|CpuMovbe|CpuXsaveopt|CpuPRFCHW" },
    110  1.1  christos   { "CPU_8087_FLAGS",
    111  1.1  christos     "Cpu8087" },
    112  1.1  christos   { "CPU_287_FLAGS",
    113  1.6  christos     "Cpu287" },
    114  1.1  christos   { "CPU_387_FLAGS",
    115  1.6  christos     "Cpu387" },
    116  1.5  christos   { "CPU_687_FLAGS",
    117  1.5  christos     "CPU_387_FLAGS|Cpu687" },
    118  1.7  christos   { "CPU_CMOV_FLAGS",
    119  1.7  christos     "CpuCMOV" },
    120  1.7  christos   { "CPU_FXSR_FLAGS",
    121  1.7  christos     "CpuFXSR" },
    122  1.1  christos   { "CPU_CLFLUSH_FLAGS",
    123  1.1  christos     "CpuClflush" },
    124  1.1  christos   { "CPU_NOP_FLAGS",
    125  1.1  christos     "CpuNop" },
    126  1.1  christos   { "CPU_SYSCALL_FLAGS",
    127  1.1  christos     "CpuSYSCALL" },
    128  1.1  christos   { "CPU_MMX_FLAGS",
    129  1.6  christos     "CpuMMX" },
    130  1.1  christos   { "CPU_SSE_FLAGS",
    131  1.6  christos     "CpuSSE" },
    132  1.1  christos   { "CPU_SSE2_FLAGS",
    133  1.5  christos     "CPU_SSE_FLAGS|CpuSSE2" },
    134  1.1  christos   { "CPU_SSE3_FLAGS",
    135  1.5  christos     "CPU_SSE2_FLAGS|CpuSSE3" },
    136  1.1  christos   { "CPU_SSSE3_FLAGS",
    137  1.5  christos     "CPU_SSE3_FLAGS|CpuSSSE3" },
    138  1.1  christos   { "CPU_SSE4_1_FLAGS",
    139  1.5  christos     "CPU_SSSE3_FLAGS|CpuSSE4_1" },
    140  1.1  christos   { "CPU_SSE4_2_FLAGS",
    141  1.5  christos     "CPU_SSE4_1_FLAGS|CpuSSE4_2" },
    142  1.1  christos   { "CPU_VMX_FLAGS",
    143  1.1  christos     "CpuVMX" },
    144  1.1  christos   { "CPU_SMX_FLAGS",
    145  1.1  christos     "CpuSMX" },
    146  1.1  christos   { "CPU_XSAVE_FLAGS",
    147  1.1  christos     "CpuXsave" },
    148  1.1  christos   { "CPU_XSAVEOPT_FLAGS",
    149  1.5  christos     "CPU_XSAVE_FLAGS|CpuXsaveopt" },
    150  1.1  christos   { "CPU_AES_FLAGS",
    151  1.5  christos     "CPU_SSE2_FLAGS|CpuAES" },
    152  1.1  christos   { "CPU_PCLMUL_FLAGS",
    153  1.5  christos     "CPU_SSE2_FLAGS|CpuPCLMUL" },
    154  1.1  christos   { "CPU_FMA_FLAGS",
    155  1.5  christos     "CPU_AVX_FLAGS|CpuFMA" },
    156  1.1  christos   { "CPU_FMA4_FLAGS",
    157  1.5  christos     "CPU_AVX_FLAGS|CpuFMA4" },
    158  1.1  christos   { "CPU_XOP_FLAGS",
    159  1.5  christos     "CPU_SSE4A_FLAGS|CPU_FMA4_FLAGS|CpuXOP" },
    160  1.1  christos   { "CPU_LWP_FLAGS",
    161  1.6  christos     "CPU_XSAVE_FLAGS|CpuLWP" },
    162  1.1  christos   { "CPU_BMI_FLAGS",
    163  1.1  christos     "CpuBMI" },
    164  1.1  christos   { "CPU_TBM_FLAGS",
    165  1.1  christos     "CpuTBM" },
    166  1.1  christos   { "CPU_MOVBE_FLAGS",
    167  1.1  christos     "CpuMovbe" },
    168  1.3  christos   { "CPU_CX16_FLAGS",
    169  1.3  christos     "CpuCX16" },
    170  1.1  christos   { "CPU_RDTSCP_FLAGS",
    171  1.1  christos     "CpuRdtscp" },
    172  1.1  christos   { "CPU_EPT_FLAGS",
    173  1.1  christos     "CpuEPT" },
    174  1.1  christos   { "CPU_FSGSBASE_FLAGS",
    175  1.1  christos     "CpuFSGSBase" },
    176  1.1  christos   { "CPU_RDRND_FLAGS",
    177  1.1  christos     "CpuRdRnd" },
    178  1.1  christos   { "CPU_F16C_FLAGS",
    179  1.5  christos     "CPU_AVX_FLAGS|CpuF16C" },
    180  1.1  christos   { "CPU_BMI2_FLAGS",
    181  1.1  christos     "CpuBMI2" },
    182  1.1  christos   { "CPU_LZCNT_FLAGS",
    183  1.1  christos     "CpuLZCNT" },
    184  1.1  christos   { "CPU_HLE_FLAGS",
    185  1.1  christos     "CpuHLE" },
    186  1.1  christos   { "CPU_RTM_FLAGS",
    187  1.1  christos     "CpuRTM" },
    188  1.1  christos   { "CPU_INVPCID_FLAGS",
    189  1.1  christos     "CpuINVPCID" },
    190  1.1  christos   { "CPU_VMFUNC_FLAGS",
    191  1.1  christos     "CpuVMFUNC" },
    192  1.1  christos   { "CPU_3DNOW_FLAGS",
    193  1.5  christos     "CPU_MMX_FLAGS|Cpu3dnow" },
    194  1.1  christos   { "CPU_3DNOWA_FLAGS",
    195  1.5  christos     "CPU_3DNOW_FLAGS|Cpu3dnowA" },
    196  1.1  christos   { "CPU_PADLOCK_FLAGS",
    197  1.1  christos     "CpuPadLock" },
    198  1.1  christos   { "CPU_SVME_FLAGS",
    199  1.1  christos     "CpuSVME" },
    200  1.1  christos   { "CPU_SSE4A_FLAGS",
    201  1.5  christos     "CPU_SSE3_FLAGS|CpuSSE4a" },
    202  1.1  christos   { "CPU_ABM_FLAGS",
    203  1.1  christos     "CpuABM" },
    204  1.1  christos   { "CPU_AVX_FLAGS",
    205  1.6  christos     "CPU_SSE4_2_FLAGS|CPU_XSAVE_FLAGS|CpuAVX" },
    206  1.1  christos   { "CPU_AVX2_FLAGS",
    207  1.5  christos     "CPU_AVX_FLAGS|CpuAVX2" },
    208  1.3  christos   { "CPU_AVX512F_FLAGS",
    209  1.7  christos     "CPU_AVX2_FLAGS|CpuAVX512F" },
    210  1.3  christos   { "CPU_AVX512CD_FLAGS",
    211  1.5  christos     "CPU_AVX512F_FLAGS|CpuAVX512CD" },
    212  1.3  christos   { "CPU_AVX512ER_FLAGS",
    213  1.5  christos     "CPU_AVX512F_FLAGS|CpuAVX512ER" },
    214  1.3  christos   { "CPU_AVX512PF_FLAGS",
    215  1.5  christos     "CPU_AVX512F_FLAGS|CpuAVX512PF" },
    216  1.5  christos   { "CPU_AVX512DQ_FLAGS",
    217  1.5  christos     "CPU_AVX512F_FLAGS|CpuAVX512DQ" },
    218  1.5  christos   { "CPU_AVX512BW_FLAGS",
    219  1.5  christos     "CPU_AVX512F_FLAGS|CpuAVX512BW" },
    220  1.5  christos   { "CPU_AVX512VL_FLAGS",
    221  1.6  christos     "CPU_AVX512F_FLAGS|CpuAVX512VL" },
    222  1.5  christos   { "CPU_AVX512IFMA_FLAGS",
    223  1.5  christos     "CPU_AVX512F_FLAGS|CpuAVX512IFMA" },
    224  1.5  christos   { "CPU_AVX512VBMI_FLAGS",
    225  1.5  christos     "CPU_AVX512F_FLAGS|CpuAVX512VBMI" },
    226  1.6  christos   { "CPU_AVX512_4FMAPS_FLAGS",
    227  1.6  christos     "CPU_AVX512F_FLAGS|CpuAVX512_4FMAPS" },
    228  1.6  christos   { "CPU_AVX512_4VNNIW_FLAGS",
    229  1.6  christos     "CPU_AVX512F_FLAGS|CpuAVX512_4VNNIW" },
    230  1.6  christos   { "CPU_AVX512_VPOPCNTDQ_FLAGS",
    231  1.6  christos     "CPU_AVX512F_FLAGS|CpuAVX512_VPOPCNTDQ" },
    232  1.6  christos   { "CPU_AVX512_VBMI2_FLAGS",
    233  1.6  christos     "CPU_AVX512F_FLAGS|CpuAVX512_VBMI2" },
    234  1.6  christos   { "CPU_AVX512_VNNI_FLAGS",
    235  1.6  christos     "CPU_AVX512F_FLAGS|CpuAVX512_VNNI" },
    236  1.6  christos   { "CPU_AVX512_BITALG_FLAGS",
    237  1.6  christos     "CPU_AVX512F_FLAGS|CpuAVX512_BITALG" },
    238  1.7  christos   { "CPU_AVX512_BF16_FLAGS",
    239  1.7  christos     "CPU_AVX512F_FLAGS|CpuAVX512_BF16" },
    240  1.1  christos   { "CPU_L1OM_FLAGS",
    241  1.1  christos     "unknown" },
    242  1.1  christos   { "CPU_K1OM_FLAGS",
    243  1.1  christos     "unknown" },
    244  1.3  christos   { "CPU_IAMCU_FLAGS",
    245  1.3  christos     "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586" },
    246  1.1  christos   { "CPU_ADX_FLAGS",
    247  1.1  christos     "CpuADX" },
    248  1.1  christos   { "CPU_RDSEED_FLAGS",
    249  1.1  christos     "CpuRdSeed" },
    250  1.1  christos   { "CPU_PRFCHW_FLAGS",
    251  1.1  christos     "CpuPRFCHW" },
    252  1.3  christos   { "CPU_SMAP_FLAGS",
    253  1.3  christos     "CpuSMAP" },
    254  1.3  christos   { "CPU_MPX_FLAGS",
    255  1.6  christos     "CPU_XSAVE_FLAGS|CpuMPX" },
    256  1.3  christos   { "CPU_SHA_FLAGS",
    257  1.5  christos     "CPU_SSE2_FLAGS|CpuSHA" },
    258  1.3  christos   { "CPU_CLFLUSHOPT_FLAGS",
    259  1.3  christos     "CpuClflushOpt" },
    260  1.3  christos   { "CPU_XSAVES_FLAGS",
    261  1.5  christos     "CPU_XSAVE_FLAGS|CpuXSAVES" },
    262  1.3  christos   { "CPU_XSAVEC_FLAGS",
    263  1.5  christos     "CPU_XSAVE_FLAGS|CpuXSAVEC" },
    264  1.3  christos   { "CPU_PREFETCHWT1_FLAGS",
    265  1.3  christos     "CpuPREFETCHWT1" },
    266  1.3  christos   { "CPU_SE1_FLAGS",
    267  1.3  christos     "CpuSE1" },
    268  1.3  christos   { "CPU_CLWB_FLAGS",
    269  1.3  christos     "CpuCLWB" },
    270  1.3  christos   { "CPU_CLZERO_FLAGS",
    271  1.3  christos     "CpuCLZERO" },
    272  1.3  christos   { "CPU_MWAITX_FLAGS",
    273  1.3  christos     "CpuMWAITX" },
    274  1.3  christos   { "CPU_OSPKE_FLAGS",
    275  1.6  christos     "CPU_XSAVE_FLAGS|CpuOSPKE" },
    276  1.5  christos   { "CPU_RDPID_FLAGS",
    277  1.5  christos     "CpuRDPID" },
    278  1.6  christos   { "CPU_PTWRITE_FLAGS",
    279  1.6  christos     "CpuPTWRITE" },
    280  1.6  christos   { "CPU_IBT_FLAGS",
    281  1.6  christos     "CpuIBT" },
    282  1.6  christos   { "CPU_SHSTK_FLAGS",
    283  1.6  christos     "CpuSHSTK" },
    284  1.6  christos   { "CPU_GFNI_FLAGS",
    285  1.6  christos     "CpuGFNI" },
    286  1.6  christos   { "CPU_VAES_FLAGS",
    287  1.6  christos     "CpuVAES" },
    288  1.6  christos   { "CPU_VPCLMULQDQ_FLAGS",
    289  1.6  christos     "CpuVPCLMULQDQ" },
    290  1.6  christos   { "CPU_WBNOINVD_FLAGS",
    291  1.6  christos     "CpuWBNOINVD" },
    292  1.6  christos   { "CPU_PCONFIG_FLAGS",
    293  1.6  christos     "CpuPCONFIG" },
    294  1.6  christos   { "CPU_WAITPKG_FLAGS",
    295  1.6  christos     "CpuWAITPKG" },
    296  1.6  christos   { "CPU_CLDEMOTE_FLAGS",
    297  1.6  christos     "CpuCLDEMOTE" },
    298  1.6  christos   { "CPU_MOVDIRI_FLAGS",
    299  1.6  christos     "CpuMOVDIRI" },
    300  1.6  christos   { "CPU_MOVDIR64B_FLAGS",
    301  1.6  christos     "CpuMOVDIR64B" },
    302  1.7  christos   { "CPU_ENQCMD_FLAGS",
    303  1.7  christos     "CpuENQCMD" },
    304  1.7  christos   { "CPU_AVX512_VP2INTERSECT_FLAGS",
    305  1.7  christos     "CpuAVX512_VP2INTERSECT" },
    306  1.7  christos   { "CPU_RDPRU_FLAGS",
    307  1.7  christos     "CpuRDPRU" },
    308  1.7  christos   { "CPU_MCOMMIT_FLAGS",
    309  1.7  christos     "CpuMCOMMIT" },
    310  1.5  christos   { "CPU_ANY_X87_FLAGS",
    311  1.5  christos     "CPU_ANY_287_FLAGS|Cpu8087" },
    312  1.5  christos   { "CPU_ANY_287_FLAGS",
    313  1.5  christos     "CPU_ANY_387_FLAGS|Cpu287" },
    314  1.5  christos   { "CPU_ANY_387_FLAGS",
    315  1.5  christos     "CPU_ANY_687_FLAGS|Cpu387" },
    316  1.5  christos   { "CPU_ANY_687_FLAGS",
    317  1.5  christos     "Cpu687|CpuFISTTP" },
    318  1.7  christos   { "CPU_ANY_CMOV_FLAGS",
    319  1.7  christos     "CpuCMOV" },
    320  1.7  christos   { "CPU_ANY_FXSR_FLAGS",
    321  1.7  christos     "CpuFXSR" },
    322  1.5  christos   { "CPU_ANY_MMX_FLAGS",
    323  1.5  christos     "CPU_3DNOWA_FLAGS" },
    324  1.5  christos   { "CPU_ANY_SSE_FLAGS",
    325  1.5  christos     "CPU_ANY_SSE2_FLAGS|CpuSSE|CpuSSE4a" },
    326  1.5  christos   { "CPU_ANY_SSE2_FLAGS",
    327  1.5  christos     "CPU_ANY_SSE3_FLAGS|CpuSSE2" },
    328  1.5  christos   { "CPU_ANY_SSE3_FLAGS",
    329  1.5  christos     "CPU_ANY_SSSE3_FLAGS|CpuSSE3" },
    330  1.5  christos   { "CPU_ANY_SSSE3_FLAGS",
    331  1.5  christos     "CPU_ANY_SSE4_1_FLAGS|CpuSSSE3" },
    332  1.5  christos   { "CPU_ANY_SSE4_1_FLAGS",
    333  1.5  christos     "CPU_ANY_SSE4_2_FLAGS|CpuSSE4_1" },
    334  1.5  christos   { "CPU_ANY_SSE4_2_FLAGS",
    335  1.5  christos     "CpuSSE4_2" },
    336  1.5  christos   { "CPU_ANY_AVX_FLAGS",
    337  1.5  christos     "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" },
    338  1.5  christos   { "CPU_ANY_AVX2_FLAGS",
    339  1.7  christos     "CPU_ANY_AVX512F_FLAGS|CpuAVX2" },
    340  1.5  christos   { "CPU_ANY_AVX512F_FLAGS",
    341  1.7  christos     "CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CpuAVX512BW|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512_4FMAPS|CpuAVX512_4VNNIW|CpuAVX512_VPOPCNTDQ|CpuAVX512_VBMI2|CpuAVX512_VNNI|CpuAVX512_BITALG|CpuAVX512_BF16|CpuAVX512_VP2INTERSECT" },
    342  1.5  christos   { "CPU_ANY_AVX512CD_FLAGS",
    343  1.5  christos     "CpuAVX512CD" },
    344  1.5  christos   { "CPU_ANY_AVX512ER_FLAGS",
    345  1.5  christos     "CpuAVX512ER" },
    346  1.5  christos   { "CPU_ANY_AVX512PF_FLAGS",
    347  1.5  christos     "CpuAVX512PF" },
    348  1.5  christos   { "CPU_ANY_AVX512DQ_FLAGS",
    349  1.5  christos     "CpuAVX512DQ" },
    350  1.5  christos   { "CPU_ANY_AVX512BW_FLAGS",
    351  1.5  christos     "CpuAVX512BW" },
    352  1.5  christos   { "CPU_ANY_AVX512VL_FLAGS",
    353  1.5  christos     "CpuAVX512VL" },
    354  1.5  christos   { "CPU_ANY_AVX512IFMA_FLAGS",
    355  1.5  christos     "CpuAVX512IFMA" },
    356  1.5  christos   { "CPU_ANY_AVX512VBMI_FLAGS",
    357  1.5  christos     "CpuAVX512VBMI" },
    358  1.6  christos   { "CPU_ANY_AVX512_4FMAPS_FLAGS",
    359  1.6  christos     "CpuAVX512_4FMAPS" },
    360  1.6  christos   { "CPU_ANY_AVX512_4VNNIW_FLAGS",
    361  1.6  christos     "CpuAVX512_4VNNIW" },
    362  1.6  christos   { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
    363  1.6  christos     "CpuAVX512_VPOPCNTDQ" },
    364  1.6  christos   { "CPU_ANY_IBT_FLAGS",
    365  1.6  christos     "CpuIBT" },
    366  1.6  christos   { "CPU_ANY_SHSTK_FLAGS",
    367  1.6  christos     "CpuSHSTK" },
    368  1.6  christos   { "CPU_ANY_AVX512_VBMI2_FLAGS",
    369  1.6  christos     "CpuAVX512_VBMI2" },
    370  1.6  christos   { "CPU_ANY_AVX512_VNNI_FLAGS",
    371  1.6  christos     "CpuAVX512_VNNI" },
    372  1.6  christos   { "CPU_ANY_AVX512_BITALG_FLAGS",
    373  1.6  christos     "CpuAVX512_BITALG" },
    374  1.7  christos   { "CPU_ANY_AVX512_BF16_FLAGS",
    375  1.7  christos     "CpuAVX512_BF16" },
    376  1.6  christos   { "CPU_ANY_MOVDIRI_FLAGS",
    377  1.6  christos     "CpuMOVDIRI" },
    378  1.6  christos   { "CPU_ANY_MOVDIR64B_FLAGS",
    379  1.6  christos     "CpuMOVDIR64B" },
    380  1.7  christos   { "CPU_ANY_ENQCMD_FLAGS",
    381  1.7  christos     "CpuENQCMD" },
    382  1.7  christos   { "CPU_ANY_AVX512_VP2INTERSECT_FLAGS",
    383  1.7  christos     "CpuAVX512_VP2INTERSECT" },
    384  1.1  christos };
    385  1.1  christos 
    386  1.1  christos static initializer operand_type_init[] =
    387  1.1  christos {
    388  1.1  christos   { "OPERAND_TYPE_NONE",
    389  1.1  christos     "0" },
    390  1.1  christos   { "OPERAND_TYPE_REG8",
    391  1.7  christos     "Class=Reg|Byte" },
    392  1.1  christos   { "OPERAND_TYPE_REG16",
    393  1.7  christos     "Class=Reg|Word" },
    394  1.1  christos   { "OPERAND_TYPE_REG32",
    395  1.7  christos     "Class=Reg|Dword" },
    396  1.1  christos   { "OPERAND_TYPE_REG64",
    397  1.7  christos     "Class=Reg|Qword" },
    398  1.1  christos   { "OPERAND_TYPE_IMM1",
    399  1.1  christos     "Imm1" },
    400  1.1  christos   { "OPERAND_TYPE_IMM8",
    401  1.1  christos     "Imm8" },
    402  1.1  christos   { "OPERAND_TYPE_IMM8S",
    403  1.1  christos     "Imm8S" },
    404  1.1  christos   { "OPERAND_TYPE_IMM16",
    405  1.1  christos     "Imm16" },
    406  1.1  christos   { "OPERAND_TYPE_IMM32",
    407  1.1  christos     "Imm32" },
    408  1.1  christos   { "OPERAND_TYPE_IMM32S",
    409  1.1  christos     "Imm32S" },
    410  1.1  christos   { "OPERAND_TYPE_IMM64",
    411  1.1  christos     "Imm64" },
    412  1.1  christos   { "OPERAND_TYPE_BASEINDEX",
    413  1.1  christos     "BaseIndex" },
    414  1.1  christos   { "OPERAND_TYPE_DISP8",
    415  1.1  christos     "Disp8" },
    416  1.1  christos   { "OPERAND_TYPE_DISP16",
    417  1.1  christos     "Disp16" },
    418  1.1  christos   { "OPERAND_TYPE_DISP32",
    419  1.1  christos     "Disp32" },
    420  1.1  christos   { "OPERAND_TYPE_DISP32S",
    421  1.1  christos     "Disp32S" },
    422  1.1  christos   { "OPERAND_TYPE_DISP64",
    423  1.1  christos     "Disp64" },
    424  1.1  christos   { "OPERAND_TYPE_INOUTPORTREG",
    425  1.7  christos     "Instance=RegD|Word" },
    426  1.1  christos   { "OPERAND_TYPE_SHIFTCOUNT",
    427  1.7  christos     "Instance=RegC|Byte" },
    428  1.1  christos   { "OPERAND_TYPE_CONTROL",
    429  1.7  christos     "Class=RegCR" },
    430  1.1  christos   { "OPERAND_TYPE_TEST",
    431  1.7  christos     "Class=RegTR" },
    432  1.1  christos   { "OPERAND_TYPE_DEBUG",
    433  1.7  christos     "Class=RegDR" },
    434  1.1  christos   { "OPERAND_TYPE_FLOATREG",
    435  1.7  christos     "Class=Reg|Tbyte" },
    436  1.1  christos   { "OPERAND_TYPE_FLOATACC",
    437  1.7  christos     "Instance=Accum|Tbyte" },
    438  1.7  christos   { "OPERAND_TYPE_SREG",
    439  1.7  christos     "Class=SReg" },
    440  1.1  christos   { "OPERAND_TYPE_REGMMX",
    441  1.7  christos     "Class=RegMMX" },
    442  1.1  christos   { "OPERAND_TYPE_REGXMM",
    443  1.7  christos     "Class=RegSIMD|Xmmword" },
    444  1.1  christos   { "OPERAND_TYPE_REGYMM",
    445  1.7  christos     "Class=RegSIMD|Ymmword" },
    446  1.3  christos   { "OPERAND_TYPE_REGZMM",
    447  1.7  christos     "Class=RegSIMD|Zmmword" },
    448  1.3  christos   { "OPERAND_TYPE_REGMASK",
    449  1.7  christos     "Class=RegMask" },
    450  1.7  christos   { "OPERAND_TYPE_REGBND",
    451  1.7  christos     "Class=RegBND" },
    452  1.7  christos   { "OPERAND_TYPE_ACC8",
    453  1.7  christos     "Instance=Accum|Byte" },
    454  1.7  christos   { "OPERAND_TYPE_ACC16",
    455  1.7  christos     "Instance=Accum|Word" },
    456  1.1  christos   { "OPERAND_TYPE_ACC32",
    457  1.7  christos     "Instance=Accum|Dword" },
    458  1.1  christos   { "OPERAND_TYPE_ACC64",
    459  1.7  christos     "Instance=Accum|Qword" },
    460  1.1  christos   { "OPERAND_TYPE_DISP16_32",
    461  1.1  christos     "Disp16|Disp32" },
    462  1.1  christos   { "OPERAND_TYPE_ANYDISP",
    463  1.1  christos     "Disp8|Disp16|Disp32|Disp32S|Disp64" },
    464  1.1  christos   { "OPERAND_TYPE_IMM16_32",
    465  1.1  christos     "Imm16|Imm32" },
    466  1.1  christos   { "OPERAND_TYPE_IMM16_32S",
    467  1.1  christos     "Imm16|Imm32S" },
    468  1.1  christos   { "OPERAND_TYPE_IMM16_32_32S",
    469  1.1  christos     "Imm16|Imm32|Imm32S" },
    470  1.3  christos   { "OPERAND_TYPE_IMM32_64",
    471  1.3  christos     "Imm32|Imm64" },
    472  1.1  christos   { "OPERAND_TYPE_IMM32_32S_DISP32",
    473  1.1  christos     "Imm32|Imm32S|Disp32" },
    474  1.1  christos   { "OPERAND_TYPE_IMM64_DISP64",
    475  1.1  christos     "Imm64|Disp64" },
    476  1.1  christos   { "OPERAND_TYPE_IMM32_32S_64_DISP32",
    477  1.1  christos     "Imm32|Imm32S|Imm64|Disp32" },
    478  1.1  christos   { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
    479  1.1  christos     "Imm32|Imm32S|Imm64|Disp32|Disp64" },
    480  1.7  christos   { "OPERAND_TYPE_ANYIMM",
    481  1.7  christos     "Imm1|Imm8|Imm8S|Imm16|Imm32|Imm32S|Imm64" },
    482  1.1  christos };
    483  1.1  christos 
    484  1.1  christos typedef struct bitfield
    485  1.1  christos {
    486  1.1  christos   int position;
    487  1.1  christos   int value;
    488  1.1  christos   const char *name;
    489  1.1  christos } bitfield;
    490  1.1  christos 
    491  1.1  christos #define BITFIELD(n) { n, 0, #n }
    492  1.1  christos 
    493  1.1  christos static bitfield cpu_flags[] =
    494  1.1  christos {
    495  1.1  christos   BITFIELD (Cpu186),
    496  1.1  christos   BITFIELD (Cpu286),
    497  1.1  christos   BITFIELD (Cpu386),
    498  1.1  christos   BITFIELD (Cpu486),
    499  1.1  christos   BITFIELD (Cpu586),
    500  1.1  christos   BITFIELD (Cpu686),
    501  1.7  christos   BITFIELD (CpuCMOV),
    502  1.7  christos   BITFIELD (CpuFXSR),
    503  1.1  christos   BITFIELD (CpuClflush),
    504  1.1  christos   BITFIELD (CpuNop),
    505  1.1  christos   BITFIELD (CpuSYSCALL),
    506  1.1  christos   BITFIELD (Cpu8087),
    507  1.1  christos   BITFIELD (Cpu287),
    508  1.1  christos   BITFIELD (Cpu387),
    509  1.1  christos   BITFIELD (Cpu687),
    510  1.1  christos   BITFIELD (CpuFISTTP),
    511  1.1  christos   BITFIELD (CpuMMX),
    512  1.1  christos   BITFIELD (CpuSSE),
    513  1.1  christos   BITFIELD (CpuSSE2),
    514  1.1  christos   BITFIELD (CpuSSE3),
    515  1.1  christos   BITFIELD (CpuSSSE3),
    516  1.1  christos   BITFIELD (CpuSSE4_1),
    517  1.1  christos   BITFIELD (CpuSSE4_2),
    518  1.1  christos   BITFIELD (CpuAVX),
    519  1.1  christos   BITFIELD (CpuAVX2),
    520  1.3  christos   BITFIELD (CpuAVX512F),
    521  1.3  christos   BITFIELD (CpuAVX512CD),
    522  1.3  christos   BITFIELD (CpuAVX512ER),
    523  1.3  christos   BITFIELD (CpuAVX512PF),
    524  1.3  christos   BITFIELD (CpuAVX512VL),
    525  1.3  christos   BITFIELD (CpuAVX512DQ),
    526  1.3  christos   BITFIELD (CpuAVX512BW),
    527  1.1  christos   BITFIELD (CpuL1OM),
    528  1.1  christos   BITFIELD (CpuK1OM),
    529  1.3  christos   BITFIELD (CpuIAMCU),
    530  1.1  christos   BITFIELD (CpuSSE4a),
    531  1.1  christos   BITFIELD (Cpu3dnow),
    532  1.1  christos   BITFIELD (Cpu3dnowA),
    533  1.1  christos   BITFIELD (CpuPadLock),
    534  1.1  christos   BITFIELD (CpuSVME),
    535  1.1  christos   BITFIELD (CpuVMX),
    536  1.1  christos   BITFIELD (CpuSMX),
    537  1.1  christos   BITFIELD (CpuABM),
    538  1.1  christos   BITFIELD (CpuXsave),
    539  1.1  christos   BITFIELD (CpuXsaveopt),
    540  1.1  christos   BITFIELD (CpuAES),
    541  1.1  christos   BITFIELD (CpuPCLMUL),
    542  1.1  christos   BITFIELD (CpuFMA),
    543  1.1  christos   BITFIELD (CpuFMA4),
    544  1.1  christos   BITFIELD (CpuXOP),
    545  1.1  christos   BITFIELD (CpuLWP),
    546  1.1  christos   BITFIELD (CpuBMI),
    547  1.1  christos   BITFIELD (CpuTBM),
    548  1.1  christos   BITFIELD (CpuLM),
    549  1.1  christos   BITFIELD (CpuMovbe),
    550  1.3  christos   BITFIELD (CpuCX16),
    551  1.1  christos   BITFIELD (CpuEPT),
    552  1.1  christos   BITFIELD (CpuRdtscp),
    553  1.1  christos   BITFIELD (CpuFSGSBase),
    554  1.1  christos   BITFIELD (CpuRdRnd),
    555  1.1  christos   BITFIELD (CpuF16C),
    556  1.1  christos   BITFIELD (CpuBMI2),
    557  1.1  christos   BITFIELD (CpuLZCNT),
    558  1.1  christos   BITFIELD (CpuHLE),
    559  1.1  christos   BITFIELD (CpuRTM),
    560  1.1  christos   BITFIELD (CpuINVPCID),
    561  1.1  christos   BITFIELD (CpuVMFUNC),
    562  1.1  christos   BITFIELD (CpuRDSEED),
    563  1.1  christos   BITFIELD (CpuADX),
    564  1.1  christos   BITFIELD (CpuPRFCHW),
    565  1.3  christos   BITFIELD (CpuSMAP),
    566  1.3  christos   BITFIELD (CpuSHA),
    567  1.3  christos   BITFIELD (CpuClflushOpt),
    568  1.3  christos   BITFIELD (CpuXSAVES),
    569  1.3  christos   BITFIELD (CpuXSAVEC),
    570  1.3  christos   BITFIELD (CpuPREFETCHWT1),
    571  1.3  christos   BITFIELD (CpuSE1),
    572  1.3  christos   BITFIELD (CpuCLWB),
    573  1.1  christos   BITFIELD (Cpu64),
    574  1.1  christos   BITFIELD (CpuNo64),
    575  1.3  christos   BITFIELD (CpuMPX),
    576  1.3  christos   BITFIELD (CpuAVX512IFMA),
    577  1.3  christos   BITFIELD (CpuAVX512VBMI),
    578  1.6  christos   BITFIELD (CpuAVX512_4FMAPS),
    579  1.6  christos   BITFIELD (CpuAVX512_4VNNIW),
    580  1.6  christos   BITFIELD (CpuAVX512_VPOPCNTDQ),
    581  1.6  christos   BITFIELD (CpuAVX512_VBMI2),
    582  1.6  christos   BITFIELD (CpuAVX512_VNNI),
    583  1.6  christos   BITFIELD (CpuAVX512_BITALG),
    584  1.7  christos   BITFIELD (CpuAVX512_BF16),
    585  1.7  christos   BITFIELD (CpuAVX512_VP2INTERSECT),
    586  1.3  christos   BITFIELD (CpuMWAITX),
    587  1.3  christos   BITFIELD (CpuCLZERO),
    588  1.3  christos   BITFIELD (CpuOSPKE),
    589  1.5  christos   BITFIELD (CpuRDPID),
    590  1.6  christos   BITFIELD (CpuPTWRITE),
    591  1.6  christos   BITFIELD (CpuIBT),
    592  1.6  christos   BITFIELD (CpuSHSTK),
    593  1.6  christos   BITFIELD (CpuGFNI),
    594  1.6  christos   BITFIELD (CpuVAES),
    595  1.6  christos   BITFIELD (CpuVPCLMULQDQ),
    596  1.6  christos   BITFIELD (CpuWBNOINVD),
    597  1.6  christos   BITFIELD (CpuPCONFIG),
    598  1.6  christos   BITFIELD (CpuWAITPKG),
    599  1.6  christos   BITFIELD (CpuCLDEMOTE),
    600  1.6  christos   BITFIELD (CpuMOVDIRI),
    601  1.6  christos   BITFIELD (CpuMOVDIR64B),
    602  1.7  christos   BITFIELD (CpuENQCMD),
    603  1.7  christos   BITFIELD (CpuRDPRU),
    604  1.7  christos   BITFIELD (CpuMCOMMIT),
    605  1.1  christos #ifdef CpuUnused
    606  1.1  christos   BITFIELD (CpuUnused),
    607  1.1  christos #endif
    608  1.1  christos };
    609  1.1  christos 
    610  1.1  christos static bitfield opcode_modifiers[] =
    611  1.1  christos {
    612  1.1  christos   BITFIELD (D),
    613  1.1  christos   BITFIELD (W),
    614  1.6  christos   BITFIELD (Load),
    615  1.1  christos   BITFIELD (Modrm),
    616  1.1  christos   BITFIELD (ShortForm),
    617  1.1  christos   BITFIELD (Jump),
    618  1.1  christos   BITFIELD (FloatMF),
    619  1.1  christos   BITFIELD (FloatR),
    620  1.7  christos   BITFIELD (Size),
    621  1.1  christos   BITFIELD (CheckRegSize),
    622  1.1  christos   BITFIELD (IgnoreSize),
    623  1.1  christos   BITFIELD (DefaultSize),
    624  1.7  christos   BITFIELD (Anysize),
    625  1.1  christos   BITFIELD (No_bSuf),
    626  1.1  christos   BITFIELD (No_wSuf),
    627  1.1  christos   BITFIELD (No_lSuf),
    628  1.1  christos   BITFIELD (No_sSuf),
    629  1.1  christos   BITFIELD (No_qSuf),
    630  1.1  christos   BITFIELD (No_ldSuf),
    631  1.1  christos   BITFIELD (FWait),
    632  1.1  christos   BITFIELD (IsString),
    633  1.7  christos   BITFIELD (RegMem),
    634  1.3  christos   BITFIELD (BNDPrefixOk),
    635  1.6  christos   BITFIELD (NoTrackPrefixOk),
    636  1.1  christos   BITFIELD (IsLockable),
    637  1.1  christos   BITFIELD (RegKludge),
    638  1.1  christos   BITFIELD (Implicit1stXmm0),
    639  1.1  christos   BITFIELD (RepPrefixOk),
    640  1.1  christos   BITFIELD (HLEPrefixOk),
    641  1.1  christos   BITFIELD (ToDword),
    642  1.1  christos   BITFIELD (ToQword),
    643  1.6  christos   BITFIELD (AddrPrefixOpReg),
    644  1.1  christos   BITFIELD (IsPrefix),
    645  1.1  christos   BITFIELD (ImmExt),
    646  1.1  christos   BITFIELD (NoRex64),
    647  1.1  christos   BITFIELD (Rex64),
    648  1.1  christos   BITFIELD (Ugh),
    649  1.1  christos   BITFIELD (Vex),
    650  1.1  christos   BITFIELD (VexVVVV),
    651  1.1  christos   BITFIELD (VexW),
    652  1.1  christos   BITFIELD (VexOpcode),
    653  1.1  christos   BITFIELD (VexSources),
    654  1.1  christos   BITFIELD (VecSIB),
    655  1.1  christos   BITFIELD (SSE2AVX),
    656  1.1  christos   BITFIELD (NoAVX),
    657  1.3  christos   BITFIELD (EVex),
    658  1.3  christos   BITFIELD (Masking),
    659  1.3  christos   BITFIELD (Broadcast),
    660  1.3  christos   BITFIELD (StaticRounding),
    661  1.3  christos   BITFIELD (SAE),
    662  1.3  christos   BITFIELD (Disp8MemShift),
    663  1.3  christos   BITFIELD (NoDefMask),
    664  1.6  christos   BITFIELD (ImplicitQuadGroup),
    665  1.6  christos   BITFIELD (Optimize),
    666  1.1  christos   BITFIELD (ATTMnemonic),
    667  1.1  christos   BITFIELD (ATTSyntax),
    668  1.1  christos   BITFIELD (IntelSyntax),
    669  1.5  christos   BITFIELD (AMD64),
    670  1.5  christos   BITFIELD (Intel64),
    671  1.1  christos };
    672  1.1  christos 
    673  1.7  christos #define CLASS(n) #n, n
    674  1.7  christos 
    675  1.7  christos static const struct {
    676  1.7  christos   const char *name;
    677  1.7  christos   enum operand_class value;
    678  1.7  christos } operand_classes[] = {
    679  1.7  christos   CLASS (Reg),
    680  1.7  christos   CLASS (SReg),
    681  1.7  christos   CLASS (RegCR),
    682  1.7  christos   CLASS (RegDR),
    683  1.7  christos   CLASS (RegTR),
    684  1.7  christos   CLASS (RegMMX),
    685  1.7  christos   CLASS (RegSIMD),
    686  1.7  christos   CLASS (RegMask),
    687  1.7  christos   CLASS (RegBND),
    688  1.7  christos };
    689  1.7  christos 
    690  1.7  christos #undef CLASS
    691  1.7  christos 
    692  1.7  christos #define INSTANCE(n) #n, n
    693  1.7  christos 
    694  1.7  christos static const struct {
    695  1.7  christos   const char *name;
    696  1.7  christos   enum operand_instance value;
    697  1.7  christos } operand_instances[] = {
    698  1.7  christos     INSTANCE (Accum),
    699  1.7  christos     INSTANCE (RegC),
    700  1.7  christos     INSTANCE (RegD),
    701  1.7  christos     INSTANCE (RegB),
    702  1.7  christos };
    703  1.7  christos 
    704  1.7  christos #undef INSTANCE
    705  1.7  christos 
    706  1.1  christos static bitfield operand_types[] =
    707  1.1  christos {
    708  1.1  christos   BITFIELD (Imm1),
    709  1.1  christos   BITFIELD (Imm8),
    710  1.1  christos   BITFIELD (Imm8S),
    711  1.1  christos   BITFIELD (Imm16),
    712  1.1  christos   BITFIELD (Imm32),
    713  1.1  christos   BITFIELD (Imm32S),
    714  1.1  christos   BITFIELD (Imm64),
    715  1.1  christos   BITFIELD (BaseIndex),
    716  1.1  christos   BITFIELD (Disp8),
    717  1.1  christos   BITFIELD (Disp16),
    718  1.1  christos   BITFIELD (Disp32),
    719  1.1  christos   BITFIELD (Disp32S),
    720  1.1  christos   BITFIELD (Disp64),
    721  1.1  christos   BITFIELD (Byte),
    722  1.1  christos   BITFIELD (Word),
    723  1.1  christos   BITFIELD (Dword),
    724  1.1  christos   BITFIELD (Fword),
    725  1.1  christos   BITFIELD (Qword),
    726  1.1  christos   BITFIELD (Tbyte),
    727  1.1  christos   BITFIELD (Xmmword),
    728  1.1  christos   BITFIELD (Ymmword),
    729  1.3  christos   BITFIELD (Zmmword),
    730  1.1  christos   BITFIELD (Unspecified),
    731  1.1  christos #ifdef OTUnused
    732  1.1  christos   BITFIELD (OTUnused),
    733  1.1  christos #endif
    734  1.1  christos };
    735  1.1  christos 
    736  1.1  christos static const char *filename;
    737  1.6  christos static i386_cpu_flags active_cpu_flags;
    738  1.6  christos static int active_isstring;
    739  1.1  christos 
    740  1.1  christos static int
    741  1.1  christos compare (const void *x, const void *y)
    742  1.1  christos {
    743  1.1  christos   const bitfield *xp = (const bitfield *) x;
    744  1.1  christos   const bitfield *yp = (const bitfield *) y;
    745  1.1  christos   return xp->position - yp->position;
    746  1.1  christos }
    747  1.1  christos 
    748  1.1  christos static void
    749  1.1  christos fail (const char *message, ...)
    750  1.1  christos {
    751  1.1  christos   va_list args;
    752  1.1  christos 
    753  1.1  christos   va_start (args, message);
    754  1.6  christos   fprintf (stderr, _("%s: error: "), program_name);
    755  1.1  christos   vfprintf (stderr, message, args);
    756  1.1  christos   va_end (args);
    757  1.1  christos   xexit (1);
    758  1.1  christos }
    759  1.1  christos 
    760  1.1  christos static void
    761  1.1  christos process_copyright (FILE *fp)
    762  1.1  christos {
    763  1.1  christos   fprintf (fp, "/* This file is automatically generated by i386-gen.  Do not edit!  */\n\
    764  1.7  christos /* Copyright (C) 2007-2020 Free Software Foundation, Inc.\n\
    765  1.1  christos \n\
    766  1.1  christos    This file is part of the GNU opcodes library.\n\
    767  1.1  christos \n\
    768  1.1  christos    This library is free software; you can redistribute it and/or modify\n\
    769  1.1  christos    it under the terms of the GNU General Public License as published by\n\
    770  1.1  christos    the Free Software Foundation; either version 3, or (at your option)\n\
    771  1.1  christos    any later version.\n\
    772  1.1  christos \n\
    773  1.1  christos    It is distributed in the hope that it will be useful, but WITHOUT\n\
    774  1.1  christos    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
    775  1.1  christos    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public\n\
    776  1.1  christos    License for more details.\n\
    777  1.1  christos \n\
    778  1.1  christos    You should have received a copy of the GNU General Public License\n\
    779  1.1  christos    along with this program; if not, write to the Free Software\n\
    780  1.1  christos    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
    781  1.1  christos    MA 02110-1301, USA.  */\n");
    782  1.1  christos }
    783  1.1  christos 
    784  1.1  christos /* Remove leading white spaces.  */
    785  1.1  christos 
    786  1.1  christos static char *
    787  1.1  christos remove_leading_whitespaces (char *str)
    788  1.1  christos {
    789  1.1  christos   while (ISSPACE (*str))
    790  1.1  christos     str++;
    791  1.1  christos   return str;
    792  1.1  christos }
    793  1.1  christos 
    794  1.1  christos /* Remove trailing white spaces.  */
    795  1.1  christos 
    796  1.1  christos static void
    797  1.1  christos remove_trailing_whitespaces (char *str)
    798  1.1  christos {
    799  1.1  christos   size_t last = strlen (str);
    800  1.1  christos 
    801  1.1  christos   if (last == 0)
    802  1.1  christos     return;
    803  1.1  christos 
    804  1.1  christos   do
    805  1.1  christos     {
    806  1.1  christos       last--;
    807  1.1  christos       if (ISSPACE (str [last]))
    808  1.1  christos 	str[last] = '\0';
    809  1.1  christos       else
    810  1.1  christos 	break;
    811  1.1  christos     }
    812  1.1  christos   while (last != 0);
    813  1.1  christos }
    814  1.1  christos 
    815  1.1  christos /* Find next field separated by SEP and terminate it. Return a
    816  1.1  christos    pointer to the one after it.  */
    817  1.1  christos 
    818  1.1  christos static char *
    819  1.1  christos next_field (char *str, char sep, char **next, char *last)
    820  1.1  christos {
    821  1.1  christos   char *p;
    822  1.1  christos 
    823  1.1  christos   p = remove_leading_whitespaces (str);
    824  1.1  christos   for (str = p; *str != sep && *str != '\0'; str++);
    825  1.1  christos 
    826  1.1  christos   *str = '\0';
    827  1.1  christos   remove_trailing_whitespaces (p);
    828  1.1  christos 
    829  1.1  christos   *next = str + 1;
    830  1.1  christos 
    831  1.1  christos   if (p >= last)
    832  1.1  christos     abort ();
    833  1.1  christos 
    834  1.1  christos   return p;
    835  1.1  christos }
    836  1.1  christos 
    837  1.5  christos static void set_bitfield (char *, bitfield *, int, unsigned int, int);
    838  1.5  christos 
    839  1.5  christos static int
    840  1.7  christos set_bitfield_from_cpu_flag_init (char *f, bitfield *array, unsigned int size,
    841  1.7  christos 				 int lineno)
    842  1.5  christos {
    843  1.5  christos   char *str, *next, *last;
    844  1.5  christos   unsigned int i;
    845  1.5  christos 
    846  1.5  christos   for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
    847  1.5  christos     if (strcmp (cpu_flag_init[i].name, f) == 0)
    848  1.5  christos       {
    849  1.5  christos 	/* Turn on selective bits.  */
    850  1.5  christos 	char *init = xstrdup (cpu_flag_init[i].init);
    851  1.5  christos 	last = init + strlen (init);
    852  1.5  christos 	for (next = init; next && next < last; )
    853  1.5  christos 	  {
    854  1.5  christos 	    str = next_field (next, '|', &next, last);
    855  1.5  christos 	    if (str)
    856  1.5  christos 	      set_bitfield (str, array, 1, size, lineno);
    857  1.5  christos 	  }
    858  1.5  christos 	free (init);
    859  1.5  christos 	return 0;
    860  1.5  christos       }
    861  1.5  christos 
    862  1.5  christos   return -1;
    863  1.5  christos }
    864  1.5  christos 
    865  1.1  christos static void
    866  1.5  christos set_bitfield (char *f, bitfield *array, int value,
    867  1.1  christos 	      unsigned int size, int lineno)
    868  1.1  christos {
    869  1.1  christos   unsigned int i;
    870  1.1  christos 
    871  1.1  christos   if (strcmp (f, "CpuFP") == 0)
    872  1.1  christos     {
    873  1.1  christos       set_bitfield("Cpu387", array, value, size, lineno);
    874  1.1  christos       set_bitfield("Cpu287", array, value, size, lineno);
    875  1.1  christos       f = "Cpu8087";
    876  1.1  christos     }
    877  1.1  christos   else if (strcmp (f, "Mmword") == 0)
    878  1.1  christos     f= "Qword";
    879  1.1  christos   else if (strcmp (f, "Oword") == 0)
    880  1.1  christos     f= "Xmmword";
    881  1.1  christos 
    882  1.1  christos   for (i = 0; i < size; i++)
    883  1.1  christos     if (strcasecmp (array[i].name, f) == 0)
    884  1.1  christos       {
    885  1.1  christos 	array[i].value = value;
    886  1.1  christos 	return;
    887  1.1  christos       }
    888  1.1  christos 
    889  1.1  christos   if (value)
    890  1.1  christos     {
    891  1.1  christos       const char *v = strchr (f, '=');
    892  1.1  christos 
    893  1.1  christos       if (v)
    894  1.1  christos 	{
    895  1.1  christos 	  size_t n = v - f;
    896  1.1  christos 	  char *end;
    897  1.1  christos 
    898  1.1  christos 	  for (i = 0; i < size; i++)
    899  1.1  christos 	    if (strncasecmp (array[i].name, f, n) == 0)
    900  1.1  christos 	      {
    901  1.1  christos 		value = strtol (v + 1, &end, 0);
    902  1.1  christos 		if (*end == '\0')
    903  1.1  christos 		  {
    904  1.1  christos 		    array[i].value = value;
    905  1.1  christos 		    return;
    906  1.1  christos 		  }
    907  1.1  christos 		break;
    908  1.1  christos 	      }
    909  1.1  christos 	}
    910  1.1  christos     }
    911  1.1  christos 
    912  1.7  christos   /* Handle CPU_XXX_FLAGS.  */
    913  1.7  christos   if (value == 1 && !set_bitfield_from_cpu_flag_init (f, array, size, lineno))
    914  1.5  christos     return;
    915  1.5  christos 
    916  1.1  christos   if (lineno != -1)
    917  1.6  christos     fail (_("%s: %d: unknown bitfield: %s\n"), filename, lineno, f);
    918  1.1  christos   else
    919  1.6  christos     fail (_("unknown bitfield: %s\n"), f);
    920  1.1  christos }
    921  1.1  christos 
    922  1.1  christos static void
    923  1.1  christos output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
    924  1.1  christos 		  int macro, const char *comma, const char *indent)
    925  1.1  christos {
    926  1.1  christos   unsigned int i;
    927  1.1  christos 
    928  1.6  christos   memset (&active_cpu_flags, 0, sizeof(active_cpu_flags));
    929  1.6  christos 
    930  1.1  christos   fprintf (table, "%s{ { ", indent);
    931  1.1  christos 
    932  1.1  christos   for (i = 0; i < size - 1; i++)
    933  1.1  christos     {
    934  1.3  christos       if (((i + 1) % 20) != 0)
    935  1.3  christos 	fprintf (table, "%d, ", flags[i].value);
    936  1.3  christos       else
    937  1.3  christos 	fprintf (table, "%d,", flags[i].value);
    938  1.1  christos       if (((i + 1) % 20) == 0)
    939  1.1  christos 	{
    940  1.1  christos 	  /* We need \\ for macro.  */
    941  1.1  christos 	  if (macro)
    942  1.1  christos 	    fprintf (table, " \\\n    %s", indent);
    943  1.1  christos 	  else
    944  1.1  christos 	    fprintf (table, "\n    %s", indent);
    945  1.1  christos 	}
    946  1.6  christos       if (flags[i].value)
    947  1.6  christos 	active_cpu_flags.array[i / 32] |= 1U << (i % 32);
    948  1.1  christos     }
    949  1.1  christos 
    950  1.1  christos   fprintf (table, "%d } }%s\n", flags[i].value, comma);
    951  1.1  christos }
    952  1.1  christos 
    953  1.1  christos static void
    954  1.1  christos process_i386_cpu_flag (FILE *table, char *flag, int macro,
    955  1.1  christos 		       const char *comma, const char *indent,
    956  1.1  christos 		       int lineno)
    957  1.1  christos {
    958  1.1  christos   char *str, *next, *last;
    959  1.1  christos   unsigned int i;
    960  1.1  christos   bitfield flags [ARRAY_SIZE (cpu_flags)];
    961  1.1  christos 
    962  1.1  christos   /* Copy the default cpu flags.  */
    963  1.1  christos   memcpy (flags, cpu_flags, sizeof (cpu_flags));
    964  1.1  christos 
    965  1.1  christos   if (strcasecmp (flag, "unknown") == 0)
    966  1.1  christos     {
    967  1.1  christos       /* We turn on everything except for cpu64 in case of
    968  1.1  christos 	 CPU_UNKNOWN_FLAGS.  */
    969  1.1  christos       for (i = 0; i < ARRAY_SIZE (flags); i++)
    970  1.1  christos 	if (flags[i].position != Cpu64)
    971  1.1  christos 	  flags[i].value = 1;
    972  1.1  christos     }
    973  1.1  christos   else if (flag[0] == '~')
    974  1.1  christos     {
    975  1.1  christos       last = flag + strlen (flag);
    976  1.1  christos 
    977  1.1  christos       if (flag[1] == '(')
    978  1.1  christos 	{
    979  1.1  christos 	  last -= 1;
    980  1.1  christos 	  next = flag + 2;
    981  1.1  christos 	  if (*last != ')')
    982  1.6  christos 	    fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename,
    983  1.1  christos 		  lineno, flag);
    984  1.1  christos 	  *last = '\0';
    985  1.1  christos 	}
    986  1.1  christos       else
    987  1.1  christos 	next = flag + 1;
    988  1.1  christos 
    989  1.1  christos       /* First we turn on everything except for cpu64.  */
    990  1.1  christos       for (i = 0; i < ARRAY_SIZE (flags); i++)
    991  1.1  christos 	if (flags[i].position != Cpu64)
    992  1.1  christos 	  flags[i].value = 1;
    993  1.1  christos 
    994  1.1  christos       /* Turn off selective bits.  */
    995  1.1  christos       for (; next && next < last; )
    996  1.1  christos 	{
    997  1.1  christos 	  str = next_field (next, '|', &next, last);
    998  1.1  christos 	  if (str)
    999  1.1  christos 	    set_bitfield (str, flags, 0, ARRAY_SIZE (flags), lineno);
   1000  1.1  christos 	}
   1001  1.1  christos     }
   1002  1.1  christos   else if (strcmp (flag, "0"))
   1003  1.1  christos     {
   1004  1.1  christos       /* Turn on selective bits.  */
   1005  1.1  christos       last = flag + strlen (flag);
   1006  1.1  christos       for (next = flag; next && next < last; )
   1007  1.1  christos 	{
   1008  1.1  christos 	  str = next_field (next, '|', &next, last);
   1009  1.1  christos 	  if (str)
   1010  1.1  christos 	    set_bitfield (str, flags, 1, ARRAY_SIZE (flags), lineno);
   1011  1.1  christos 	}
   1012  1.1  christos     }
   1013  1.1  christos 
   1014  1.1  christos   output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
   1015  1.1  christos 		    comma, indent);
   1016  1.1  christos }
   1017  1.1  christos 
   1018  1.1  christos static void
   1019  1.1  christos output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
   1020  1.1  christos {
   1021  1.1  christos   unsigned int i;
   1022  1.1  christos 
   1023  1.1  christos   fprintf (table, "    { ");
   1024  1.1  christos 
   1025  1.1  christos   for (i = 0; i < size - 1; i++)
   1026  1.1  christos     {
   1027  1.3  christos       if (((i + 1) % 20) != 0)
   1028  1.3  christos         fprintf (table, "%d, ", modifier[i].value);
   1029  1.3  christos       else
   1030  1.3  christos         fprintf (table, "%d,", modifier[i].value);
   1031  1.1  christos       if (((i + 1) % 20) == 0)
   1032  1.1  christos 	fprintf (table, "\n      ");
   1033  1.1  christos     }
   1034  1.1  christos 
   1035  1.1  christos   fprintf (table, "%d },\n", modifier[i].value);
   1036  1.1  christos }
   1037  1.1  christos 
   1038  1.7  christos static int
   1039  1.7  christos adjust_broadcast_modifier (char **opnd)
   1040  1.7  christos {
   1041  1.7  christos   char *str, *next, *last, *op;
   1042  1.7  christos   int bcst_type = INT_MAX;
   1043  1.7  christos 
   1044  1.7  christos   /* Skip the immediate operand.  */
   1045  1.7  christos   op = opnd[0];
   1046  1.7  christos   if (strcasecmp(op, "Imm8") == 0)
   1047  1.7  christos     op = opnd[1];
   1048  1.7  christos 
   1049  1.7  christos   op = xstrdup (op);
   1050  1.7  christos   last = op + strlen (op);
   1051  1.7  christos   for (next = op; next && next < last; )
   1052  1.7  christos     {
   1053  1.7  christos       str = next_field (next, '|', &next, last);
   1054  1.7  christos       if (str)
   1055  1.7  christos 	{
   1056  1.7  christos 	  if (strcasecmp(str, "Byte") == 0)
   1057  1.7  christos 	    {
   1058  1.7  christos 	      /* The smalest broadcast type, no need to check
   1059  1.7  christos 		 further.  */
   1060  1.7  christos 	      bcst_type = BYTE_BROADCAST;
   1061  1.7  christos 	      break;
   1062  1.7  christos 	    }
   1063  1.7  christos 	  else if (strcasecmp(str, "Word") == 0)
   1064  1.7  christos 	    {
   1065  1.7  christos 	      if (bcst_type > WORD_BROADCAST)
   1066  1.7  christos 		bcst_type = WORD_BROADCAST;
   1067  1.7  christos 	    }
   1068  1.7  christos 	  else if (strcasecmp(str, "Dword") == 0)
   1069  1.7  christos 	    {
   1070  1.7  christos 	      if (bcst_type > DWORD_BROADCAST)
   1071  1.7  christos 		bcst_type = DWORD_BROADCAST;
   1072  1.7  christos 	    }
   1073  1.7  christos 	  else if (strcasecmp(str, "Qword") == 0)
   1074  1.7  christos 	    {
   1075  1.7  christos 	      if (bcst_type > QWORD_BROADCAST)
   1076  1.7  christos 		bcst_type = QWORD_BROADCAST;
   1077  1.7  christos 	    }
   1078  1.7  christos 	}
   1079  1.7  christos     }
   1080  1.7  christos   free (op);
   1081  1.7  christos 
   1082  1.7  christos   if (bcst_type == INT_MAX)
   1083  1.7  christos     fail (_("unknown broadcast operand: %s\n"), op);
   1084  1.7  christos 
   1085  1.7  christos   return bcst_type;
   1086  1.7  christos }
   1087  1.7  christos 
   1088  1.1  christos static void
   1089  1.7  christos process_i386_opcode_modifier (FILE *table, char *mod, char **opnd, int lineno)
   1090  1.1  christos {
   1091  1.1  christos   char *str, *next, *last;
   1092  1.1  christos   bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
   1093  1.1  christos 
   1094  1.6  christos   active_isstring = 0;
   1095  1.6  christos 
   1096  1.1  christos   /* Copy the default opcode modifier.  */
   1097  1.1  christos   memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
   1098  1.1  christos 
   1099  1.1  christos   if (strcmp (mod, "0"))
   1100  1.1  christos     {
   1101  1.7  christos       unsigned int have_w = 0, bwlq_suf = 0xf;
   1102  1.7  christos 
   1103  1.1  christos       last = mod + strlen (mod);
   1104  1.1  christos       for (next = mod; next && next < last; )
   1105  1.1  christos 	{
   1106  1.1  christos 	  str = next_field (next, '|', &next, last);
   1107  1.1  christos 	  if (str)
   1108  1.6  christos 	    {
   1109  1.7  christos 	      int val = 1;
   1110  1.7  christos 	      if (strcasecmp(str, "Broadcast") == 0)
   1111  1.7  christos 		  val = adjust_broadcast_modifier (opnd);
   1112  1.7  christos 	      set_bitfield (str, modifiers, val, ARRAY_SIZE (modifiers),
   1113  1.1  christos 			  lineno);
   1114  1.6  christos 	      if (strcasecmp(str, "IsString") == 0)
   1115  1.6  christos 		active_isstring = 1;
   1116  1.7  christos 
   1117  1.7  christos 	      if (strcasecmp(str, "W") == 0)
   1118  1.7  christos 		have_w = 1;
   1119  1.7  christos 
   1120  1.7  christos 	      if (strcasecmp(str, "No_bSuf") == 0)
   1121  1.7  christos 		bwlq_suf &= ~1;
   1122  1.7  christos 	      if (strcasecmp(str, "No_wSuf") == 0)
   1123  1.7  christos 		bwlq_suf &= ~2;
   1124  1.7  christos 	      if (strcasecmp(str, "No_lSuf") == 0)
   1125  1.7  christos 		bwlq_suf &= ~4;
   1126  1.7  christos 	      if (strcasecmp(str, "No_qSuf") == 0)
   1127  1.7  christos 		bwlq_suf &= ~8;
   1128  1.6  christos 	    }
   1129  1.1  christos 	}
   1130  1.7  christos 
   1131  1.7  christos       if (have_w && !bwlq_suf)
   1132  1.7  christos 	fail ("%s: %d: stray W modifier\n", filename, lineno);
   1133  1.7  christos       if (have_w && !(bwlq_suf & 1))
   1134  1.7  christos 	fprintf (stderr, "%s: %d: W modifier without Byte operand(s)\n",
   1135  1.7  christos 		 filename, lineno);
   1136  1.7  christos       if (have_w && !(bwlq_suf & ~1))
   1137  1.7  christos 	fprintf (stderr,
   1138  1.7  christos 		 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
   1139  1.7  christos 		 filename, lineno);
   1140  1.1  christos     }
   1141  1.1  christos   output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
   1142  1.1  christos }
   1143  1.1  christos 
   1144  1.6  christos enum stage {
   1145  1.6  christos   stage_macros,
   1146  1.6  christos   stage_opcodes,
   1147  1.6  christos   stage_registers,
   1148  1.6  christos };
   1149  1.6  christos 
   1150  1.1  christos static void
   1151  1.7  christos output_operand_type (FILE *table, enum operand_class class,
   1152  1.7  christos 		     enum operand_instance instance,
   1153  1.7  christos 		     const bitfield *types, unsigned int size,
   1154  1.6  christos 		     enum stage stage, const char *indent)
   1155  1.1  christos {
   1156  1.1  christos   unsigned int i;
   1157  1.1  christos 
   1158  1.7  christos   fprintf (table, "{ { %d, %d, ", class, instance);
   1159  1.1  christos 
   1160  1.1  christos   for (i = 0; i < size - 1; i++)
   1161  1.1  christos     {
   1162  1.7  christos       if (((i + 3) % 20) != 0)
   1163  1.3  christos 	fprintf (table, "%d, ", types[i].value);
   1164  1.3  christos       else
   1165  1.3  christos 	fprintf (table, "%d,", types[i].value);
   1166  1.7  christos       if (((i + 3) % 20) == 0)
   1167  1.1  christos 	{
   1168  1.1  christos 	  /* We need \\ for macro.  */
   1169  1.6  christos 	  if (stage == stage_macros)
   1170  1.3  christos 	    fprintf (table, " \\\n%s", indent);
   1171  1.1  christos 	  else
   1172  1.1  christos 	    fprintf (table, "\n%s", indent);
   1173  1.1  christos 	}
   1174  1.1  christos     }
   1175  1.1  christos 
   1176  1.1  christos   fprintf (table, "%d } }", types[i].value);
   1177  1.1  christos }
   1178  1.1  christos 
   1179  1.1  christos static void
   1180  1.6  christos process_i386_operand_type (FILE *table, char *op, enum stage stage,
   1181  1.1  christos 			   const char *indent, int lineno)
   1182  1.1  christos {
   1183  1.1  christos   char *str, *next, *last;
   1184  1.7  christos   enum operand_class class = ClassNone;
   1185  1.7  christos   enum operand_instance instance = InstanceNone;
   1186  1.1  christos   bitfield types [ARRAY_SIZE (operand_types)];
   1187  1.1  christos 
   1188  1.1  christos   /* Copy the default operand type.  */
   1189  1.1  christos   memcpy (types, operand_types, sizeof (types));
   1190  1.1  christos 
   1191  1.1  christos   if (strcmp (op, "0"))
   1192  1.1  christos     {
   1193  1.6  christos       int baseindex = 0;
   1194  1.6  christos 
   1195  1.1  christos       last = op + strlen (op);
   1196  1.1  christos       for (next = op; next && next < last; )
   1197  1.1  christos 	{
   1198  1.1  christos 	  str = next_field (next, '|', &next, last);
   1199  1.1  christos 	  if (str)
   1200  1.6  christos 	    {
   1201  1.7  christos 	      unsigned int i;
   1202  1.7  christos 
   1203  1.7  christos 	      if (!strncmp(str, "Class=", 6))
   1204  1.7  christos 		{
   1205  1.7  christos 		  for (i = 0; i < ARRAY_SIZE(operand_classes); ++i)
   1206  1.7  christos 		    if (!strcmp(str + 6, operand_classes[i].name))
   1207  1.7  christos 		      {
   1208  1.7  christos 			class = operand_classes[i].value;
   1209  1.7  christos 			str = NULL;
   1210  1.7  christos 			break;
   1211  1.7  christos 		      }
   1212  1.7  christos 		}
   1213  1.7  christos 
   1214  1.7  christos 	      if (str && !strncmp(str, "Instance=", 9))
   1215  1.7  christos 		{
   1216  1.7  christos 		  for (i = 0; i < ARRAY_SIZE(operand_instances); ++i)
   1217  1.7  christos 		    if (!strcmp(str + 9, operand_instances[i].name))
   1218  1.7  christos 		      {
   1219  1.7  christos 			instance = operand_instances[i].value;
   1220  1.7  christos 			str = NULL;
   1221  1.7  christos 			break;
   1222  1.7  christos 		      }
   1223  1.7  christos 		}
   1224  1.7  christos 	    }
   1225  1.7  christos 	  if (str)
   1226  1.7  christos 	    {
   1227  1.6  christos 	      set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
   1228  1.6  christos 	      if (strcasecmp(str, "BaseIndex") == 0)
   1229  1.6  christos 		baseindex = 1;
   1230  1.6  christos 	    }
   1231  1.6  christos 	}
   1232  1.6  christos 
   1233  1.6  christos       if (stage == stage_opcodes && baseindex && !active_isstring)
   1234  1.6  christos 	{
   1235  1.6  christos 	  set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
   1236  1.6  christos 	  if (!active_cpu_flags.bitfield.cpu64
   1237  1.6  christos 	      && !active_cpu_flags.bitfield.cpumpx)
   1238  1.6  christos 	    set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
   1239  1.7  christos 	  if (!active_cpu_flags.bitfield.cpu64)
   1240  1.7  christos 	    set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
   1241  1.6  christos 	  if (!active_cpu_flags.bitfield.cpuno64)
   1242  1.6  christos 	    set_bitfield("Disp32S", types, 1, ARRAY_SIZE (types), lineno);
   1243  1.1  christos 	}
   1244  1.1  christos     }
   1245  1.7  christos   output_operand_type (table, class, instance, types, ARRAY_SIZE (types),
   1246  1.7  christos 		       stage, indent);
   1247  1.1  christos }
   1248  1.1  christos 
   1249  1.1  christos static void
   1250  1.1  christos output_i386_opcode (FILE *table, const char *name, char *str,
   1251  1.1  christos 		    char *last, int lineno)
   1252  1.1  christos {
   1253  1.1  christos   unsigned int i;
   1254  1.1  christos   char *operands, *base_opcode, *extension_opcode, *opcode_length;
   1255  1.1  christos   char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
   1256  1.1  christos 
   1257  1.1  christos   /* Find number of operands.  */
   1258  1.1  christos   operands = next_field (str, ',', &str, last);
   1259  1.1  christos 
   1260  1.1  christos   /* Find base_opcode.  */
   1261  1.1  christos   base_opcode = next_field (str, ',', &str, last);
   1262  1.1  christos 
   1263  1.1  christos   /* Find extension_opcode.  */
   1264  1.1  christos   extension_opcode = next_field (str, ',', &str, last);
   1265  1.1  christos 
   1266  1.1  christos   /* Find opcode_length.  */
   1267  1.1  christos   opcode_length = next_field (str, ',', &str, last);
   1268  1.1  christos 
   1269  1.1  christos   /* Find cpu_flags.  */
   1270  1.1  christos   cpu_flags = next_field (str, ',', &str, last);
   1271  1.1  christos 
   1272  1.1  christos   /* Find opcode_modifier.  */
   1273  1.1  christos   opcode_modifier = next_field (str, ',', &str, last);
   1274  1.1  christos 
   1275  1.1  christos   /* Remove the first {.  */
   1276  1.1  christos   str = remove_leading_whitespaces (str);
   1277  1.1  christos   if (*str != '{')
   1278  1.1  christos     abort ();
   1279  1.1  christos   str = remove_leading_whitespaces (str + 1);
   1280  1.1  christos 
   1281  1.1  christos   i = strlen (str);
   1282  1.1  christos 
   1283  1.1  christos   /* There are at least "X}".  */
   1284  1.1  christos   if (i < 2)
   1285  1.1  christos     abort ();
   1286  1.1  christos 
   1287  1.1  christos   /* Remove trailing white spaces and }. */
   1288  1.1  christos   do
   1289  1.1  christos     {
   1290  1.1  christos       i--;
   1291  1.1  christos       if (ISSPACE (str[i]) || str[i] == '}')
   1292  1.1  christos 	str[i] = '\0';
   1293  1.1  christos       else
   1294  1.1  christos 	break;
   1295  1.1  christos     }
   1296  1.1  christos   while (i != 0);
   1297  1.1  christos 
   1298  1.1  christos   last = str + i;
   1299  1.1  christos 
   1300  1.1  christos   /* Find operand_types.  */
   1301  1.1  christos   for (i = 0; i < ARRAY_SIZE (operand_types); i++)
   1302  1.1  christos     {
   1303  1.1  christos       if (str >= last)
   1304  1.1  christos 	{
   1305  1.1  christos 	  operand_types [i] = NULL;
   1306  1.1  christos 	  break;
   1307  1.1  christos 	}
   1308  1.1  christos 
   1309  1.1  christos       operand_types [i] = next_field (str, ',', &str, last);
   1310  1.1  christos       if (*operand_types[i] == '0')
   1311  1.1  christos 	{
   1312  1.1  christos 	  if (i != 0)
   1313  1.1  christos 	    operand_types[i] = NULL;
   1314  1.1  christos 	  break;
   1315  1.1  christos 	}
   1316  1.1  christos     }
   1317  1.1  christos 
   1318  1.1  christos   fprintf (table, "  { \"%s\", %s, %s, %s, %s,\n",
   1319  1.7  christos 	   name, base_opcode, extension_opcode, opcode_length, operands);
   1320  1.1  christos 
   1321  1.1  christos   process_i386_cpu_flag (table, cpu_flags, 0, ",", "    ", lineno);
   1322  1.1  christos 
   1323  1.7  christos   process_i386_opcode_modifier (table, opcode_modifier, operand_types, lineno);
   1324  1.1  christos 
   1325  1.1  christos   fprintf (table, "    { ");
   1326  1.1  christos 
   1327  1.1  christos   for (i = 0; i < ARRAY_SIZE (operand_types); i++)
   1328  1.1  christos     {
   1329  1.1  christos       if (operand_types[i] == NULL || *operand_types[i] == '0')
   1330  1.1  christos 	{
   1331  1.1  christos 	  if (i == 0)
   1332  1.6  christos 	    process_i386_operand_type (table, "0", stage_opcodes, "\t  ",
   1333  1.6  christos 				       lineno);
   1334  1.1  christos 	  break;
   1335  1.1  christos 	}
   1336  1.1  christos 
   1337  1.1  christos       if (i != 0)
   1338  1.1  christos 	fprintf (table, ",\n      ");
   1339  1.1  christos 
   1340  1.6  christos       process_i386_operand_type (table, operand_types[i], stage_opcodes,
   1341  1.1  christos 				 "\t  ", lineno);
   1342  1.1  christos     }
   1343  1.1  christos   fprintf (table, " } },\n");
   1344  1.1  christos }
   1345  1.1  christos 
   1346  1.1  christos struct opcode_hash_entry
   1347  1.1  christos {
   1348  1.1  christos   struct opcode_hash_entry *next;
   1349  1.1  christos   char *name;
   1350  1.1  christos   char *opcode;
   1351  1.1  christos   int lineno;
   1352  1.1  christos };
   1353  1.1  christos 
   1354  1.1  christos /* Calculate the hash value of an opcode hash entry P.  */
   1355  1.1  christos 
   1356  1.1  christos static hashval_t
   1357  1.1  christos opcode_hash_hash (const void *p)
   1358  1.1  christos {
   1359  1.1  christos   struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
   1360  1.1  christos   return htab_hash_string (entry->name);
   1361  1.1  christos }
   1362  1.1  christos 
   1363  1.1  christos /* Compare a string Q against an opcode hash entry P.  */
   1364  1.1  christos 
   1365  1.1  christos static int
   1366  1.1  christos opcode_hash_eq (const void *p, const void *q)
   1367  1.1  christos {
   1368  1.1  christos   struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
   1369  1.1  christos   const char *name = (const char *) q;
   1370  1.1  christos   return strcmp (name, entry->name) == 0;
   1371  1.1  christos }
   1372  1.1  christos 
   1373  1.1  christos static void
   1374  1.1  christos process_i386_opcodes (FILE *table)
   1375  1.1  christos {
   1376  1.1  christos   FILE *fp;
   1377  1.1  christos   char buf[2048];
   1378  1.1  christos   unsigned int i, j;
   1379  1.1  christos   char *str, *p, *last, *name;
   1380  1.1  christos   struct opcode_hash_entry **hash_slot, **entry, *next;
   1381  1.1  christos   htab_t opcode_hash_table;
   1382  1.1  christos   struct opcode_hash_entry **opcode_array;
   1383  1.1  christos   unsigned int opcode_array_size = 1024;
   1384  1.7  christos   int lineno = 0, marker = 0;
   1385  1.1  christos 
   1386  1.1  christos   filename = "i386-opc.tbl";
   1387  1.7  christos   fp = stdin;
   1388  1.1  christos 
   1389  1.1  christos   i = 0;
   1390  1.1  christos   opcode_array = (struct opcode_hash_entry **)
   1391  1.1  christos     xmalloc (sizeof (*opcode_array) * opcode_array_size);
   1392  1.1  christos 
   1393  1.1  christos   opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
   1394  1.1  christos 					 opcode_hash_eq, NULL,
   1395  1.1  christos 					 xcalloc, free);
   1396  1.1  christos 
   1397  1.1  christos   fprintf (table, "\n/* i386 opcode table.  */\n\n");
   1398  1.1  christos   fprintf (table, "const insn_template i386_optab[] =\n{\n");
   1399  1.1  christos 
   1400  1.1  christos   /* Put everything on opcode array.  */
   1401  1.1  christos   while (!feof (fp))
   1402  1.1  christos     {
   1403  1.1  christos       if (fgets (buf, sizeof (buf), fp) == NULL)
   1404  1.1  christos 	break;
   1405  1.1  christos 
   1406  1.1  christos       lineno++;
   1407  1.1  christos 
   1408  1.1  christos       p = remove_leading_whitespaces (buf);
   1409  1.1  christos 
   1410  1.1  christos       /* Skip comments.  */
   1411  1.1  christos       str = strstr (p, "//");
   1412  1.1  christos       if (str != NULL)
   1413  1.1  christos 	str[0] = '\0';
   1414  1.1  christos 
   1415  1.1  christos       /* Remove trailing white spaces.  */
   1416  1.1  christos       remove_trailing_whitespaces (p);
   1417  1.1  christos 
   1418  1.1  christos       switch (p[0])
   1419  1.1  christos 	{
   1420  1.1  christos 	case '#':
   1421  1.7  christos 	  if (!strcmp("### MARKER ###", buf))
   1422  1.7  christos 	    marker = 1;
   1423  1.7  christos 	  else
   1424  1.7  christos 	    {
   1425  1.7  christos 	      /* Since we ignore all included files (we only care about their
   1426  1.7  christos 		 #define-s here), we don't need to monitor filenames.  The final
   1427  1.7  christos 		 line number directive is going to refer to the main source file
   1428  1.7  christos 		 again.  */
   1429  1.7  christos 	      char *end;
   1430  1.7  christos 	      unsigned long ln;
   1431  1.7  christos 
   1432  1.7  christos 	      p = remove_leading_whitespaces (p + 1);
   1433  1.7  christos 	      if (!strncmp(p, "line", 4))
   1434  1.7  christos 		p += 4;
   1435  1.7  christos 	      ln = strtoul (p, &end, 10);
   1436  1.7  christos 	      if (ln > 1 && ln < INT_MAX
   1437  1.7  christos 		  && *remove_leading_whitespaces (end) == '"')
   1438  1.7  christos 		lineno = ln - 1;
   1439  1.7  christos 	    }
   1440  1.1  christos 	  /* Ignore comments.  */
   1441  1.1  christos 	case '\0':
   1442  1.1  christos 	  continue;
   1443  1.1  christos 	  break;
   1444  1.1  christos 	default:
   1445  1.7  christos 	  if (!marker)
   1446  1.7  christos 	    continue;
   1447  1.1  christos 	  break;
   1448  1.1  christos 	}
   1449  1.1  christos 
   1450  1.1  christos       last = p + strlen (p);
   1451  1.1  christos 
   1452  1.1  christos       /* Find name.  */
   1453  1.1  christos       name = next_field (p, ',', &str, last);
   1454  1.1  christos 
   1455  1.1  christos       /* Get the slot in hash table.  */
   1456  1.1  christos       hash_slot = (struct opcode_hash_entry **)
   1457  1.1  christos 	htab_find_slot_with_hash (opcode_hash_table, name,
   1458  1.1  christos 				  htab_hash_string (name),
   1459  1.1  christos 				  INSERT);
   1460  1.1  christos 
   1461  1.1  christos       if (*hash_slot == NULL)
   1462  1.1  christos 	{
   1463  1.1  christos 	  /* It is the new one.  Put it on opcode array.  */
   1464  1.1  christos 	  if (i >= opcode_array_size)
   1465  1.1  christos 	    {
   1466  1.1  christos 	      /* Grow the opcode array when needed.  */
   1467  1.1  christos 	      opcode_array_size += 1024;
   1468  1.1  christos 	      opcode_array = (struct opcode_hash_entry **)
   1469  1.1  christos 		xrealloc (opcode_array,
   1470  1.1  christos 			  sizeof (*opcode_array) * opcode_array_size);
   1471  1.1  christos 	    }
   1472  1.1  christos 
   1473  1.1  christos 	  opcode_array[i] = (struct opcode_hash_entry *)
   1474  1.1  christos 	    xmalloc (sizeof (struct opcode_hash_entry));
   1475  1.1  christos 	  opcode_array[i]->next = NULL;
   1476  1.1  christos 	  opcode_array[i]->name = xstrdup (name);
   1477  1.1  christos 	  opcode_array[i]->opcode = xstrdup (str);
   1478  1.1  christos 	  opcode_array[i]->lineno = lineno;
   1479  1.1  christos 	  *hash_slot = opcode_array[i];
   1480  1.1  christos 	  i++;
   1481  1.1  christos 	}
   1482  1.1  christos       else
   1483  1.1  christos 	{
   1484  1.1  christos 	  /* Append it to the existing one.  */
   1485  1.1  christos 	  entry = hash_slot;
   1486  1.1  christos 	  while ((*entry) != NULL)
   1487  1.1  christos 	    entry = &(*entry)->next;
   1488  1.1  christos 	  *entry = (struct opcode_hash_entry *)
   1489  1.1  christos 	    xmalloc (sizeof (struct opcode_hash_entry));
   1490  1.1  christos 	  (*entry)->next = NULL;
   1491  1.1  christos 	  (*entry)->name = (*hash_slot)->name;
   1492  1.1  christos 	  (*entry)->opcode = xstrdup (str);
   1493  1.1  christos 	  (*entry)->lineno = lineno;
   1494  1.1  christos 	}
   1495  1.1  christos     }
   1496  1.1  christos 
   1497  1.1  christos   /* Process opcode array.  */
   1498  1.1  christos   for (j = 0; j < i; j++)
   1499  1.1  christos     {
   1500  1.1  christos       for (next = opcode_array[j]; next; next = next->next)
   1501  1.1  christos 	{
   1502  1.1  christos 	  name = next->name;
   1503  1.1  christos 	  str = next->opcode;
   1504  1.1  christos 	  lineno = next->lineno;
   1505  1.1  christos 	  last = str + strlen (str);
   1506  1.1  christos 	  output_i386_opcode (table, name, str, last, lineno);
   1507  1.1  christos 	}
   1508  1.1  christos     }
   1509  1.1  christos 
   1510  1.1  christos   fclose (fp);
   1511  1.1  christos 
   1512  1.1  christos   fprintf (table, "  { NULL, 0, 0, 0, 0,\n");
   1513  1.1  christos 
   1514  1.1  christos   process_i386_cpu_flag (table, "0", 0, ",", "    ", -1);
   1515  1.1  christos 
   1516  1.7  christos   process_i386_opcode_modifier (table, "0", NULL, -1);
   1517  1.1  christos 
   1518  1.1  christos   fprintf (table, "    { ");
   1519  1.6  christos   process_i386_operand_type (table, "0", stage_opcodes, "\t  ", -1);
   1520  1.1  christos   fprintf (table, " } }\n");
   1521  1.1  christos 
   1522  1.1  christos   fprintf (table, "};\n");
   1523  1.1  christos }
   1524  1.1  christos 
   1525  1.1  christos static void
   1526  1.1  christos process_i386_registers (FILE *table)
   1527  1.1  christos {
   1528  1.1  christos   FILE *fp;
   1529  1.1  christos   char buf[2048];
   1530  1.1  christos   char *str, *p, *last;
   1531  1.1  christos   char *reg_name, *reg_type, *reg_flags, *reg_num;
   1532  1.1  christos   char *dw2_32_num, *dw2_64_num;
   1533  1.1  christos   int lineno = 0;
   1534  1.1  christos 
   1535  1.1  christos   filename = "i386-reg.tbl";
   1536  1.1  christos   fp = fopen (filename, "r");
   1537  1.1  christos   if (fp == NULL)
   1538  1.1  christos     fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
   1539  1.1  christos 	  xstrerror (errno));
   1540  1.1  christos 
   1541  1.1  christos   fprintf (table, "\n/* i386 register table.  */\n\n");
   1542  1.1  christos   fprintf (table, "const reg_entry i386_regtab[] =\n{\n");
   1543  1.1  christos 
   1544  1.1  christos   while (!feof (fp))
   1545  1.1  christos     {
   1546  1.1  christos       if (fgets (buf, sizeof (buf), fp) == NULL)
   1547  1.1  christos 	break;
   1548  1.1  christos 
   1549  1.1  christos       lineno++;
   1550  1.1  christos 
   1551  1.1  christos       p = remove_leading_whitespaces (buf);
   1552  1.1  christos 
   1553  1.1  christos       /* Skip comments.  */
   1554  1.1  christos       str = strstr (p, "//");
   1555  1.1  christos       if (str != NULL)
   1556  1.1  christos 	str[0] = '\0';
   1557  1.1  christos 
   1558  1.1  christos       /* Remove trailing white spaces.  */
   1559  1.1  christos       remove_trailing_whitespaces (p);
   1560  1.1  christos 
   1561  1.1  christos       switch (p[0])
   1562  1.1  christos 	{
   1563  1.1  christos 	case '#':
   1564  1.1  christos 	  fprintf (table, "%s\n", p);
   1565  1.1  christos 	case '\0':
   1566  1.1  christos 	  continue;
   1567  1.1  christos 	  break;
   1568  1.1  christos 	default:
   1569  1.1  christos 	  break;
   1570  1.1  christos 	}
   1571  1.1  christos 
   1572  1.1  christos       last = p + strlen (p);
   1573  1.1  christos 
   1574  1.1  christos       /* Find reg_name.  */
   1575  1.1  christos       reg_name = next_field (p, ',', &str, last);
   1576  1.1  christos 
   1577  1.1  christos       /* Find reg_type.  */
   1578  1.1  christos       reg_type = next_field (str, ',', &str, last);
   1579  1.1  christos 
   1580  1.1  christos       /* Find reg_flags.  */
   1581  1.1  christos       reg_flags = next_field (str, ',', &str, last);
   1582  1.1  christos 
   1583  1.1  christos       /* Find reg_num.  */
   1584  1.1  christos       reg_num = next_field (str, ',', &str, last);
   1585  1.1  christos 
   1586  1.1  christos       fprintf (table, "  { \"%s\",\n    ", reg_name);
   1587  1.1  christos 
   1588  1.6  christos       process_i386_operand_type (table, reg_type, stage_registers, "\t",
   1589  1.6  christos 				 lineno);
   1590  1.1  christos 
   1591  1.1  christos       /* Find 32-bit Dwarf2 register number.  */
   1592  1.1  christos       dw2_32_num = next_field (str, ',', &str, last);
   1593  1.1  christos 
   1594  1.1  christos       /* Find 64-bit Dwarf2 register number.  */
   1595  1.1  christos       dw2_64_num = next_field (str, ',', &str, last);
   1596  1.1  christos 
   1597  1.1  christos       fprintf (table, ",\n    %s, %s, { %s, %s } },\n",
   1598  1.1  christos 	       reg_flags, reg_num, dw2_32_num, dw2_64_num);
   1599  1.1  christos     }
   1600  1.1  christos 
   1601  1.1  christos   fclose (fp);
   1602  1.1  christos 
   1603  1.1  christos   fprintf (table, "};\n");
   1604  1.1  christos 
   1605  1.1  christos   fprintf (table, "\nconst unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
   1606  1.1  christos }
   1607  1.1  christos 
   1608  1.1  christos static void
   1609  1.1  christos process_i386_initializers (void)
   1610  1.1  christos {
   1611  1.1  christos   unsigned int i;
   1612  1.1  christos   FILE *fp = fopen ("i386-init.h", "w");
   1613  1.1  christos   char *init;
   1614  1.1  christos 
   1615  1.1  christos   if (fp == NULL)
   1616  1.1  christos     fail (_("can't create i386-init.h, errno = %s\n"),
   1617  1.1  christos 	  xstrerror (errno));
   1618  1.1  christos 
   1619  1.1  christos   process_copyright (fp);
   1620  1.1  christos 
   1621  1.1  christos   for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
   1622  1.1  christos     {
   1623  1.1  christos       fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
   1624  1.1  christos       init = xstrdup (cpu_flag_init[i].init);
   1625  1.1  christos       process_i386_cpu_flag (fp, init, 1, "", "  ", -1);
   1626  1.1  christos       free (init);
   1627  1.1  christos     }
   1628  1.1  christos 
   1629  1.1  christos   for (i = 0; i < ARRAY_SIZE (operand_type_init); i++)
   1630  1.1  christos     {
   1631  1.1  christos       fprintf (fp, "\n\n#define %s \\\n  ", operand_type_init[i].name);
   1632  1.1  christos       init = xstrdup (operand_type_init[i].init);
   1633  1.6  christos       process_i386_operand_type (fp, init, stage_macros, "      ", -1);
   1634  1.1  christos       free (init);
   1635  1.1  christos     }
   1636  1.1  christos   fprintf (fp, "\n");
   1637  1.1  christos 
   1638  1.1  christos   fclose (fp);
   1639  1.1  christos }
   1640  1.1  christos 
   1641  1.1  christos /* Program options.  */
   1642  1.1  christos #define OPTION_SRCDIR	200
   1643  1.1  christos 
   1644  1.1  christos struct option long_options[] =
   1645  1.1  christos {
   1646  1.1  christos   {"srcdir",  required_argument, NULL, OPTION_SRCDIR},
   1647  1.1  christos   {"debug",   no_argument,       NULL, 'd'},
   1648  1.1  christos   {"version", no_argument,       NULL, 'V'},
   1649  1.1  christos   {"help",    no_argument,       NULL, 'h'},
   1650  1.1  christos   {0,         no_argument,       NULL, 0}
   1651  1.1  christos };
   1652  1.1  christos 
   1653  1.1  christos static void
   1654  1.1  christos print_version (void)
   1655  1.1  christos {
   1656  1.1  christos   printf ("%s: version 1.0\n", program_name);
   1657  1.1  christos   xexit (0);
   1658  1.1  christos }
   1659  1.1  christos 
   1660  1.1  christos static void
   1661  1.1  christos usage (FILE * stream, int status)
   1662  1.1  christos {
   1663  1.1  christos   fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
   1664  1.1  christos 	   program_name);
   1665  1.1  christos   xexit (status);
   1666  1.1  christos }
   1667  1.1  christos 
   1668  1.1  christos int
   1669  1.1  christos main (int argc, char **argv)
   1670  1.1  christos {
   1671  1.1  christos   extern int chdir (char *);
   1672  1.1  christos   char *srcdir = NULL;
   1673  1.1  christos   int c;
   1674  1.5  christos   unsigned int i, cpumax;
   1675  1.1  christos   FILE *table;
   1676  1.1  christos 
   1677  1.1  christos   program_name = *argv;
   1678  1.1  christos   xmalloc_set_program_name (program_name);
   1679  1.1  christos 
   1680  1.1  christos   while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
   1681  1.1  christos     switch (c)
   1682  1.1  christos       {
   1683  1.1  christos       case OPTION_SRCDIR:
   1684  1.1  christos 	srcdir = optarg;
   1685  1.1  christos 	break;
   1686  1.1  christos       case 'V':
   1687  1.1  christos       case 'v':
   1688  1.1  christos 	print_version ();
   1689  1.1  christos 	break;
   1690  1.1  christos       case 'd':
   1691  1.1  christos 	debug = 1;
   1692  1.1  christos 	break;
   1693  1.1  christos       case 'h':
   1694  1.1  christos       case '?':
   1695  1.1  christos 	usage (stderr, 0);
   1696  1.1  christos       default:
   1697  1.1  christos       case 0:
   1698  1.1  christos 	break;
   1699  1.1  christos       }
   1700  1.1  christos 
   1701  1.1  christos   if (optind != argc)
   1702  1.1  christos     usage (stdout, 1);
   1703  1.1  christos 
   1704  1.1  christos   if (srcdir != NULL)
   1705  1.1  christos     if (chdir (srcdir) != 0)
   1706  1.1  christos       fail (_("unable to change directory to \"%s\", errno = %s\n"),
   1707  1.1  christos 	    srcdir, xstrerror (errno));
   1708  1.1  christos 
   1709  1.5  christos   /* cpu_flags isn't sorted by position.  */
   1710  1.5  christos   cpumax = 0;
   1711  1.5  christos   for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
   1712  1.5  christos     if (cpu_flags[i].position > cpumax)
   1713  1.5  christos       cpumax = cpu_flags[i].position;
   1714  1.5  christos 
   1715  1.1  christos   /* Check the unused bitfield in i386_cpu_flags.  */
   1716  1.5  christos #ifdef CpuUnused
   1717  1.7  christos   static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 2);
   1718  1.7  christos 
   1719  1.5  christos   if ((cpumax - 1) != CpuMax)
   1720  1.5  christos     fail (_("CpuMax != %d!\n"), cpumax);
   1721  1.5  christos #else
   1722  1.7  christos   static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 1);
   1723  1.7  christos 
   1724  1.5  christos   if (cpumax != CpuMax)
   1725  1.5  christos     fail (_("CpuMax != %d!\n"), cpumax);
   1726  1.5  christos 
   1727  1.1  christos   c = CpuNumOfBits - CpuMax - 1;
   1728  1.1  christos   if (c)
   1729  1.1  christos     fail (_("%d unused bits in i386_cpu_flags.\n"), c);
   1730  1.1  christos #endif
   1731  1.1  christos 
   1732  1.7  christos   static_assert (ARRAY_SIZE (opcode_modifiers) == Opcode_Modifier_Num);
   1733  1.7  christos 
   1734  1.1  christos   /* Check the unused bitfield in i386_operand_type.  */
   1735  1.7  christos #ifdef OTUnused
   1736  1.7  christos   static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
   1737  1.7  christos 		 == OTNum + 1);
   1738  1.7  christos #else
   1739  1.7  christos   static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
   1740  1.7  christos 		 == OTNum);
   1741  1.7  christos 
   1742  1.7  christos   c = OTNumOfBits - OTNum;
   1743  1.1  christos   if (c)
   1744  1.1  christos     fail (_("%d unused bits in i386_operand_type.\n"), c);
   1745  1.1  christos #endif
   1746  1.1  christos 
   1747  1.1  christos   qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
   1748  1.1  christos 	 compare);
   1749  1.1  christos 
   1750  1.1  christos   qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
   1751  1.1  christos 	 sizeof (opcode_modifiers [0]), compare);
   1752  1.1  christos 
   1753  1.1  christos   qsort (operand_types, ARRAY_SIZE (operand_types),
   1754  1.1  christos 	 sizeof (operand_types [0]), compare);
   1755  1.1  christos 
   1756  1.1  christos   table = fopen ("i386-tbl.h", "w");
   1757  1.1  christos   if (table == NULL)
   1758  1.1  christos     fail (_("can't create i386-tbl.h, errno = %s\n"),
   1759  1.1  christos 	  xstrerror (errno));
   1760  1.1  christos 
   1761  1.1  christos   process_copyright (table);
   1762  1.1  christos 
   1763  1.1  christos   process_i386_opcodes (table);
   1764  1.1  christos   process_i386_registers (table);
   1765  1.1  christos   process_i386_initializers ();
   1766  1.1  christos 
   1767  1.1  christos   fclose (table);
   1768  1.1  christos 
   1769  1.1  christos   exit (0);
   1770  1.1  christos }
   1771