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