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