VapourSynth-llvmexpr
Loading...
Searching...
No Matches
MathFunctionImpl< VectorWidth, MathOp::Log > 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::Log >

Definition at line 305 of file Math.hpp.

Member Function Documentation

◆ generate()

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

Definition at line 306 of file Math.hpp.

306 {
307 constexpr auto OP_INFO = get_math_op_info(MathOp::Log);
308 // https://github.com/vapoursynth/vapoursynth/blob/2a3d3657320ca505c784b98f10e7cd9649d6169a/src/core/expr/jitcompiler_x86.cpp#L671
309 return gen->createFunction(
310 OP_INFO.name, OP_INFO.arity,
312 auto* x = args[0];
313 // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
314 auto* min_norm_pos = gen->getInt32Constant(0x00800000);
315 auto* inv_mant_mask = gen->getInt32Constant(~0x7F800000);
316 auto* sqrt_1_2 = gen->getConstant(0.707106781186547524F);
317 auto* log_p0 = gen->getConstant(7.0376836292E-2F);
318 auto* log_p1 = gen->getConstant(-1.1514610310E-1F);
319 auto* log_p2 = gen->getConstant(1.1676998740E-1F);
320 auto* log_p3 = gen->getConstant(-1.2420140846E-1F);
321 auto* log_p4 = gen->getConstant(1.4249322787E-1F);
322 auto* log_p5 = gen->getConstant(-1.6668057665E-1F);
323 auto* log_p6 = gen->getConstant(2.0000714765E-1F);
324 auto* log_p7 = gen->getConstant(-2.4999993993E-1F);
325 auto* log_p8 = gen->getConstant(3.3333331174E-1F);
326 auto* log_q2 = gen->getConstant(0.693359375F);
327 auto* log_q1 = gen->getConstant(-2.12194440e-4F);
328 auto* one = gen->getConstant(1.0F);
329 auto* neg_half = gen->getConstant(-0.5F);
330 auto* const_0x7f = gen->getInt32Constant(0x7F);
331 auto* const_23 = gen->getInt32Constant(23);
332 // NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
333 auto* is_one = gen->builder.CreateFCmpOEQ(x, one);
334 auto* min_norm_pos_float = gen->builder.CreateBitCast(
335 min_norm_pos, gen->getFloatType());
336 x = gen->createIntrinsicCall(llvm::Intrinsic::maxnum,
337 {x, min_norm_pos_float});
338 auto* x_as_int =
339 gen->builder.CreateBitCast(x, gen->getInt32Type());
340 auto* emm0i = gen->builder.CreateLShr(x_as_int, const_23);
341 auto* x_masked =
342 gen->builder.CreateAnd(x_as_int, inv_mant_mask);
343 auto* half_as_int = gen->builder.CreateBitCast(
344 gen->getConstant(
345 0.5F), // NOLINT(cppcoreguidelines-avoid-magic-numbers)
346 gen->getInt32Type()); // NOLINT(cppcoreguidelines-avoid-magic-numbers)
347 x_masked = gen->builder.CreateOr(x_masked, half_as_int);
348 x = gen->builder.CreateBitCast(x_masked, gen->getFloatType());
349 emm0i = gen->builder.CreateSub(emm0i, const_0x7f);
350 auto* emm0 =
351 gen->builder.CreateSIToFP(emm0i, gen->getFloatType());
352 emm0 = gen->builder.CreateFAdd(emm0, one);
353 auto* mask = gen->builder.CreateFCmpOLT(x, sqrt_1_2);
354 auto* ext_mask =
355 gen->builder.CreateSExt(mask, gen->getInt32Type());
356 x_as_int = gen->builder.CreateBitCast(x, gen->getInt32Type());
357 auto* etmp_as_int = gen->builder.CreateAnd(ext_mask, x_as_int);
358 auto* etmp = gen->builder.CreateBitCast(etmp_as_int,
359 gen->getFloatType());
360 x = gen->builder.CreateFSub(x, one);
361 auto* one_as_int =
362 gen->builder.CreateBitCast(one, gen->getInt32Type());
363 auto* maskf_as_int =
364 gen->builder.CreateAnd(ext_mask, one_as_int);
365 auto* maskf = gen->builder.CreateBitCast(maskf_as_int,
366 gen->getFloatType());
367 emm0 = gen->builder.CreateFSub(emm0, maskf);
368 x = gen->builder.CreateFAdd(x, etmp);
369 auto* z = gen->builder.CreateFMul(x, x);
371 y = gen->createIntrinsicCall(llvm::Intrinsic::fma,
372 {y, x, log_p1});
373 y = gen->createIntrinsicCall(llvm::Intrinsic::fma,
374 {y, x, log_p2});
375 y = gen->createIntrinsicCall(llvm::Intrinsic::fma,
376 {y, x, log_p3});
377 y = gen->createIntrinsicCall(llvm::Intrinsic::fma,
378 {y, x, log_p4});
379 y = gen->createIntrinsicCall(llvm::Intrinsic::fma,
380 {y, x, log_p5});
381 y = gen->createIntrinsicCall(llvm::Intrinsic::fma,
382 {y, x, log_p6});
383 y = gen->createIntrinsicCall(llvm::Intrinsic::fma,
384 {y, x, log_p7});
385 y = gen->createIntrinsicCall(llvm::Intrinsic::fma,
386 {y, x, log_p8});
387 y = gen->builder.CreateFMul(y, x);
388 y = gen->builder.CreateFMul(y, z);
389 y = gen->createIntrinsicCall(llvm::Intrinsic::fma,
390 {emm0, log_q1, y});
391 y = gen->createIntrinsicCall(llvm::Intrinsic::fma,
392 {z, neg_half, y});
393 x = gen->builder.CreateFAdd(x, y);
394 x = gen->createIntrinsicCall(llvm::Intrinsic::fma,
395 {emm0, log_q2, x});
396 x_as_int = gen->builder.CreateBitCast(x, gen->getInt32Type());
397 auto* ext_is_one =
398 gen->builder.CreateSExt(is_one, gen->getInt32Type());
399 auto* not_ext_is_one = gen->builder.CreateNot(ext_is_one);
400 auto* result_as_int =
401 gen->builder.CreateAnd(not_ext_is_one, x_as_int);
402 x = gen->builder.CreateBitCast(result_as_int,
403 gen->getFloatType());
404 return x;
405 });
406 }
constexpr MathopInfo get_math_op_info(MathOp op)
Definition Math.hpp:86

References get_math_op_info(), and Log.


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