add isTerminatortto b and bcond
[oota-llvm.git] / lib / Target / ARM / ARMRegisterInfo.cpp
index 18e273134c525fcb78bdca84e33a73f9648b0a87..b313d548578e2bfef16e6a73732f257ac702129e 100644 (file)
@@ -31,9 +31,8 @@ void ARMRegisterInfo::
 storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
                     unsigned SrcReg, int FI,
                     const TargetRegisterClass *RC) const {
-  // On the order of operands here: think "[FI + 0] = SrcReg".
   assert (RC == ARM::IntRegsRegisterClass);
-  BuildMI(MBB, I, ARM::str, 3).addFrameIndex(FI).addImm(0).addReg(SrcReg);
+  BuildMI(MBB, I, ARM::str, 3).addReg(SrcReg).addImm(0).addFrameIndex(FI);
 }
 
 void ARMRegisterInfo::
@@ -41,15 +40,24 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
                      unsigned DestReg, int FI,
                      const TargetRegisterClass *RC) const {
   assert (RC == ARM::IntRegsRegisterClass);
-  BuildMI(MBB, I, ARM::ldr, 2, DestReg).addFrameIndex(FI).addImm(0);
+  BuildMI(MBB, I, ARM::ldr, 2, DestReg).addImm(0).addFrameIndex(FI);
 }
 
 void ARMRegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
                                      MachineBasicBlock::iterator I,
                                      unsigned DestReg, unsigned SrcReg,
                                      const TargetRegisterClass *RC) const {
-  assert (RC == ARM::IntRegsRegisterClass);
-  BuildMI(MBB, I, ARM::movrr, 1, DestReg).addReg(SrcReg);
+  assert(RC == ARM::IntRegsRegisterClass ||
+         RC == ARM::FPRegsRegisterClass  ||
+         RC == ARM::DFPRegsRegisterClass);
+
+  if (RC == ARM::IntRegsRegisterClass)
+    BuildMI(MBB, I, ARM::MOV, 3, DestReg).addReg(SrcReg).addImm(0)
+      .addImm(ARMShift::LSL);
+  else if (RC == ARM::FPRegsRegisterClass)
+    BuildMI(MBB, I, ARM::FCPYS, 1, DestReg).addReg(SrcReg);
+  else
+    BuildMI(MBB, I, ARM::FCPYD, 1, DestReg).addReg(SrcReg);
 }
 
 MachineInstr *ARMRegisterInfo::foldMemoryOperand(MachineInstr* MI,
@@ -59,13 +67,21 @@ MachineInstr *ARMRegisterInfo::foldMemoryOperand(MachineInstr* MI,
 }
 
 const unsigned* ARMRegisterInfo::getCalleeSaveRegs() const {
-  static const unsigned CalleeSaveRegs[] = { 0 };
+  static const unsigned CalleeSaveRegs[] = {
+    ARM::R4,  ARM::R5, ARM::R6,  ARM::R7,
+    ARM::R8,  ARM::R9, ARM::R10, ARM::R11,
+    ARM::R14, 0
+  };
   return CalleeSaveRegs;
 }
 
 const TargetRegisterClass* const *
 ARMRegisterInfo::getCalleeSaveRegClasses() const {
-  static const TargetRegisterClass * const CalleeSaveRegClasses[] = { 0 };
+  static const TargetRegisterClass * const CalleeSaveRegClasses[] = {
+    &ARM::IntRegsRegClass, &ARM::IntRegsRegClass, &ARM::IntRegsRegClass, &ARM::IntRegsRegClass,
+    &ARM::IntRegsRegClass, &ARM::IntRegsRegClass, &ARM::IntRegsRegClass, &ARM::IntRegsRegClass,
+    &ARM::IntRegsRegClass, 0
+  };
   return CalleeSaveRegClasses;
 }
 
@@ -77,17 +93,82 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
 
 void
 ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const {
-  assert(0 && "Not Implemented");
+  MachineInstr &MI = *II;
+  MachineBasicBlock &MBB = *MI.getParent();
+  MachineFunction &MF = *MBB.getParent();
+
+  assert (MI.getOpcode() == ARM::ldr ||
+         MI.getOpcode() == ARM::str ||
+         MI.getOpcode() == ARM::lea_addri);
+
+  unsigned FrameIdx = 2;
+  unsigned OffIdx = 1;
+
+  int FrameIndex = MI.getOperand(FrameIdx).getFrameIndex();
+
+  int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
+               MI.getOperand(OffIdx).getImmedValue();
+
+  unsigned StackSize = MF.getFrameInfo()->getStackSize();
+
+  Offset += StackSize;
+
+  assert (Offset >= 0);
+  if (Offset < 4096) {
+    // Replace the FrameIndex with r13
+    MI.getOperand(FrameIdx).ChangeToRegister(ARM::R13, false);
+    // Replace the ldr offset with Offset
+    MI.getOperand(OffIdx).ChangeToImmediate(Offset);
+  } else {
+    // Insert a set of r12 with the full address
+    // r12 = r13 + offset
+    MachineBasicBlock *MBB2 = MI.getParent();
+    BuildMI(*MBB2, II, ARM::ADD, 4, ARM::R12).addReg(ARM::R13).addImm(Offset)
+           .addImm(0).addImm(ARMShift::LSL);
+
+    // Replace the FrameIndex with r12
+    MI.getOperand(FrameIdx).ChangeToRegister(ARM::R12, false);
+  }
 }
 
 void ARMRegisterInfo::
 processFunctionBeforeFrameFinalized(MachineFunction &MF) const {}
 
 void ARMRegisterInfo::emitPrologue(MachineFunction &MF) const {
+  MachineBasicBlock &MBB = MF.front();
+  MachineBasicBlock::iterator MBBI = MBB.begin();
+  MachineFrameInfo  *MFI = MF.getFrameInfo();
+  int           NumBytes = (int) MFI->getStackSize();
+
+  if (MFI->hasCalls()) {
+    // We reserve argument space for call sites in the function immediately on
+    // entry to the current function.  This eliminates the need for add/sub
+    // brackets around call sites.
+    NumBytes += MFI->getMaxCallFrameSize();
+  }
+
+  // Align to 8 bytes
+  NumBytes = ((NumBytes + 7) / 8) * 8;
+
+  MFI->setStackSize(NumBytes);
+
+  //sub sp, sp, #NumBytes
+  BuildMI(MBB, MBBI, ARM::SUB, 4, ARM::R13).addReg(ARM::R13).addImm(NumBytes)
+         .addImm(0).addImm(ARMShift::LSL);
 }
 
 void ARMRegisterInfo::emitEpilogue(MachineFunction &MF,
                                   MachineBasicBlock &MBB) const {
+  MachineBasicBlock::iterator MBBI = prior(MBB.end());
+  assert(MBBI->getOpcode() == ARM::bx &&
+         "Can only insert epilog into returning blocks");
+
+  MachineFrameInfo *MFI = MF.getFrameInfo();
+  int          NumBytes = (int) MFI->getStackSize();
+
+  //add sp, sp, #NumBytes
+  BuildMI(MBB, MBBI, ARM::ADD, 4, ARM::R13).addReg(ARM::R13).addImm(NumBytes)
+         .addImm(0).addImm(ARMShift::LSL);
 }
 
 unsigned ARMRegisterInfo::getRARegister() const {