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