- Reorg Thumb load / store instructions. Combine each rr and ri pair of
authorEvan Cheng <evan.cheng@apple.com>
Tue, 23 Jan 2007 22:59:13 +0000 (22:59 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Tue, 23 Jan 2007 22:59:13 +0000 (22:59 +0000)
  instructions into one (e.g. tLDRrr, tLDRri -> tLDR).
- Thumb ldrsb and ldrsh only have the [reg, reg] address format. If the
  address is not an add, materialize a 0 immediate into a register and use
  it as the offset field.

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

lib/Target/ARM/ARMAsmPrinter.cpp
lib/Target/ARM/ARMISelDAGToDAG.cpp
lib/Target/ARM/ARMInstrThumb.td

index bd87539aa0b04e51c56e780cb270418afa4b3168..1ca8bfd75cfea9b8a99131c2e441b5527853d42b 100644 (file)
@@ -98,9 +98,9 @@ namespace {
     void printThumbAddrModeRROperand(const MachineInstr *MI, int OpNo);
     void printThumbAddrModeRI5Operand(const MachineInstr *MI, int OpNo,
                                       unsigned Scale);
-    void printThumbAddrModeRI5_1Operand(const MachineInstr *MI, int OpNo);
-    void printThumbAddrModeRI5_2Operand(const MachineInstr *MI, int OpNo);
-    void printThumbAddrModeRI5_4Operand(const MachineInstr *MI, int OpNo);
+    void printThumbAddrModeS1Operand(const MachineInstr *MI, int OpNo);
+    void printThumbAddrModeS2Operand(const MachineInstr *MI, int OpNo);
+    void printThumbAddrModeS4Operand(const MachineInstr *MI, int OpNo);
     void printThumbAddrModeSPOperand(const MachineInstr *MI, int OpNo);
     void printCCOperand(const MachineInstr *MI, int opNum);
     void printPCLabel(const MachineInstr *MI, int opNum);
@@ -518,7 +518,7 @@ void
 ARMAsmPrinter::printThumbAddrModeRI5Operand(const MachineInstr *MI, int Op,
                                             unsigned Scale) {
   const MachineOperand &MO1 = MI->getOperand(Op);
-  const MachineOperand &MO2 = MI->getOperand(Op+1);
+  const MachineOperand &MO2 = MI->getOperand(Op+2);
 
   if (!MO1.isRegister()) {   // FIXME: This is for CP entries, but isn't right.
     printOperand(MI, Op);
@@ -535,16 +535,25 @@ ARMAsmPrinter::printThumbAddrModeRI5Operand(const MachineInstr *MI, int Op,
 }
 
 void
-ARMAsmPrinter::printThumbAddrModeRI5_1Operand(const MachineInstr *MI, int Op) {
-  printThumbAddrModeRI5Operand(MI, Op, 1);
+ARMAsmPrinter::printThumbAddrModeS1Operand(const MachineInstr *MI, int Op) {
+  if (MI->getOperand(Op+1).getReg())
+    printThumbAddrModeRROperand(MI, Op);
+  else
+    printThumbAddrModeRI5Operand(MI, Op, 1);
 }
 void
-ARMAsmPrinter::printThumbAddrModeRI5_2Operand(const MachineInstr *MI, int Op) {
-  printThumbAddrModeRI5Operand(MI, Op, 2);
+ARMAsmPrinter::printThumbAddrModeS2Operand(const MachineInstr *MI, int Op) {
+  if (MI->getOperand(Op+1).getReg())
+    printThumbAddrModeRROperand(MI, Op);
+  else
+    printThumbAddrModeRI5Operand(MI, Op, 2);
 }
 void
-ARMAsmPrinter::printThumbAddrModeRI5_4Operand(const MachineInstr *MI, int Op) {
-  printThumbAddrModeRI5Operand(MI, Op, 4);
+ARMAsmPrinter::printThumbAddrModeS4Operand(const MachineInstr *MI, int Op) {
+  if (MI->getOperand(Op+1).getReg())
+    printThumbAddrModeRROperand(MI, Op);
+  else
+    printThumbAddrModeRI5Operand(MI, Op, 4);
 }
 
 void ARMAsmPrinter::printThumbAddrModeSPOperand(const MachineInstr *MI,int Op) {
index f5f4599b5ce890d007cf5e8dafd55bd03194bbf3..42fbcfd670f45bc44a26e4bf1c49a45db6c57721 100644 (file)
@@ -71,12 +71,12 @@ public:
 
   bool SelectThumbAddrModeRR(SDOperand Op, SDOperand N, SDOperand &Base,
                              SDOperand &Offset);
-  bool SelectThumbAddrModeRI5_1(SDOperand Op, SDOperand N, SDOperand &Base,
-                                SDOperand &Offset);
-  bool SelectThumbAddrModeRI5_2(SDOperand Op, SDOperand N, SDOperand &Base,
-                                SDOperand &Offset);
-  bool SelectThumbAddrModeRI5_4(SDOperand Op, SDOperand N, SDOperand &Base,
-                                SDOperand &Offset);
+  bool SelectThumbAddrModeS1(SDOperand Op, SDOperand N, SDOperand &Base,
+                             SDOperand &Offset, SDOperand &OffImm);
+  bool SelectThumbAddrModeS2(SDOperand Op, SDOperand N, SDOperand &Base,
+                             SDOperand &Offset, SDOperand &OffImm);
+  bool SelectThumbAddrModeS4(SDOperand Op, SDOperand N, SDOperand &Base,
+                             SDOperand &Offset, SDOperand &OffImm);
   bool SelectThumbAddrModeSP(SDOperand Op, SDOperand N, SDOperand &Base,
                              SDOperand &Offset);
 
@@ -340,8 +340,16 @@ bool ARMDAGToDAGISel::SelectAddrModePC(SDOperand Op, SDOperand N,
 
 bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDOperand Op, SDOperand N,
                                             SDOperand &Base, SDOperand &Offset){
-  if (N.getOpcode() != ISD::ADD)
-    return false;
+  if (N.getOpcode() != ISD::ADD) {
+    Base = N;
+    // We must materialize a zero in a reg! Returning an constant here won't
+    // work since its node is -1 so it won't get added to the selection queue.
+    // Explicitly issue a tMOVri8 node!
+    Offset = SDOperand(CurDAG->getTargetNode(ARM::tMOVri8, MVT::i32,
+                                    CurDAG->getTargetConstant(0, MVT::i32)), 0);
+    return true;
+  }
+
   Base = N.getOperand(0);
   Offset = N.getOperand(1);
   return true;
@@ -349,13 +357,15 @@ bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDOperand Op, SDOperand N,
 
 static bool SelectThumbAddrModeRI5(SDOperand N, unsigned Scale,
                                    TargetLowering &TLI, SelectionDAG *CurDAG,
-                                   SDOperand &Base, SDOperand &Offset) {
+                                   SDOperand &Base, SDOperand &Offset,
+                                   SDOperand &OffImm) {
   if (N.getOpcode() == ISD::FrameIndex)
     return false;
     
   if (N.getOpcode() != ISD::ADD) {
     Base = (N.getOpcode() == ARMISD::Wrapper) ? N.getOperand(0) : N;
-    Offset = CurDAG->getTargetConstant(0, MVT::i32);
+    Offset = CurDAG->getRegister(0, MVT::i32);
+    OffImm = CurDAG->getTargetConstant(0, MVT::i32);
     return true;
   }
 
@@ -366,28 +376,35 @@ static bool SelectThumbAddrModeRI5(SDOperand N, unsigned Scale,
       RHSC /= Scale;
       if (RHSC >= 0 && RHSC < 32) {
         Base = N.getOperand(0);
-        Offset = CurDAG->getTargetConstant(RHSC, MVT::i32);
+        Offset = CurDAG->getRegister(0, MVT::i32);
+        OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32);
         return true;
       }
     }
   }
 
-  return false;
+  Base = N.getOperand(0);
+  Offset = N.getOperand(1);
+  OffImm = CurDAG->getTargetConstant(0, MVT::i32);
+  return true;
 }
 
-bool ARMDAGToDAGISel::SelectThumbAddrModeRI5_1(SDOperand Op, SDOperand N,
-                                            SDOperand &Base, SDOperand &Offset){
-  return SelectThumbAddrModeRI5(N, 1, TLI, CurDAG, Base, Offset);
+bool ARMDAGToDAGISel::SelectThumbAddrModeS1(SDOperand Op, SDOperand N,
+                                            SDOperand &Base, SDOperand &Offset,
+                                            SDOperand &OffImm) {
+  return SelectThumbAddrModeRI5(N, 1, TLI, CurDAG, Base, Offset, OffImm);
 }
 
-bool ARMDAGToDAGISel::SelectThumbAddrModeRI5_2(SDOperand Op, SDOperand N,
-                                            SDOperand &Base, SDOperand &Offset){
-  return SelectThumbAddrModeRI5(N, 2, TLI, CurDAG, Base, Offset);
+bool ARMDAGToDAGISel::SelectThumbAddrModeS2(SDOperand Op, SDOperand N,
+                                            SDOperand &Base, SDOperand &Offset,
+                                            SDOperand &OffImm) {
+  return SelectThumbAddrModeRI5(N, 2, TLI, CurDAG, Base, Offset, OffImm);
 }
 
-bool ARMDAGToDAGISel::SelectThumbAddrModeRI5_4(SDOperand Op, SDOperand N,
-                                            SDOperand &Base, SDOperand &Offset){
-  return SelectThumbAddrModeRI5(N, 4, TLI, CurDAG, Base, Offset);
+bool ARMDAGToDAGISel::SelectThumbAddrModeS4(SDOperand Op, SDOperand N,
+                                            SDOperand &Base, SDOperand &Offset,
+                                            SDOperand &OffImm) {
+  return SelectThumbAddrModeRI5(N, 4, TLI, CurDAG, Base, Offset, OffImm);
 }
 
 bool ARMDAGToDAGISel::SelectThumbAddrModeSP(SDOperand Op, SDOperand N,
index 58cef041886fcf953c9b88037d9c3f7f79025285..fa7afea976dae0271b6231bc5395551500d45f3c 100644 (file)
@@ -114,22 +114,31 @@ def t_addrmode_rr : Operand<i32>,
   let MIOperandInfo = (ops GPR:$base, GPR:$offsreg);
 }
 
-// t_addrmode_ri5_{1|2|4} := reg + imm5 * {1|2|4}
+// t_addrmode_s4 := reg + reg
+//                  reg + imm5 * 4
 //
-def t_addrmode_ri5_1 : Operand<i32>,
-                       ComplexPattern<i32, 2, "SelectThumbAddrModeRI5_1", []> {
-  let PrintMethod = "printThumbAddrModeRI5_1Operand";
-  let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
+def t_addrmode_s4 : Operand<i32>,
+                    ComplexPattern<i32, 3, "SelectThumbAddrModeS4", []> {
+  let PrintMethod = "printThumbAddrModeS4Operand";
+  let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
 }
-def t_addrmode_ri5_2 : Operand<i32>,
-                       ComplexPattern<i32, 2, "SelectThumbAddrModeRI5_2", []> {
-  let PrintMethod = "printThumbAddrModeRI5_2Operand";
-  let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
+
+// t_addrmode_s2 := reg + reg
+//                  reg + imm5 * 2
+//
+def t_addrmode_s2 : Operand<i32>,
+                    ComplexPattern<i32, 3, "SelectThumbAddrModeS2", []> {
+  let PrintMethod = "printThumbAddrModeS2Operand";
+  let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
 }
-def t_addrmode_ri5_4 : Operand<i32>,
-                       ComplexPattern<i32, 2, "SelectThumbAddrModeRI5_4", []> {
-  let PrintMethod = "printThumbAddrModeRI5_4Operand";
-  let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
+
+// t_addrmode_s1 := reg + reg
+//                  reg + imm5
+//
+def t_addrmode_s1 : Operand<i32>,
+                    ComplexPattern<i32, 3, "SelectThumbAddrModeS1", []> {
+  let PrintMethod = "printThumbAddrModeS1Operand";
+  let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
 }
 
 // t_addrmode_sp := sp + imm8 * 4
@@ -191,71 +200,48 @@ let isBranch = 1, isTerminator = 1, noResults = 1, isBarrier = 1 in
 //
 
 let isLoad = 1 in {
-def tLDRri : TI4<(ops GPR:$dst, t_addrmode_ri5_4:$addr),
-                 "ldr $dst, $addr",
-                 [(set GPR:$dst, (load t_addrmode_ri5_4:$addr))]>;
-
-def tLDRrr : TI<(ops GPR:$dst, t_addrmode_rr:$addr),
-                "ldr $dst, $addr",
-                [(set GPR:$dst, (load t_addrmode_rr:$addr))]>;
-// def tLDRpci
-def tLDRspi : TIs<(ops GPR:$dst, t_addrmode_sp:$addr),
-                  "ldr $dst, $addr",
-                  [(set GPR:$dst, (load t_addrmode_sp:$addr))]>;
-
-def tLDRBri : TI1<(ops GPR:$dst, t_addrmode_ri5_1:$addr),
-                  "ldrb $dst, $addr",
-                  [(set GPR:$dst, (zextloadi8 t_addrmode_ri5_1:$addr))]>;
+def tLDR : TI4<(ops GPR:$dst, t_addrmode_s4:$addr),
+               "ldr $dst, $addr",
+               [(set GPR:$dst, (load t_addrmode_s4:$addr))]>;
 
-def tLDRBrr : TI1<(ops GPR:$dst, t_addrmode_rr:$addr),
-                  "ldrb $dst, $addr",
-                  [(set GPR:$dst, (zextloadi8 t_addrmode_rr:$addr))]>;
+def tLDRB : TI1<(ops GPR:$dst, t_addrmode_s1:$addr),
+                "ldrb $dst, $addr",
+                [(set GPR:$dst, (zextloadi8 t_addrmode_s1:$addr))]>;
 
-def tLDRHri : TI2<(ops GPR:$dst, t_addrmode_ri5_2:$addr),
-                  "ldrh $dst, $addr",
-                  [(set GPR:$dst, (zextloadi16 t_addrmode_ri5_2:$addr))]>;
+def tLDRH : TI2<(ops GPR:$dst, t_addrmode_s2:$addr),
+                "ldrh $dst, $addr",
+                [(set GPR:$dst, (zextloadi16 t_addrmode_s2:$addr))]>;
 
-def tLDRHrr : TI2<(ops GPR:$dst, t_addrmode_rr:$addr),
-                  "ldrh $dst, $addr",
-                  [(set GPR:$dst, (zextloadi16 t_addrmode_rr:$addr))]>;
+def tLDRSB : TI1<(ops GPR:$dst, t_addrmode_rr:$addr),
+                 "ldrsb $dst, $addr",
+                 [(set GPR:$dst, (sextloadi8 t_addrmode_rr:$addr))]>;
 
-def tLDRSBrr : TI1<(ops GPR:$dst, t_addrmode_rr:$addr),
-                   "ldrsb $dst, $addr",
-                   [(set GPR:$dst, (sextloadi8 t_addrmode_rr:$addr))]>;
+def tLDRSH : TI2<(ops GPR:$dst, t_addrmode_rr:$addr),
+                 "ldrsh $dst, $addr",
+                 [(set GPR:$dst, (sextloadi16 t_addrmode_rr:$addr))]>;
 
-def tLDRSHrr : TI2<(ops GPR:$dst, t_addrmode_rr:$addr),
-                   "ldrsh $dst, $addr",
-                   [(set GPR:$dst, (sextloadi16 t_addrmode_rr:$addr))]>;
+// def tLDRpci
+def tLDRspi : TIs<(ops GPR:$dst, t_addrmode_sp:$addr),
+                  "ldr $dst, $addr",
+                  [(set GPR:$dst, (load t_addrmode_sp:$addr))]>;
 } // isLoad
 
 let isStore = 1 in {
-def tSTRri : TI4<(ops GPR:$src, t_addrmode_ri5_4:$addr),
-                 "str $src, $addr",
-                 [(store GPR:$src, t_addrmode_ri5_4:$addr)]>;
+def tSTR : TI4<(ops GPR:$src, t_addrmode_s4:$addr),
+               "str $src, $addr",
+               [(store GPR:$src, t_addrmode_s4:$addr)]>;
 
-def tSTRrr : TI<(ops GPR:$src, t_addrmode_rr:$addr),
-                 "str $src, $addr",
-                 [(store GPR:$src, t_addrmode_rr:$addr)]>;
+def tSTRB : TI1<(ops GPR:$src, t_addrmode_s1:$addr),
+                 "strb $src, $addr",
+                 [(truncstorei8 GPR:$src, t_addrmode_s1:$addr)]>;
+
+def tSTRH : TI2<(ops GPR:$src, t_addrmode_s2:$addr),
+                 "strh $src, $addr",
+                 [(truncstorei16 GPR:$src, t_addrmode_s2:$addr)]>;
 
 def tSTRspi : TIs<(ops GPR:$src, t_addrmode_sp:$addr),
                    "str $src, $addr",
                    [(store GPR:$src, t_addrmode_sp:$addr)]>;
-
-def tSTRBri : TI1<(ops GPR:$src, t_addrmode_ri5_1:$addr),
-                   "strb $src, $addr",
-                   [(truncstorei8 GPR:$src, t_addrmode_ri5_1:$addr)]>;
-
-def tSTRBrr : TI1<(ops GPR:$src, t_addrmode_rr:$addr),
-                   "strb $src, $addr",
-                   [(truncstorei8 GPR:$src, t_addrmode_rr:$addr)]>;
-
-def tSTRHri : TI2<(ops GPR:$src, t_addrmode_ri5_2:$addr),
-                   "strh $src, $addr",
-                   [(truncstorei16 GPR:$src, t_addrmode_ri5_1:$addr)]>;
-
-def tSTRHrr : TI2<(ops GPR:$src, t_addrmode_rr:$addr),
-                   "strh $src, $addr",
-                   [(truncstorei16 GPR:$src, t_addrmode_rr:$addr)]>;
 }
 
 //===----------------------------------------------------------------------===//
@@ -491,16 +477,12 @@ def : ThumbV5Pat<(ARMcall texternalsym:$func), (tBLXi texternalsym:$func)>;
 def : ThumbV5Pat<(ARMcall GPR:$dst), (tBLXr GPR:$dst)>;
 
 // zextload i1 -> zextload i8
-def : ThumbPat<(zextloadi1 t_addrmode_ri5_1:$addr),
-               (tLDRBri t_addrmode_ri5_1:$addr)>;
-def : ThumbPat<(zextloadi1 t_addrmode_rr:$addr),
-               (tLDRBri t_addrmode_rr:$addr)>;
+def : ThumbPat<(zextloadi1 t_addrmode_s1:$addr),
+               (tLDRB t_addrmode_s1:$addr)>;
                   
 // truncstore i1 -> truncstore i8
-def : ThumbPat<(truncstorei1 GPR:$src, t_addrmode_ri5_1:$dst), 
-               (tSTRBri GPR:$src, t_addrmode_ri5_1:$dst)>;
-def : ThumbPat<(truncstorei1 GPR:$src, t_addrmode_rr:$dst), 
-               (tSTRBrr GPR:$src, t_addrmode_rr:$dst)>;
+def : ThumbPat<(truncstorei1 GPR:$src, t_addrmode_s1:$dst), 
+               (tSTRB GPR:$src, t_addrmode_s1:$dst)>;
 
 // Large immediate handling.