@@ -250,6 +250,24 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
250250 break ;
251251 }
252252
253+ case Step::Type::Sin: {
254+ assert (step.args .size () == 1 );
255+ const auto &arg = step.args [0 ];
256+ // round(sin(x * pi / 180.0) * 1e10) / 1e10 + 0.0
257+ // +0.0 to avoid -0.0
258+ llvm::Constant *zero = llvm::ConstantFP::get (m_ctx, llvm::APFloat (0.0 ));
259+ llvm::Constant *pi = llvm::ConstantFP::get (m_ctx, llvm::APFloat (std::acos (-1.0 )));
260+ llvm::Constant *piDeg = llvm::ConstantFP::get (m_ctx, llvm::APFloat (180.0 ));
261+ llvm::Constant *factor = llvm::ConstantFP::get (m_ctx, llvm::APFloat (1e10 ));
262+ llvm::Function *sinFunc = llvm::Intrinsic::getDeclaration (m_module.get (), llvm::Intrinsic::sin, m_builder.getDoubleTy ());
263+ llvm::Function *roundFunc = llvm::Intrinsic::getDeclaration (m_module.get (), llvm::Intrinsic::round, m_builder.getDoubleTy ());
264+ llvm::Value *num = removeNaN (castValue (arg.second , arg.first ));
265+ llvm::Value *sinResult = m_builder.CreateCall (sinFunc, m_builder.CreateFDiv (m_builder.CreateFMul (num, pi), piDeg)); // sin(x * pi / 180)
266+ llvm::Value *rounded = m_builder.CreateCall (roundFunc, m_builder.CreateFMul (sinResult, factor)); // round(sin(x * 180) * 1e10)
267+ step.functionReturnReg ->value = m_builder.CreateFAdd (m_builder.CreateFDiv (rounded, factor), zero);
268+ break ;
269+ }
270+
253271 case Step::Type::Yield:
254272 if (!m_warp) {
255273 freeHeap ();
@@ -648,6 +666,11 @@ void LLVMCodeBuilder::createSqrt()
648666 createOp (Step::Type::Sqrt, Compiler::StaticType::Number, Compiler::StaticType::Number, 1 );
649667}
650668
669+ void LLVMCodeBuilder::createSin ()
670+ {
671+ createOp (Step::Type::Sin, Compiler::StaticType::Number, Compiler::StaticType::Number, 1 );
672+ }
673+
651674void LLVMCodeBuilder::beginIfStatement ()
652675{
653676 Step step (Step::Type::BeginIf);
0 commit comments