For PR950:
Make necessary changes to support DIV -> [SUF]Div. This changes llvm to
have three division instructions: signed, unsigned, floating point. The
bytecode and assembler are bacwards compatible, however.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31195 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/ExecutionEngine/Interpreter/Execution.cpp b/lib/ExecutionEngine/Interpreter/Execution.cpp
index 8c812f8..41f0750 100644
--- a/lib/ExecutionEngine/Interpreter/Execution.cpp
+++ b/lib/ExecutionEngine/Interpreter/Execution.cpp
@@ -42,8 +42,12 @@
                                    const Type *Ty);
 static GenericValue executeRemInst(GenericValue Src1, GenericValue Src2,
                                    const Type *Ty);
-static GenericValue executeDivInst(GenericValue Src1, GenericValue Src2,
-                                   const Type *Ty);
+static GenericValue executeUDivInst(GenericValue Src1, GenericValue Src2,
+                                    const Type *Ty);
+static GenericValue executeSDivInst(GenericValue Src1, GenericValue Src2,
+                                    const Type *Ty);
+static GenericValue executeFDivInst(GenericValue Src1, GenericValue Src2,
+                                    const Type *Ty);
 static GenericValue executeAndInst(GenericValue Src1, GenericValue Src2,
                                    const Type *Ty);
 static GenericValue executeOrInst(GenericValue Src1, GenericValue Src2,
@@ -89,10 +93,18 @@
     return executeMulInst(getOperandValue(CE->getOperand(0), SF),
                           getOperandValue(CE->getOperand(1), SF),
                           CE->getOperand(0)->getType());
-  case Instruction::Div:
-    return executeDivInst(getOperandValue(CE->getOperand(0), SF),
-                          getOperandValue(CE->getOperand(1), SF),
-                          CE->getOperand(0)->getType());
+  case Instruction::SDiv:
+    return executeSDivInst(getOperandValue(CE->getOperand(0), SF),
+                           getOperandValue(CE->getOperand(1), SF),
+                           CE->getOperand(0)->getType());
+  case Instruction::UDiv:
+    return executeUDivInst(getOperandValue(CE->getOperand(0), SF),
+                           getOperandValue(CE->getOperand(1), SF),
+                           CE->getOperand(0)->getType());
+  case Instruction::FDiv:
+    return executeFDivInst(getOperandValue(CE->getOperand(0), SF),
+                           getOperandValue(CE->getOperand(1), SF),
+                           CE->getOperand(0)->getType());
   case Instruction::Rem:
     return executeRemInst(getOperandValue(CE->getOperand(0), SF),
                           getOperandValue(CE->getOperand(1), SF),
@@ -242,18 +254,44 @@
   return Dest;
 }
 
-static GenericValue executeDivInst(GenericValue Src1, GenericValue Src2,
+static GenericValue executeUDivInst(GenericValue Src1, GenericValue Src2,
+                                   const Type *Ty) {
+  GenericValue Dest;
+  if (Ty->isSigned())
+    Ty = Ty->getUnsignedVersion();
+  switch (Ty->getTypeID()) {
+    IMPLEMENT_BINARY_OPERATOR(/, UByte);
+    IMPLEMENT_BINARY_OPERATOR(/, UShort);
+    IMPLEMENT_BINARY_OPERATOR(/, UInt);
+    IMPLEMENT_BINARY_OPERATOR(/, ULong);
+  default:
+    std::cout << "Unhandled type for UDiv instruction: " << *Ty << "\n";
+    abort();
+  }
+  return Dest;
+}
+
+static GenericValue executeSDivInst(GenericValue Src1, GenericValue Src2,
+                                   const Type *Ty) {
+  GenericValue Dest;
+  if (Ty->isUnsigned())
+    Ty = Ty->getSignedVersion();
+  switch (Ty->getTypeID()) {
+    IMPLEMENT_BINARY_OPERATOR(/, SByte);
+    IMPLEMENT_BINARY_OPERATOR(/, Short);
+    IMPLEMENT_BINARY_OPERATOR(/, Int);
+    IMPLEMENT_BINARY_OPERATOR(/, Long);
+  default:
+    std::cout << "Unhandled type for SDiv instruction: " << *Ty << "\n";
+    abort();
+  }
+  return Dest;
+}
+
+static GenericValue executeFDivInst(GenericValue Src1, GenericValue Src2,
                                    const Type *Ty) {
   GenericValue Dest;
   switch (Ty->getTypeID()) {
-    IMPLEMENT_BINARY_OPERATOR(/, UByte);
-    IMPLEMENT_BINARY_OPERATOR(/, SByte);
-    IMPLEMENT_BINARY_OPERATOR(/, UShort);
-    IMPLEMENT_BINARY_OPERATOR(/, Short);
-    IMPLEMENT_BINARY_OPERATOR(/, UInt);
-    IMPLEMENT_BINARY_OPERATOR(/, Int);
-    IMPLEMENT_BINARY_OPERATOR(/, ULong);
-    IMPLEMENT_BINARY_OPERATOR(/, Long);
     IMPLEMENT_BINARY_OPERATOR(/, Float);
     IMPLEMENT_BINARY_OPERATOR(/, Double);
   default:
@@ -504,7 +542,9 @@
   case Instruction::Add:   R = executeAddInst  (Src1, Src2, Ty); break;
   case Instruction::Sub:   R = executeSubInst  (Src1, Src2, Ty); break;
   case Instruction::Mul:   R = executeMulInst  (Src1, Src2, Ty); break;
-  case Instruction::Div:   R = executeDivInst  (Src1, Src2, Ty); break;
+  case Instruction::UDiv:  R = executeUDivInst (Src1, Src2, Ty); break;
+  case Instruction::SDiv:  R = executeSDivInst (Src1, Src2, Ty); break;
+  case Instruction::FDiv:  R = executeFDivInst (Src1, Src2, Ty); break;
   case Instruction::Rem:   R = executeRemInst  (Src1, Src2, Ty); break;
   case Instruction::And:   R = executeAndInst  (Src1, Src2, Ty); break;
   case Instruction::Or:    R = executeOrInst   (Src1, Src2, Ty); break;