6
6
#include <wasm_simd128.h>
7
7
#endif
8
8
9
+ #include <mono/utils/mono-math.h>
10
+
9
11
#ifdef INTERP_ENABLE_SIMD
10
12
11
13
gboolean interp_simd_enabled = TRUE;
@@ -175,13 +177,18 @@ interp_v128_op_bitwise_or (gpointer res, gpointer v1, gpointer v2)
175
177
static void
176
178
interp_v128_op_bitwise_equality (gpointer res , gpointer v1 , gpointer v2 )
177
179
{
178
- gint64 * v1_cast = (gint64 * )v1 ;
179
- gint64 * v2_cast = (gint64 * )v2 ;
180
+ gint64 * v1_typed = (gint64 * )v1 ;
181
+ gint64 * v2_typed = (gint64 * )v2 ;
180
182
181
- if (* v1_cast == * v2_cast && * (v1_cast + 1 ) == * (v2_cast + 1 ))
182
- * (gint32 * )res = 1 ;
183
- else
184
- * (gint32 * )res = 0 ;
183
+ bool succeeded = true;
184
+
185
+ if (v1_typed [0 ] != v2_typed [0 ]) {
186
+ succeeded = false;
187
+ } else if (v1_typed [1 ] != v2_typed [1 ]) {
188
+ succeeded = false;
189
+ }
190
+
191
+ * (gint32 * )res = succeeded ? 1 : 0 ;
185
192
}
186
193
187
194
// op_ExclusiveOr
@@ -195,36 +202,83 @@ interp_v128_op_exclusive_or (gpointer res, gpointer v1, gpointer v2)
195
202
static void
196
203
interp_v128_op_bitwise_inequality (gpointer res , gpointer v1 , gpointer v2 )
197
204
{
198
- gint64 * v1_cast = (gint64 * )v1 ;
199
- gint64 * v2_cast = (gint64 * )v2 ;
205
+ gint64 * v1_typed = (gint64 * )v1 ;
206
+ gint64 * v2_typed = (gint64 * )v2 ;
207
+
208
+ bool succeeded = false;
200
209
201
- if (* v1_cast == * v2_cast && * (v1_cast + 1 ) == * (v2_cast + 1 ))
202
- * (gint32 * )res = 0 ;
203
- else
204
- * (gint32 * )res = 1 ;
210
+ if (v1_typed [0 ] != v2_typed [0 ]) {
211
+ succeeded = true;
212
+ } else if (v1_typed [1 ] != v2_typed [1 ]) {
213
+ succeeded = true;
214
+ }
215
+
216
+ * (gint32 * )res = succeeded ? 1 : 0 ;
205
217
}
206
218
207
- // Vector128<float>EqualsFloatingPoint
219
+ static bool
220
+ r4_float_equality (float v1 , float v2 )
221
+ {
222
+ if (v1 == v2 ) {
223
+ return true;
224
+ } else if (mono_isnan (v1 ) && mono_isnan (v2 )) {
225
+ return true;
226
+ }
227
+
228
+ return false;
229
+ }
230
+
231
+ // Vector128<float>.EqualsFloatingPoint
208
232
static void
209
233
interp_v128_r4_float_equality (gpointer res , gpointer v1 , gpointer v2 )
210
234
{
211
- v128_r4 v1_cast = * (v128_r4 * )v1 ;
212
- v128_r4 v2_cast = * (v128_r4 * )v2 ;
213
- v128_r4 result = (v1_cast == v2_cast ) | ~((v1_cast == v1_cast ) | (v2_cast == v2_cast ));
214
- memset (& v1_cast , 0xff , SIZEOF_V128 );
235
+ float * v1_typed = (float * )v1 ;
236
+ float * v2_typed = (float * )v2 ;
237
+
238
+ bool succeeded = true;
239
+
240
+ if (!r4_float_equality (v1_typed [0 ], v2_typed [0 ])) {
241
+ succeeded = false;
242
+ } else if (!r4_float_equality (v1_typed [1 ], v2_typed [1 ])) {
243
+ succeeded = false;
244
+ } else if (!r4_float_equality (v1_typed [2 ], v2_typed [2 ])) {
245
+ succeeded = false;
246
+ } else if (!r4_float_equality (v1_typed [3 ], v2_typed [3 ])) {
247
+ succeeded = false;
248
+ }
249
+
250
+ * (gint32 * )res = succeeded ? 1 : 0 ;
251
+ }
252
+
253
+ static bool
254
+ r8_float_equality (double v1 , double v2 )
255
+ {
256
+ bool succeeded = false;
257
+
258
+ if (v1 == v2 ) {
259
+ return true;
260
+ } else if (mono_isnan (v1 ) && mono_isnan (v2 )) {
261
+ return true;
262
+ }
215
263
216
- * ( gint32 * ) res = memcmp ( & v1_cast , & result , SIZEOF_V128 ) == 0 ;
264
+ return false ;
217
265
}
218
266
219
267
static void
220
268
interp_v128_r8_float_equality (gpointer res , gpointer v1 , gpointer v2 )
221
269
{
222
- v128_r8 v1_cast = * (v128_r8 * )v1 ;
223
- v128_r8 v2_cast = * (v128_r8 * )v2 ;
224
- v128_r8 result = (v1_cast == v2_cast ) | ~((v1_cast == v1_cast ) | (v2_cast == v2_cast ));
225
- memset (& v1_cast , 0xff , SIZEOF_V128 );
270
+ double * v1_typed = (double * )v1 ;
271
+ double * v2_typed = (double * )v2 ;
272
+
273
+ bool succeeded = true;
274
+
275
+ if (!r8_float_equality (v1_typed [0 ], v2_typed [0 ])) {
276
+ succeeded = false;
277
+ } else if (!r8_float_equality (v1_typed [1 ], v2_typed [1 ])) {
278
+ succeeded = false;
279
+ }
226
280
227
- * (gint32 * )res = memcmp ( & v1_cast , & result , SIZEOF_V128 ) == 0 ;
281
+ * (gint32 * )res = succeeded ? 1 : 0 ;
228
282
}
229
283
230
284
// op_Multiply
0 commit comments