diff options
Diffstat (limited to 'lib/Core/Executor.cpp')
-rw-r--r-- | lib/Core/Executor.cpp | 63 |
1 files changed, 38 insertions, 25 deletions
diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp index 845fa8ff..05e20f65 100644 --- a/lib/Core/Executor.cpp +++ b/lib/Core/Executor.cpp @@ -1319,6 +1319,28 @@ void Executor::stepInstruction(ExecutionState &state) { haltExecution = true; } +static inline const llvm::fltSemantics *fpWidthToSemantics(unsigned width) { + switch (width) { +#if LLVM_VERSION_CODE >= LLVM_VERSION(4, 0) + case Expr::Int32: + return &llvm::APFloat::IEEEsingle(); + case Expr::Int64: + return &llvm::APFloat::IEEEdouble(); + case Expr::Fl80: + return &llvm::APFloat::x87DoubleExtended(); +#else + case Expr::Int32: + return &llvm::APFloat::IEEEsingle; + case Expr::Int64: + return &llvm::APFloat::IEEEdouble; + case Expr::Fl80: + return &llvm::APFloat::x87DoubleExtended; +#endif + default: + return 0; + } +} + void Executor::executeCall(ExecutionState &state, KInstruction *ki, Function *f, @@ -1332,9 +1354,22 @@ void Executor::executeCall(ExecutionState &state, // state may be destroyed by this call, cannot touch callExternalFunction(state, ki, f, arguments); break; - - // va_arg is handled by caller and intrinsic lowering, see comment for - // ExecutionState::varargs + case Intrinsic::fabs: { + ref<ConstantExpr> arg = + toConstant(state, eval(ki, 0, state).value, "floating point"); + if (!fpWidthToSemantics(arg->getWidth())) + return terminateStateOnExecError( + state, "Unsupported intrinsic llvm.fabs call"); + + llvm::APFloat Res(*fpWidthToSemantics(arg->getWidth()), + arg->getAPValue()); + Res = llvm::abs(Res); + + bindLocal(ki, state, ConstantExpr::alloc(Res.bitcastToAPInt())); + break; + } + // va_arg is handled by caller and intrinsic lowering, see comment for + // ExecutionState::varargs case Intrinsic::vastart: { StackFrame &sf = state.stack.back(); @@ -1579,28 +1614,6 @@ Function* Executor::getTargetFunction(Value *calledVal, ExecutionState &state) { } } -static inline const llvm::fltSemantics * fpWidthToSemantics(unsigned width) { - switch(width) { -#if LLVM_VERSION_CODE >= LLVM_VERSION(4, 0) - case Expr::Int32: - return &llvm::APFloat::IEEEsingle(); - case Expr::Int64: - return &llvm::APFloat::IEEEdouble(); - case Expr::Fl80: - return &llvm::APFloat::x87DoubleExtended(); -#else - case Expr::Int32: - return &llvm::APFloat::IEEEsingle; - case Expr::Int64: - return &llvm::APFloat::IEEEdouble; - case Expr::Fl80: - return &llvm::APFloat::x87DoubleExtended; -#endif - default: - return 0; - } -} - void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { Instruction *i = ki->inst; switch (i->getOpcode()) { |