From 5933c2f824175f1f17fcb59a5904268cac0506ba Mon Sep 17 00:00:00 2001 From: Adam Nemet Date: Thu, 17 Jul 2014 17:04:56 +0000 Subject: [PATCH] [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 llvm-svn: 213281 --- .../Target/X86/Disassembler/X86Disassembler.cpp | 2 +- .../X86/Disassembler/X86DisassemblerDecoder.cpp | 7 ++-- .../Disassembler/X86DisassemblerDecoderCommon.h | 15 +++++++++ llvm/test/MC/Disassembler/X86/avx-512.txt | 39 ++++++++++++++++++++++ llvm/utils/TableGen/X86RecognizableInstr.cpp | 17 ++++++++-- llvm/utils/TableGen/X86RecognizableInstr.h | 5 +++ 6 files changed, 80 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp b/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp index c366725..521bd21 100644 --- a/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp +++ b/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp @@ -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: diff --git a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp index 55587d4..ab3d1f7 100644 --- a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp +++ b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp @@ -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: diff --git a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h index f59e0b6..4baaf1e 100644 --- a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h +++ b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h @@ -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)") \ diff --git a/llvm/test/MC/Disassembler/X86/avx-512.txt b/llvm/test/MC/Disassembler/X86/avx-512.txt index b1a8aaf..f78db55 100644 --- a/llvm/test/MC/Disassembler/X86/avx-512.txt +++ b/llvm/test/MC/Disassembler/X86/avx-512.txt @@ -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 diff --git a/llvm/utils/TableGen/X86RecognizableInstr.cpp b/llvm/utils/TableGen/X86RecognizableInstr.cpp index ead419e..4137a57 100644 --- a/llvm/utils/TableGen/X86RecognizableInstr.cpp +++ b/llvm/utils/TableGen/X86RecognizableInstr.cpp @@ -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); diff --git a/llvm/utils/TableGen/X86RecognizableInstr.h b/llvm/utils/TableGen/X86RecognizableInstr.h index 77286bc..4bc52eb 100644 --- a/llvm/utils/TableGen/X86RecognizableInstr.h +++ b/llvm/utils/TableGen/X86RecognizableInstr.h @@ -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. -- 2.7.4