R600: Add CF_END
[oota-llvm.git] / lib / Target / R600 / R600ControlFlowFinalizer.cpp
index bc1ca58b863e0c8e93f6b85abed3e04ae9e09d5a..e683d7594ba8b9891e150829792d69c8d06449f3 100644 (file)
@@ -39,7 +39,8 @@ private:
     CF_LOOP_CONTINUE,
     CF_JUMP,
     CF_ELSE,
-    CF_POP
+    CF_POP,
+    CF_END
   };
 
   static char ID;
@@ -91,49 +92,46 @@ private:
   }
 
   const MCInstrDesc &getHWInstrDesc(ControlFlowInstruction CFI) const {
-    if (ST.device()->getGeneration() <= AMDGPUDeviceInfo::HD4XXX) {
-      switch (CFI) {
-      case CF_TC:
-        return TII->get(AMDGPU::CF_TC_R600);
-      case CF_CALL_FS:
-        return TII->get(AMDGPU::CF_CALL_FS_R600);
-      case CF_WHILE_LOOP:
-        return TII->get(AMDGPU::WHILE_LOOP_R600);
-      case CF_END_LOOP:
-        return TII->get(AMDGPU::END_LOOP_R600);
-      case CF_LOOP_BREAK:
-        return TII->get(AMDGPU::LOOP_BREAK_R600);
-      case CF_LOOP_CONTINUE:
-        return TII->get(AMDGPU::CF_CONTINUE_R600);
-      case CF_JUMP:
-        return TII->get(AMDGPU::CF_JUMP_R600);
-      case CF_ELSE:
-        return TII->get(AMDGPU::CF_ELSE_R600);
-      case CF_POP:
-        return TII->get(AMDGPU::POP_R600);
-      }
-    } else {
-      switch (CFI) {
-      case CF_TC:
-        return TII->get(AMDGPU::CF_TC_EG);
-      case CF_CALL_FS:
-        return TII->get(AMDGPU::CF_CALL_FS_EG);
-      case CF_WHILE_LOOP:
-        return TII->get(AMDGPU::WHILE_LOOP_EG);
-      case CF_END_LOOP:
-        return TII->get(AMDGPU::END_LOOP_EG);
-      case CF_LOOP_BREAK:
-        return TII->get(AMDGPU::LOOP_BREAK_EG);
-      case CF_LOOP_CONTINUE:
-        return TII->get(AMDGPU::CF_CONTINUE_EG);
-      case CF_JUMP:
-        return TII->get(AMDGPU::CF_JUMP_EG);
-      case CF_ELSE:
-        return TII->get(AMDGPU::CF_ELSE_EG);
-      case CF_POP:
-        return TII->get(AMDGPU::POP_EG);
+    unsigned Opcode = 0;
+    bool isEg = (ST.device()->getGeneration() >= AMDGPUDeviceInfo::HD5XXX);
+    switch (CFI) {
+    case CF_TC:
+      Opcode = isEg ? AMDGPU::CF_TC_EG : AMDGPU::CF_TC_R600;
+      break;
+    case CF_CALL_FS:
+      Opcode = isEg ? AMDGPU::CF_CALL_FS_EG : AMDGPU::CF_CALL_FS_R600;
+      break;
+    case CF_WHILE_LOOP:
+      Opcode = isEg ? AMDGPU::WHILE_LOOP_EG : AMDGPU::WHILE_LOOP_R600;
+      break;
+    case CF_END_LOOP:
+      Opcode = isEg ? AMDGPU::END_LOOP_EG : AMDGPU::END_LOOP_R600;
+      break;
+    case CF_LOOP_BREAK:
+      Opcode = isEg ? AMDGPU::LOOP_BREAK_EG : AMDGPU::LOOP_BREAK_R600;
+      break;
+    case CF_LOOP_CONTINUE:
+      Opcode = isEg ? AMDGPU::CF_CONTINUE_EG : AMDGPU::CF_CONTINUE_R600;
+      break;
+    case CF_JUMP:
+      Opcode = isEg ? AMDGPU::CF_JUMP_EG : AMDGPU::CF_JUMP_R600;
+      break;
+    case CF_ELSE:
+      Opcode = isEg ? AMDGPU::CF_ELSE_EG : AMDGPU::CF_ELSE_R600;
+      break;
+    case CF_POP:
+      Opcode = isEg ? AMDGPU::POP_EG : AMDGPU::POP_R600;
+      break;
+    case CF_END:
+      if (ST.device()->getGeneration() == AMDGPUDeviceInfo::HD6XXX) {
+        Opcode = AMDGPU::CF_END_CM;
+        break;
       }
+      Opcode = isEg ? AMDGPU::CF_END_EG : AMDGPU::CF_END_R600;
+      break;
     }
+    assert (Opcode && "No opcode selected");
+    return TII->get(Opcode);
   }
 
   MachineBasicBlock::iterator
@@ -310,6 +308,15 @@ public:
           CfCount++;
           break;
         }
+        case AMDGPU::RETURN: {
+          BuildMI(MBB, MI, MBB.findDebugLoc(MI), getHWInstrDesc(CF_END));
+          CfCount++;
+          MI->eraseFromParent();
+          if (CfCount % 2) {
+            BuildMI(MBB, I, MBB.findDebugLoc(MI), TII->get(AMDGPU::PAD));
+            CfCount++;
+          }
+        }
         default:
           break;
         }