mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-30 04:35:00 +00:00
Fix disassembling of popcntw. Also remove some code that says it accounts for 64BIT_REXW_XD not existing, but it does exist.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141642 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
7aabcb1fc0
commit
29480fd798
@ -703,34 +703,6 @@ static BOOL is16BitEquvalent(const char* orig, const char* equiv) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* is64BitEquivalent - Determines whether two instruction names refer to
|
|
||||||
* equivalent instructions but one is 64-bit whereas the other is not.
|
|
||||||
*
|
|
||||||
* @param orig - The instruction that is not 64-bit
|
|
||||||
* @param equiv - The instruction that is 64-bit
|
|
||||||
*/
|
|
||||||
static BOOL is64BitEquivalent(const char* orig, const char* equiv) {
|
|
||||||
off_t i;
|
|
||||||
|
|
||||||
for (i = 0;; i++) {
|
|
||||||
if (orig[i] == '\0' && equiv[i] == '\0')
|
|
||||||
return TRUE;
|
|
||||||
if (orig[i] == '\0' || equiv[i] == '\0')
|
|
||||||
return FALSE;
|
|
||||||
if (orig[i] != equiv[i]) {
|
|
||||||
if ((orig[i] == 'W' || orig[i] == 'L') && equiv[i] == 'Q')
|
|
||||||
continue;
|
|
||||||
if ((orig[i] == '1' || orig[i] == '3') && equiv[i] == '6')
|
|
||||||
continue;
|
|
||||||
if ((orig[i] == '6' || orig[i] == '2') && equiv[i] == '4')
|
|
||||||
continue;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* getID - Determines the ID of an instruction, consuming the ModR/M byte as
|
* getID - Determines the ID of an instruction, consuming the ModR/M byte as
|
||||||
* appropriate for extended and escape opcodes. Determines the attributes and
|
* appropriate for extended and escape opcodes. Determines the attributes and
|
||||||
@ -840,46 +812,6 @@ static int getID(struct InternalInstruction* insn) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((attrMask & ATTR_XD) && (attrMask & ATTR_REXW)) {
|
|
||||||
/*
|
|
||||||
* Although for SSE instructions it is usually necessary to treat REX.W+F2
|
|
||||||
* as F2 for decode (in the absence of a 64BIT_REXW_XD category) there is
|
|
||||||
* an occasional instruction where F2 is incidental and REX.W is the more
|
|
||||||
* significant. If the decoded instruction is 32-bit and adding REX.W
|
|
||||||
* instead of F2 changes a 32 to a 64, we adopt the new encoding.
|
|
||||||
*/
|
|
||||||
|
|
||||||
const struct InstructionSpecifier *spec;
|
|
||||||
uint16_t instructionIDWithREXw;
|
|
||||||
const struct InstructionSpecifier *specWithREXw;
|
|
||||||
|
|
||||||
spec = specifierForUID(instructionID);
|
|
||||||
|
|
||||||
if (getIDWithAttrMask(&instructionIDWithREXw,
|
|
||||||
insn,
|
|
||||||
attrMask & (~ATTR_XD))) {
|
|
||||||
/*
|
|
||||||
* Decoding with REX.w would yield nothing; give up and return original
|
|
||||||
* decode.
|
|
||||||
*/
|
|
||||||
|
|
||||||
insn->instructionID = instructionID;
|
|
||||||
insn->spec = spec;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
specWithREXw = specifierForUID(instructionIDWithREXw);
|
|
||||||
|
|
||||||
if (is64BitEquivalent(spec->name, specWithREXw->name)) {
|
|
||||||
insn->instructionID = instructionIDWithREXw;
|
|
||||||
insn->spec = specWithREXw;
|
|
||||||
} else {
|
|
||||||
insn->instructionID = instructionID;
|
|
||||||
insn->spec = spec;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (insn->prefixPresent[0x66] && !(attrMask & ATTR_OPSIZE)) {
|
if (insn->prefixPresent[0x66] && !(attrMask & ATTR_OPSIZE)) {
|
||||||
/*
|
/*
|
||||||
* The instruction tables make no distinction between instructions that
|
* The instruction tables make no distinction between instructions that
|
||||||
|
@ -83,6 +83,8 @@ enum attributeBits {
|
|||||||
"but not the operands") \
|
"but not the operands") \
|
||||||
ENUM_ENTRY(IC_XD_OPSIZE, 3, "requires an OPSIZE prefix, so " \
|
ENUM_ENTRY(IC_XD_OPSIZE, 3, "requires an OPSIZE prefix, so " \
|
||||||
"operands change width") \
|
"operands change width") \
|
||||||
|
ENUM_ENTRY(IC_XS_OPSIZE, 3, "requires an OPSIZE prefix, so " \
|
||||||
|
"operands change width") \
|
||||||
ENUM_ENTRY(IC_64BIT_REXW, 4, "requires a REX.W prefix, so operands "\
|
ENUM_ENTRY(IC_64BIT_REXW, 4, "requires a REX.W prefix, so operands "\
|
||||||
"change width; overrides IC_OPSIZE") \
|
"change width; overrides IC_OPSIZE") \
|
||||||
ENUM_ENTRY(IC_64BIT_OPSIZE, 3, "Just as meaningful as IC_OPSIZE") \
|
ENUM_ENTRY(IC_64BIT_OPSIZE, 3, "Just as meaningful as IC_OPSIZE") \
|
||||||
@ -90,6 +92,7 @@ enum attributeBits {
|
|||||||
"secondary") \
|
"secondary") \
|
||||||
ENUM_ENTRY(IC_64BIT_XS, 5, "Just as meaningful as IC_64BIT_XD") \
|
ENUM_ENTRY(IC_64BIT_XS, 5, "Just as meaningful as IC_64BIT_XD") \
|
||||||
ENUM_ENTRY(IC_64BIT_XD_OPSIZE, 3, "Just as meaningful as IC_XD_OPSIZE") \
|
ENUM_ENTRY(IC_64BIT_XD_OPSIZE, 3, "Just as meaningful as IC_XD_OPSIZE") \
|
||||||
|
ENUM_ENTRY(IC_64BIT_XS_OPSIZE, 3, "Just as meaningful as IC_XS_OPSIZE") \
|
||||||
ENUM_ENTRY(IC_64BIT_REXW_XS, 6, "OPSIZE could mean a different " \
|
ENUM_ENTRY(IC_64BIT_REXW_XS, 6, "OPSIZE could mean a different " \
|
||||||
"opcode") \
|
"opcode") \
|
||||||
ENUM_ENTRY(IC_64BIT_REXW_XD, 6, "Just as meaningful as " \
|
ENUM_ENTRY(IC_64BIT_REXW_XD, 6, "Just as meaningful as " \
|
||||||
|
@ -479,3 +479,12 @@
|
|||||||
|
|
||||||
# CHECK: vcvtps2ph $0, %ymm0, (%rax)
|
# CHECK: vcvtps2ph $0, %ymm0, (%rax)
|
||||||
0xc4 0xe3 0x7d 0x1d 0x00 0x00
|
0xc4 0xe3 0x7d 0x1d 0x00 0x00
|
||||||
|
|
||||||
|
# CHECK: popcntl %eax, %eax
|
||||||
|
0xf3 0x0f 0xb8 0xc0
|
||||||
|
|
||||||
|
# CHECK: popcntw %ax, %ax
|
||||||
|
0x66 0xf3 0x0f 0xb8 0xc0
|
||||||
|
|
||||||
|
# CHECK: popcntq %rax, %rax
|
||||||
|
0xf3 0x48 0x0f 0xb8 0xc0
|
||||||
|
@ -465,3 +465,9 @@
|
|||||||
|
|
||||||
# CHECK: vcvtps2ph $0, %ymm0, (%eax)
|
# CHECK: vcvtps2ph $0, %ymm0, (%eax)
|
||||||
0xc4 0xe3 0x7d 0x1d 0x00 0x00
|
0xc4 0xe3 0x7d 0x1d 0x00 0x00
|
||||||
|
|
||||||
|
# CHECK: popcntl %eax, %eax
|
||||||
|
0xf3 0x0f 0xb8 0xc0
|
||||||
|
|
||||||
|
# CHECK: popcntw %ax, %ax
|
||||||
|
0x66 0xf3 0x0f 0xb8 0xc0
|
||||||
|
@ -56,6 +56,8 @@ static inline bool inheritsFrom(InstructionContext child,
|
|||||||
return inheritsFrom(child, IC_64BIT_XS);
|
return inheritsFrom(child, IC_64BIT_XS);
|
||||||
case IC_XD_OPSIZE:
|
case IC_XD_OPSIZE:
|
||||||
return inheritsFrom(child, IC_64BIT_XD_OPSIZE);
|
return inheritsFrom(child, IC_64BIT_XD_OPSIZE);
|
||||||
|
case IC_XS_OPSIZE:
|
||||||
|
return inheritsFrom(child, IC_64BIT_XS_OPSIZE);
|
||||||
case IC_64BIT_REXW:
|
case IC_64BIT_REXW:
|
||||||
return(inheritsFrom(child, IC_64BIT_REXW_XS) ||
|
return(inheritsFrom(child, IC_64BIT_REXW_XS) ||
|
||||||
inheritsFrom(child, IC_64BIT_REXW_XD) ||
|
inheritsFrom(child, IC_64BIT_REXW_XD) ||
|
||||||
@ -67,6 +69,7 @@ static inline bool inheritsFrom(InstructionContext child,
|
|||||||
case IC_64BIT_XS:
|
case IC_64BIT_XS:
|
||||||
return(inheritsFrom(child, IC_64BIT_REXW_XS));
|
return(inheritsFrom(child, IC_64BIT_REXW_XS));
|
||||||
case IC_64BIT_XD_OPSIZE:
|
case IC_64BIT_XD_OPSIZE:
|
||||||
|
case IC_64BIT_XS_OPSIZE:
|
||||||
return false;
|
return false;
|
||||||
case IC_64BIT_REXW_XD:
|
case IC_64BIT_REXW_XD:
|
||||||
case IC_64BIT_REXW_XS:
|
case IC_64BIT_REXW_XS:
|
||||||
@ -524,6 +527,8 @@ void DisassemblerTables::emitContextTable(raw_ostream &o, uint32_t &i) const {
|
|||||||
o << "IC_64BIT_REXW_OPSIZE";
|
o << "IC_64BIT_REXW_OPSIZE";
|
||||||
else if ((index & ATTR_64BIT) && (index & ATTR_XD) && (index & ATTR_OPSIZE))
|
else if ((index & ATTR_64BIT) && (index & ATTR_XD) && (index & ATTR_OPSIZE))
|
||||||
o << "IC_64BIT_XD_OPSIZE";
|
o << "IC_64BIT_XD_OPSIZE";
|
||||||
|
else if ((index & ATTR_64BIT) && (index & ATTR_XS) && (index & ATTR_OPSIZE))
|
||||||
|
o << "IC_64BIT_XS_OPSIZE";
|
||||||
else if ((index & ATTR_64BIT) && (index & ATTR_XS))
|
else if ((index & ATTR_64BIT) && (index & ATTR_XS))
|
||||||
o << "IC_64BIT_XS";
|
o << "IC_64BIT_XS";
|
||||||
else if ((index & ATTR_64BIT) && (index & ATTR_XD))
|
else if ((index & ATTR_64BIT) && (index & ATTR_XD))
|
||||||
@ -534,6 +539,8 @@ void DisassemblerTables::emitContextTable(raw_ostream &o, uint32_t &i) const {
|
|||||||
o << "IC_64BIT_REXW";
|
o << "IC_64BIT_REXW";
|
||||||
else if ((index & ATTR_64BIT))
|
else if ((index & ATTR_64BIT))
|
||||||
o << "IC_64BIT";
|
o << "IC_64BIT";
|
||||||
|
else if ((index & ATTR_XS) && (index & ATTR_OPSIZE))
|
||||||
|
o << "IC_XS_OPSIZE";
|
||||||
else if ((index & ATTR_XD) && (index & ATTR_OPSIZE))
|
else if ((index & ATTR_XD) && (index & ATTR_OPSIZE))
|
||||||
o << "IC_XD_OPSIZE";
|
o << "IC_XD_OPSIZE";
|
||||||
else if (index & ATTR_XS)
|
else if (index & ATTR_XS)
|
||||||
|
@ -314,13 +314,17 @@ InstructionContext RecognizableInstr::insnContext() const {
|
|||||||
} else if (Is64Bit || HasREX_WPrefix) {
|
} else if (Is64Bit || HasREX_WPrefix) {
|
||||||
if (HasREX_WPrefix && HasOpSizePrefix)
|
if (HasREX_WPrefix && HasOpSizePrefix)
|
||||||
insnContext = IC_64BIT_REXW_OPSIZE;
|
insnContext = IC_64BIT_REXW_OPSIZE;
|
||||||
else if (HasOpSizePrefix && (Prefix == X86Local::XD || Prefix == X86Local::TF))
|
else if (HasOpSizePrefix &&
|
||||||
|
(Prefix == X86Local::XD || Prefix == X86Local::TF))
|
||||||
insnContext = IC_64BIT_XD_OPSIZE;
|
insnContext = IC_64BIT_XD_OPSIZE;
|
||||||
|
else if (HasOpSizePrefix && Prefix == X86Local::XS)
|
||||||
|
insnContext = IC_64BIT_XS_OPSIZE;
|
||||||
else if (HasOpSizePrefix)
|
else if (HasOpSizePrefix)
|
||||||
insnContext = IC_64BIT_OPSIZE;
|
insnContext = IC_64BIT_OPSIZE;
|
||||||
else if (HasREX_WPrefix && Prefix == X86Local::XS)
|
else if (HasREX_WPrefix && Prefix == X86Local::XS)
|
||||||
insnContext = IC_64BIT_REXW_XS;
|
insnContext = IC_64BIT_REXW_XS;
|
||||||
else if (HasREX_WPrefix && (Prefix == X86Local::XD || Prefix == X86Local::TF))
|
else if (HasREX_WPrefix &&
|
||||||
|
(Prefix == X86Local::XD || Prefix == X86Local::TF))
|
||||||
insnContext = IC_64BIT_REXW_XD;
|
insnContext = IC_64BIT_REXW_XD;
|
||||||
else if (Prefix == X86Local::XD || Prefix == X86Local::TF)
|
else if (Prefix == X86Local::XD || Prefix == X86Local::TF)
|
||||||
insnContext = IC_64BIT_XD;
|
insnContext = IC_64BIT_XD;
|
||||||
@ -334,6 +338,8 @@ InstructionContext RecognizableInstr::insnContext() const {
|
|||||||
if (HasOpSizePrefix &&
|
if (HasOpSizePrefix &&
|
||||||
(Prefix == X86Local::XD || Prefix == X86Local::TF))
|
(Prefix == X86Local::XD || Prefix == X86Local::TF))
|
||||||
insnContext = IC_XD_OPSIZE;
|
insnContext = IC_XD_OPSIZE;
|
||||||
|
else if (HasOpSizePrefix && Prefix == X86Local::XS)
|
||||||
|
insnContext = IC_XS_OPSIZE;
|
||||||
else if (HasOpSizePrefix)
|
else if (HasOpSizePrefix)
|
||||||
insnContext = IC_OPSIZE;
|
insnContext = IC_OPSIZE;
|
||||||
else if (Prefix == X86Local::XD || Prefix == X86Local::TF)
|
else if (Prefix == X86Local::XD || Prefix == X86Local::TF)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user