mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-09 10:31:14 +00:00
[X86] Fix a bug where the disassembler was ignoring the VEX.W bit in 32-bit mode for certain instructions it shouldn't.
Unfortunately, this isn't easy to fix since there's no simple way to figure out from the disassembler tables whether the W-bit is being used to select a 64-bit GPR or if its a required part of the opcode. The fix implemented here just looks for "64" in the instruction name and ignores the W-bit in 32-bit mode if its present. Fixes PR21169. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@219194 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ada4703cba
commit
95717dbb11
@ -851,6 +851,22 @@ static bool is16BitEquivalent(const char* orig, const char* equiv) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* is64Bit - Determines whether this instruction is a 64-bit instruction.
|
||||
*
|
||||
* @param name - The instruction that is not 16-bit
|
||||
*/
|
||||
static bool is64Bit(const char* name) {
|
||||
off_t i;
|
||||
|
||||
for (i = 0;; ++i) {
|
||||
if (name[i] == '\0')
|
||||
return false;
|
||||
if (name[i] == '6' && name[i+1] == '4')
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* getID - Determines the ID of an instruction, consuming the ModR/M byte as
|
||||
* appropriate for extended and escape opcodes. Determines the attributes and
|
||||
@ -983,6 +999,37 @@ static int getID(struct InternalInstruction* insn, const void *miiArg) {
|
||||
|
||||
/* The following clauses compensate for limitations of the tables. */
|
||||
|
||||
if (insn->mode != MODE_64BIT &&
|
||||
insn->vectorExtensionType != TYPE_NO_VEX_XOP) {
|
||||
/*
|
||||
* The tables can't distinquish between cases where the W-bit is used to
|
||||
* select register size and cases where its a required part of the opcode.
|
||||
*/
|
||||
if ((insn->vectorExtensionType == TYPE_EVEX &&
|
||||
wFromEVEX3of4(insn->vectorExtensionPrefix[2])) ||
|
||||
(insn->vectorExtensionType == TYPE_VEX_3B &&
|
||||
wFromVEX3of3(insn->vectorExtensionPrefix[2])) ||
|
||||
(insn->vectorExtensionType == TYPE_XOP &&
|
||||
wFromXOP3of3(insn->vectorExtensionPrefix[2]))) {
|
||||
|
||||
uint16_t instructionIDWithREXW;
|
||||
if (getIDWithAttrMask(&instructionIDWithREXW,
|
||||
insn, attrMask | ATTR_REXW)) {
|
||||
insn->instructionID = instructionID;
|
||||
insn->spec = specifierForUID(instructionID);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *SpecName = GetInstrName(instructionIDWithREXW, miiArg);
|
||||
// If not a 64-bit instruction. Switch the opcode.
|
||||
if (!is64Bit(SpecName)) {
|
||||
insn->instructionID = instructionIDWithREXW;
|
||||
insn->spec = specifierForUID(instructionIDWithREXW);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((insn->mode == MODE_16BIT || insn->prefixPresent[0x66]) &&
|
||||
!(attrMask & ATTR_OPSIZE)) {
|
||||
/*
|
||||
|
@ -711,3 +711,6 @@
|
||||
|
||||
# CHECK: movq %mm0, %mm1
|
||||
0x0f 0x7f 0xc1
|
||||
|
||||
# CHECK: vpermq $-18, %ymm2, %ymm2
|
||||
0xc4 0xe3 0xfd 0x00 0xd2 0xee
|
||||
|
Loading…
Reference in New Issue
Block a user