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