[llvm] [AVR] Simplify eocoding of load/store instructions (PR #118279)
Ben Shi via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 2 01:51:29 PST 2024
https://github.com/benshi001 created https://github.com/llvm/llvm-project/pull/118279
Fixes https://github.com/llvm/llvm-project/issues/113774
>From ab4b9c67fb33bc7d2a55edee6997ce64bca95530 Mon Sep 17 00:00:00 2001
From: Ben Shi <bennshi at tencent.com>
Date: Mon, 2 Dec 2024 17:38:01 +0800
Subject: [PATCH] [AVR] Simplify eocoding of load/store instructions
Fixes https://github.com/llvm/llvm-project/issues/113774
---
llvm/lib/Target/AVR/AVRInstrFormats.td | 2 -
llvm/lib/Target/AVR/AVRInstrInfo.td | 48 ++++--------------
.../AVR/MCTargetDesc/AVRMCCodeEmitter.cpp | 50 ++++++++-----------
.../AVR/MCTargetDesc/AVRMCCodeEmitter.h | 5 --
llvm/test/CodeGen/AVR/inline-asm/loadstore.ll | 26 ++++++++++
5 files changed, 57 insertions(+), 74 deletions(-)
diff --git a/llvm/lib/Target/AVR/AVRInstrFormats.td b/llvm/lib/Target/AVR/AVRInstrFormats.td
index 06d14a2fb47fec..407e14a079f3ea 100644
--- a/llvm/lib/Target/AVR/AVRInstrFormats.td
+++ b/llvm/lib/Target/AVR/AVRInstrFormats.td
@@ -173,7 +173,6 @@ class FSTDLDD<bit type, dag outs, dag ins, string asmstr, list<dag> pattern>
//===---------------------------------------------------------------------===//
class FSTLD<bit type, bits<2> mode, dag outs, dag ins, string asmstr,
list<dag> pattern> : AVRInst16<outs, ins, asmstr, pattern> {
- bits<2> ptrreg;
bits<5> reg;
let Inst{15 - 13} = 0b100;
@@ -187,7 +186,6 @@ class FSTLD<bit type, bits<2> mode, dag outs, dag ins, string asmstr,
let Inst{7 - 4} = reg{3 - 0};
- let Inst{3 - 2} = ptrreg{1 - 0};
let Inst{1 - 0} = mode{1 - 0};
let DecoderMethod = "decodeLoadStore";
diff --git a/llvm/lib/Target/AVR/AVRInstrInfo.td b/llvm/lib/Target/AVR/AVRInstrInfo.td
index 3973cd30de1ecb..61c17090e3fbe8 100644
--- a/llvm/lib/Target/AVR/AVRInstrInfo.td
+++ b/llvm/lib/Target/AVR/AVRInstrInfo.td
@@ -234,31 +234,6 @@ def imm_port6 : Operand<i8> {
// Addressing mode pattern reg+imm6
def addr : ComplexPattern<iPTR, 2, "SelectAddr", [], [SDNPWantRoot]>;
-// AsmOperand class for a pointer register.
-// Used with the LD/ST family of instructions.
-// See FSTLD in AVRInstrFormats.td
-def PtrRegAsmOperand : AsmOperandClass { let Name = "Reg"; }
-
-// A special operand type for the LD/ST instructions.
-// It converts the pointer register number into a two-bit field used in the
-// instruction.
-def LDSTPtrReg : Operand<i16> {
- let MIOperandInfo = (ops PTRREGS);
- let EncoderMethod = "encodeLDSTPtrReg";
-
- let ParserMatchClass = PtrRegAsmOperand;
-}
-
-// A special operand type for the LDD/STD instructions.
-// It behaves identically to the LD/ST version, except restricts
-// the pointer registers to Y and Z.
-def LDDSTDPtrReg : Operand<i16> {
- let MIOperandInfo = (ops PTRDISPREGS);
- let EncoderMethod = "encodeLDSTPtrReg";
-
- let ParserMatchClass = PtrRegAsmOperand;
-}
-
//===----------------------------------------------------------------------===//
// AVR predicates for subtarget features
//===----------------------------------------------------------------------===//
@@ -896,7 +871,7 @@ let canFoldAsLoad = 1, isReMaterializable = 1 in {
// Indirect loads.
let canFoldAsLoad = 1, isReMaterializable = 1 in {
- def LDRdPtr : FSTLD<0, 0b00, (outs GPR8:$reg), (ins LDSTPtrReg:$ptrreg),
+ def LDRdPtr : FSTLD<0, 0b00, (outs GPR8:$reg), (ins PTRREGS:$ptrreg),
"ld\t$reg, $ptrreg",
[(set GPR8:$reg, (load i16:$ptrreg))]>,
Requires<[HasSRAM]>;
@@ -919,13 +894,8 @@ let canFoldAsLoad = 1, isReMaterializable = 1 in {
// Indirect loads (with postincrement or predecrement).
let mayLoad = 1, hasSideEffects = 0,
Constraints = "$ptrreg = $base_wb, at earlyclobber $reg" in {
- def LDRdPtrPi : FSTLD<0, 0b01,
- (outs GPR8
- : $reg, PTRREGS
- : $base_wb),
- (ins LDSTPtrReg
- : $ptrreg),
- "ld\t$reg, $ptrreg+", []>,
+ def LDRdPtrPi : FSTLD<0, 0b01, (outs GPR8:$reg, PTRREGS:$base_wb),
+ (ins PTRREGS:$ptrreg), "ld\t$reg, $ptrreg+", []>,
Requires<[HasSRAM]>;
// LDW Rd+1:Rd, P+
@@ -937,7 +907,7 @@ let mayLoad = 1, hasSideEffects = 0,
Requires<[HasSRAM]>;
def LDRdPtrPd : FSTLD<0, 0b10, (outs GPR8:$reg, PTRREGS:$base_wb),
- (ins LDSTPtrReg:$ptrreg), "ld\t$reg, -$ptrreg", []>,
+ (ins PTRREGS:$ptrreg), "ld\t$reg, -$ptrreg", []>,
Requires<[HasSRAM]>;
// LDW Rd+1:Rd, -P
@@ -1063,7 +1033,7 @@ def STSWKRr : Pseudo<(outs), (ins i16imm:$dst, DREGS:$src),
// Indirect stores.
// ST P, Rr
// Stores the value of Rr into the location addressed by pointer P.
-def STPtrRr : FSTLD<1, 0b00, (outs), (ins LDSTPtrReg:$ptrreg, GPR8:$reg),
+def STPtrRr : FSTLD<1, 0b00, (outs), (ins PTRREGS:$ptrreg, GPR8:$reg),
"st\t$ptrreg, $reg", [(store GPR8:$reg, i16:$ptrreg)]>,
Requires<[HasSRAM]>;
@@ -1087,8 +1057,8 @@ let Constraints = "$ptrreg = $base_wb, at earlyclobber $base_wb" in {
// ST P+, Rr
// Stores the value of Rr into the location addressed by pointer P.
// Post increments P.
- def STPtrPiRr : FSTLD<1, 0b01, (outs LDSTPtrReg:$base_wb),
- (ins LDSTPtrReg:$ptrreg, GPR8:$reg, i8imm:$offs),
+ def STPtrPiRr : FSTLD<1, 0b01, (outs PTRREGS:$base_wb),
+ (ins PTRREGS:$ptrreg, GPR8:$reg, i8imm:$offs),
"st\t$ptrreg+, $reg",
[(set i16:$base_wb, (post_store GPR8:$reg, i16:$ptrreg,
imm:$offs))]>,
@@ -1112,8 +1082,8 @@ let Constraints = "$ptrreg = $base_wb, at earlyclobber $base_wb" in {
// ST -P, Rr
// Stores the value of Rr into the location addressed by pointer P.
// Pre decrements P.
- def STPtrPdRr : FSTLD<1, 0b10, (outs LDSTPtrReg:$base_wb),
- (ins LDSTPtrReg:$ptrreg, GPR8:$reg, i8imm:$offs),
+ def STPtrPdRr : FSTLD<1, 0b10, (outs PTRREGS:$base_wb),
+ (ins PTRREGS:$ptrreg, GPR8:$reg, i8imm:$offs),
"st\t-$ptrreg, $reg",
[(set i16: $base_wb,
(pre_store GPR8:$reg, i16:$ptrreg, imm:$offs))]>,
diff --git a/llvm/lib/Target/AVR/MCTargetDesc/AVRMCCodeEmitter.cpp b/llvm/lib/Target/AVR/MCTargetDesc/AVRMCCodeEmitter.cpp
index 5a0ad8119ddd54..98ddacb31a3481 100644
--- a/llvm/lib/Target/AVR/MCTargetDesc/AVRMCCodeEmitter.cpp
+++ b/llvm/lib/Target/AVR/MCTargetDesc/AVRMCCodeEmitter.cpp
@@ -72,16 +72,31 @@ AVRMCCodeEmitter::loadStorePostEncoder(const MCInst &MI, unsigned EncodedValue,
unsigned Opcode = MI.getOpcode();
- // check whether either of the registers are the X pointer register.
- bool IsRegX = MI.getOperand(0).getReg() == AVR::R27R26 ||
- MI.getOperand(1).getReg() == AVR::R27R26;
+ // Get the index of the pointer register operand.
+ unsigned Idx = 0;
+ if (Opcode == AVR::LDRdPtrPd || Opcode == AVR::LDRdPtrPi ||
+ Opcode == AVR::LDRdPtr)
+ Idx = 1;
+ // Check if we need to set the inconsistent bit
bool IsPredec = Opcode == AVR::LDRdPtrPd || Opcode == AVR::STPtrPdRr;
bool IsPostinc = Opcode == AVR::LDRdPtrPi || Opcode == AVR::STPtrPiRr;
-
- // Check if we need to set the inconsistent bit
- if (IsRegX || IsPredec || IsPostinc) {
+ if (MI.getOperand(Idx).getReg() == AVR::R27R26 || IsPredec || IsPostinc)
EncodedValue |= (1 << 12);
+
+ // Encode the pointer register.
+ switch (MI.getOperand(Idx).getReg()) {
+ case AVR::R27R26:
+ EncodedValue |= 0xc;
+ break;
+ case AVR::R29R28:
+ EncodedValue |= 0x8;
+ break;
+ case AVR::R31R30:
+ break;
+ default:
+ llvm_unreachable("invalid pointer register");
+ break;
}
return EncodedValue;
@@ -109,26 +124,6 @@ AVRMCCodeEmitter::encodeRelCondBrTarget(const MCInst &MI, unsigned OpNo,
return target;
}
-unsigned AVRMCCodeEmitter::encodeLDSTPtrReg(const MCInst &MI, unsigned OpNo,
- SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI) const {
- auto MO = MI.getOperand(OpNo);
-
- // The operand should be a pointer register.
- assert(MO.isReg());
-
- switch (MO.getReg().id()) {
- case AVR::R27R26:
- return 0x03; // X: 0b11
- case AVR::R29R28:
- return 0x02; // Y: 0b10
- case AVR::R31R30:
- return 0x00; // Z: 0b00
- default:
- llvm_unreachable("invalid pointer register");
- }
-}
-
/// Encodes a `memri` operand.
/// The operand is 7-bits.
/// * The lower 6 bits is the immediate
@@ -288,8 +283,7 @@ void AVRMCCodeEmitter::encodeInstruction(const MCInst &MI,
}
}
-MCCodeEmitter *createAVRMCCodeEmitter(const MCInstrInfo &MCII,
- MCContext &Ctx) {
+MCCodeEmitter *createAVRMCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx) {
return new AVRMCCodeEmitter(MCII, Ctx);
}
diff --git a/llvm/lib/Target/AVR/MCTargetDesc/AVRMCCodeEmitter.h b/llvm/lib/Target/AVR/MCTargetDesc/AVRMCCodeEmitter.h
index a00bbb9ae498bb..5b301dfb03ee9d 100644
--- a/llvm/lib/Target/AVR/MCTargetDesc/AVRMCCodeEmitter.h
+++ b/llvm/lib/Target/AVR/MCTargetDesc/AVRMCCodeEmitter.h
@@ -52,11 +52,6 @@ class AVRMCCodeEmitter : public MCCodeEmitter {
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
- /// Encodes the `PTRREGS` operand to a load or store instruction.
- unsigned encodeLDSTPtrReg(const MCInst &MI, unsigned OpNo,
- SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI) const;
-
/// Encodes a `register+immediate` operand for `LDD`/`STD`.
unsigned encodeMemri(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
diff --git a/llvm/test/CodeGen/AVR/inline-asm/loadstore.ll b/llvm/test/CodeGen/AVR/inline-asm/loadstore.ll
index 524fef28382fbc..5d45ece8f31c98 100644
--- a/llvm/test/CodeGen/AVR/inline-asm/loadstore.ll
+++ b/llvm/test/CodeGen/AVR/inline-asm/loadstore.ll
@@ -44,6 +44,19 @@ define i8 @loadz(ptr %0) {
ret i8 %2
}
+define i8 @load_ptr_imm() {
+; CHECK-LABEL: load_ptr_imm:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: ldi r26, 210
+; CHECK-NEXT: ldi r27, 4
+; CHECK-NEXT: ;APP
+; CHECK-NEXT: ld r24, X
+; CHECK-NEXT: ;NO_APP
+; CHECK-NEXT: ret
+ %1 = tail call i8 asm sideeffect "ld $0, $1", "=r,e"(i16 1234)
+ ret i8 %1
+}
+
define void @storex(ptr %0, i8 %1) {
; CHECK-LABEL: storex:
; CHECK: ; %bb.0:
@@ -86,3 +99,16 @@ define void @storez(ptr %0, i8 %1) {
tail call void asm sideeffect "st ${0:a}, $1", "z,r"(ptr %0, i8 %1)
ret void
}
+
+define void @store_ptr_imm(i8 %0) {
+; CHECK-LABEL: store_ptr_imm:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: ldi r26, 210
+; CHECK-NEXT: ldi r27, 4
+; CHECK-NEXT: ;APP
+; CHECK-NEXT: st X, r24
+; CHECK-NEXT: ;NO_APP
+; CHECK-NEXT: ret
+ tail call void asm sideeffect "st $0, $1", "e,r"(i16 1234, i8 %0)
+ ret void
+}
More information about the llvm-commits
mailing list