X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=opcodes%2Fi386-gen.c;h=847a7bb1d9f05f68a308e77693b07d0733dce5a9;hb=189b8c2e104017600104457b97315da74a22f549;hp=077f47ae278dd73b87585c0784f1bc474b9b61e0;hpb=2571583aed598dd3f9651b53434e5f177a0e3cf7;p=deliverable%2Fbinutils-gdb.git diff --git a/opcodes/i386-gen.c b/opcodes/i386-gen.c index 077f47ae27..847a7bb1d9 100644 --- a/opcodes/i386-gen.c +++ b/opcodes/i386-gen.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2007-2017 Free Software Foundation, Inc. +/* Copyright (C) 2007-2019 Free Software Foundation, Inc. This file is part of the GNU opcodes library. @@ -58,9 +58,9 @@ static initializer cpu_flag_init[] = { "CPU_I486_FLAGS", "CPU_I386_FLAGS|Cpu486" }, { "CPU_I586_FLAGS", - "CPU_I486_FLAGS|CPU_387_FLAGS|Cpu586" }, + "CPU_I486_FLAGS|Cpu387|Cpu586" }, { "CPU_I686_FLAGS", - "CPU_I586_FLAGS|Cpu686|Cpu687" }, + "CPU_I586_FLAGS|Cpu686|Cpu687|CpuCMOV|CpuFXSR" }, { "CPU_PENTIUMPRO_FLAGS", "CPU_I686_FLAGS|CpuNop" }, { "CPU_P2_FLAGS", @@ -88,7 +88,7 @@ static initializer cpu_flag_init[] = { "CPU_AMDFAM10_FLAGS", "CPU_K8_FLAGS|CpuFISTTP|CPU_SSE4A_FLAGS|CpuABM" }, { "CPU_BDVER1_FLAGS", - "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_SSE4_2_FLAGS|CpuSSE4A|CpuABM|CpuFMA4|CpuXOP|CpuLWP|CpuSVME|CpuXsave|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW" }, + "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_XOP_FLAGS|CpuABM|CpuLWP|CpuSVME|CpuAES|CpuPCLMUL|CpuLZCNT|CpuPRFCHW" }, { "CPU_BDVER2_FLAGS", "CPU_BDVER1_FLAGS|CpuFMA|CpuBMI|CpuTBM|CpuF16C" }, { "CPU_BDVER3_FLAGS", @@ -96,19 +96,25 @@ static initializer cpu_flag_init[] = { "CPU_BDVER4_FLAGS", "CPU_BDVER3_FLAGS|CpuAVX2|CpuMovbe|CpuBMI2|CpuRdRnd|CpuMWAITX" }, { "CPU_ZNVER1_FLAGS", - "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" }, + "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuRdtscp|CpuCX16|CPU_AVX2_FLAGS|CpuSSE4A|CpuABM|CpuSVME|CpuAES|CpuPCLMUL|CpuLZCNT|CpuPRFCHW|CpuFMA|CpuBMI|CpuF16C|CpuXsaveopt|CpuFSGSBase|CpuMovbe|CpuBMI2|CpuRdRnd|CpuADX|CpuRdSeed|CpuSMAP|CpuSHA|CpuXSAVEC|CpuXSAVES|CpuClflushOpt|CpuCLZERO|CpuMWAITX" }, + { "CPU_ZNVER2_FLAGS", + "CPU_ZNVER1_FLAGS|CpuRDPID|CpuWBNOINVD|CpuCLWB" }, { "CPU_BTVER1_FLAGS", "CPU_GENERIC64_FLAGS|CpuFISTTP|CpuCX16|CpuRdtscp|CPU_SSSE3_FLAGS|CpuSSE4A|CpuABM|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME|CpuLZCNT" }, { "CPU_BTVER2_FLAGS", - "CPU_BTVER1_FLAGS|CPU_SSE4_2_FLAGS|CpuBMI|CpuF16C|CpuAES|CpuPCLMUL|CpuAVX|CpuMovbe|CpuXsave|CpuXsaveopt|CpuPRFCHW" }, + "CPU_BTVER1_FLAGS|CPU_AVX_FLAGS|CpuBMI|CpuF16C|CpuAES|CpuPCLMUL|CpuMovbe|CpuXsaveopt|CpuPRFCHW" }, { "CPU_8087_FLAGS", "Cpu8087" }, { "CPU_287_FLAGS", - "CPU_8087_FLAGS|Cpu287" }, + "Cpu287" }, { "CPU_387_FLAGS", - "CPU_287_FLAGS|Cpu387" }, + "Cpu387" }, { "CPU_687_FLAGS", "CPU_387_FLAGS|Cpu687" }, + { "CPU_CMOV_FLAGS", + "CpuCMOV" }, + { "CPU_FXSR_FLAGS", + "CpuFXSR" }, { "CPU_CLFLUSH_FLAGS", "CpuClflush" }, { "CPU_NOP_FLAGS", @@ -116,9 +122,9 @@ static initializer cpu_flag_init[] = { "CPU_SYSCALL_FLAGS", "CpuSYSCALL" }, { "CPU_MMX_FLAGS", - "CpuRegMMX|CpuMMX" }, + "CpuMMX" }, { "CPU_SSE_FLAGS", - "CpuRegXMM|CpuSSE" }, + "CpuSSE" }, { "CPU_SSE2_FLAGS", "CPU_SSE_FLAGS|CpuSSE2" }, { "CPU_SSE3_FLAGS", @@ -148,7 +154,7 @@ static initializer cpu_flag_init[] = { "CPU_XOP_FLAGS", "CPU_SSE4A_FLAGS|CPU_FMA4_FLAGS|CpuXOP" }, { "CPU_LWP_FLAGS", - "CpuLWP" }, + "CPU_XSAVE_FLAGS|CpuLWP" }, { "CPU_BMI_FLAGS", "CpuBMI" }, { "CPU_TBM_FLAGS", @@ -192,13 +198,11 @@ static initializer cpu_flag_init[] = { "CPU_ABM_FLAGS", "CpuABM" }, { "CPU_AVX_FLAGS", - "CPU_SSE4_2_FLAGS|CpuRegYMM|CpuAVX" }, + "CPU_SSE4_2_FLAGS|CPU_XSAVE_FLAGS|CpuAVX" }, { "CPU_AVX2_FLAGS", "CPU_AVX_FLAGS|CpuAVX2" }, - /* Don't use CPU_AVX2_FLAGS on CPU_AVX512F_FLAGS since AVX512F doesn't - support YMM registers. */ { "CPU_AVX512F_FLAGS", - "CpuVREX|CPU_SSE4_2_FLAGS|CpuRegZMM|CpuRegMask|CpuAVX|CpuAVX2|CpuAVX512F" }, + "CPU_AVX2_FLAGS|CpuAVX512F" }, { "CPU_AVX512CD_FLAGS", "CPU_AVX512F_FLAGS|CpuAVX512CD" }, { "CPU_AVX512ER_FLAGS", @@ -210,9 +214,7 @@ static initializer cpu_flag_init[] = { "CPU_AVX512BW_FLAGS", "CPU_AVX512F_FLAGS|CpuAVX512BW" }, { "CPU_AVX512VL_FLAGS", - /* Use CPU_AVX2_FLAGS on CPU_AVX512VL_FLAGS since AVX512VL supports YMM - registers. */ - "CPU_AVX512F_FLAGS|CPU_AVX2_FLAGS|CpuAVX512VL" }, + "CPU_AVX512F_FLAGS|CpuAVX512VL" }, { "CPU_AVX512IFMA_FLAGS", "CPU_AVX512F_FLAGS|CpuAVX512IFMA" }, { "CPU_AVX512VBMI_FLAGS", @@ -221,6 +223,16 @@ static initializer cpu_flag_init[] = "CPU_AVX512F_FLAGS|CpuAVX512_4FMAPS" }, { "CPU_AVX512_4VNNIW_FLAGS", "CPU_AVX512F_FLAGS|CpuAVX512_4VNNIW" }, + { "CPU_AVX512_VPOPCNTDQ_FLAGS", + "CPU_AVX512F_FLAGS|CpuAVX512_VPOPCNTDQ" }, + { "CPU_AVX512_VBMI2_FLAGS", + "CPU_AVX512F_FLAGS|CpuAVX512_VBMI2" }, + { "CPU_AVX512_VNNI_FLAGS", + "CPU_AVX512F_FLAGS|CpuAVX512_VNNI" }, + { "CPU_AVX512_BITALG_FLAGS", + "CPU_AVX512F_FLAGS|CpuAVX512_BITALG" }, + { "CPU_AVX512_BF16_FLAGS", + "CPU_AVX512F_FLAGS|CpuAVX512_BF16" }, { "CPU_L1OM_FLAGS", "unknown" }, { "CPU_K1OM_FLAGS", @@ -236,7 +248,7 @@ static initializer cpu_flag_init[] = { "CPU_SMAP_FLAGS", "CpuSMAP" }, { "CPU_MPX_FLAGS", - "CpuMPX" }, + "CPU_XSAVE_FLAGS|CpuMPX" }, { "CPU_SHA_FLAGS", "CPU_SSE2_FLAGS|CpuSHA" }, { "CPU_CLFLUSHOPT_FLAGS", @@ -256,11 +268,33 @@ static initializer cpu_flag_init[] = { "CPU_MWAITX_FLAGS", "CpuMWAITX" }, { "CPU_OSPKE_FLAGS", - "CpuOSPKE" }, + "CPU_XSAVE_FLAGS|CpuOSPKE" }, { "CPU_RDPID_FLAGS", "CpuRDPID" }, { "CPU_PTWRITE_FLAGS", "CpuPTWRITE" }, + { "CPU_IBT_FLAGS", + "CpuIBT" }, + { "CPU_SHSTK_FLAGS", + "CpuSHSTK" }, + { "CPU_GFNI_FLAGS", + "CpuGFNI" }, + { "CPU_VAES_FLAGS", + "CpuVAES" }, + { "CPU_VPCLMULQDQ_FLAGS", + "CpuVPCLMULQDQ" }, + { "CPU_WBNOINVD_FLAGS", + "CpuWBNOINVD" }, + { "CPU_PCONFIG_FLAGS", + "CpuPCONFIG" }, + { "CPU_WAITPKG_FLAGS", + "CpuWAITPKG" }, + { "CPU_CLDEMOTE_FLAGS", + "CpuCLDEMOTE" }, + { "CPU_MOVDIRI_FLAGS", + "CpuMOVDIRI" }, + { "CPU_MOVDIR64B_FLAGS", + "CpuMOVDIR64B" }, { "CPU_ANY_X87_FLAGS", "CPU_ANY_287_FLAGS|Cpu8087" }, { "CPU_ANY_287_FLAGS", @@ -269,6 +303,10 @@ static initializer cpu_flag_init[] = "CPU_ANY_687_FLAGS|Cpu387" }, { "CPU_ANY_687_FLAGS", "Cpu687|CpuFISTTP" }, + { "CPU_ANY_CMOV_FLAGS", + "CpuCMOV" }, + { "CPU_ANY_FXSR_FLAGS", + "CpuFXSR" }, { "CPU_ANY_MMX_FLAGS", "CPU_3DNOWA_FLAGS" }, { "CPU_ANY_SSE_FLAGS", @@ -286,9 +324,9 @@ static initializer cpu_flag_init[] = { "CPU_ANY_AVX_FLAGS", "CPU_ANY_AVX2_FLAGS|CpuF16C|CpuFMA|CpuFMA4|CpuXOP|CpuAVX" }, { "CPU_ANY_AVX2_FLAGS", - "CpuAVX2" }, + "CPU_ANY_AVX512F_FLAGS|CpuAVX2" }, { "CPU_ANY_AVX512F_FLAGS", - "CpuVREX|CpuRegZMM|CpuRegMask|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CpuAVX512BW|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512_4FMAPS|CpuAVX512_4VNNIW|CpuAVX512F" }, + "CpuAVX512F|CpuAVX512CD|CpuAVX512ER|CpuAVX512PF|CpuAVX512DQ|CpuAVX512BW|CpuAVX512VL|CpuAVX512IFMA|CpuAVX512VBMI|CpuAVX512_4FMAPS|CpuAVX512_4VNNIW|CpuAVX512_VPOPCNTDQ|CpuAVX512_VBMI2|CpuAVX512_VNNI|CpuAVX512_BITALG|CpuAVX512_BF16" }, { "CPU_ANY_AVX512CD_FLAGS", "CpuAVX512CD" }, { "CPU_ANY_AVX512ER_FLAGS", @@ -309,6 +347,37 @@ static initializer cpu_flag_init[] = "CpuAVX512_4FMAPS" }, { "CPU_ANY_AVX512_4VNNIW_FLAGS", "CpuAVX512_4VNNIW" }, + { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS", + "CpuAVX512_VPOPCNTDQ" }, + { "CPU_ANY_IBT_FLAGS", + "CpuIBT" }, + { "CPU_ANY_SHSTK_FLAGS", + "CpuSHSTK" }, + { "CPU_ANY_AVX512_VBMI2_FLAGS", + "CpuAVX512_VBMI2" }, + { "CPU_ANY_AVX512_VNNI_FLAGS", + "CpuAVX512_VNNI" }, + { "CPU_ANY_AVX512_BITALG_FLAGS", + "CpuAVX512_BITALG" }, + { "CPU_ANY_AVX512_BF16_FLAGS", + "CpuAVX512_BF16" }, + { "CPU_ANY_MOVDIRI_FLAGS", + "CpuMOVDIRI" }, + { "CPU_ANY_MOVDIR64B_FLAGS", + "CpuMOVDIR64B" }, +}; + +static const initializer operand_type_shorthands[] = +{ + { "Reg8", "Reg|Byte" }, + { "Reg16", "Reg|Word" }, + { "Reg32", "Reg|Dword" }, + { "Reg64", "Reg|Qword" }, + { "FloatAcc", "Acc|Tbyte" }, + { "FloatReg", "Reg|Tbyte" }, + { "RegXMM", "RegSIMD|Xmmword" }, + { "RegYMM", "RegSIMD|Ymmword" }, + { "RegZMM", "RegSIMD|Zmmword" }, }; static initializer operand_type_init[] = @@ -387,10 +456,6 @@ static initializer operand_type_init[] = "Reg32|Acc|Dword" }, { "OPERAND_TYPE_ACC64", "Reg64|Acc|Qword" }, - { "OPERAND_TYPE_INOUTPORTREG", - "InOutPortReg" }, - { "OPERAND_TYPE_REG16_INOUTPORTREG", - "Reg16|InOutPortReg" }, { "OPERAND_TYPE_DISP16_32", "Disp16|Disp32" }, { "OPERAND_TYPE_ANYDISP", @@ -415,8 +480,6 @@ static initializer operand_type_init[] = "Vec_Imm4" }, { "OPERAND_TYPE_REGBND", "RegBND" }, - { "OPERAND_TYPE_VEC_DISP8", - "Vec_Disp8" }, }; typedef struct bitfield @@ -436,6 +499,8 @@ static bitfield cpu_flags[] = BITFIELD (Cpu486), BITFIELD (Cpu586), BITFIELD (Cpu686), + BITFIELD (CpuCMOV), + BITFIELD (CpuFXSR), BITFIELD (CpuClflush), BITFIELD (CpuNop), BITFIELD (CpuSYSCALL), @@ -500,7 +565,6 @@ static bitfield cpu_flags[] = BITFIELD (CpuPRFCHW), BITFIELD (CpuSMAP), BITFIELD (CpuSHA), - BITFIELD (CpuVREX), BITFIELD (CpuClflushOpt), BITFIELD (CpuXSAVES), BITFIELD (CpuXSAVEC), @@ -514,16 +578,27 @@ static bitfield cpu_flags[] = BITFIELD (CpuAVX512VBMI), BITFIELD (CpuAVX512_4FMAPS), BITFIELD (CpuAVX512_4VNNIW), + BITFIELD (CpuAVX512_VPOPCNTDQ), + BITFIELD (CpuAVX512_VBMI2), + BITFIELD (CpuAVX512_VNNI), + BITFIELD (CpuAVX512_BITALG), + BITFIELD (CpuAVX512_BF16), BITFIELD (CpuMWAITX), BITFIELD (CpuCLZERO), BITFIELD (CpuOSPKE), BITFIELD (CpuRDPID), BITFIELD (CpuPTWRITE), - BITFIELD (CpuRegMMX), - BITFIELD (CpuRegXMM), - BITFIELD (CpuRegYMM), - BITFIELD (CpuRegZMM), - BITFIELD (CpuRegMask), + BITFIELD (CpuIBT), + BITFIELD (CpuSHSTK), + BITFIELD (CpuGFNI), + BITFIELD (CpuVAES), + BITFIELD (CpuVPCLMULQDQ), + BITFIELD (CpuWBNOINVD), + BITFIELD (CpuPCONFIG), + BITFIELD (CpuWAITPKG), + BITFIELD (CpuCLDEMOTE), + BITFIELD (CpuMOVDIRI), + BITFIELD (CpuMOVDIR64B), #ifdef CpuUnused BITFIELD (CpuUnused), #endif @@ -533,7 +608,7 @@ static bitfield opcode_modifiers[] = { BITFIELD (D), BITFIELD (W), - BITFIELD (S), + BITFIELD (Load), BITFIELD (Modrm), BITFIELD (ShortForm), BITFIELD (Jump), @@ -542,10 +617,7 @@ static bitfield opcode_modifiers[] = BITFIELD (JumpInterSegment), BITFIELD (FloatMF), BITFIELD (FloatR), - BITFIELD (FloatD), - BITFIELD (Size16), - BITFIELD (Size32), - BITFIELD (Size64), + BITFIELD (Size), BITFIELD (CheckRegSize), BITFIELD (IgnoreSize), BITFIELD (DefaultSize), @@ -558,15 +630,15 @@ static bitfield opcode_modifiers[] = BITFIELD (FWait), BITFIELD (IsString), BITFIELD (BNDPrefixOk), + BITFIELD (NoTrackPrefixOk), BITFIELD (IsLockable), BITFIELD (RegKludge), - BITFIELD (FirstXmm0), BITFIELD (Implicit1stXmm0), BITFIELD (RepPrefixOk), BITFIELD (HLEPrefixOk), BITFIELD (ToDword), BITFIELD (ToQword), - BITFIELD (AddrPrefixOp0), + BITFIELD (AddrPrefixOpReg), BITFIELD (IsPrefix), BITFIELD (ImmExt), BITFIELD (NoRex64), @@ -577,20 +649,18 @@ static bitfield opcode_modifiers[] = BITFIELD (VexW), BITFIELD (VexOpcode), BITFIELD (VexSources), - BITFIELD (VexImmExt), BITFIELD (VecSIB), BITFIELD (SSE2AVX), BITFIELD (NoAVX), BITFIELD (EVex), BITFIELD (Masking), - BITFIELD (VecESize), BITFIELD (Broadcast), BITFIELD (StaticRounding), BITFIELD (SAE), BITFIELD (Disp8MemShift), BITFIELD (NoDefMask), BITFIELD (ImplicitQuadGroup), - BITFIELD (OldGcc), + BITFIELD (Optimize), BITFIELD (ATTMnemonic), BITFIELD (ATTSyntax), BITFIELD (IntelSyntax), @@ -600,15 +670,9 @@ static bitfield opcode_modifiers[] = static bitfield operand_types[] = { - BITFIELD (Reg8), - BITFIELD (Reg16), - BITFIELD (Reg32), - BITFIELD (Reg64), - BITFIELD (FloatReg), + BITFIELD (Reg), BITFIELD (RegMMX), - BITFIELD (RegXMM), - BITFIELD (RegYMM), - BITFIELD (RegZMM), + BITFIELD (RegSIMD), BITFIELD (RegMask), BITFIELD (Imm1), BITFIELD (Imm8), @@ -631,11 +695,9 @@ static bitfield operand_types[] = BITFIELD (SReg2), BITFIELD (SReg3), BITFIELD (Acc), - BITFIELD (FloatAcc), BITFIELD (JumpAbsolute), BITFIELD (EsSeg), BITFIELD (RegMem), - BITFIELD (Mem), BITFIELD (Byte), BITFIELD (Word), BITFIELD (Dword), @@ -649,13 +711,14 @@ static bitfield operand_types[] = BITFIELD (Anysize), BITFIELD (Vec_Imm4), BITFIELD (RegBND), - BITFIELD (Vec_Disp8), #ifdef OTUnused BITFIELD (OTUnused), #endif }; static const char *filename; +static i386_cpu_flags active_cpu_flags; +static int active_isstring; static int compare (const void *x, const void *y) @@ -671,7 +734,7 @@ fail (const char *message, ...) va_list args; va_start (args, message); - fprintf (stderr, _("%s: Error: "), program_name); + fprintf (stderr, _("%s: error: "), program_name); vfprintf (stderr, message, args); va_end (args); xexit (1); @@ -681,7 +744,7 @@ static void process_copyright (FILE *fp) { fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\ -/* Copyright (C) 2007-2017 Free Software Foundation, Inc.\n\ +/* Copyright (C) 2007-2019 Free Software Foundation, Inc.\n\ \n\ This file is part of the GNU opcodes library.\n\ \n\ @@ -757,9 +820,8 @@ next_field (char *str, char sep, char **next, char *last) static void set_bitfield (char *, bitfield *, int, unsigned int, int); static int -set_bitfield_from_cpu_flag_init (char *f, bitfield *array, - int value, unsigned int size, - int lineno) +set_bitfield_from_shorthand (char *f, bitfield *array, unsigned int size, + int lineno) { char *str, *next, *last; unsigned int i; @@ -780,6 +842,22 @@ set_bitfield_from_cpu_flag_init (char *f, bitfield *array, return 0; } + for (i = 0; i < ARRAY_SIZE (operand_type_shorthands); i++) + if (strcmp (operand_type_shorthands[i].name, f) == 0) + { + /* Turn on selective bits. */ + char *init = xstrdup (operand_type_shorthands[i].init); + last = init + strlen (init); + for (next = init; next && next < last; ) + { + str = next_field (next, '|', &next, last); + if (str) + set_bitfield (str, array, 1, size, lineno); + } + free (init); + return 0; + } + return -1; } @@ -830,14 +908,14 @@ set_bitfield (char *f, bitfield *array, int value, } } - /* Handle CPU_XXX_FLAGS. */ - if (!set_bitfield_from_cpu_flag_init (f, array, value, size, lineno)) + /* Handle shorthands. */ + if (value == 1 && !set_bitfield_from_shorthand (f, array, size, lineno)) return; if (lineno != -1) - fail (_("%s: %d: Unknown bitfield: %s\n"), filename, lineno, f); + fail (_("%s: %d: unknown bitfield: %s\n"), filename, lineno, f); else - fail (_("Unknown bitfield: %s\n"), f); + fail (_("unknown bitfield: %s\n"), f); } static void @@ -846,6 +924,8 @@ output_cpu_flags (FILE *table, bitfield *flags, unsigned int size, { unsigned int i; + memset (&active_cpu_flags, 0, sizeof(active_cpu_flags)); + fprintf (table, "%s{ { ", indent); for (i = 0; i < size - 1; i++) @@ -862,6 +942,8 @@ output_cpu_flags (FILE *table, bitfield *flags, unsigned int size, else fprintf (table, "\n %s", indent); } + if (flags[i].value) + active_cpu_flags.array[i / 32] |= 1U << (i % 32); } fprintf (table, "%d } }%s\n", flags[i].value, comma); @@ -896,7 +978,7 @@ process_i386_cpu_flag (FILE *table, char *flag, int macro, last -= 1; next = flag + 2; if (*last != ')') - fail (_("%s: %d: Missing `)' in bitfield: %s\n"), filename, + fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename, lineno, flag); *last = '\0'; } @@ -952,12 +1034,64 @@ output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size) fprintf (table, "%d },\n", modifier[i].value); } +static int +adjust_broadcast_modifier (char **opnd) +{ + char *str, *next, *last, *op; + int bcst_type = INT_MAX; + + /* Skip the immediate operand. */ + op = opnd[0]; + if (strcasecmp(op, "Imm8") == 0) + op = opnd[1]; + + op = xstrdup (op); + last = op + strlen (op); + for (next = op; next && next < last; ) + { + str = next_field (next, '|', &next, last); + if (str) + { + if (strcasecmp(str, "Byte") == 0) + { + /* The smalest broadcast type, no need to check + further. */ + bcst_type = BYTE_BROADCAST; + break; + } + else if (strcasecmp(str, "Word") == 0) + { + if (bcst_type > WORD_BROADCAST) + bcst_type = WORD_BROADCAST; + } + else if (strcasecmp(str, "Dword") == 0) + { + if (bcst_type > DWORD_BROADCAST) + bcst_type = DWORD_BROADCAST; + } + else if (strcasecmp(str, "Qword") == 0) + { + if (bcst_type > QWORD_BROADCAST) + bcst_type = QWORD_BROADCAST; + } + } + } + free (op); + + if (bcst_type == INT_MAX) + fail (_("unknown broadcast operand: %s\n"), op); + + return bcst_type; +} + static void -process_i386_opcode_modifier (FILE *table, char *mod, int lineno) +process_i386_opcode_modifier (FILE *table, char *mod, char **opnd, int lineno) { char *str, *next, *last; bitfield modifiers [ARRAY_SIZE (opcode_modifiers)]; + active_isstring = 0; + /* Copy the default opcode modifier. */ memcpy (modifiers, opcode_modifiers, sizeof (modifiers)); @@ -968,16 +1102,29 @@ process_i386_opcode_modifier (FILE *table, char *mod, int lineno) { str = next_field (next, '|', &next, last); if (str) - set_bitfield (str, modifiers, 1, ARRAY_SIZE (modifiers), + { + int val = 1; + if (strcasecmp(str, "Broadcast") == 0) + val = adjust_broadcast_modifier (opnd); + set_bitfield (str, modifiers, val, ARRAY_SIZE (modifiers), lineno); + if (strcasecmp(str, "IsString") == 0) + active_isstring = 1; + } } } output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers)); } +enum stage { + stage_macros, + stage_opcodes, + stage_registers, +}; + static void output_operand_type (FILE *table, bitfield *types, unsigned int size, - int macro, const char *indent) + enum stage stage, const char *indent) { unsigned int i; @@ -992,7 +1139,7 @@ output_operand_type (FILE *table, bitfield *types, unsigned int size, if (((i + 1) % 20) == 0) { /* We need \\ for macro. */ - if (macro) + if (stage == stage_macros) fprintf (table, " \\\n%s", indent); else fprintf (table, "\n%s", indent); @@ -1003,7 +1150,7 @@ output_operand_type (FILE *table, bitfield *types, unsigned int size, } static void -process_i386_operand_type (FILE *table, char *op, int macro, +process_i386_operand_type (FILE *table, char *op, enum stage stage, const char *indent, int lineno) { char *str, *next, *last; @@ -1014,15 +1161,32 @@ process_i386_operand_type (FILE *table, char *op, int macro, if (strcmp (op, "0")) { + int baseindex = 0; + last = op + strlen (op); for (next = op; next && next < last; ) { str = next_field (next, '|', &next, last); if (str) - set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno); + { + set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno); + if (strcasecmp(str, "BaseIndex") == 0) + baseindex = 1; + } + } + + if (stage == stage_opcodes && baseindex && !active_isstring) + { + set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno); + if (!active_cpu_flags.bitfield.cpu64 + && !active_cpu_flags.bitfield.cpumpx) + set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno); + set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno); + if (!active_cpu_flags.bitfield.cpuno64) + set_bitfield("Disp32S", types, 1, ARRAY_SIZE (types), lineno); } } - output_operand_type (table, types, ARRAY_SIZE (types), macro, + output_operand_type (table, types, ARRAY_SIZE (types), stage, indent); } @@ -1101,7 +1265,7 @@ output_i386_opcode (FILE *table, const char *name, char *str, process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno); - process_i386_opcode_modifier (table, opcode_modifier, lineno); + process_i386_opcode_modifier (table, opcode_modifier, operand_types, lineno); fprintf (table, " { "); @@ -1110,14 +1274,15 @@ output_i386_opcode (FILE *table, const char *name, char *str, if (operand_types[i] == NULL || *operand_types[i] == '0') { if (i == 0) - process_i386_operand_type (table, "0", 0, "\t ", lineno); + process_i386_operand_type (table, "0", stage_opcodes, "\t ", + lineno); break; } if (i != 0) fprintf (table, ",\n "); - process_i386_operand_type (table, operand_types[i], 0, + process_i386_operand_type (table, operand_types[i], stage_opcodes, "\t ", lineno); } fprintf (table, " } },\n"); @@ -1161,14 +1326,10 @@ process_i386_opcodes (FILE *table) htab_t opcode_hash_table; struct opcode_hash_entry **opcode_array; unsigned int opcode_array_size = 1024; - int lineno = 0; + int lineno = 0, marker = 0; filename = "i386-opc.tbl"; - fp = fopen (filename, "r"); - - if (fp == NULL) - fail (_("can't find i386-opc.tbl for reading, errno = %s\n"), - xstrerror (errno)); + fp = stdin; i = 0; opcode_array = (struct opcode_hash_entry **) @@ -1202,11 +1363,32 @@ process_i386_opcodes (FILE *table) switch (p[0]) { case '#': + if (!strcmp("### MARKER ###", buf)) + marker = 1; + else + { + /* Since we ignore all included files (we only care about their + #define-s here), we don't need to monitor filenames. The final + line number directive is going to refer to the main source file + again. */ + char *end; + unsigned long ln; + + p = remove_leading_whitespaces (p + 1); + if (!strncmp(p, "line", 4)) + p += 4; + ln = strtoul (p, &end, 10); + if (ln > 1 && ln < INT_MAX + && *remove_leading_whitespaces (end) == '"') + lineno = ln - 1; + } /* Ignore comments. */ case '\0': continue; break; default: + if (!marker) + continue; break; } @@ -1276,10 +1458,10 @@ process_i386_opcodes (FILE *table) process_i386_cpu_flag (table, "0", 0, ",", " ", -1); - process_i386_opcode_modifier (table, "0", -1); + process_i386_opcode_modifier (table, "0", NULL, -1); fprintf (table, " { "); - process_i386_operand_type (table, "0", 0, "\t ", -1); + process_i386_operand_type (table, "0", stage_opcodes, "\t ", -1); fprintf (table, " } }\n"); fprintf (table, "};\n"); @@ -1348,7 +1530,8 @@ process_i386_registers (FILE *table) fprintf (table, " { \"%s\",\n ", reg_name); - process_i386_operand_type (table, reg_type, 0, "\t", lineno); + process_i386_operand_type (table, reg_type, stage_registers, "\t", + lineno); /* Find 32-bit Dwarf2 register number. */ dw2_32_num = next_field (str, ',', &str, last); @@ -1392,7 +1575,7 @@ process_i386_initializers (void) { fprintf (fp, "\n\n#define %s \\\n ", operand_type_init[i].name); init = xstrdup (operand_type_init[i].init); - process_i386_operand_type (fp, init, 1, " ", -1); + process_i386_operand_type (fp, init, stage_macros, " ", -1); free (init); } fprintf (fp, "\n");