Clean up Thumb load/store multiple definitions.
authorJim Grosbach <grosbach@apple.com>
Tue, 23 Aug 2011 17:41:15 +0000 (17:41 +0000)
committerJim Grosbach <grosbach@apple.com>
Tue, 23 Aug 2011 17:41:15 +0000 (17:41 +0000)
There is no non-writeback store multiple instruction in Thumb1, so
don't define one. As a result load multiple is the only instantiation of
the multiclass, so refactor that away entirely.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@138338 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMBaseInstrInfo.cpp
lib/Target/ARM/ARMInstrThumb.td
lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp

index 0d49ea9a5546ff5260c33a090637c9f8e6e8a0e6..0e2915fedd2aa23fc264dea78523fcdda85baf19 100644 (file)
@@ -1930,7 +1930,6 @@ ARMBaseInstrInfo::getNumMicroOps(const InstrItineraryData *ItinData,
   case ARM::STMIB_UPD:
   case ARM::tLDMIA:
   case ARM::tLDMIA_UPD:
-  case ARM::tSTMIA:
   case ARM::tSTMIA_UPD:
   case ARM::tPOP_RET:
   case ARM::tPOP:
@@ -2196,7 +2195,6 @@ ARMBaseInstrInfo::getOperandLatency(const InstrItineraryData *ItinData,
   case ARM::STMDA_UPD:
   case ARM::STMDB_UPD:
   case ARM::STMIB_UPD:
-  case ARM::tSTMIA:
   case ARM::tSTMIA_UPD:
   case ARM::tPOP_RET:
   case ARM::tPOP:
index f58cb34e60002acaa6b8732b631644c2c918f9c3..563b0ef3b63098412eed2d45d9a3bc160eff23c3 100644 (file)
@@ -694,44 +694,45 @@ def tSTRspi : T1pIs<(outs), (ins tGPR:$Rt, t_addrmode_sp:$addr), IIC_iStore_i,
 //  Load / store multiple Instructions.
 //
 
-multiclass thumb_ldst_mult<string asm, InstrItinClass itin,
-                           InstrItinClass itin_upd, bits<6> T1Enc,
-                           bit L_bit, string baseOpc> {
-  def IA :
-    T1I<(outs), (ins tGPR:$Rn, pred:$p, reglist:$regs, variable_ops),
-        itin, !strconcat(asm, "${p}\t$Rn, $regs"), []>,
-       T1Encoding<T1Enc> {
-    bits<3> Rn;
-    bits<8> regs;
-    let Inst{10-8} = Rn;
-    let Inst{7-0}  = regs;
-  }
-
-  def IA_UPD :
-    InstTemplate<AddrModeNone, 0, IndexModeNone, Pseudo, GenericDomain, 
-                 "$Rn = $wb", itin_upd>,
-    PseudoInstExpansion<(!cast<Instruction>(!strconcat(baseOpc, "IA"))
-                       tGPR:$Rn, pred:$p, reglist:$regs)> {
-    let Size = 2;
-    let OutOperandList = (outs GPR:$wb);
-    let InOperandList = (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops);
-    let Pattern = [];
-    let isCodeGenOnly = 1;
-    let isPseudo = 1;
-    list<Predicate> Predicates = [IsThumb];
-  }
-}
-
 // These require base address to be written back or one of the loaded regs.
 let neverHasSideEffects = 1 in {
 
 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
-defm tLDM : thumb_ldst_mult<"ldm", IIC_iLoad_m, IIC_iLoad_mu,
-                            {1,1,0,0,1,?}, 1, "tLDM">;
-
+def tLDMIA : T1I<(outs), (ins tGPR:$Rn, pred:$p, reglist:$regs, variable_ops),
+        IIC_iLoad_m, "ldm${p}\t$Rn, $regs", []>, T1Encoding<{1,1,0,0,1,?}> {
+  bits<3> Rn;
+  bits<8> regs;
+  let Inst{10-8} = Rn;
+  let Inst{7-0}  = regs;
+}
+
+// Writeback version is just a pseudo, as there's no encoding difference.
+// Writeback happens iff the base register is not in the destination register
+// list.
+def tLDMIA_UPD :
+    InstTemplate<AddrModeNone, 0, IndexModeNone, Pseudo, GenericDomain,
+                 "$Rn = $wb", IIC_iLoad_mu>,
+    PseudoInstExpansion<(tLDMIA tGPR:$Rn, pred:$p, reglist:$regs)> {
+  let Size = 2;
+  let OutOperandList = (outs GPR:$wb);
+  let InOperandList = (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops);
+  let Pattern = [];
+  let isCodeGenOnly = 1;
+  let isPseudo = 1;
+  list<Predicate> Predicates = [IsThumb];
+}
+
+// There is no non-writeback version of STM for Thumb.
 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
-defm tSTM : thumb_ldst_mult<"stm", IIC_iStore_m, IIC_iStore_mu,
-                            {1,1,0,0,0,?}, 0, "tSTM">;
+def tSTMIA_UPD : T1I<(outs),
+                     (ins tGPR:$Rn, pred:$p, reglist:$regs, variable_ops),
+                     IIC_iStore_mu, "stm${p}\t$Rn!, $regs", []>,
+                     T1Encoding<{1,1,0,0,0,?}> {
+  bits<3> Rn;
+  bits<8> regs;
+  let Inst{10-8} = Rn;
+  let Inst{7-0}  = regs;
+}
 
 } // neverHasSideEffects
 
@@ -739,7 +740,6 @@ def : InstAlias<"ldm${p} $Rn!, $regs",
                 (tLDMIA tGPR:$Rn, pred:$p, reglist:$regs)>,
         Requires<[IsThumb, IsThumb1Only]>;
 
-
 let mayLoad = 1, Uses = [SP], Defs = [SP], hasExtraDefRegAllocReq = 1 in
 def tPOP : T1I<(outs), (ins pred:$p, reglist:$regs, variable_ops),
                IIC_iPop,
@@ -1147,8 +1147,6 @@ def tSUBrr :                    // A8.6.212
                 "sub", "\t$Rd, $Rn, $Rm",
                 [(set tGPR:$Rd, (sub tGPR:$Rn, tGPR:$Rm))]>;
 
-// TODO: A7-96: STMIA - store multiple.
-
 // Sign-extend byte
 def tSXTB :                     // A8.6.222
   T1pIMiscEncode<{0,0,1,0,0,1,?}, (outs tGPR:$Rd), (ins tGPR:$Rm),
index 153f68d62c8f726e87577e9af4787b6747f3a537..2c96eb74ebc7cb9b9d7a482a247ac7484ed6e8cf 100644 (file)
@@ -146,7 +146,7 @@ void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O) {
     return;
   }
 
-  if (Opcode == ARM::tLDMIA || Opcode == ARM::tSTMIA) {
+  if (Opcode == ARM::tLDMIA) {
     bool Writeback = true;
     unsigned BaseReg = MI->getOperand(0).getReg();
     for (unsigned i = 3; i < MI->getNumOperands(); ++i) {
@@ -154,12 +154,7 @@ void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O) {
         Writeback = false;
     }
 
-    if (Opcode == ARM::tLDMIA)
-      O << "\tldm";
-    else if (Opcode == ARM::tSTMIA)
-      O << "\tstm";
-    else
-      llvm_unreachable("Unknown opcode!");
+    O << "\tldm";
 
     printPredicateOperand(MI, 1, O);
     O << '\t' << getRegisterName(BaseReg);