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