Fix a FIXME by making GlobalVariable::getInitializer() return a
[oota-llvm.git] / lib / Target / MBlaze / MBlazeDelaySlotFiller.cpp
index 024d3d55fcc5631486f5cb475b1bb50a0a721d74..973e96844e81eac9ac78fd1dd070bd7f1be25085 100644 (file)
@@ -77,7 +77,7 @@ static bool hasImmInstruction(MachineBasicBlock::iterator &candidate) {
 
         // We must assume that unknown immediate values require more than
         // 16-bits to represent.
-        if (mop.isGlobal() || mop.isSymbol())
+        if (mop.isGlobal() || mop.isSymbol() || mop.isJTI() || mop.isCPI())
           return true;
 
         // FIXME: we could probably check to see if the FP value happens
@@ -90,6 +90,20 @@ static bool hasImmInstruction(MachineBasicBlock::iterator &candidate) {
     return false;
 }
 
+static unsigned getLastRealOperand(MachineBasicBlock::iterator &instr) {
+  switch (instr->getOpcode()) {
+  default: return instr->getNumOperands();
+
+  // These instructions have a variable number of operands but the first two
+  // are the "real" operands that we care about during hazard detection.
+  case MBlaze::BRLID:
+  case MBlaze::BRALID:
+  case MBlaze::BRLD:
+  case MBlaze::BRALD:
+    return 2;
+  }
+}
+
 static bool delayHasHazard(MachineBasicBlock::iterator &candidate,
                            MachineBasicBlock::iterator &slot) {
   // Hazard check
@@ -111,17 +125,23 @@ static bool delayHasHazard(MachineBasicBlock::iterator &candidate,
   //    contains a store operation.
   bool a_is_memory = desc.mayLoad() || desc.mayStore();
 
+  // Determine the number of operands in the slot instruction and in the
+  // candidate instruction.
+  const unsigned aend = getLastRealOperand(a);
+  const unsigned bend = getLastRealOperand(b);
+
   // Check hazards type 1, 2 and 5 by scanning the middle bit
   MachineBasicBlock::iterator m = a;
   for (++m; m != b; ++m) {
-    for (unsigned aop = 0, aend = a->getNumOperands(); aop<aend; ++aop) {
+    for (unsigned aop = 0; aop<aend; ++aop) {
       bool aop_is_reg = a->getOperand(aop).isReg();
       if (!aop_is_reg) continue;
 
       bool aop_is_def = a->getOperand(aop).isDef();
       unsigned aop_reg = a->getOperand(aop).getReg();
 
-      for (unsigned mop = 0, mend = m->getNumOperands(); mop<mend; ++mop) {
+      const unsigned mend = getLastRealOperand(m);
+      for (unsigned mop = 0; mop<mend; ++mop) {
         bool mop_is_reg = m->getOperand(mop).isReg();
         if (!mop_is_reg) continue;
 
@@ -141,12 +161,12 @@ static bool delayHasHazard(MachineBasicBlock::iterator &candidate,
   }
 
   // Check hazard type 3 & 4
-  for (unsigned aop = 0, aend = a->getNumOperands(); aop<aend; ++aop) {
+  for (unsigned aop = 0; aop<aend; ++aop) {
     if (a->getOperand(aop).isReg()) {
       unsigned aop_reg = a->getOperand(aop).getReg();
 
-      for (unsigned bop = 0, bend = b->getNumOperands(); bop<bend; ++bop) {
-        if (b->getOperand(bop).isReg() && (!b->getOperand(bop).isImplicit())) {
+      for (unsigned bop = 0; bop<bend; ++bop) {
+        if (b->getOperand(bop).isReg() && !b->getOperand(bop).isImplicit()) {
           unsigned bop_reg = b->getOperand(bop).getReg();
           if (aop_reg == bop_reg)
             return true;
@@ -167,6 +187,22 @@ static bool isDelayFiller(MachineBasicBlock &MBB,
   return (brdesc.hasDelaySlot());
 }
 
+static bool hasUnknownSideEffects(MachineBasicBlock::iterator &I) {
+  if (!I->hasUnmodeledSideEffects())
+    return false;
+
+  unsigned op = I->getOpcode();
+  if (op == MBlaze::ADDK || op == MBlaze::ADDIK ||
+      op == MBlaze::ADDC || op == MBlaze::ADDIC ||
+      op == MBlaze::ADDKC || op == MBlaze::ADDIKC ||
+      op == MBlaze::RSUBK || op == MBlaze::RSUBIK ||
+      op == MBlaze::RSUBC || op == MBlaze::RSUBIC ||
+      op == MBlaze::RSUBKC || op == MBlaze::RSUBIKC)
+    return false;
+
+  return true;
+}
+
 static MachineBasicBlock::iterator
 findDelayInstr(MachineBasicBlock &MBB,MachineBasicBlock::iterator slot) {
   MachineBasicBlock::iterator I = slot;
@@ -178,7 +214,7 @@ findDelayInstr(MachineBasicBlock &MBB,MachineBasicBlock::iterator slot) {
     TargetInstrDesc desc = I->getDesc();
     if (desc.hasDelaySlot() || desc.isBranch() || isDelayFiller(MBB,I) ||
         desc.isCall() || desc.isReturn() || desc.isBarrier() ||
-        desc.hasUnmodeledSideEffects())
+        hasUnknownSideEffects(I))
       break;
 
     if (hasImmInstruction(I) || delayHasHazard(I,slot))