Move the ARM reloc constants to Support/ELF.h
[oota-llvm.git] / lib / Target / ARM / ARMBaseInstrInfo.cpp
index f61dfb76292cb73ab101d3880d3db4b94b9a7ae6..cb9c11295bcbddfe649d9d37aef31a9de6f3154c 100644 (file)
@@ -197,26 +197,29 @@ ARMBaseInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
   return NewMIs[0];
 }
 
-bool
-ARMBaseInstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
-                                        MachineBasicBlock::iterator MI,
-                                        const std::vector<CalleeSavedInfo> &CSI,
-                                        const TargetRegisterInfo *TRI) const {
-  if (CSI.empty())
-    return false;
-
+void
+ARMBaseInstrInfo::emitPushInst(MachineBasicBlock &MBB, 
+                MachineBasicBlock::iterator MI,
+                const std::vector<CalleeSavedInfo> &CSI, unsigned Opc,
+                bool(*Func)(unsigned, bool)) const {
+  MachineFunction &MF = *MBB.getParent();
   DebugLoc DL;
   if (MI != MBB.end()) DL = MI->getDebugLoc();
 
-  for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
-    unsigned Reg = CSI[i].getReg();
-    bool isKill = true;
-
+  MachineInstrBuilder MIB = BuildMI(MF, DL, get(Opc));
+  MIB.addReg(ARM::SP, getDefRegState(true));
+  MIB.addReg(ARM::SP);
+  AddDefaultPred(MIB);
+  bool NumRegs = false;
+  for (unsigned i = CSI.size(); i != 0; --i) {
+    unsigned Reg = CSI[i-1].getReg();
+    if (!(Func)(Reg, Subtarget.isTargetDarwin())) continue;
+    
     // Add the callee-saved register as live-in unless it's LR and
     // @llvm.returnaddress is called. If LR is returned for @llvm.returnaddress
     // then it's already added to the function and entry block live-in sets.
+    bool isKill = true;
     if (Reg == ARM::LR) {
-      MachineFunction &MF = *MBB.getParent();
       if (MF.getFrameInfo()->isReturnAddressTaken() &&
           MF.getRegInfo().isLiveIn(Reg))
         isKill = false;
@@ -224,16 +227,99 @@ ARMBaseInstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
 
     if (isKill)
       MBB.addLiveIn(Reg);
+    
+    NumRegs = true;
+    MIB.addReg(Reg, getKillRegState(isKill));
+  }
+  
+  // It's illegal to emit push instruction without operands.
+  if (NumRegs)
+    MBB.insert(MI, &*MIB);
+  else
+    MF.DeleteMachineInstr(MIB);        
+}
+
+bool
+ARMBaseInstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
+                                        MachineBasicBlock::iterator MI,
+                                        const std::vector<CalleeSavedInfo> &CSI,
+                                        const TargetRegisterInfo *TRI) const {
+  if (CSI.empty())
+    return false;
+
+  MachineFunction &MF = *MBB.getParent();
+  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
+  DebugLoc DL = MI->getDebugLoc();
+  
+  unsigned PushOpc = AFI->isThumbFunction() ? ARM::t2STMDB_UPD : ARM::STMDB_UPD;
+  unsigned FltOpc = ARM::VSTMDDB_UPD;
+  emitPushInst(MBB, MI, CSI, PushOpc, &isARMArea1Register);
+  emitPushInst(MBB, MI, CSI, PushOpc, &isARMArea2Register);
+  emitPushInst(MBB, MI, CSI, FltOpc, &isARMArea3Register);
+
+  return true;
+}
+
+void
+ARMBaseInstrInfo::emitPopInst(MachineBasicBlock &MBB, 
+                MachineBasicBlock::iterator MI,
+                const std::vector<CalleeSavedInfo> &CSI, unsigned Opc,
+                bool isVarArg, bool(*Func)(unsigned, bool)) const {
+  
+  MachineFunction &MF = *MBB.getParent();
+  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
+  DebugLoc DL = MI->getDebugLoc();
+  
+  MachineInstrBuilder MIB = BuildMI(MF, DL, get(Opc));
+  MIB.addReg(ARM::SP, getDefRegState(true));
+  MIB.addReg(ARM::SP);
+  AddDefaultPred(MIB);
+  bool NumRegs = false;
+  for (unsigned i = CSI.size(); i != 0; --i) {
+    unsigned Reg = CSI[i-1].getReg();
+    if (!(Func)(Reg, Subtarget.isTargetDarwin())) continue;
+
+    if (Reg == ARM::LR && !isVarArg) {
+      Reg = ARM::PC;
+      unsigned Opc = AFI->isThumbFunction() ? ARM::t2LDMIA_RET : ARM::LDMIA_RET;
+      (*MIB).setDesc(get(Opc));
+      MI = MBB.erase(MI);
+    }
 
-    // Insert the spill to the stack frame. The register is killed at the spill
-    //
-    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
-    storeRegToStackSlot(MBB, MI, Reg, isKill,
-                        CSI[i].getFrameIdx(), RC, TRI);
+    MIB.addReg(Reg, RegState::Define);
+    NumRegs = true;
   }
+    
+  // It's illegal to emit pop instruction without operands.
+  if (NumRegs)
+    MBB.insert(MI, &*MIB);
+  else
+    MF.DeleteMachineInstr(MIB);
+}
+
+bool
+ARMBaseInstrInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
+                                        MachineBasicBlock::iterator MI,
+                                        const std::vector<CalleeSavedInfo> &CSI,
+                                        const TargetRegisterInfo *TRI) const {
+  if (CSI.empty())
+    return false;
+  
+  MachineFunction &MF = *MBB.getParent();
+  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
+  bool isVarArg = AFI->getVarArgsRegSaveSize() > 0;
+  DebugLoc DL = MI->getDebugLoc();
+  
+  unsigned PopOpc = AFI->isThumbFunction() ? ARM::t2LDMIA_UPD : ARM::LDMIA_UPD;
+  unsigned FltOpc = ARM::VLDMDIA_UPD;
+  emitPopInst(MBB, MI, CSI, FltOpc, isVarArg, &isARMArea3Register);
+  emitPopInst(MBB, MI, CSI, PopOpc, isVarArg, &isARMArea2Register);
+  emitPopInst(MBB, MI, CSI, PopOpc, isVarArg, &isARMArea1Register);
+
   return true;
 }
 
+
 // Branch analysis.
 bool
 ARMBaseInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
@@ -1571,9 +1657,9 @@ bool ARMBaseInstrInfo::FoldImmediate(MachineInstr *UseMI,
     return false;
 
   unsigned UseOpc = UseMI->getOpcode();
-  unsigned NewUseOpc;
+  unsigned NewUseOpc = 0;
   uint32_t ImmVal = (uint32_t)DefMI->getOperand(1).getImm();
-  uint32_t SOImmValV1, SOImmValV2;
+  uint32_t SOImmValV1 = 0, SOImmValV2 = 0;
   bool Commute = false;
   switch (UseOpc) {
   default: return false;
@@ -2195,7 +2281,7 @@ int ARMBaseInstrInfo::getInstrLatency(const InstrItineraryData *ItinData,
   case ARM::VSTMQIA:
   case ARM::VSTMQDB:
     return 2;
-  }  
+  }
 }
 
 bool ARMBaseInstrInfo::