diff options
author | Reid Spencer <rspencer@reidspencer.com> | 2006-10-26 06:15:43 +0000 |
---|---|---|
committer | Reid Spencer <rspencer@reidspencer.com> | 2006-10-26 06:15:43 +0000 |
commit | 1628cec4d7fce310d9cde0bcc73997e5a71692c4 (patch) | |
tree | 6dff5a70de8406b153e32fdd2d60c782d6202f63 /lib/ExecutionEngine | |
parent | 7043d00750c558a518d08a638638ebe4d241f159 (diff) | |
download | external_llvm-1628cec4d7fce310d9cde0bcc73997e5a71692c4.zip external_llvm-1628cec4d7fce310d9cde0bcc73997e5a71692c4.tar.gz external_llvm-1628cec4d7fce310d9cde0bcc73997e5a71692c4.tar.bz2 |
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
Diffstat (limited to 'lib/ExecutionEngine')
-rw-r--r-- | lib/ExecutionEngine/Interpreter/Execution.cpp | 62 |
1 files changed, 51 insertions, 11 deletions
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 @@ static GenericValue executeMulInst(GenericValue Src1, GenericValue Src2, 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 @@ GenericValue Interpreter::getConstantExprValue (ConstantExpr *CE, 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 @@ static GenericValue executeMulInst(GenericValue Src1, GenericValue Src2, 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(/, SByte); IMPLEMENT_BINARY_OPERATOR(/, UShort); - IMPLEMENT_BINARY_OPERATOR(/, Short); IMPLEMENT_BINARY_OPERATOR(/, UInt); - IMPLEMENT_BINARY_OPERATOR(/, Int); 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(/, Float); IMPLEMENT_BINARY_OPERATOR(/, Double); default: @@ -504,7 +542,9 @@ void Interpreter::visitBinaryOperator(BinaryOperator &I) { 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; |