mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 04:30:23 +00:00
[X86] AVX512: Add disassembler support for compressed displacement
There are two parts here. First is to modify tablegen to adjust the encoding type ENCODING_RM with the scaling factor. The second is to use the new encoding types to compute the correct displacement in the decoder. Fixes <rdar://problem/17608489> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@213281 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
f166cc13e2
commit
6ae2941874
@ -717,7 +717,7 @@ static bool translateOperand(MCInst &mcInst, const OperandSpecifier &operand,
|
||||
return false;
|
||||
case ENCODING_WRITEMASK:
|
||||
return translateMaskRegister(mcInst, insn.writemask);
|
||||
case ENCODING_RM:
|
||||
CASE_ENCODING_RM:
|
||||
return translateRM(mcInst, operand, insn, Dis);
|
||||
case ENCODING_CB:
|
||||
case ENCODING_CW:
|
||||
|
@ -1488,7 +1488,7 @@ static int fixupReg(struct InternalInstruction *insn,
|
||||
if (!valid)
|
||||
return -1;
|
||||
break;
|
||||
case ENCODING_RM:
|
||||
CASE_ENCODING_RM:
|
||||
if (insn->eaBase >= insn->eaRegBase) {
|
||||
insn->eaBase = (EABase)fixupRMValue(insn,
|
||||
(OperandType)op->type,
|
||||
@ -1681,11 +1681,14 @@ static int readOperands(struct InternalInstruction* insn) {
|
||||
case ENCODING_DI:
|
||||
break;
|
||||
case ENCODING_REG:
|
||||
case ENCODING_RM:
|
||||
CASE_ENCODING_RM:
|
||||
if (readModRM(insn))
|
||||
return -1;
|
||||
if (fixupReg(insn, &Op))
|
||||
return -1;
|
||||
// Apply the AVX512 compressed displacement scaling factor.
|
||||
if (Op.encoding != ENCODING_REG && insn->eaDisplacement == EA_DISP_8)
|
||||
insn->displacement *= 1 << (Op.encoding - ENCODING_RM);
|
||||
break;
|
||||
case ENCODING_CB:
|
||||
case ENCODING_CW:
|
||||
|
@ -325,11 +325,26 @@ enum ModRMDecisionType {
|
||||
};
|
||||
#undef ENUM_ENTRY
|
||||
|
||||
#define CASE_ENCODING_RM \
|
||||
case ENCODING_RM: \
|
||||
case ENCODING_RM_CD2: \
|
||||
case ENCODING_RM_CD4: \
|
||||
case ENCODING_RM_CD8: \
|
||||
case ENCODING_RM_CD16: \
|
||||
case ENCODING_RM_CD32: \
|
||||
case ENCODING_RM_CD64
|
||||
|
||||
// Physical encodings of instruction operands.
|
||||
#define ENCODINGS \
|
||||
ENUM_ENTRY(ENCODING_NONE, "") \
|
||||
ENUM_ENTRY(ENCODING_REG, "Register operand in ModR/M byte.") \
|
||||
ENUM_ENTRY(ENCODING_RM, "R/M operand in ModR/M byte.") \
|
||||
ENUM_ENTRY(ENCODING_RM_CD2, "R/M operand with CDisp scaling of 2") \
|
||||
ENUM_ENTRY(ENCODING_RM_CD4, "R/M operand with CDisp scaling of 4") \
|
||||
ENUM_ENTRY(ENCODING_RM_CD8, "R/M operand with CDisp scaling of 8") \
|
||||
ENUM_ENTRY(ENCODING_RM_CD16,"R/M operand with CDisp scaling of 16") \
|
||||
ENUM_ENTRY(ENCODING_RM_CD32,"R/M operand with CDisp scaling of 32") \
|
||||
ENUM_ENTRY(ENCODING_RM_CD64,"R/M operand with CDisp scaling of 64") \
|
||||
ENUM_ENTRY(ENCODING_VVVV, "Register operand in VEX.vvvv byte.") \
|
||||
ENUM_ENTRY(ENCODING_WRITEMASK, "Register operand in EVEX.aaa byte.") \
|
||||
ENUM_ENTRY(ENCODING_CB, "1-byte code offset (possible new CS value)") \
|
||||
|
@ -63,3 +63,42 @@
|
||||
|
||||
# CHECK: kmovw %k5, %k1
|
||||
0xc5 0xf8 0x90 0xcd
|
||||
|
||||
#####################################################
|
||||
# COMPRESSED DISPLACEMENT #
|
||||
#####################################################
|
||||
|
||||
# TupleType = FVM
|
||||
# CHECK: vmovdqu32 %zmm0, -448(%rcx)
|
||||
0x62 0xf1 0x7e 0x48 0x7f 0x41 0xf9
|
||||
|
||||
# TupleType = T1S, 64-bit eltsize
|
||||
# CHECK: vaddsd 256(%rdx), %xmm0, %xmm16
|
||||
0x62 0xe1 0xff 0x08 0x58 0x42 0x20
|
||||
|
||||
# TupleType = T1S, 32-bit eltsize
|
||||
# CHECK: vaddss 256(%rdx), %xmm0, %xmm16
|
||||
0x62 0xe1 0x7e 0x08 0x58 0x42 0x40
|
||||
|
||||
# TupleType = FV
|
||||
# CHECK: vaddpd 256(%rdx), %zmm0, %zmm16
|
||||
0x62 0xe1 0xfd 0x48 0x58 0x42 0x04
|
||||
|
||||
# TupleType = FV, broadcast, 64-bit eltsize
|
||||
# CHECK: vaddpd 256(%rdx){1to8}, %zmm0, %zmm16
|
||||
0x62 0xe1 0xfd 0x58 0x58 0x42 0x20
|
||||
|
||||
# TupleType = FV, broadcast, 32-bit eltsize
|
||||
# CHECK: vaddps 256(%rdx){1to16}, %zmm0, %zmm16
|
||||
0x62 0xe1 0x7c 0x58 0x58 0x42 0x40
|
||||
|
||||
# TupleType = T4
|
||||
# CHECK: vbroadcasti32x4 256(%rdx), %zmm16
|
||||
0x62 0xe2 0x7d 0x48 0x5a 0x42 0x10
|
||||
|
||||
# Cases where we can't use cdisp8
|
||||
# CHECK: vaddss 255(%rdx), %xmm0, %xmm16
|
||||
0x62 0xe1 0x7e 0x08 0x58 0x82 0xff 0x00 0x00 0x00
|
||||
|
||||
# CHECK: vaddss 1024(%rdx), %xmm0, %xmm16
|
||||
0x62 0xe1 0x7e 0x08 0x58 0x82 0x00 0x04 0x00 0x00
|
||||
|
@ -205,6 +205,7 @@ RecognizableInstr::RecognizableInstr(DisassemblerTables &tables,
|
||||
HasEVEX_B = Rec->getValueAsBit("hasEVEX_B");
|
||||
IsCodeGenOnly = Rec->getValueAsBit("isCodeGenOnly");
|
||||
ForceDisassemble = Rec->getValueAsBit("ForceDisassemble");
|
||||
CD8_Scale = byteFromRec(Rec, "CD8_Scale");
|
||||
|
||||
Name = Rec->getName();
|
||||
AsmString = Rec->getValueAsString("AsmString");
|
||||
@ -441,6 +442,16 @@ InstructionContext RecognizableInstr::insnContext() const {
|
||||
return insnContext;
|
||||
}
|
||||
|
||||
void RecognizableInstr::adjustOperandEncoding(OperandEncoding &encoding) {
|
||||
// The scaling factor for AVX512 compressed displacement encoding is an
|
||||
// instruction attribute. Adjust the ModRM encoding type to include the
|
||||
// scale for compressed displacement.
|
||||
if (encoding != ENCODING_RM || CD8_Scale == 0)
|
||||
return;
|
||||
encoding = (OperandEncoding)(encoding + Log2_32(CD8_Scale));
|
||||
assert(encoding <= ENCODING_RM_CD64 && "Invalid CDisp scaling");
|
||||
}
|
||||
|
||||
void RecognizableInstr::handleOperand(bool optional, unsigned &operandIndex,
|
||||
unsigned &physicalOperandIndex,
|
||||
unsigned &numPhysicalOperands,
|
||||
@ -464,8 +475,10 @@ void RecognizableInstr::handleOperand(bool optional, unsigned &operandIndex,
|
||||
|
||||
const std::string &typeName = (*Operands)[operandIndex].Rec->getName();
|
||||
|
||||
Spec->operands[operandIndex].encoding = encodingFromString(typeName,
|
||||
OpSize);
|
||||
OperandEncoding encoding = encodingFromString(typeName, OpSize);
|
||||
// Adjust the encoding type for an operand based on the instruction.
|
||||
adjustOperandEncoding(encoding);
|
||||
Spec->operands[operandIndex].encoding = encoding;
|
||||
Spec->operands[operandIndex].type = typeFromString(typeName,
|
||||
HasREX_WPrefix, OpSize);
|
||||
|
||||
|
@ -78,6 +78,8 @@ private:
|
||||
bool IsCodeGenOnly;
|
||||
/// The ForceDisassemble field from the record
|
||||
bool ForceDisassemble;
|
||||
// The CD8_Scale field from the record
|
||||
uint8_t CD8_Scale;
|
||||
// Whether the instruction has the predicate "In64BitMode"
|
||||
bool Is64Bit;
|
||||
// Whether the instruction has the predicate "In32BitMode"
|
||||
@ -153,6 +155,9 @@ private:
|
||||
static OperandEncoding writemaskRegisterEncodingFromString(const std::string &s,
|
||||
uint8_t OpSize);
|
||||
|
||||
/// \brief Adjust the encoding type for an operand based on the instruction.
|
||||
void adjustOperandEncoding(OperandEncoding &encoding);
|
||||
|
||||
/// handleOperand - Converts a single operand from the LLVM table format to
|
||||
/// the emitted table format, handling any duplicate operands it encounters
|
||||
/// and then one non-duplicate.
|
||||
|
Loading…
Reference in New Issue
Block a user