1 /**
2 * Copyright (c) 2021-2022 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 <gtest/gtest.h>
17
18 #include "runtime/interpreter/math_helpers.h"
19
20 namespace panda::interpreter::math_helpers::test {
21
22 template <class T>
TestBitShl()23 void TestBitShl()
24 {
25 std::ostringstream ss;
26 ss << "Test bit_shl with sizeof(T) = ";
27 ss << sizeof(T);
28
29 using unsigned_type = std::make_unsigned_t<T>;
30
31 {
32 T v = 1;
33 size_t shift = 5;
34 T res = bit_shl<T>()(v, shift);
35 EXPECT_EQ(res, v << shift) << ss.str();
36 }
37
38 {
39 T v = 1;
40 size_t shift = std::numeric_limits<unsigned_type>::digits - 1;
41 T res = bit_shl<T>()(v, shift);
42 EXPECT_EQ(res, static_cast<T>(v << shift)) << ss.str();
43 }
44
45 {
46 T v = 1;
47 size_t shift = std::numeric_limits<unsigned_type>::digits;
48 T res = bit_shl<T>()(v, shift);
49 EXPECT_EQ(res, v) << ss.str();
50 }
51
52 {
53 T v = 1;
54 size_t shift = std::numeric_limits<unsigned_type>::digits + 2;
55 T res = bit_shl<T>()(v, shift);
56 EXPECT_EQ(res, v << 2) << ss.str();
57 }
58 }
59
60 template <class T>
TestBitShr()61 void TestBitShr()
62 {
63 std::ostringstream ss;
64 ss << "Test bit_shr with sizeof(T) = ";
65 ss << sizeof(T);
66
67 using unsigned_type = std::make_unsigned_t<T>;
68
69 {
70 T v = 64;
71 T shift = 5;
72 T res = bit_shr<T>()(v, shift);
73 EXPECT_EQ(res, v >> shift) << ss.str();
74 }
75
76 {
77 T v = std::numeric_limits<T>::min();
78 T shift = std::numeric_limits<unsigned_type>::digits - 1;
79 T res = bit_shr<T>()(v, shift);
80 EXPECT_EQ(res, 1) << ss.str();
81 }
82
83 {
84 T v = 1;
85 T shift = std::numeric_limits<unsigned_type>::digits;
86 T res = bit_shr<T>()(v, shift);
87 EXPECT_EQ(res, v) << ss.str();
88 }
89
90 {
91 T v = 20;
92 T shift = std::numeric_limits<unsigned_type>::digits + 2;
93 T res = bit_shr<T>()(v, shift);
94 EXPECT_EQ(res, v >> 2) << ss.str();
95 }
96 }
97
98 template <class T>
TestBitAshr()99 void TestBitAshr()
100 {
101 std::ostringstream ss;
102 ss << "Test bit_ashr with sizeof(T) = ";
103 ss << sizeof(T);
104
105 using unsigned_type = std::make_unsigned_t<T>;
106
107 {
108 T v = 64;
109 T shift = 5;
110 T res = bit_ashr<T>()(v, shift);
111 EXPECT_EQ(res, v >> shift) << ss.str();
112 }
113
114 {
115 T v = std::numeric_limits<T>::min();
116 T shift = std::numeric_limits<unsigned_type>::digits - 1;
117 T res = bit_ashr<T>()(v, shift);
118 EXPECT_EQ(res, -1) << ss.str();
119 }
120
121 {
122 T v = 1;
123 T shift = std::numeric_limits<unsigned_type>::digits;
124 T res = bit_ashr<T>()(v, shift);
125 EXPECT_EQ(res, v) << ss.str();
126 }
127
128 {
129 T v = 20;
130 T shift = std::numeric_limits<unsigned_type>::digits + 2;
131 T res = bit_ashr<T>()(v, shift);
132 EXPECT_EQ(res, v >> 2) << ss.str();
133 }
134 }
135
136 template <class T>
137 T GetNaN();
138
139 template <>
GetNaN()140 float GetNaN()
141 {
142 return nanf("");
143 }
144
145 template <>
GetNaN()146 double GetNaN()
147 {
148 return nan("");
149 }
150
151 template <class T>
TestFcmpl()152 void TestFcmpl()
153 {
154 std::ostringstream ss;
155 ss << "Test fcmpl with sizeof(T) = ";
156 ss << sizeof(T);
157
158 {
159 T v1 = 1.0;
160 T v2 = GetNaN<T>();
161 EXPECT_EQ(fcmpl<T>()(v1, v2), -1);
162 }
163
164 {
165 T v1 = GetNaN<T>();
166 T v2 = 1.0;
167 EXPECT_EQ(fcmpl<T>()(v1, v2), -1);
168 }
169
170 {
171 T v1 = GetNaN<T>();
172 T v2 = GetNaN<T>();
173 EXPECT_EQ(fcmpl<T>()(v1, v2), -1);
174 }
175
176 {
177 T v1 = 1.0;
178 T v2 = 2.0;
179 EXPECT_EQ(fcmpl<T>()(v1, v2), -1);
180 }
181
182 {
183 T v1 = 1.0;
184 T v2 = v1;
185 EXPECT_EQ(fcmpl<T>()(v1, v2), 0);
186 }
187
188 {
189 T v1 = 2.0;
190 T v2 = 1.0;
191 EXPECT_EQ(fcmpl<T>()(v1, v2), 1);
192 }
193 }
194
195 template <class T>
TestFcmpg()196 void TestFcmpg()
197 {
198 std::ostringstream ss;
199 ss << "Test fcmpg with sizeof(T) = ";
200 ss << sizeof(T);
201
202 {
203 T v1 = 1.0;
204 T v2 = GetNaN<T>();
205 EXPECT_EQ(fcmpg<T>()(v1, v2), 1);
206 }
207
208 {
209 T v1 = GetNaN<T>();
210 T v2 = 1.0;
211 EXPECT_EQ(fcmpg<T>()(v1, v2), 1);
212 }
213
214 {
215 T v1 = GetNaN<T>();
216 T v2 = GetNaN<T>();
217 EXPECT_EQ(fcmpg<T>()(v1, v2), 1);
218 }
219
220 {
221 T v1 = 1.0;
222 T v2 = 2.0;
223 EXPECT_EQ(fcmpg<T>()(v1, v2), -1);
224 }
225
226 {
227 T v1 = 1.0;
228 T v2 = v1;
229 EXPECT_EQ(fcmpg<T>()(v1, v2), 0);
230 }
231
232 {
233 T v1 = 2.0;
234 T v2 = 1.0;
235 EXPECT_EQ(fcmpg<T>()(v1, v2), 1);
236 }
237 }
238
TEST(MathHelpers,BitShl)239 TEST(MathHelpers, BitShl)
240 {
241 TestBitShl<int8_t>();
242 TestBitShl<int16_t>();
243 TestBitShl<int32_t>();
244 TestBitShl<int64_t>();
245 }
246
TEST(MathHelpers,BitShr)247 TEST(MathHelpers, BitShr)
248 {
249 TestBitShr<int8_t>();
250 TestBitShr<int16_t>();
251 TestBitShr<int32_t>();
252 TestBitShr<int64_t>();
253 }
254
TEST(MathHelpers,BitAshr)255 TEST(MathHelpers, BitAshr)
256 {
257 TestBitAshr<int8_t>();
258 TestBitAshr<int16_t>();
259 TestBitAshr<int32_t>();
260 TestBitAshr<int64_t>();
261 }
262
TEST(MathHelpers,Fcmpl)263 TEST(MathHelpers, Fcmpl)
264 {
265 TestFcmpl<float>();
266 TestFcmpl<double>();
267 }
268
TEST(MathHelpers,Fcmpg)269 TEST(MathHelpers, Fcmpg)
270 {
271 TestFcmpg<float>();
272 TestFcmpg<double>();
273 }
274
275 } // namespace panda::interpreter::math_helpers::test
276