[llvm] eb1248f - [X86][MC] Add missing support for pseudo rex/rex2 prefix in assembler
Shengchen Kan via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 13 19:19:13 PDT 2024
Author: Shengchen Kan
Date: 2024-06-14T10:18:21+08:00
New Revision: eb1248f20a86eb1bc8a7cc61d4ce71293a6caa75
URL: https://github.com/llvm/llvm-project/commit/eb1248f20a86eb1bc8a7cc61d4ce71293a6caa75
DIFF: https://github.com/llvm/llvm-project/commit/eb1248f20a86eb1bc8a7cc61d4ce71293a6caa75.diff
LOG: [X86][MC] Add missing support for pseudo rex/rex2 prefix in assembler
This fixes https://github.com/llvm/llvm-project/issues/95417
Added:
llvm/test/MC/X86/apx/pseudo-rex2.s
llvm/test/MC/X86/pseudo-rex.s
Modified:
llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
llvm/test/MC/X86/x86_errors.s
Removed:
################################################################################
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
index ffd66aa800584..c0f54b223877c 100644
--- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -90,6 +90,8 @@ class X86AsmParser : public MCTargetAsmParser {
enum OpcodePrefix {
OpcodePrefix_Default,
+ OpcodePrefix_REX,
+ OpcodePrefix_REX2,
OpcodePrefix_VEX,
OpcodePrefix_VEX2,
OpcodePrefix_VEX3,
@@ -3201,7 +3203,11 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
return Error(Parser.getTok().getLoc(), "Expected '}'");
Parser.Lex(); // Eat curly.
- if (Prefix == "vex")
+ if (Prefix == "rex")
+ ForcedOpcodePrefix = OpcodePrefix_REX;
+ else if (Prefix == "rex2")
+ ForcedOpcodePrefix = OpcodePrefix_REX2;
+ else if (Prefix == "vex")
ForcedOpcodePrefix = OpcodePrefix_VEX;
else if (Prefix == "vex2")
ForcedOpcodePrefix = OpcodePrefix_VEX2;
@@ -4025,9 +4031,13 @@ bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
MCInst Inst;
- // If VEX/EVEX encoding is forced, we need to pass the USE_* flag to the
- // encoder and printer.
- if (ForcedOpcodePrefix == OpcodePrefix_VEX)
+ // If REX/REX2/VEX/EVEX encoding is forced, we need to pass the USE_* flag to
+ // the encoder and printer.
+ if (ForcedOpcodePrefix == OpcodePrefix_REX)
+ Prefixes |= X86::IP_USE_REX;
+ else if (ForcedOpcodePrefix == OpcodePrefix_REX2)
+ Prefixes |= X86::IP_USE_REX2;
+ else if (ForcedOpcodePrefix == OpcodePrefix_VEX)
Prefixes |= X86::IP_USE_VEX;
else if (ForcedOpcodePrefix == OpcodePrefix_VEX2)
Prefixes |= X86::IP_USE_VEX2;
@@ -4095,24 +4105,34 @@ bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc,
unsigned X86AsmParser::checkTargetMatchPredicate(MCInst &Inst) {
unsigned Opc = Inst.getOpcode();
const MCInstrDesc &MCID = MII.get(Opc);
+ uint64_t TSFlags = MCID.TSFlags;
if (UseApxExtendedReg && !X86II::canUseApxExtendedReg(MCID))
return Match_Unsupported;
- if (ForcedNoFlag == !(MCID.TSFlags & X86II::EVEX_NF) && !X86::isCFCMOVCC(Opc))
+ if (ForcedNoFlag == !(TSFlags & X86II::EVEX_NF) && !X86::isCFCMOVCC(Opc))
return Match_Unsupported;
- if (ForcedOpcodePrefix == OpcodePrefix_EVEX &&
- (MCID.TSFlags & X86II::EncodingMask) != X86II::EVEX)
- return Match_Unsupported;
-
- if ((ForcedOpcodePrefix == OpcodePrefix_VEX ||
- ForcedOpcodePrefix == OpcodePrefix_VEX2 ||
- ForcedOpcodePrefix == OpcodePrefix_VEX3) &&
- (MCID.TSFlags & X86II::EncodingMask) != X86II::VEX)
- return Match_Unsupported;
+ switch (ForcedOpcodePrefix) {
+ case OpcodePrefix_Default:
+ break;
+ case OpcodePrefix_REX:
+ case OpcodePrefix_REX2:
+ if (TSFlags & X86II::EncodingMask)
+ return Match_Unsupported;
+ break;
+ case OpcodePrefix_VEX:
+ case OpcodePrefix_VEX2:
+ case OpcodePrefix_VEX3:
+ if ((TSFlags & X86II::EncodingMask) != X86II::VEX)
+ return Match_Unsupported;
+ break;
+ case OpcodePrefix_EVEX:
+ if ((TSFlags & X86II::EncodingMask) != X86II::EVEX)
+ return Match_Unsupported;
+ break;
+ }
- if ((MCID.TSFlags & X86II::ExplicitOpPrefixMask) ==
- X86II::ExplicitVEXPrefix &&
+ if ((TSFlags & X86II::ExplicitOpPrefixMask) == X86II::ExplicitVEXPrefix &&
(ForcedOpcodePrefix != OpcodePrefix_VEX &&
ForcedOpcodePrefix != OpcodePrefix_VEX2 &&
ForcedOpcodePrefix != OpcodePrefix_VEX3))
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h b/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
index 8e40157836415..a89408bb79b06 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
@@ -56,12 +56,14 @@ enum IPREFIXES {
IP_HAS_REPEAT = 1U << 3,
IP_HAS_LOCK = 1U << 4,
IP_HAS_NOTRACK = 1U << 5,
- IP_USE_VEX = 1U << 6,
- IP_USE_VEX2 = 1U << 7,
- IP_USE_VEX3 = 1U << 8,
- IP_USE_EVEX = 1U << 9,
- IP_USE_DISP8 = 1U << 10,
- IP_USE_DISP32 = 1U << 11,
+ IP_USE_REX = 1U << 6,
+ IP_USE_REX2 = 1U << 7,
+ IP_USE_VEX = 1U << 8,
+ IP_USE_VEX2 = 1U << 9,
+ IP_USE_VEX3 = 1U << 10,
+ IP_USE_EVEX = 1U << 11,
+ IP_USE_DISP8 = 1U << 12,
+ IP_USE_DISP32 = 1U << 13,
};
enum OperandType : unsigned {
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
index b4633b91bee32..72219c136c7e1 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
@@ -1365,7 +1365,10 @@ PrefixKind X86MCCodeEmitter::emitREXPrefix(int MemOperand, const MCInst &MI,
}
}
}
- if ((TSFlags & X86II::ExplicitOpPrefixMask) == X86II::ExplicitREX2Prefix)
+ if (MI.getFlags() & X86::IP_USE_REX)
+ Prefix.setLowerBound(REX);
+ if ((TSFlags & X86II::ExplicitOpPrefixMask) == X86II::ExplicitREX2Prefix ||
+ MI.getFlags() & X86::IP_USE_REX2)
Prefix.setLowerBound(REX2);
switch (TSFlags & X86II::FormMask) {
default:
diff --git a/llvm/test/MC/X86/apx/pseudo-rex2.s b/llvm/test/MC/X86/apx/pseudo-rex2.s
new file mode 100644
index 0000000000000..bbe1508524381
--- /dev/null
+++ b/llvm/test/MC/X86/apx/pseudo-rex2.s
@@ -0,0 +1,9 @@
+# RUN: llvm-mc -triple x86_64 -show-encoding %s | FileCheck %s
+
+# CHECK: addl %ebx, %ecx
+# CHECK: encoding: [0xd5,0x00,0x01,0xd9]
+{rex2} addl %ebx, %ecx
+
+# CHECK: popcntl %edi, %esi
+# CHECK: encoding: [0xf3,0xd5,0x80,0xb8,0xf7]
+{rex2} popcnt %edi,%esi
diff --git a/llvm/test/MC/X86/pseudo-rex.s b/llvm/test/MC/X86/pseudo-rex.s
new file mode 100644
index 0000000000000..fc4c4dad54343
--- /dev/null
+++ b/llvm/test/MC/X86/pseudo-rex.s
@@ -0,0 +1,9 @@
+# RUN: llvm-mc -triple x86_64 -show-encoding %s | FileCheck %s
+
+# CHECK: addl %ebx, %ecx
+# CHECK: encoding: [0x40,0x01,0xd9]
+{rex} addl %ebx, %ecx
+
+# CHECK: popcntl %edi, %esi
+# CHECK: encoding: [0xf3,0x40,0x0f,0xb8,0xf7]
+{rex} popcnt %edi,%esi
diff --git a/llvm/test/MC/X86/x86_errors.s b/llvm/test/MC/X86/x86_errors.s
index da8659f3621e3..543575f38815a 100644
--- a/llvm/test/MC/X86/x86_errors.s
+++ b/llvm/test/MC/X86/x86_errors.s
@@ -168,6 +168,14 @@ cltq
// X86: error: instruction requires: 64-bit mode
cmpxchg16b (%eax)
+// X86: error: unsupported instruction
+// X64: error: unsupported instruction
+{rex} vmovdqu32 %xmm0, %xmm0
+
+// X86: error: unsupported instruction
+// X64: error: unsupported instruction
+{rex2} vmovdqu32 %xmm0, %xmm0
+
// X86: error: unsupported instruction
// X64: error: unsupported instruction
{vex} vmovdqu32 %xmm0, %xmm0
More information about the llvm-commits
mailing list