diff options
author | Shengchen Kan <shengchen.kan@intel.com> | 2024-03-08 20:54:33 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-08 20:54:33 +0800 |
commit | 1ca8092e87aea58f1c3752d03c20bdfc4259e409 (patch) | |
tree | 2f375b2a41d94b42abe55a11fa28d7485ef3c7a7 /llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp | |
parent | d74287226ac8c144a2700ba589d34a8bebd85d0d (diff) | |
download | llvm-1ca8092e87aea58f1c3752d03c20bdfc4259e409.zip llvm-1ca8092e87aea58f1c3752d03c20bdfc4259e409.tar.gz llvm-1ca8092e87aea58f1c3752d03c20bdfc4259e409.tar.bz2 |
[X86][MC] Support encoding/decoding for APX CCMP/CTEST (#83863)
APX assembly syntax recommendations:
https://cdrdv2.intel.com/v1/dl/getContent/817241
NOTE:
The change in llvm/tools/llvm-exegesis/lib/X86/Target.cpp is for test
LLVM ::
tools/llvm-exegesis/X86/latency/latency-SETCCr-cond-codes-sweep.s
For `SETcc`, llvm-exegesis would randomly choose 1 other instruction to
test with `SETcc`, after selecting the instruction, llvm-exegesis would
check if the operand is initialized and valid, if not
`randomizeTargetMCOperand` would choose a value for invalid operand, it
misses support for condition code operand, which cause the flaky failure
after `CCMP` supported.
llvm-exegesis can choose `CCMP` without specifying ccmp feature b/c it
use `MCSubtarget` and only16/32/64 bit is considered.
llvm-exegesis doesn't choose other instructions b/c requirement in
`hasAliasingRegistersThrough`: the instruction should use GPR (defined
by `SETcc`) and define `EFLAGS` (used by `SETcc`).
Diffstat (limited to 'llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp')
-rw-r--r-- | llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp | 43 |
1 files changed, 39 insertions, 4 deletions
diff --git a/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp b/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp index dbc2cef..0ff440b 100644 --- a/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp +++ b/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp @@ -1141,6 +1141,25 @@ static int getInstructionIDWithAttrMask(uint16_t *instructionID, return 0; } +static bool isCCMPOrCTEST(InternalInstruction *insn) { + if (insn->opcodeType != MAP4) + return false; + if (insn->opcode == 0x83 && regFromModRM(insn->modRM) == 7) + return true; + switch (insn->opcode & 0xfe) { + default: + return false; + case 0x38: + case 0x3a: + case 0x84: + return true; + case 0x80: + return regFromModRM(insn->modRM) == 7; + case 0xf6: + return regFromModRM(insn->modRM) == 0; + } +} + static bool isNF(InternalInstruction *insn) { if (!nfFromEVEX4of4(insn->vectorExtensionPrefix[3])) return false; @@ -1197,9 +1216,12 @@ static int getInstructionID(struct InternalInstruction *insn, attrMask |= ATTR_EVEXKZ; if (bFromEVEX4of4(insn->vectorExtensionPrefix[3])) attrMask |= ATTR_EVEXB; - if (isNF(insn)) // NF bit is the MSB of aaa. + if (isNF(insn) && !readModRM(insn) && + !isCCMPOrCTEST(insn)) // NF bit is the MSB of aaa. attrMask |= ATTR_EVEXNF; - else if (aaaFromEVEX4of4(insn->vectorExtensionPrefix[3])) + // aaa is not used a opmask in MAP4 + else if (aaaFromEVEX4of4(insn->vectorExtensionPrefix[3]) && + (insn->opcodeType != MAP4)) attrMask |= ATTR_EVEXK; if (lFromEVEX4of4(insn->vectorExtensionPrefix[3])) attrMask |= ATTR_VEXL; @@ -1732,8 +1754,15 @@ static int readOperands(struct InternalInstruction *insn) { if (readOpcodeRegister(insn, 0)) return -1; break; + case ENCODING_CF: + insn->immediates[1] = oszcFromEVEX3of4(insn->vectorExtensionPrefix[2]); + needVVVV = false; // oszc shares the same bits with VVVV + break; case ENCODING_CC: - insn->immediates[1] = insn->opcode & 0xf; + if (isCCMPOrCTEST(insn)) + insn->immediates[2] = scFromEVEX4of4(insn->vectorExtensionPrefix[3]); + else + insn->immediates[1] = insn->opcode & 0xf; break; case ENCODING_FP: break; @@ -2371,9 +2400,15 @@ static bool translateOperand(MCInst &mcInst, const OperandSpecifier &operand, case ENCODING_Rv: translateRegister(mcInst, insn.opcodeRegister); return false; - case ENCODING_CC: + case ENCODING_CF: mcInst.addOperand(MCOperand::createImm(insn.immediates[1])); return false; + case ENCODING_CC: + if (isCCMPOrCTEST(&insn)) + mcInst.addOperand(MCOperand::createImm(insn.immediates[2])); + else + mcInst.addOperand(MCOperand::createImm(insn.immediates[1])); + return false; case ENCODING_FP: translateFPRegister(mcInst, insn.modRM & 7); return false; |