Skip to content

Commit 71b49aa

Browse files
committed
[X86] Allow lsl/lar to be parsed with a GR16, GR32, or GR64 as source register.
This matches GNU assembler behavior. Operand size is determined only from the destination register.
1 parent b893822 commit 71b49aa

File tree

6 files changed

+48
-18
lines changed

6 files changed

+48
-18
lines changed

llvm/lib/Target/X86/AsmParser/X86Operand.h

+17-1
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,14 @@ struct X86Operand final : public MCParsedAsmOperand {
463463
bool isGR32orGR64() const {
464464
return Kind == Register &&
465465
(X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
466-
X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
466+
X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
467+
}
468+
469+
bool isGR16orGR32orGR64() const {
470+
return Kind == Register &&
471+
(X86MCRegisterClasses[X86::GR16RegClassID].contains(getReg()) ||
472+
X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
473+
X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
467474
}
468475

469476
bool isVectorReg() const {
@@ -520,6 +527,15 @@ struct X86Operand final : public MCParsedAsmOperand {
520527
Inst.addOperand(MCOperand::createReg(RegNo));
521528
}
522529

530+
void addGR16orGR32orGR64Operands(MCInst &Inst, unsigned N) const {
531+
assert(N == 1 && "Invalid number of operands!");
532+
MCRegister RegNo = getReg();
533+
if (X86MCRegisterClasses[X86::GR32RegClassID].contains(RegNo) ||
534+
X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
535+
RegNo = getX86SubSuperRegister(RegNo, 16);
536+
Inst.addOperand(MCOperand::createReg(RegNo));
537+
}
538+
523539
void addAVX512RCOperands(MCInst &Inst, unsigned N) const {
524540
assert(N == 1 && "Invalid number of operands!");
525541
addExpr(Inst, getImm());

llvm/lib/Target/X86/X86InstrInfo.td

+8-1
Original file line numberDiff line numberDiff line change
@@ -640,10 +640,17 @@ class ImmSExtAsmOperandClass : AsmOperandClass {
640640
def X86GR32orGR64AsmOperand : AsmOperandClass {
641641
let Name = "GR32orGR64";
642642
}
643-
644643
def GR32orGR64 : RegisterOperand<GR32> {
645644
let ParserMatchClass = X86GR32orGR64AsmOperand;
646645
}
646+
647+
def X86GR16orGR32orGR64AsmOperand : AsmOperandClass {
648+
let Name = "GR16orGR32orGR64";
649+
}
650+
def GR16orGR32orGR64 : RegisterOperand<GR16> {
651+
let ParserMatchClass = X86GR16orGR32orGR64AsmOperand;
652+
}
653+
647654
def AVX512RCOperand : AsmOperandClass {
648655
let Name = "AVX512RC";
649656
}

llvm/lib/Target/X86/X86InstrSystem.td

+6-10
Original file line numberDiff line numberDiff line change
@@ -207,45 +207,41 @@ let mayLoad = 1 in
207207
def LAR16rm : I<0x02, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
208208
"lar{w}\t{$src, $dst|$dst, $src}", []>, TB,
209209
OpSize16, NotMemoryFoldable;
210-
def LAR16rr : I<0x02, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
210+
def LAR16rr : I<0x02, MRMSrcReg, (outs GR16:$dst), (ins GR16orGR32orGR64:$src),
211211
"lar{w}\t{$src, $dst|$dst, $src}", []>, TB,
212212
OpSize16, NotMemoryFoldable;
213213

214-
// i16mem operand in LAR32rm and GR32 operand in LAR32rr is not a typo.
215214
let mayLoad = 1 in
216215
def LAR32rm : I<0x02, MRMSrcMem, (outs GR32:$dst), (ins i16mem:$src),
217216
"lar{l}\t{$src, $dst|$dst, $src}", []>, TB,
218217
OpSize32, NotMemoryFoldable;
219-
def LAR32rr : I<0x02, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
218+
def LAR32rr : I<0x02, MRMSrcReg, (outs GR32:$dst), (ins GR16orGR32orGR64:$src),
220219
"lar{l}\t{$src, $dst|$dst, $src}", []>, TB,
221220
OpSize32, NotMemoryFoldable;
222-
// i16mem operand in LAR64rm and GR32 operand in LAR64rr is not a typo.
223221
let mayLoad = 1 in
224222
def LAR64rm : RI<0x02, MRMSrcMem, (outs GR64:$dst), (ins i16mem:$src),
225223
"lar{q}\t{$src, $dst|$dst, $src}", []>, TB, NotMemoryFoldable;
226-
def LAR64rr : RI<0x02, MRMSrcReg, (outs GR64:$dst), (ins GR32orGR64:$src),
224+
def LAR64rr : RI<0x02, MRMSrcReg, (outs GR64:$dst), (ins GR16orGR32orGR64:$src),
227225
"lar{q}\t{$src, $dst|$dst, $src}", []>, TB, NotMemoryFoldable;
228226

229-
// i16mem operand in LSL32rm and GR32 operand in LSL32rr is not a typo.
230227
let mayLoad = 1 in
231228
def LSL16rm : I<0x03, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
232229
"lsl{w}\t{$src, $dst|$dst, $src}", []>, TB,
233230
OpSize16, NotMemoryFoldable;
234-
def LSL16rr : I<0x03, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
231+
def LSL16rr : I<0x03, MRMSrcReg, (outs GR16:$dst), (ins GR16orGR32orGR64:$src),
235232
"lsl{w}\t{$src, $dst|$dst, $src}", []>, TB,
236233
OpSize16, NotMemoryFoldable;
237-
// i16mem operand in LSL64rm and GR32 operand in LSL64rr is not a typo.
238234
let mayLoad = 1 in
239235
def LSL32rm : I<0x03, MRMSrcMem, (outs GR32:$dst), (ins i16mem:$src),
240236
"lsl{l}\t{$src, $dst|$dst, $src}", []>, TB,
241237
OpSize32, NotMemoryFoldable;
242-
def LSL32rr : I<0x03, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
238+
def LSL32rr : I<0x03, MRMSrcReg, (outs GR32:$dst), (ins GR16orGR32orGR64:$src),
243239
"lsl{l}\t{$src, $dst|$dst, $src}", []>, TB,
244240
OpSize32, NotMemoryFoldable;
245241
let mayLoad = 1 in
246242
def LSL64rm : RI<0x03, MRMSrcMem, (outs GR64:$dst), (ins i16mem:$src),
247243
"lsl{q}\t{$src, $dst|$dst, $src}", []>, TB, NotMemoryFoldable;
248-
def LSL64rr : RI<0x03, MRMSrcReg, (outs GR64:$dst), (ins GR32orGR64:$src),
244+
def LSL64rr : RI<0x03, MRMSrcReg, (outs GR64:$dst), (ins GR16orGR32orGR64:$src),
249245
"lsl{q}\t{$src, $dst|$dst, $src}", []>, TB, NotMemoryFoldable;
250246

251247
def INVLPG : I<0x01, MRM7m, (outs), (ins i8mem:$addr), "invlpg\t$addr", []>, TB;

llvm/test/MC/X86/I286-32.s

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ larl 485498096(%edx), %eax
2424
// CHECK: encoding: [0x0f,0x02,0x44,0x02,0x40]
2525
larl 64(%edx,%eax), %eax
2626

27-
// CHECK: larl %eax, %eax
27+
// CHECK: larl %ax, %eax
2828
// CHECK: encoding: [0x0f,0x02,0xc0]
2929
larl %eax, %eax
3030

@@ -100,7 +100,7 @@ lsll 485498096(%edx), %eax
100100
// CHECK: encoding: [0x0f,0x03,0x44,0x02,0x40]
101101
lsll 64(%edx,%eax), %eax
102102

103-
// CHECK: lsll %eax, %eax
103+
// CHECK: lsll %ax, %eax
104104
// CHECK: encoding: [0x0f,0x03,0xc0]
105105
lsll %eax, %eax
106106

llvm/test/MC/X86/I286-64.s

+12-4
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,19 @@ larl -64(%rdx,%rax,4), %r13d
2424
// CHECK: encoding: [0x44,0x0f,0x02,0x6c,0x02,0x40]
2525
larl 64(%rdx,%rax), %r13d
2626

27-
// CHECK: larl %r13d, %r13d
27+
// CHECK: larl %r13w, %r13d
2828
// CHECK: encoding: [0x45,0x0f,0x02,0xed]
2929
larl %r13d, %r13d
3030

3131
// CHECK: larl (%rdx), %r13d
3232
// CHECK: encoding: [0x44,0x0f,0x02,0x2a]
3333
larl (%rdx), %r13d
3434

35-
// CHECK: larq %eax, %rax
35+
// CHECK: larq %ax, %rax
36+
// CHECK: encoding: [0x48,0x0f,0x02,0xc0]
37+
lar %ax, %rax
38+
39+
// CHECK: larq %ax, %rax
3640
// CHECK: encoding: [0x48,0x0f,0x02,0xc0]
3741
lar %rax, %rax
3842

@@ -160,15 +164,19 @@ lsll -64(%rdx,%rax,4), %r13d
160164
// CHECK: encoding: [0x44,0x0f,0x03,0x6c,0x02,0x40]
161165
lsll 64(%rdx,%rax), %r13d
162166

163-
// CHECK: lsll %r13d, %r13d
167+
// CHECK: lsll %r13w, %r13d
164168
// CHECK: encoding: [0x45,0x0f,0x03,0xed]
165169
lsll %r13d, %r13d
166170

167171
// CHECK: lsll (%rdx), %r13d
168172
// CHECK: encoding: [0x44,0x0f,0x03,0x2a]
169173
lsll (%rdx), %r13d
170174

171-
// CHECK: lslq %eax, %rax
175+
// CHECK: lslq %ax, %rax
176+
// CHECK: encoding: [0x48,0x0f,0x03,0xc0]
177+
lsl %ax, %rax
178+
179+
// CHECK: lslq %ax, %rax
172180
// CHECK: encoding: [0x48,0x0f,0x03,0xc0]
173181
lsl %rax, %rax
174182

llvm/utils/TableGen/X86RecognizableInstr.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -874,6 +874,7 @@ OperandType RecognizableInstr::typeFromString(const std::string &s,
874874
TYPE("i16imm", TYPE_IMM)
875875
TYPE("i16i8imm", TYPE_IMM)
876876
TYPE("GR16", TYPE_R16)
877+
TYPE("GR16orGR32orGR64", TYPE_R16)
877878
TYPE("i32mem", TYPE_M)
878879
TYPE("i32imm", TYPE_IMM)
879880
TYPE("i32i8imm", TYPE_IMM)
@@ -1035,6 +1036,7 @@ RecognizableInstr::rmRegisterEncodingFromString(const std::string &s,
10351036
ENCODING("RST", ENCODING_FP)
10361037
ENCODING("RSTi", ENCODING_FP)
10371038
ENCODING("GR16", ENCODING_RM)
1039+
ENCODING("GR16orGR32orGR64",ENCODING_RM)
10381040
ENCODING("GR32", ENCODING_RM)
10391041
ENCODING("GR32orGR64", ENCODING_RM)
10401042
ENCODING("GR64", ENCODING_RM)
@@ -1072,6 +1074,7 @@ OperandEncoding
10721074
RecognizableInstr::roRegisterEncodingFromString(const std::string &s,
10731075
uint8_t OpSize) {
10741076
ENCODING("GR16", ENCODING_REG)
1077+
ENCODING("GR16orGR32orGR64",ENCODING_REG)
10751078
ENCODING("GR32", ENCODING_REG)
10761079
ENCODING("GR32orGR64", ENCODING_REG)
10771080
ENCODING("GR64", ENCODING_REG)

0 commit comments

Comments
 (0)