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 | 7e80b0b31ef448877c60de9b3d518a2a79c0a8a7 (patch) | |
tree | 12ea272f456d91b5260218887fe5d8c257bb807a /llvm/lib/ExecutionEngine/Interpreter/Execution.cpp | |
parent | 5b979ae531ed5fd89f648b528f924b547df591b8 (diff) | |
download | bcm5719-llvm-7e80b0b31ef448877c60de9b3d518a2a79c0a8a7.tar.gz bcm5719-llvm-7e80b0b31ef448877c60de9b3d518a2a79c0a8a7.zip |
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.
llvm-svn: 31195
Diffstat (limited to 'llvm/lib/ExecutionEngine/Interpreter/Execution.cpp')
-rw-r--r-- | llvm/lib/ExecutionEngine/Interpreter/Execution.cpp | 62 |
1 files changed, 51 insertions, 11 deletions
diff --git a/llvm/lib/ExecutionEngine/Interpreter/Execution.cpp b/llvm/lib/ExecutionEngine/Interpreter/Execution.cpp index 8c812f82d4d..41f07507d46 100644 --- a/llvm/lib/ExecutionEngine/Interpreter/Execution.cpp +++ b/llvm/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; |