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