Skip to content

Commit dba0861

Browse files
authored
[AVR] Simplify eocoding of load/store instructions (#118279)
Fixes #113774
1 parent a996a15 commit dba0861

File tree

5 files changed

+57
-74
lines changed

5 files changed

+57
-74
lines changed

llvm/lib/Target/AVR/AVRInstrFormats.td

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,6 @@ class FSTDLDD<bit type, dag outs, dag ins, string asmstr, list<dag> pattern>
173173
//===---------------------------------------------------------------------===//
174174
class FSTLD<bit type, bits<2> mode, dag outs, dag ins, string asmstr,
175175
list<dag> pattern> : AVRInst16<outs, ins, asmstr, pattern> {
176-
bits<2> ptrreg;
177176
bits<5> reg;
178177

179178
let Inst{15 - 13} = 0b100;
@@ -187,7 +186,6 @@ class FSTLD<bit type, bits<2> mode, dag outs, dag ins, string asmstr,
187186

188187
let Inst{7 - 4} = reg{3 - 0};
189188

190-
let Inst{3 - 2} = ptrreg{1 - 0};
191189
let Inst{1 - 0} = mode{1 - 0};
192190

193191
let DecoderMethod = "decodeLoadStore";

llvm/lib/Target/AVR/AVRInstrInfo.td

Lines changed: 9 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -234,31 +234,6 @@ def imm_port6 : Operand<i8> {
234234
// Addressing mode pattern reg+imm6
235235
def addr : ComplexPattern<iPTR, 2, "SelectAddr", [], [SDNPWantRoot]>;
236236

237-
// AsmOperand class for a pointer register.
238-
// Used with the LD/ST family of instructions.
239-
// See FSTLD in AVRInstrFormats.td
240-
def PtrRegAsmOperand : AsmOperandClass { let Name = "Reg"; }
241-
242-
// A special operand type for the LD/ST instructions.
243-
// It converts the pointer register number into a two-bit field used in the
244-
// instruction.
245-
def LDSTPtrReg : Operand<i16> {
246-
let MIOperandInfo = (ops PTRREGS);
247-
let EncoderMethod = "encodeLDSTPtrReg";
248-
249-
let ParserMatchClass = PtrRegAsmOperand;
250-
}
251-
252-
// A special operand type for the LDD/STD instructions.
253-
// It behaves identically to the LD/ST version, except restricts
254-
// the pointer registers to Y and Z.
255-
def LDDSTDPtrReg : Operand<i16> {
256-
let MIOperandInfo = (ops PTRDISPREGS);
257-
let EncoderMethod = "encodeLDSTPtrReg";
258-
259-
let ParserMatchClass = PtrRegAsmOperand;
260-
}
261-
262237
//===----------------------------------------------------------------------===//
263238
// AVR predicates for subtarget features
264239
//===----------------------------------------------------------------------===//
@@ -896,7 +871,7 @@ let canFoldAsLoad = 1, isReMaterializable = 1 in {
896871

897872
// Indirect loads.
898873
let canFoldAsLoad = 1, isReMaterializable = 1 in {
899-
def LDRdPtr : FSTLD<0, 0b00, (outs GPR8:$reg), (ins LDSTPtrReg:$ptrreg),
874+
def LDRdPtr : FSTLD<0, 0b00, (outs GPR8:$reg), (ins PTRREGS:$ptrreg),
900875
"ld\t$reg, $ptrreg",
901876
[(set GPR8:$reg, (load i16:$ptrreg))]>,
902877
Requires<[HasSRAM]>;
@@ -919,13 +894,8 @@ let canFoldAsLoad = 1, isReMaterializable = 1 in {
919894
// Indirect loads (with postincrement or predecrement).
920895
let mayLoad = 1, hasSideEffects = 0,
921896
Constraints = "$ptrreg = $base_wb,@earlyclobber $reg" in {
922-
def LDRdPtrPi : FSTLD<0, 0b01,
923-
(outs GPR8
924-
: $reg, PTRREGS
925-
: $base_wb),
926-
(ins LDSTPtrReg
927-
: $ptrreg),
928-
"ld\t$reg, $ptrreg+", []>,
897+
def LDRdPtrPi : FSTLD<0, 0b01, (outs GPR8:$reg, PTRREGS:$base_wb),
898+
(ins PTRREGS:$ptrreg), "ld\t$reg, $ptrreg+", []>,
929899
Requires<[HasSRAM]>;
930900

931901
// LDW Rd+1:Rd, P+
@@ -937,7 +907,7 @@ let mayLoad = 1, hasSideEffects = 0,
937907
Requires<[HasSRAM]>;
938908

939909
def LDRdPtrPd : FSTLD<0, 0b10, (outs GPR8:$reg, PTRREGS:$base_wb),
940-
(ins LDSTPtrReg:$ptrreg), "ld\t$reg, -$ptrreg", []>,
910+
(ins PTRREGS:$ptrreg), "ld\t$reg, -$ptrreg", []>,
941911
Requires<[HasSRAM]>;
942912

943913
// LDW Rd+1:Rd, -P
@@ -1063,7 +1033,7 @@ def STSWKRr : Pseudo<(outs), (ins i16imm:$dst, DREGS:$src),
10631033
// Indirect stores.
10641034
// ST P, Rr
10651035
// Stores the value of Rr into the location addressed by pointer P.
1066-
def STPtrRr : FSTLD<1, 0b00, (outs), (ins LDSTPtrReg:$ptrreg, GPR8:$reg),
1036+
def STPtrRr : FSTLD<1, 0b00, (outs), (ins PTRREGS:$ptrreg, GPR8:$reg),
10671037
"st\t$ptrreg, $reg", [(store GPR8:$reg, i16:$ptrreg)]>,
10681038
Requires<[HasSRAM]>;
10691039

@@ -1087,8 +1057,8 @@ let Constraints = "$ptrreg = $base_wb,@earlyclobber $base_wb" in {
10871057
// ST P+, Rr
10881058
// Stores the value of Rr into the location addressed by pointer P.
10891059
// Post increments P.
1090-
def STPtrPiRr : FSTLD<1, 0b01, (outs LDSTPtrReg:$base_wb),
1091-
(ins LDSTPtrReg:$ptrreg, GPR8:$reg, i8imm:$offs),
1060+
def STPtrPiRr : FSTLD<1, 0b01, (outs PTRREGS:$base_wb),
1061+
(ins PTRREGS:$ptrreg, GPR8:$reg, i8imm:$offs),
10921062
"st\t$ptrreg+, $reg",
10931063
[(set i16:$base_wb, (post_store GPR8:$reg, i16:$ptrreg,
10941064
imm:$offs))]>,
@@ -1112,8 +1082,8 @@ let Constraints = "$ptrreg = $base_wb,@earlyclobber $base_wb" in {
11121082
// ST -P, Rr
11131083
// Stores the value of Rr into the location addressed by pointer P.
11141084
// Pre decrements P.
1115-
def STPtrPdRr : FSTLD<1, 0b10, (outs LDSTPtrReg:$base_wb),
1116-
(ins LDSTPtrReg:$ptrreg, GPR8:$reg, i8imm:$offs),
1085+
def STPtrPdRr : FSTLD<1, 0b10, (outs PTRREGS:$base_wb),
1086+
(ins PTRREGS:$ptrreg, GPR8:$reg, i8imm:$offs),
11171087
"st\t-$ptrreg, $reg",
11181088
[(set i16: $base_wb,
11191089
(pre_store GPR8:$reg, i16:$ptrreg, imm:$offs))]>,

llvm/lib/Target/AVR/MCTargetDesc/AVRMCCodeEmitter.cpp

Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -72,16 +72,31 @@ AVRMCCodeEmitter::loadStorePostEncoder(const MCInst &MI, unsigned EncodedValue,
7272

7373
unsigned Opcode = MI.getOpcode();
7474

75-
// check whether either of the registers are the X pointer register.
76-
bool IsRegX = MI.getOperand(0).getReg() == AVR::R27R26 ||
77-
MI.getOperand(1).getReg() == AVR::R27R26;
75+
// Get the index of the pointer register operand.
76+
unsigned Idx = 0;
77+
if (Opcode == AVR::LDRdPtrPd || Opcode == AVR::LDRdPtrPi ||
78+
Opcode == AVR::LDRdPtr)
79+
Idx = 1;
7880

81+
// Check if we need to set the inconsistent bit
7982
bool IsPredec = Opcode == AVR::LDRdPtrPd || Opcode == AVR::STPtrPdRr;
8083
bool IsPostinc = Opcode == AVR::LDRdPtrPi || Opcode == AVR::STPtrPiRr;
81-
82-
// Check if we need to set the inconsistent bit
83-
if (IsRegX || IsPredec || IsPostinc) {
84+
if (MI.getOperand(Idx).getReg() == AVR::R27R26 || IsPredec || IsPostinc)
8485
EncodedValue |= (1 << 12);
86+
87+
// Encode the pointer register.
88+
switch (MI.getOperand(Idx).getReg()) {
89+
case AVR::R27R26:
90+
EncodedValue |= 0xc;
91+
break;
92+
case AVR::R29R28:
93+
EncodedValue |= 0x8;
94+
break;
95+
case AVR::R31R30:
96+
break;
97+
default:
98+
llvm_unreachable("invalid pointer register");
99+
break;
85100
}
86101

87102
return EncodedValue;
@@ -109,26 +124,6 @@ AVRMCCodeEmitter::encodeRelCondBrTarget(const MCInst &MI, unsigned OpNo,
109124
return target;
110125
}
111126

112-
unsigned AVRMCCodeEmitter::encodeLDSTPtrReg(const MCInst &MI, unsigned OpNo,
113-
SmallVectorImpl<MCFixup> &Fixups,
114-
const MCSubtargetInfo &STI) const {
115-
auto MO = MI.getOperand(OpNo);
116-
117-
// The operand should be a pointer register.
118-
assert(MO.isReg());
119-
120-
switch (MO.getReg().id()) {
121-
case AVR::R27R26:
122-
return 0x03; // X: 0b11
123-
case AVR::R29R28:
124-
return 0x02; // Y: 0b10
125-
case AVR::R31R30:
126-
return 0x00; // Z: 0b00
127-
default:
128-
llvm_unreachable("invalid pointer register");
129-
}
130-
}
131-
132127
/// Encodes a `memri` operand.
133128
/// The operand is 7-bits.
134129
/// * The lower 6 bits is the immediate
@@ -288,8 +283,7 @@ void AVRMCCodeEmitter::encodeInstruction(const MCInst &MI,
288283
}
289284
}
290285

291-
MCCodeEmitter *createAVRMCCodeEmitter(const MCInstrInfo &MCII,
292-
MCContext &Ctx) {
286+
MCCodeEmitter *createAVRMCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx) {
293287
return new AVRMCCodeEmitter(MCII, Ctx);
294288
}
295289

llvm/lib/Target/AVR/MCTargetDesc/AVRMCCodeEmitter.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,6 @@ class AVRMCCodeEmitter : public MCCodeEmitter {
5252
SmallVectorImpl<MCFixup> &Fixups,
5353
const MCSubtargetInfo &STI) const;
5454

55-
/// Encodes the `PTRREGS` operand to a load or store instruction.
56-
unsigned encodeLDSTPtrReg(const MCInst &MI, unsigned OpNo,
57-
SmallVectorImpl<MCFixup> &Fixups,
58-
const MCSubtargetInfo &STI) const;
59-
6055
/// Encodes a `register+immediate` operand for `LDD`/`STD`.
6156
unsigned encodeMemri(const MCInst &MI, unsigned OpNo,
6257
SmallVectorImpl<MCFixup> &Fixups,

llvm/test/CodeGen/AVR/inline-asm/loadstore.ll

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,19 @@ define i8 @loadz(ptr %0) {
4444
ret i8 %2
4545
}
4646

47+
define i8 @load_ptr_imm() {
48+
; CHECK-LABEL: load_ptr_imm:
49+
; CHECK: ; %bb.0:
50+
; CHECK-NEXT: ldi r26, 210
51+
; CHECK-NEXT: ldi r27, 4
52+
; CHECK-NEXT: ;APP
53+
; CHECK-NEXT: ld r24, X
54+
; CHECK-NEXT: ;NO_APP
55+
; CHECK-NEXT: ret
56+
%1 = tail call i8 asm sideeffect "ld $0, $1", "=r,e"(i16 1234)
57+
ret i8 %1
58+
}
59+
4760
define void @storex(ptr %0, i8 %1) {
4861
; CHECK-LABEL: storex:
4962
; CHECK: ; %bb.0:
@@ -86,3 +99,16 @@ define void @storez(ptr %0, i8 %1) {
8699
tail call void asm sideeffect "st ${0:a}, $1", "z,r"(ptr %0, i8 %1)
87100
ret void
88101
}
102+
103+
define void @store_ptr_imm(i8 %0) {
104+
; CHECK-LABEL: store_ptr_imm:
105+
; CHECK: ; %bb.0:
106+
; CHECK-NEXT: ldi r26, 210
107+
; CHECK-NEXT: ldi r27, 4
108+
; CHECK-NEXT: ;APP
109+
; CHECK-NEXT: st X, r24
110+
; CHECK-NEXT: ;NO_APP
111+
; CHECK-NEXT: ret
112+
tail call void asm sideeffect "st $0, $1", "e,r"(i16 1234, i8 %0)
113+
ret void
114+
}

0 commit comments

Comments
 (0)