[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