Fix pr4091: Add support for "m" constraint in ARM inline assembly.
[oota-llvm.git] / lib / Target / XCore / XCoreInstrInfo.cpp
index 4d0f42a02082b2940e00f008e807b4fa59cbf2a8..0402f59aa5dc291c6a4e2154475b7746beaf75e5 100644 (file)
@@ -49,7 +49,10 @@ static bool isZeroImm(const MachineOperand &op) {
 /// leave the source and dest operands in the passed parameters.
 ///
 bool XCoreInstrInfo::isMoveInstr(const MachineInstr &MI,
-                                 unsigned &SrcReg, unsigned &DstReg) const {
+                                 unsigned &SrcReg, unsigned &DstReg,
+                                 unsigned &SrcSR, unsigned &DstSR) const {
+  SrcSR = DstSR = 0; // No sub-registers.
+
   // We look for 4 kinds of patterns here:
   // add dst, src, 0
   // sub dst, src, 0
@@ -75,9 +78,9 @@ bool XCoreInstrInfo::isMoveInstr(const MachineInstr &MI,
 /// not, return 0.  This predicate must return 0 if the instruction has
 /// any side effects other than loading from the stack slot.
 unsigned
-XCoreInstrInfo::isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const{
+XCoreInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const{
   int Opcode = MI->getOpcode();
-  if (Opcode == XCore::LDWSP_ru6 || Opcode == XCore::LDWSP_lru6
+  if (Opcode == XCore::LDWFI
   {
     if ((MI->getOperand(1).isFI()) && // is a stack slot
         (MI->getOperand(2).isImm()) &&  // the imm is zero
@@ -96,21 +99,14 @@ XCoreInstrInfo::isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const{
   /// not, return 0.  This predicate must return 0 if the instruction has
   /// any side effects other than storing to the stack slot.
 unsigned
-XCoreInstrInfo::isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const {
+XCoreInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
+                                   int &FrameIndex) const {
   int Opcode = MI->getOpcode();
-  if (Opcode == XCore::STWSP_ru6 || Opcode == XCore::STWSP_lru6) 
+  if (Opcode == XCore::STWFI)
   {
     if ((MI->getOperand(1).isFI()) && // is a stack slot
         (MI->getOperand(2).isImm()) &&  // the imm is zero
-        (isZeroImm(MI->getOperand(2)))) 
-    {
-      FrameIndex = MI->getOperand(1).getIndex();
-      return MI->getOperand(0).getReg();
-    }
-  }
-  else if (Opcode == XCore::STWSP_ru6_2 || Opcode == XCore::STWSP_lru6_2)
-  {
-    if (MI->getOperand(1).isFI())
+        (isZeroImm(MI->getOperand(2))))
     {
       FrameIndex = MI->getOperand(1).getIndex();
       return MI->getOperand(0).getReg();
@@ -126,7 +122,7 @@ XCoreInstrInfo::isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const {
 /// only return true of *all* loads the instruction does are invariant (if it
 /// does multiple loads).
 bool
-XCoreInstrInfo::isInvariantLoad(MachineInstr *MI) const {
+XCoreInstrInfo::isInvariantLoad(const MachineInstr *MI) const {
   // Loads from constants pools and loads from invariant argument slots are
   // invariant
   int Opcode = MI->getOpcode();
@@ -232,8 +228,9 @@ static inline XCore::CondCode GetOppositeBranchCondition(XCore::CondCode CC)
 ///
 bool
 XCoreInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
-                           MachineBasicBlock *&FBB,
-                           SmallVectorImpl<MachineOperand> &Cond) const {
+                              MachineBasicBlock *&FBB,
+                              SmallVectorImpl<MachineOperand> &Cond,
+                              bool AllowModify) const {
   // If the block has no terminators, it just falls into the block after it.
   MachineBasicBlock::iterator I = MBB.end();
   if (I == MBB.begin() || !isUnpredicatedTerminator(--I))
@@ -292,7 +289,8 @@ XCoreInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
       IsBRU(LastInst->getOpcode())) {
     TBB = SecondLastInst->getOperand(0).getMBB();
     I = LastInst;
-    I->eraseFromParent();
+    if (AllowModify)
+      I->eraseFromParent();
     return false;
   }
 
@@ -304,6 +302,8 @@ unsigned
 XCoreInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB,
                              MachineBasicBlock *FBB,
                              const SmallVectorImpl<MachineOperand> &Cond)const{
+  // FIXME there should probably be a DebugLoc argument here
+  DebugLoc dl = DebugLoc::getUnknownLoc();
   // Shouldn't be a fall through.
   assert(TBB && "InsertBranch must not be told to insert a fallthrough");
   assert((Cond.size() == 2 || Cond.size() == 0) &&
@@ -312,11 +312,11 @@ XCoreInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB,
   if (FBB == 0) { // One way branch.
     if (Cond.empty()) {
       // Unconditional branch
-      BuildMI(&MBB, get(XCore::BRFU_lu6)).addMBB(TBB);
+      BuildMI(&MBB, dl, get(XCore::BRFU_lu6)).addMBB(TBB);
     } else {
       // Conditional branch.
       unsigned Opc = GetCondBranchFromCond((XCore::CondCode)Cond[0].getImm());
-      BuildMI(&MBB, get(Opc)).addReg(Cond[1].getReg())
+      BuildMI(&MBB, dl, get(Opc)).addReg(Cond[1].getReg())
                              .addMBB(TBB);
     }
     return 1;
@@ -325,9 +325,9 @@ XCoreInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB,
   // Two-way Conditional branch.
   assert(Cond.size() == 2 && "Unexpected number of components!");
   unsigned Opc = GetCondBranchFromCond((XCore::CondCode)Cond[0].getImm());
-  BuildMI(&MBB, get(Opc)).addReg(Cond[1].getReg())
+  BuildMI(&MBB, dl, get(Opc)).addReg(Cond[1].getReg())
                          .addMBB(TBB);
-  BuildMI(&MBB, get(XCore::BRFU_lu6)).addMBB(FBB);
+  BuildMI(&MBB, dl, get(XCore::BRFU_lu6)).addMBB(FBB);
   return 2;
 }
 
@@ -355,13 +355,18 @@ XCoreInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
 }
 
 bool XCoreInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
-                                     MachineBasicBlock::iterator I,
-                                     unsigned DestReg, unsigned SrcReg,
-                                     const TargetRegisterClass *DestRC,
-                                     const TargetRegisterClass *SrcRC) const {
+                                  MachineBasicBlock::iterator I,
+                                  unsigned DestReg, unsigned SrcReg,
+                                  const TargetRegisterClass *DestRC,
+                                  const TargetRegisterClass *SrcRC) const {
+  DebugLoc DL = DebugLoc::getUnknownLoc();
+  if (I != MBB.end()) DL = I->getDebugLoc();
+
   if (DestRC == SrcRC) {
     if (DestRC == XCore::GRRegsRegisterClass) {
-      BuildMI(MBB, I, get(XCore::ADD_2rus), DestReg).addReg(SrcReg).addImm(0);
+      BuildMI(MBB, I, DL, get(XCore::ADD_2rus), DestReg)
+        .addReg(SrcReg)
+        .addImm(0);
       return true;
     } else {
       return false;
@@ -370,24 +375,31 @@ bool XCoreInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
   
   if (SrcRC == XCore::RRegsRegisterClass && SrcReg == XCore::SP &&
     DestRC == XCore::GRRegsRegisterClass) {
-    BuildMI(MBB, I, get(XCore::LDAWSP_ru6), DestReg).addImm(0).addImm(0);
+    BuildMI(MBB, I, DL, get(XCore::LDAWSP_ru6), DestReg)
+      .addImm(0);
     return true;
   }
   if (DestRC == XCore::RRegsRegisterClass && DestReg == XCore::SP &&
     SrcRC == XCore::GRRegsRegisterClass) {
-    BuildMI(MBB, I, get(XCore::SETSP_1r)).addReg(SrcReg);
+    BuildMI(MBB, I, DL, get(XCore::SETSP_1r))
+      .addReg(SrcReg);
     return true;
   }
   return false;
 }
 
 void XCoreInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
-                                  MachineBasicBlock::iterator I,
-                                  unsigned SrcReg, bool isKill, int FrameIndex,
-                                  const TargetRegisterClass *RC) const
+                                         MachineBasicBlock::iterator I,
+                                         unsigned SrcReg, bool isKill,
+                                         int FrameIndex,
+                                         const TargetRegisterClass *RC) const
 {
-  BuildMI(MBB, I, get(XCore::STWSP_lru6)).addReg(SrcReg, false, false, isKill)
-                                         .addFrameIndex(FrameIndex).addImm(0);
+  DebugLoc DL = DebugLoc::getUnknownLoc();
+  if (I != MBB.end()) DL = I->getDebugLoc();
+  BuildMI(MBB, I, DL, get(XCore::STWFI))
+    .addReg(SrcReg, getKillRegState(isKill))
+    .addFrameIndex(FrameIndex)
+    .addImm(0);
 }
 
 void XCoreInstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg,
@@ -399,12 +411,15 @@ void XCoreInstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg,
 }
 
 void XCoreInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
-                                  MachineBasicBlock::iterator I,
-                                  unsigned DestReg, int FrameIndex,
-                                  const TargetRegisterClass *RC) const
+                                          MachineBasicBlock::iterator I,
+                                          unsigned DestReg, int FrameIndex,
+                                          const TargetRegisterClass *RC) const
 {
-  BuildMI(MBB, I, get(XCore::LDWSP_lru6), DestReg).addFrameIndex(FrameIndex)
-                                                  .addImm(0);
+  DebugLoc DL = DebugLoc::getUnknownLoc();
+  if (I != MBB.end()) DL = I->getDebugLoc();
+  BuildMI(MBB, I, DL, get(XCore::LDWFI), DestReg)
+    .addFrameIndex(FrameIndex)
+    .addImm(0);
 }
 
 void XCoreInstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
@@ -428,6 +443,9 @@ bool XCoreInstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
   XCoreFunctionInfo *XFI = MF->getInfo<XCoreFunctionInfo>();
   
   bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(*MF);
+
+  DebugLoc DL = DebugLoc::getUnknownLoc();
+  if (MI != MBB.end()) DL = MI->getDebugLoc();
   
   for (std::vector<CalleeSavedInfo>::const_iterator it = CSI.begin();
                                                     it != CSI.end(); ++it) {
@@ -435,10 +453,10 @@ bool XCoreInstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
     MBB.addLiveIn(it->getReg());
 
     storeRegToStackSlot(MBB, MI, it->getReg(), true,
-                                   it->getFrameIdx(), it->getRegClass());
+                        it->getFrameIdx(), it->getRegClass());
     if (emitFrameMoves) {
       unsigned SaveLabelId = MMI->NextLabelID();
-      BuildMI(MBB, MI, get(XCore::DBG_LABEL)).addImm(SaveLabelId);
+      BuildMI(MBB, MI, DL, get(XCore::DBG_LABEL)).addImm(SaveLabelId);
       XFI->getSpillLabels().push_back(
           std::pair<unsigned, CalleeSavedInfo>(SaveLabelId, *it));
     }