VapourSynth-llvmexpr
Loading...
Searching...
No Matches
MathFunctionImpl< VectorWidth, MathOp::Exp > Struct Template Reference

#include <llvmexpr/codegen/llvm/Math.hpp>

Static Public Member Functions

static llvm::Function * generate (MathFunctionGenerator< VectorWidth > *gen)

Detailed Description

template<int VectorWidth>
struct MathFunctionImpl< VectorWidth, MathOp::Exp >

Definition at line 231 of file Math.hpp.

Member Function Documentation

◆ generate()

template<int VectorWidth>
llvm::Function * MathFunctionImpl< VectorWidth, MathOp::Exp >::generate ( MathFunctionGenerator< VectorWidth > * gen)
inlinestatic

Definition at line 232 of file Math.hpp.

232 {
233 constexpr auto OP_INFO = get_math_op_info(MathOp::Exp);
234 // https://github.com/vapoursynth/vapoursynth/blob/2a3d3657320ca505c784b98f10e7cd9649d6169a/src/core/expr/jitcompiler_x86.cpp#L635
235 return gen->createFunction(
236 OP_INFO.name, OP_INFO.arity,
238 auto* x = args[0];
239 // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
240 auto* exp_hi = gen->getConstant(88.3762626647949F);
241 auto* exp_lo = gen->getConstant(-88.3762626647949F);
242 auto* log2e = gen->getConstant(std::numbers::log2e_v<float>);
243 auto* exp_p0 = gen->getConstant(1.9875691500E-4F);
244 auto* exp_p1 = gen->getConstant(1.3981999507E-3F);
245 auto* exp_p2 = gen->getConstant(8.3334519073E-3F);
246 auto* exp_p3 = gen->getConstant(4.1665795894E-2F);
247 auto* exp_p4 = gen->getConstant(1.6666665459E-1F);
248 auto* exp_p5 = gen->getConstant(5.0000001201E-1F);
249 auto* half = gen->getConstant(0.5F);
250 auto* one = gen->getConstant(1.0F);
251 auto* neg_exp_c1 = gen->getConstant(-0.693359375F);
252 auto* neg_exp_c2 = gen->getConstant(2.12194440e-4F);
253 auto* const_0x7f = gen->getInt32Constant(0x7F);
254 auto* const_23 = gen->getInt32Constant(23);
255 // NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
256 x = gen->createIntrinsicCall(llvm::Intrinsic::minnum,
257 {x, exp_hi});
258 x = gen->createIntrinsicCall(llvm::Intrinsic::maxnum,
259 {x, exp_lo});
260 auto* fx = gen->createIntrinsicCall(llvm::Intrinsic::fma,
261 {log2e, x, half});
262 auto* etmp =
263 gen->createIntrinsicCall(llvm::Intrinsic::nearbyint, {fx});
264 auto* cmp_gt = gen->builder.CreateFCmpOGT(etmp, fx);
265 auto* ext_cmp =
266 gen->builder.CreateSExt(cmp_gt, gen->getInt32Type());
267 auto* one_int =
268 gen->builder.CreateBitCast(one, gen->getInt32Type());
269 auto* mask_int = gen->builder.CreateAnd(ext_cmp, one_int);
270 auto* mask =
271 gen->builder.CreateBitCast(mask_int, gen->getFloatType());
272 fx = gen->builder.CreateFSub(etmp, mask);
273 x = gen->createIntrinsicCall(llvm::Intrinsic::fma,
274 {fx, neg_exp_c1, x});
275 x = gen->createIntrinsicCall(llvm::Intrinsic::fma,
276 {fx, neg_exp_c2, x});
277 auto* z = gen->builder.CreateFMul(x, x);
279 y = gen->createIntrinsicCall(llvm::Intrinsic::fma,
280 {y, x, exp_p1});
281 y = gen->createIntrinsicCall(llvm::Intrinsic::fma,
282 {y, x, exp_p2});
283 y = gen->createIntrinsicCall(llvm::Intrinsic::fma,
284 {y, x, exp_p3});
285 y = gen->createIntrinsicCall(llvm::Intrinsic::fma,
286 {y, x, exp_p4});
287 y = gen->createIntrinsicCall(llvm::Intrinsic::fma,
288 {y, x, exp_p5});
289 y = gen->createIntrinsicCall(llvm::Intrinsic::fma, {y, z, x});
290 y = gen->builder.CreateFAdd(y, one);
291 auto* emm0_float =
292 gen->createIntrinsicCall(llvm::Intrinsic::nearbyint, {fx});
293 auto* emm0 =
294 gen->builder.CreateFPToSI(emm0_float, gen->getInt32Type());
295 emm0 = gen->builder.CreateAdd(emm0, const_0x7f);
296 emm0 = gen->builder.CreateShl(emm0, const_23);
297 auto* emm0_as_float =
298 gen->builder.CreateBitCast(emm0, gen->getFloatType());
299 x = gen->builder.CreateFMul(y, emm0_as_float);
300 return x;
301 });
302 }
constexpr MathopInfo get_math_op_info(MathOp op)
Definition Math.hpp:86

References Exp, and get_math_op_info().


The documentation for this struct was generated from the following file: