• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <climits>
17 #include <cstdint>
18 #include <cstdlib>
19 #include <limits>
20 #include <random>
21 #include <cmath>
22 
23 #include "libpandabase/utils/bit_utils.h"
24 #include "macros.h"
25 #include "plugins/ets/runtime/ets_coroutine.h"
26 #include "plugins/ets/runtime/ets_vm.h"
27 
28 namespace ark::ets::intrinsics {
29 
30 namespace {
31 constexpr int INT_MAX_SIZE = 63;
32 constexpr double ROUND_BIAS = 0.5;
33 
ToInt32(double x)34 int32_t ToInt32(double x)
35 {
36     if (std::isinf(x)) {
37         return 0;
38     }
39 
40     if ((std::isfinite(x)) && (x <= INT_MAX) && (x >= INT_MIN)) {
41         return static_cast<int32_t>(x);
42     }
43 
44     double intPart = 0.0;
45     std::modf(x, &intPart);
46     double int64Max = std::pow(2, INT_MAX_SIZE);
47     intPart = std::fmod(intPart, int64Max);
48     return static_cast<int32_t>(static_cast<int64_t>(intPart));
49 }
50 
ToUint32(double x)51 uint32_t ToUint32(double x)
52 {
53     return static_cast<uint32_t>(ToInt32(x));
54 }
55 }  // namespace
56 
StdMathRandom()57 extern "C" double StdMathRandom()
58 {
59     std::uniform_real_distribution<double> urd(0.0, 1.0);
60     auto *coro = EtsCoroutine::GetCurrent();
61     ASSERT(coro != nullptr);
62     auto *pandaVM = coro->GetPandaVM();
63     ASSERT(pandaVM != nullptr);
64     return urd(pandaVM->GetRandomEngine());
65 }
66 
StdMathAcos(double val)67 extern "C" double StdMathAcos(double val)
68 {
69     return std::acos(val);
70 }
71 
StdMathAcosh(double val)72 extern "C" double StdMathAcosh(double val)
73 {
74     return std::acosh(val);
75 }
76 
StdMathAsin(double val)77 extern "C" double StdMathAsin(double val)
78 {
79     return std::asin(val);
80 }
81 
StdMathAsinh(double val)82 extern "C" double StdMathAsinh(double val)
83 {
84     return std::asinh(val);
85 }
86 
StdMathAtan2(double val1,double val2)87 extern "C" double StdMathAtan2(double val1, double val2)
88 {
89     return std::atan2(val1, val2);
90 }
91 
StdMathAtanh(double val)92 extern "C" double StdMathAtanh(double val)
93 {
94     return std::atanh(val);
95 }
96 
StdMathAtan(double val)97 extern "C" double StdMathAtan(double val)
98 {
99     return std::atan(val);
100 }
101 
StdMathSinh(double val)102 extern "C" double StdMathSinh(double val)
103 {
104     return std::sinh(val);
105 }
106 
StdMathCosh(double val)107 extern "C" double StdMathCosh(double val)
108 {
109     return std::cosh(val);
110 }
111 
StdMathFloor(double val)112 extern "C" double StdMathFloor(double val)
113 {
114     return std::floor(val);
115 }
116 
StdMathRound(double val)117 extern "C" double StdMathRound(double val)
118 {
119     double res = std::ceil(val);
120     if (res - val > ROUND_BIAS) {
121         res -= 1.0;
122     }
123     return res;
124 }
125 
StdMathTrunc(double val)126 extern "C" double StdMathTrunc(double val)
127 {
128     return std::trunc(val);
129 }
130 
StdMathCbrt(double val)131 extern "C" double StdMathCbrt(double val)
132 {
133     return std::cbrt(val);
134 }
135 
StdMathTan(double val)136 extern "C" double StdMathTan(double val)
137 {
138     return std::tan(val);
139 }
140 
StdMathTanh(double val)141 extern "C" double StdMathTanh(double val)
142 {
143     return std::tanh(val);
144 }
145 
StdMathExp(double val)146 extern "C" double StdMathExp(double val)
147 {
148     return std::exp(val);
149 }
150 
StdMathLog10(double val)151 extern "C" double StdMathLog10(double val)
152 {
153     return std::log10(val);
154 }
155 
StdMathExpm1(double val)156 extern "C" double StdMathExpm1(double val)
157 {
158     return std::expm1(val);
159 }
160 
StdMathCeil(double val)161 extern "C" double StdMathCeil(double val)
162 {
163     return std::ceil(val);
164 }
165 
StdMathClz64(int64_t val)166 extern "C" int32_t StdMathClz64(int64_t val)
167 {
168     if (val != 0) {
169         return Clz(static_cast<uint64_t>(val));
170     }
171     return std::numeric_limits<uint64_t>::digits;
172 }
173 
StdMathClz32(int32_t val)174 extern "C" int32_t StdMathClz32(int32_t val)
175 {
176     if (val != 0) {
177         return Clz(static_cast<uint32_t>(val));
178     }
179     return std::numeric_limits<uint32_t>::digits;
180 }
181 
StdMathClz32Double(double val)182 extern "C" double StdMathClz32Double(double val)
183 {
184     auto intValue = ToUint32(val);
185     if (intValue != 0) {
186         return static_cast<double>(Clz(intValue));
187     }
188     return std::numeric_limits<uint32_t>::digits;
189 }
190 
StdMathLog(double val)191 extern "C" double StdMathLog(double val)
192 {
193     return std::log(val);
194 }
195 
StdMathRem(double val,double val2)196 extern "C" double StdMathRem(double val, double val2)
197 {
198     return std::remainder(val, val2);
199 }
200 
StdMathMod(double val,double val2)201 extern "C" double StdMathMod(double val, double val2)
202 {
203     return std::fmod(val, val2);
204 }
205 
StdMathSignbit(double val)206 extern "C" bool StdMathSignbit(double val)
207 {
208     return std::signbit(val);
209 }
210 
StdMathImul(double val,double val2)211 extern "C" int StdMathImul(double val, double val2)
212 {
213     if (!std::isfinite(val) || !std::isfinite(val2)) {
214         return 0;
215     }
216     return static_cast<int32_t>(static_cast<int64_t>(val) * static_cast<int64_t>(val2));
217 }
218 
StdMathFround(double val)219 extern "C" double StdMathFround(double val)
220 {
221     if (std::isnan(val)) {
222         return std::numeric_limits<float>::quiet_NaN();
223     }
224 
225     return static_cast<float>(val);
226 }
StdMathHypot(double val1,double val2)227 extern "C" double StdMathHypot(double val1, double val2)
228 {
229     return std::hypot(val1, val2);
230 }
231 }  // namespace ark::ets::intrinsics
232