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