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