aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp
diff options
context:
space:
mode:
authorShengchen Kan <shengchen.kan@intel.com>2024-03-08 20:54:33 +0800
committerGitHub <noreply@github.com>2024-03-08 20:54:33 +0800
commit1ca8092e87aea58f1c3752d03c20bdfc4259e409 (patch)
tree2f375b2a41d94b42abe55a11fa28d7485ef3c7a7 /llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp
parentd74287226ac8c144a2700ba589d34a8bebd85d0d (diff)
downloadllvm-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.cpp43
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;