Skip to content

Commit eb1248f

Browse files
committed
[X86][MC] Add missing support for pseudo rex/rex2 prefix in assembler
This fixes #95417
1 parent 75882ed commit eb1248f

File tree

6 files changed

+74
-23
lines changed

6 files changed

+74
-23
lines changed

llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ class X86AsmParser : public MCTargetAsmParser {
9090

9191
enum OpcodePrefix {
9292
OpcodePrefix_Default,
93+
OpcodePrefix_REX,
94+
OpcodePrefix_REX2,
9395
OpcodePrefix_VEX,
9496
OpcodePrefix_VEX2,
9597
OpcodePrefix_VEX3,
@@ -3201,7 +3203,11 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
32013203
return Error(Parser.getTok().getLoc(), "Expected '}'");
32023204
Parser.Lex(); // Eat curly.
32033205

3204-
if (Prefix == "vex")
3206+
if (Prefix == "rex")
3207+
ForcedOpcodePrefix = OpcodePrefix_REX;
3208+
else if (Prefix == "rex2")
3209+
ForcedOpcodePrefix = OpcodePrefix_REX2;
3210+
else if (Prefix == "vex")
32053211
ForcedOpcodePrefix = OpcodePrefix_VEX;
32063212
else if (Prefix == "vex2")
32073213
ForcedOpcodePrefix = OpcodePrefix_VEX2;
@@ -4025,9 +4031,13 @@ bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
40254031

40264032
MCInst Inst;
40274033

4028-
// If VEX/EVEX encoding is forced, we need to pass the USE_* flag to the
4029-
// encoder and printer.
4030-
if (ForcedOpcodePrefix == OpcodePrefix_VEX)
4034+
// If REX/REX2/VEX/EVEX encoding is forced, we need to pass the USE_* flag to
4035+
// the encoder and printer.
4036+
if (ForcedOpcodePrefix == OpcodePrefix_REX)
4037+
Prefixes |= X86::IP_USE_REX;
4038+
else if (ForcedOpcodePrefix == OpcodePrefix_REX2)
4039+
Prefixes |= X86::IP_USE_REX2;
4040+
else if (ForcedOpcodePrefix == OpcodePrefix_VEX)
40314041
Prefixes |= X86::IP_USE_VEX;
40324042
else if (ForcedOpcodePrefix == OpcodePrefix_VEX2)
40334043
Prefixes |= X86::IP_USE_VEX2;
@@ -4095,24 +4105,34 @@ bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc,
40954105
unsigned X86AsmParser::checkTargetMatchPredicate(MCInst &Inst) {
40964106
unsigned Opc = Inst.getOpcode();
40974107
const MCInstrDesc &MCID = MII.get(Opc);
4108+
uint64_t TSFlags = MCID.TSFlags;
40984109

40994110
if (UseApxExtendedReg && !X86II::canUseApxExtendedReg(MCID))
41004111
return Match_Unsupported;
4101-
if (ForcedNoFlag == !(MCID.TSFlags & X86II::EVEX_NF) && !X86::isCFCMOVCC(Opc))
4112+
if (ForcedNoFlag == !(TSFlags & X86II::EVEX_NF) && !X86::isCFCMOVCC(Opc))
41024113
return Match_Unsupported;
41034114

4104-
if (ForcedOpcodePrefix == OpcodePrefix_EVEX &&
4105-
(MCID.TSFlags & X86II::EncodingMask) != X86II::EVEX)
4106-
return Match_Unsupported;
4107-
4108-
if ((ForcedOpcodePrefix == OpcodePrefix_VEX ||
4109-
ForcedOpcodePrefix == OpcodePrefix_VEX2 ||
4110-
ForcedOpcodePrefix == OpcodePrefix_VEX3) &&
4111-
(MCID.TSFlags & X86II::EncodingMask) != X86II::VEX)
4112-
return Match_Unsupported;
4115+
switch (ForcedOpcodePrefix) {
4116+
case OpcodePrefix_Default:
4117+
break;
4118+
case OpcodePrefix_REX:
4119+
case OpcodePrefix_REX2:
4120+
if (TSFlags & X86II::EncodingMask)
4121+
return Match_Unsupported;
4122+
break;
4123+
case OpcodePrefix_VEX:
4124+
case OpcodePrefix_VEX2:
4125+
case OpcodePrefix_VEX3:
4126+
if ((TSFlags & X86II::EncodingMask) != X86II::VEX)
4127+
return Match_Unsupported;
4128+
break;
4129+
case OpcodePrefix_EVEX:
4130+
if ((TSFlags & X86II::EncodingMask) != X86II::EVEX)
4131+
return Match_Unsupported;
4132+
break;
4133+
}
41134134

4114-
if ((MCID.TSFlags & X86II::ExplicitOpPrefixMask) ==
4115-
X86II::ExplicitVEXPrefix &&
4135+
if ((TSFlags & X86II::ExplicitOpPrefixMask) == X86II::ExplicitVEXPrefix &&
41164136
(ForcedOpcodePrefix != OpcodePrefix_VEX &&
41174137
ForcedOpcodePrefix != OpcodePrefix_VEX2 &&
41184138
ForcedOpcodePrefix != OpcodePrefix_VEX3))

llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,14 @@ enum IPREFIXES {
5656
IP_HAS_REPEAT = 1U << 3,
5757
IP_HAS_LOCK = 1U << 4,
5858
IP_HAS_NOTRACK = 1U << 5,
59-
IP_USE_VEX = 1U << 6,
60-
IP_USE_VEX2 = 1U << 7,
61-
IP_USE_VEX3 = 1U << 8,
62-
IP_USE_EVEX = 1U << 9,
63-
IP_USE_DISP8 = 1U << 10,
64-
IP_USE_DISP32 = 1U << 11,
59+
IP_USE_REX = 1U << 6,
60+
IP_USE_REX2 = 1U << 7,
61+
IP_USE_VEX = 1U << 8,
62+
IP_USE_VEX2 = 1U << 9,
63+
IP_USE_VEX3 = 1U << 10,
64+
IP_USE_EVEX = 1U << 11,
65+
IP_USE_DISP8 = 1U << 12,
66+
IP_USE_DISP32 = 1U << 13,
6567
};
6668

6769
enum OperandType : unsigned {

llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1365,7 +1365,10 @@ PrefixKind X86MCCodeEmitter::emitREXPrefix(int MemOperand, const MCInst &MI,
13651365
}
13661366
}
13671367
}
1368-
if ((TSFlags & X86II::ExplicitOpPrefixMask) == X86II::ExplicitREX2Prefix)
1368+
if (MI.getFlags() & X86::IP_USE_REX)
1369+
Prefix.setLowerBound(REX);
1370+
if ((TSFlags & X86II::ExplicitOpPrefixMask) == X86II::ExplicitREX2Prefix ||
1371+
MI.getFlags() & X86::IP_USE_REX2)
13691372
Prefix.setLowerBound(REX2);
13701373
switch (TSFlags & X86II::FormMask) {
13711374
default:

llvm/test/MC/X86/apx/pseudo-rex2.s

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# RUN: llvm-mc -triple x86_64 -show-encoding %s | FileCheck %s
2+
3+
# CHECK: addl %ebx, %ecx
4+
# CHECK: encoding: [0xd5,0x00,0x01,0xd9]
5+
{rex2} addl %ebx, %ecx
6+
7+
# CHECK: popcntl %edi, %esi
8+
# CHECK: encoding: [0xf3,0xd5,0x80,0xb8,0xf7]
9+
{rex2} popcnt %edi,%esi

llvm/test/MC/X86/pseudo-rex.s

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# RUN: llvm-mc -triple x86_64 -show-encoding %s | FileCheck %s
2+
3+
# CHECK: addl %ebx, %ecx
4+
# CHECK: encoding: [0x40,0x01,0xd9]
5+
{rex} addl %ebx, %ecx
6+
7+
# CHECK: popcntl %edi, %esi
8+
# CHECK: encoding: [0xf3,0x40,0x0f,0xb8,0xf7]
9+
{rex} popcnt %edi,%esi

llvm/test/MC/X86/x86_errors.s

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,14 @@ cltq
168168
// X86: error: instruction requires: 64-bit mode
169169
cmpxchg16b (%eax)
170170

171+
// X86: error: unsupported instruction
172+
// X64: error: unsupported instruction
173+
{rex} vmovdqu32 %xmm0, %xmm0
174+
175+
// X86: error: unsupported instruction
176+
// X64: error: unsupported instruction
177+
{rex2} vmovdqu32 %xmm0, %xmm0
178+
171179
// X86: error: unsupported instruction
172180
// X64: error: unsupported instruction
173181
{vex} vmovdqu32 %xmm0, %xmm0

0 commit comments

Comments
 (0)