llvm.org GIT mirror llvm / 6ae2941
[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 Adam Nemet 5 years ago
6 changed file(s) with 80 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
716716 return false;
717717 case ENCODING_WRITEMASK:
718718 return translateMaskRegister(mcInst, insn.writemask);
719 case ENCODING_RM:
719 CASE_ENCODING_RM:
720720 return translateRM(mcInst, operand, insn, Dis);
721721 case ENCODING_CB:
722722 case ENCODING_CW:
14871487 if (!valid)
14881488 return -1;
14891489 break;
1490 case ENCODING_RM:
1490 CASE_ENCODING_RM:
14911491 if (insn->eaBase >= insn->eaRegBase) {
14921492 insn->eaBase = (EABase)fixupRMValue(insn,
14931493 (OperandType)op->type,
16801680 case ENCODING_DI:
16811681 break;
16821682 case ENCODING_REG:
1683 case ENCODING_RM:
1683 CASE_ENCODING_RM:
16841684 if (readModRM(insn))
16851685 return -1;
16861686 if (fixupReg(insn, &Op))
16871687 return -1;
1688 // Apply the AVX512 compressed displacement scaling factor.
1689 if (Op.encoding != ENCODING_REG && insn->eaDisplacement == EA_DISP_8)
1690 insn->displacement *= 1 << (Op.encoding - ENCODING_RM);
16881691 break;
16891692 case ENCODING_CB:
16901693 case ENCODING_CW:
324324 };
325325 #undef ENUM_ENTRY
326326
327 #define CASE_ENCODING_RM \
328 case ENCODING_RM: \
329 case ENCODING_RM_CD2: \
330 case ENCODING_RM_CD4: \
331 case ENCODING_RM_CD8: \
332 case ENCODING_RM_CD16: \
333 case ENCODING_RM_CD32: \
334 case ENCODING_RM_CD64
335
327336 // Physical encodings of instruction operands.
328337 #define ENCODINGS \
329338 ENUM_ENTRY(ENCODING_NONE, "") \
330339 ENUM_ENTRY(ENCODING_REG, "Register operand in ModR/M byte.") \
331340 ENUM_ENTRY(ENCODING_RM, "R/M operand in ModR/M byte.") \
341 ENUM_ENTRY(ENCODING_RM_CD2, "R/M operand with CDisp scaling of 2") \
342 ENUM_ENTRY(ENCODING_RM_CD4, "R/M operand with CDisp scaling of 4") \
343 ENUM_ENTRY(ENCODING_RM_CD8, "R/M operand with CDisp scaling of 8") \
344 ENUM_ENTRY(ENCODING_RM_CD16,"R/M operand with CDisp scaling of 16") \
345 ENUM_ENTRY(ENCODING_RM_CD32,"R/M operand with CDisp scaling of 32") \
346 ENUM_ENTRY(ENCODING_RM_CD64,"R/M operand with CDisp scaling of 64") \
332347 ENUM_ENTRY(ENCODING_VVVV, "Register operand in VEX.vvvv byte.") \
333348 ENUM_ENTRY(ENCODING_WRITEMASK, "Register operand in EVEX.aaa byte.") \
334349 ENUM_ENTRY(ENCODING_CB, "1-byte code offset (possible new CS value)") \
6262
6363 # CHECK: kmovw %k5, %k1
6464 0xc5 0xf8 0x90 0xcd
65
66 #####################################################
67 # COMPRESSED DISPLACEMENT #
68 #####################################################
69
70 # TupleType = FVM
71 # CHECK: vmovdqu32 %zmm0, -448(%rcx)
72 0x62 0xf1 0x7e 0x48 0x7f 0x41 0xf9
73
74 # TupleType = T1S, 64-bit eltsize
75 # CHECK: vaddsd 256(%rdx), %xmm0, %xmm16
76 0x62 0xe1 0xff 0x08 0x58 0x42 0x20
77
78 # TupleType = T1S, 32-bit eltsize
79 # CHECK: vaddss 256(%rdx), %xmm0, %xmm16
80 0x62 0xe1 0x7e 0x08 0x58 0x42 0x40
81
82 # TupleType = FV
83 # CHECK: vaddpd 256(%rdx), %zmm0, %zmm16
84 0x62 0xe1 0xfd 0x48 0x58 0x42 0x04
85
86 # TupleType = FV, broadcast, 64-bit eltsize
87 # CHECK: vaddpd 256(%rdx){1to8}, %zmm0, %zmm16
88 0x62 0xe1 0xfd 0x58 0x58 0x42 0x20
89
90 # TupleType = FV, broadcast, 32-bit eltsize
91 # CHECK: vaddps 256(%rdx){1to16}, %zmm0, %zmm16
92 0x62 0xe1 0x7c 0x58 0x58 0x42 0x40
93
94 # TupleType = T4
95 # CHECK: vbroadcasti32x4 256(%rdx), %zmm16
96 0x62 0xe2 0x7d 0x48 0x5a 0x42 0x10
97
98 # Cases where we can't use cdisp8
99 # CHECK: vaddss 255(%rdx), %xmm0, %xmm16
100 0x62 0xe1 0x7e 0x08 0x58 0x82 0xff 0x00 0x00 0x00
101
102 # CHECK: vaddss 1024(%rdx), %xmm0, %xmm16
103 0x62 0xe1 0x7e 0x08 0x58 0x82 0x00 0x04 0x00 0x00
204204 HasEVEX_B = Rec->getValueAsBit("hasEVEX_B");
205205 IsCodeGenOnly = Rec->getValueAsBit("isCodeGenOnly");
206206 ForceDisassemble = Rec->getValueAsBit("ForceDisassemble");
207 CD8_Scale = byteFromRec(Rec, "CD8_Scale");
207208
208209 Name = Rec->getName();
209210 AsmString = Rec->getValueAsString("AsmString");
440441 return insnContext;
441442 }
442443
444 void RecognizableInstr::adjustOperandEncoding(OperandEncoding &encoding) {
445 // The scaling factor for AVX512 compressed displacement encoding is an
446 // instruction attribute. Adjust the ModRM encoding type to include the
447 // scale for compressed displacement.
448 if (encoding != ENCODING_RM || CD8_Scale == 0)
449 return;
450 encoding = (OperandEncoding)(encoding + Log2_32(CD8_Scale));
451 assert(encoding <= ENCODING_RM_CD64 && "Invalid CDisp scaling");
452 }
453
443454 void RecognizableInstr::handleOperand(bool optional, unsigned &operandIndex,
444455 unsigned &physicalOperandIndex,
445456 unsigned &numPhysicalOperands,
463474
464475 const std::string &typeName = (*Operands)[operandIndex].Rec->getName();
465476
466 Spec->operands[operandIndex].encoding = encodingFromString(typeName,
467 OpSize);
477 OperandEncoding encoding = encodingFromString(typeName, OpSize);
478 // Adjust the encoding type for an operand based on the instruction.
479 adjustOperandEncoding(encoding);
480 Spec->operands[operandIndex].encoding = encoding;
468481 Spec->operands[operandIndex].type = typeFromString(typeName,
469482 HasREX_WPrefix, OpSize);
470483
7777 bool IsCodeGenOnly;
7878 /// The ForceDisassemble field from the record
7979 bool ForceDisassemble;
80 // The CD8_Scale field from the record
81 uint8_t CD8_Scale;
8082 // Whether the instruction has the predicate "In64BitMode"
8183 bool Is64Bit;
8284 // Whether the instruction has the predicate "In32BitMode"
151153 uint8_t OpSize);
152154 static OperandEncoding writemaskRegisterEncodingFromString(const std::string &s,
153155 uint8_t OpSize);
156
157 /// \brief Adjust the encoding type for an operand based on the instruction.
158 void adjustOperandEncoding(OperandEncoding &encoding);
154159
155160 /// handleOperand - Converts a single operand from the LLVM table format to
156161 /// the emitted table format, handling any duplicate operands it encounters