[llvm] r356200 - [ARC] Add more load/store variants.

Pete Couperus via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 14 13:50:54 PDT 2019


Author: petecoup
Date: Thu Mar 14 13:50:54 2019
New Revision: 356200

URL: http://llvm.org/viewvc/llvm-project?rev=356200&view=rev
Log:
[ARC] Add more load/store variants.

On ARC ISA, general format of load instruction is this:

    LD<zz><.x><.aa><.di> a, [b,c]
And general format of store is this:
    ST<zz><.aa><.di> c, [b,s9]
Where:

<zz> is data size field and can be one of
  <empty> (bits 00) - Word (32-bit), default behavior
  B             (bits 01) - Byte
  H             (bits 10) - Half-word (16-bit)

 <.x> is data extend mode:
  <empty> (bit 0) - If size is not Word(32-bit), then data is zero extended
  X       (bit 1) - If size is not Word(32-bit), then data is sign extended

 <.aa> is address write-back mode:
  <empty> (bits 00) - no write-back
  .AW  (bits 01) - Preincrement, base register updated pre memory transaction
  .AB  (bits 10) - Postincrement, base register updated post memory transaction

 <.di> is cache bypass mode:
  <empty> (bit 0) - Cached memory access, default mode
  .DI     (bit 1) - Non-cached data memory access

  This patch adds these load/store instruction variants to the ARC backend.

Patch By Denis Antrushin! <denis at synopsys.com>

Differential Revision: https://reviews.llvm.org/D58980

Modified:
    llvm/trunk/lib/Target/ARC/ARCInstrFormats.td
    llvm/trunk/lib/Target/ARC/ARCInstrInfo.cpp
    llvm/trunk/lib/Target/ARC/ARCInstrInfo.h
    llvm/trunk/lib/Target/ARC/ARCInstrInfo.td
    llvm/trunk/test/MC/Disassembler/ARC/ldst.txt

Modified: llvm/trunk/lib/Target/ARC/ARCInstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARC/ARCInstrFormats.td?rev=356200&r1=356199&r2=356200&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARC/ARCInstrFormats.td (original)
+++ llvm/trunk/lib/Target/ARC/ARCInstrFormats.td Thu Mar 14 13:50:54 2019
@@ -55,6 +55,44 @@ def GPR32Reduced : Operand<iAny> {
   let DecoderMethod = "DecodeGBR32ShortRegister";
 }
 
+// Helper classes for load/store instructions
+class DataSizeMode<bits<2> mode, string instSfx, string asmSfx> {
+  bits<2> Value = mode;
+  string  InstSuffix = instSfx;
+  string  AsmSuffix  = asmSfx;
+}
+class ExtMode<bit mode, string instSfx, string asmSfx> {
+  bit     Value = mode;
+  string  InstSuffix = instSfx;
+  string  AsmSuffix  = asmSfx;
+}
+
+class AddrMode<bits<2> mode, string instSfx, string asmSfx> {
+  bits<2> Value = mode;
+  string  InstSuffix = instSfx;
+  string  AsmSuffix  = asmSfx;
+}
+
+class CacheMode<bit mode, string instSfx, string asmSfx> {
+  bit     Value = mode;
+  string  InstSuffix = instSfx;
+  string  AsmSuffix  = asmSfx;
+}
+
+def ByteSM : DataSizeMode<0b01, "B", "b">;
+def HalfSM : DataSizeMode<0b10, "H", "h">;
+def WordSM : DataSizeMode<0b00,  "",  "">;
+
+def NoEM      : ExtMode<0,   "",   "">;
+def SignedEM  : ExtMode<1, "_X", ".x">;
+
+def NoAM      : AddrMode<0b00, "", "">;
+def PreIncAM  : AddrMode<0b01, "_AW", ".aw">;
+def PostIncAM : AddrMode<0b10, "_AB", ".ab">;
+
+def NoCC       : CacheMode<0b0,    "",    "">;
+def UncachedCC : CacheMode<0b1, "_DI", ".di">;
+
 class InstARC<int sz, dag outs, dag ins, string asmstr, list<dag> pattern>
     : Instruction, Encoding64 {
 
@@ -64,6 +102,18 @@ class InstARC<int sz, dag outs, dag ins,
   let AsmString = asmstr;
   let Pattern = pattern;
   let Size = sz;
+
+  // Load/Store instruction properties
+  DataSizeMode ZZ = WordSM;
+  ExtMode X = NoEM;
+  AddrMode AA = NoAM;
+  CacheMode DI = NoCC;
+
+  // Field used for relation models
+  string BaseOpcode = "";
+
+  //TSFlags
+  let TSFlags{1-0} = AA.Value;
 }
 
 // ARC pseudo instructions format
@@ -354,6 +404,8 @@ class F32_LD_RS9<bit x, bits<2> aa, bit
   let Inst{8-7} = zz;
   let Inst{6} = x;
   let Inst{5-0} = A;
+
+  let BaseOpcode = "ld_rs9";
 }
 
 class F32_LD_ADDR<bit x, bits<2> aa, bit di, bits<2> zz, dag outs, dag ins,
@@ -363,6 +415,8 @@ class F32_LD_ADDR<bit x, bits<2> aa, bit
 
   let B = addr{14-9};
   let S9 = addr{8-0};
+
+  let BaseOpcode = "ld_rs9";
 }
 
 
@@ -387,6 +441,8 @@ class F32_LD_LIMM<bit x, bit di, bits<2>
   let Inst{6} = x;
   let Inst{5-0} = A;
   let DecoderMethod = "DecodeLdLImmInstruction";
+
+  let BaseOpcode = "ld_limm";
 }
 
 // Register + LImm load.  The 32-bit immediate address is in Inst[63-32].
@@ -415,6 +471,8 @@ class F32_LD_RLIMM<bit x, bits<2> aa, bi
   let Inst{11-6} = LImmReg;
   let Inst{5-0} = A;
   let DecoderMethod = "DecodeLdRLImmInstruction";
+
+  let BaseOpcode = "ld_rlimm";
 }
 
 // Register + S9 Store. (B + S9)
@@ -437,6 +495,8 @@ class F32_ST_RS9<bits<2> aa, bit di, bit
   let Inst{4-3} = aa;
   let Inst{2-1} = zz;
   let Inst{0} = 0;
+
+  let BaseOpcode = "st_rs9";
 }
 
 class F32_ST_ADDR<bits<2> aa, bit di, bits<2> zz, dag outs, dag ins,
@@ -446,6 +506,8 @@ class F32_ST_ADDR<bits<2> aa, bit di, bi
 
   let B = addr{14-9};
   let S9 = addr{8-0};
+
+  let BaseOpcode = "st_rs9";
 }
 
 // LImm Store.
@@ -469,6 +531,8 @@ class F32_ST_LIMM<bit di, bits<2> zz, da
   let Inst{2-1} = zz;
   let Inst{0} = 0;
   let DecoderMethod = "DecodeStLImmInstruction";
+
+  let BaseOpcode = "st_limm";
 }
 
 // Compact Move/Load.

Modified: llvm/trunk/lib/Target/ARC/ARCInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARC/ARCInstrInfo.cpp?rev=356200&r1=356199&r2=356200&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARC/ARCInstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/ARC/ARCInstrInfo.cpp Thu Mar 14 13:50:54 2019
@@ -27,6 +27,19 @@ using namespace llvm;
 #include "ARCGenInstrInfo.inc"
 
 #define DEBUG_TYPE "arc-inst-info"
+
+enum AddrIncType {
+    NoAddInc = 0,
+    PreInc   = 1,
+    PostInc  = 2,
+    Scaled   = 3
+};
+
+enum TSFlagsConstants {
+    TSF_AddrModeOff = 0,
+    TSF_AddModeMask = 3
+};
+
 // Pin the vtable to this file.
 void ARCInstrInfo::anchor() {}
 
@@ -395,3 +408,35 @@ unsigned ARCInstrInfo::getInstSizeInByte
   }
   return MI.getDesc().getSize();
 }
+
+bool ARCInstrInfo::isPostIncrement(const MachineInstr &MI) const {
+  const MCInstrDesc &MID = MI.getDesc();
+  const uint64_t F = MID.TSFlags;
+  return ((F >> TSF_AddrModeOff) & TSF_AddModeMask) == PostInc;
+}
+
+bool ARCInstrInfo::isPreIncrement(const MachineInstr &MI) const {
+  const MCInstrDesc &MID = MI.getDesc();
+  const uint64_t F = MID.TSFlags;
+  return ((F >> TSF_AddrModeOff) & TSF_AddModeMask) == PreInc;
+}
+
+bool ARCInstrInfo::getBaseAndOffsetPosition(const MachineInstr &MI,
+                                        unsigned &BasePos,
+                                        unsigned &OffsetPos) const {
+  if (!MI.mayLoad() && !MI.mayStore())
+    return false;
+
+  BasePos = 1;
+  OffsetPos = 2;
+
+  if (isPostIncrement(MI) || isPreIncrement(MI)) {
+    BasePos++;
+    OffsetPos++;
+  }
+
+  if (!MI.getOperand(BasePos).isReg() || !MI.getOperand(OffsetPos).isImm())
+    return false;
+
+  return true;
+}

Modified: llvm/trunk/lib/Target/ARC/ARCInstrInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARC/ARCInstrInfo.h?rev=356200&r1=356199&r2=356200&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARC/ARCInstrInfo.h (original)
+++ llvm/trunk/lib/Target/ARC/ARCInstrInfo.h Thu Mar 14 13:50:54 2019
@@ -81,6 +81,16 @@ public:
   bool
   reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override;
 
+
+  bool isPostIncrement(const MachineInstr &MI) const override;
+
+  // ARC-specific
+  bool isPreIncrement(const MachineInstr &MI) const;
+
+  virtual bool getBaseAndOffsetPosition(const MachineInstr &MI,
+                                        unsigned &BasePos,
+                                        unsigned &OffsetPos) const override;
+
   // Emit code before MBBI to load immediate value into physical register Reg.
   // Returns an iterator to the new instruction.
   MachineBasicBlock::iterator loadImmediate(MachineBasicBlock &MBB,

Modified: llvm/trunk/lib/Target/ARC/ARCInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARC/ARCInstrInfo.td?rev=356200&r1=356199&r2=356200&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARC/ARCInstrInfo.td (original)
+++ llvm/trunk/lib/Target/ARC/ARCInstrInfo.td Thu Mar 14 13:50:54 2019
@@ -787,50 +787,47 @@ let isReturn = 1, isTerminator = 1 in {
 // Load/Store instructions.
 //----------------------------------------------------------------------------
 
+// Filter  class for load/store mappings
+class ArcLdStRel;
+
 // Load instruction variants:
 // Control bits: x, aa, di, zz
 // x - sign extend.
 // aa - incrementing mode. (N/A for LIMM).
 // di - uncached.
 // zz - data size.
-multiclass ArcLdInst<bits<2> zz, string asmop> {
-  let mayLoad = 1 in {
-  def _rs9 : F32_LD_ADDR<0, 0b00, 0, zz,
-                         (outs GPR32:$A), (ins MEMrs9:$addr),
-                         !strconcat(asmop, "\t$A, [$addr]"), []>;
-
-  def _limm : F32_LD_LIMM<0, 0, zz,
-                         (outs GPR32:$A), (ins MEMii:$addr),
-                         !strconcat(asmop, "\t$A, [$addr]"), []>;
-
-  def _rlimm : F32_LD_RLIMM<0, 0b00, 0, zz,
-                           (outs GPR32:$A), (ins MEMrlimm:$addr),
-                           !strconcat(asmop, "\t$A, [$addr]"), []>;
-
-  def _X_rs9 : F32_LD_ADDR<1, 0b00, 0, zz,
-                         (outs GPR32:$A), (ins MEMrs9:$addr),
-                         !strconcat(asmop, ".x\t$A, [$addr]"), []>;
-
-  def _X_limm : F32_LD_LIMM<1, 0, zz,
-                         (outs GPR32:$A), (ins MEMii:$addr),
-                         !strconcat(asmop, ".x\t$A, [$addr]"), []>;
-
-  def _X_rlimm : F32_LD_RLIMM<1, 0b00, 0, zz,
-                           (outs GPR32:$A), (ins MEMrlimm:$addr),
-                           !strconcat(asmop, ".x\t$A, [$addr]"), []>;
-
-  def _AB_rs9 : F32_LD_RS9<0, 0b10, 0, zz,
-                      (outs GPR32:$addrout, GPR32:$A),
-                      (ins GPR32:$B, immS<9>:$S9),
-                      !strconcat(asmop, ".ab\t$A, [$B,$S9]"), []>
-    { let Constraints = "$addrout = $B"; }
+multiclass ArcLdInst<DataSizeMode zz, ExtMode x, CacheMode di, string asmop> {
+  let mayLoad = 1, ZZ = zz, X = x, DI = di in {
+    def _rs9: F32_LD_ADDR<x.Value, NoAM.Value, di.Value, zz.Value,
+			   (outs GPR32:$A), (ins MEMrs9:$addr),
+			   !strconcat(asmop, "\t$A, [$addr]"), []>, ArcLdStRel;
+
+    def _limm: F32_LD_LIMM<x.Value, di.Value, zz.Value,
+			   (outs GPR32:$A), (ins MEMii:$addr),
+			   !strconcat(asmop, "\t$A, [$addr]"), []>, ArcLdStRel;
+
+    def _rlimm: F32_LD_RLIMM<x.Value, NoAM.Value, di.Value, zz.Value,
+			     (outs GPR32:$A), (ins MEMrlimm:$addr),
+			     !strconcat(asmop, "\t$A, [$addr]"), []>, ArcLdStRel;
+
+    foreach aa = [PreIncAM, PostIncAM] in {
+      def aa.InstSuffix#_rs9: F32_LD_RS9<x.Value, aa.Value, di.Value, zz.Value,
+					  (outs GPR32:$A, GPR32:$addrout),
+					  (ins GPR32:$B, immS<9>:$S9),
+					  asmop#aa.AsmSuffix#"\t$A, [$B,$S9]", []>, ArcLdStRel
+			       { let Constraints = "$addrout = $B"; let AA = aa; }
+    }
+  }
+}
+
+foreach di = [NoCC, UncachedCC] in {
+  defm LD#di.InstSuffix : ArcLdInst<WordSM, NoEM, di, "ld"#di.AsmSuffix>;
+  foreach zz = [ByteSM, HalfSM] in {
+    foreach x = [NoEM, SignedEM] in {
+      defm LD#zz.InstSuffix#x.InstSuffix#di.InstSuffix : ArcLdInst<zz, x, di, "ld"#zz.AsmSuffix#x.AsmSuffix#di.AsmSuffix>;
+    }
   }
 }
-                         
-// Load instruction definitions.
-defm LD  : ArcLdInst<0b00, "ld">;
-defm LDH : ArcLdInst<0b10, "ldh">;
-defm LDB : ArcLdInst<0b01, "ldb">;
 
 // Load instruction patterns.
 // 32-bit loads.
@@ -872,25 +869,32 @@ def : Pat<(sextloadi8 AddrModeS9:$addr),
 // aa - incrementing mode. (N/A for LIMM).
 // di - uncached.
 // zz - data size.
-multiclass ArcStInst<bits<2> zz, string asmop> {
-  let mayStore = 1 in {
-  def _rs9  : F32_ST_ADDR<0b00, 0, zz, (outs), (ins GPR32:$C, MEMrs9:$addr),
-                         !strconcat(asmop, "\t$C, [$addr]"), []>;
-
-  def _limm : F32_ST_LIMM<0, zz, (outs), (ins GPR32:$C, MEMii:$addr),
-                         !strconcat(asmop, "\t$C, [$addr]"), []>;
-
-  def _AW_rs9 : F32_ST_RS9<0b01, 0, zz, (outs GPR32:$addrout),
-                      (ins GPR32:$C, GPR32:$B, immS<9>:$S9),
-                      !strconcat(asmop, ".aw\t$C, [$B,$S9]"), []>
-    { let Constraints = "$addrout = $B"; }
+multiclass ArcStInst<DataSizeMode zz, CacheMode di, string asmop> {
+  let mayStore = 1, ZZ = zz, DI = di in {
+    def _rs9: F32_ST_ADDR<NoAM.Value, di.Value, zz.Value,
+			   (outs), (ins GPR32:$C, MEMrs9:$addr),
+			   !strconcat(asmop, "\t$C, [$addr]"), []>, ArcLdStRel;
+
+    def _limm: F32_ST_LIMM<di.Value, zz.Value,
+			   (outs), (ins GPR32:$C, MEMii:$addr),
+			   !strconcat(asmop, "\t$C, [$addr]"), []>, ArcLdStRel;
+
+
+    foreach aa = [PreIncAM, PostIncAM] in {
+      def aa.InstSuffix#_rs9: F32_ST_RS9<aa.Value, di.Value, zz.Value,
+					  (outs GPR32:$addrout),
+					  (ins GPR32:$C, GPR32:$B, immS<9>:$S9),
+					  asmop#aa.AsmSuffix#"\t$C, [$B,$S9]", []>, ArcLdStRel
+			       { let Constraints = "$addrout = $B"; let AA = aa; }
+    }
   }
 }
 
-// Store instruction definitions.
-defm ST  : ArcStInst<0b00, "st">;
-defm STH : ArcStInst<0b10, "sth">;
-defm STB : ArcStInst<0b01, "stb">;
+foreach di = [NoCC, UncachedCC] in {
+  foreach zz = [ByteSM, HalfSM, WordSM] in {
+      defm ST#zz.InstSuffix#di.InstSuffix : ArcStInst<zz, di, "st"#zz.AsmSuffix#di.AsmSuffix>;
+  }
+}
 
 // Store instruction patterns.
 // 32-bit stores
@@ -911,3 +915,10 @@ def : Pat<(truncstorei8 i32:$C, AddrMode
 def : Pat<(truncstorei8 i32:$C, AddrModeImm:$addr),
           (STB_limm i32:$C, AddrModeImm:$addr)>;
 
+def getPostIncOpcode : InstrMapping {
+  let FilterClass = "ArcLdStRel";
+  let RowFields = [ "BaseOpcode", "ZZ", "DI", "X"];
+  let ColFields = [ "AA" ];
+  let KeyCol = [ "NoAM" ];
+  let ValueCols = [["PostIncAM"]];
+}

Modified: llvm/trunk/test/MC/Disassembler/ARC/ldst.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARC/ldst.txt?rev=356200&r1=356199&r2=356200&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/ARC/ldst.txt (original)
+++ llvm/trunk/test/MC/Disassembler/ARC/ldst.txt Thu Mar 14 13:50:54 2019
@@ -45,3 +45,50 @@
 # CHECK: st %r7, [63920]
 0x00 0x1e 0xc0 0x71 0x00 0x00 0xb0 0xf9
 
+# CHECK: ldb.ab	%r1, [%r0,1]
+0x01 0x10 0x81 0x04
+
+# CHECK: stb.ab	%r2, [%r0,1]
+0x01 0x18 0x92 0x00
+
+# CHECK: ldh.ab  %r3, [%r0,12]
+0x0C 0x10 0x03 0x05
+
+# CHECK: sth.ab  %r4, [%r0,18]
+0x12 0x18 0x14 0x01
+
+# CHECK: ld.ab   %r5, [%r2,128]
+0x80 0x12 0x05 0x04
+
+# CHECK: st.ab   %r6, [%r2,64]
+0x40 0x1A 0x90 0x01
+
+# CHECK: ldb.aw	%r7, [%r0,1]
+0x01 0x10 0x87 0x02
+
+# CHECK: stb.aw	%r8, [%r0,1]
+0x01 0x18 0x0A 0x02
+
+# CHECK: ldh.aw  %r3, [%r0,12]
+0x0C 0x10 0x03 0x03
+
+# CHECK: sth.aw  %r3, [%r0,18]
+0x12 0x18 0xCC 0x00
+
+# CHECK: ld.aw   %r6, [%r2,128]
+0x80 0x12 0x06 0x02
+
+# CHECK: st.aw   %r6, [%r2,64]
+0x40 0x1A 0x88 0x01
+
+# CHECK: ld.aw   %r6, [%r2,128]
+0x80 0x12 0x06 0x02
+
+# CHECK: st.aw   %r6, [%r2,64]
+0x40 0x1A 0x88 0x01
+
+# CHECK: ldb.x.di.aw %r0, [%r8,8]
+0x08 0x10 0xC0 0x1A
+
+# CHECK: stb.di.ab   %r0, [%r9,64]
+0x40 0x19 0x32 0x10




More information about the llvm-commits mailing list