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