22#include "interp-internals.h"
33#include "interp-simd.h"
44
5+ #if HOST_BROWSER
6+ #include <wasm_simd128.h>
7+ #endif
8+
59#ifdef INTERP_ENABLE_SIMD
610
711typedef gint64 v128_i8 __attribute__ ((vector_size (SIZEOF_V128 )));
@@ -12,6 +16,7 @@ typedef gint16 v128_i2 __attribute__ ((vector_size (SIZEOF_V128)));
1216typedef guint16 v128_u2 __attribute__ ((vector_size (SIZEOF_V128 )));
1317typedef gint8 v128_i1 __attribute__ ((vector_size (SIZEOF_V128 )));
1418typedef guint8 v128_u1 __attribute__ ((vector_size (SIZEOF_V128 )));
19+ typedef float v128_r4 __attribute__ ((vector_size (SIZEOF_V128 )));
1520
1621// get_AllBitsSet
1722static void
@@ -39,6 +44,12 @@ interp_v128_i4_op_addition (gpointer res, gpointer v1, gpointer v2)
3944 * (v128_i4 * )res = * (v128_i4 * )v1 + * (v128_i4 * )v2 ;
4045}
4146
47+ static void
48+ interp_v128_r4_op_addition (gpointer res , gpointer v1 , gpointer v2 )
49+ {
50+ * (v128_r4 * )res = * (v128_r4 * )v1 + * (v128_r4 * )v2 ;
51+ }
52+
4253// op_Subtraction
4354static void
4455interp_v128_i1_op_subtraction (gpointer res , gpointer v1 , gpointer v2 )
@@ -58,6 +69,12 @@ interp_v128_i4_op_subtraction (gpointer res, gpointer v1, gpointer v2)
5869 * (v128_i4 * )res = * (v128_i4 * )v1 - * (v128_i4 * )v2 ;
5970}
6071
72+ static void
73+ interp_v128_r4_op_subtraction (gpointer res , gpointer v1 , gpointer v2 )
74+ {
75+ * (v128_r4 * )res = * (v128_r4 * )v1 - * (v128_r4 * )v2 ;
76+ }
77+
6178// op_BitwiseAnd
6279static void
6380interp_v128_op_bitwise_and (gpointer res , gpointer v1 , gpointer v2 )
@@ -124,6 +141,18 @@ interp_v128_i4_op_multiply (gpointer res, gpointer v1, gpointer v2)
124141 * (v128_i4 * )res = * (v128_i4 * )v1 * * (v128_i4 * )v2 ;
125142}
126143
144+ static void
145+ interp_v128_r4_op_multiply (gpointer res , gpointer v1 , gpointer v2 )
146+ {
147+ * (v128_r4 * )res = * (v128_r4 * )v1 * * (v128_r4 * )v2 ;
148+ }
149+
150+ static void
151+ interp_v128_r4_op_division (gpointer res , gpointer v1 , gpointer v2 )
152+ {
153+ * (v128_r4 * )res = * (v128_r4 * )v1 / * (v128_r4 * )v2 ;
154+ }
155+
127156// op_UnaryNegation
128157static void
129158interp_v128_i1_op_negation (gpointer res , gpointer v1 )
@@ -535,32 +564,122 @@ interp_v128_i8_shuffle (gpointer res, gpointer v1, gpointer v2)
535564 V128_SHUFFLE (gint64 , guint64 );
536565}
537566
538- #define INTERP_SIMD_INTRINSIC_P_P (a ,b )
539- #define INTERP_SIMD_INTRINSIC_P_PP (a ,b )
540- #define INTERP_SIMD_INTRINSIC_P_PPP (a ,b )
567+ #define INTERP_SIMD_INTRINSIC_P_P (a ,b ,c )
568+ #define INTERP_SIMD_INTRINSIC_P_PP (a ,b ,c )
569+ #define INTERP_SIMD_INTRINSIC_P_PPP (a ,b ,c )
570+
571+ // For the wasm packed simd intrinsics we want to automatically generate the C implementations from
572+ // their corresponding clang intrinsics. See also:
573+ // https://github.com/llvm/llvm-project/blob/main/clang/lib/Headers/wasm_simd128.h
574+ // In this context V means Vector128 and P means void* pointer.
575+ #ifdef HOST_BROWSER
576+
577+ static v128_t
578+ _interp_wasm_simd_assert_not_reached (v128_t lhs , v128_t rhs ) {
579+ g_assert_not_reached ();
580+ }
581+
582+ #define INTERP_WASM_SIMD_INTRINSIC_V_P (id , c_intrinsic , wasm_opcode ) \
583+ static void \
584+ _mono_interp_simd_ ## id (gpointer res, gpointer v1) { \
585+ *((v128_t *)res) = c_intrinsic (v1); \
586+ }
587+
588+ #define INTERP_WASM_SIMD_INTRINSIC_V_V (id , c_intrinsic , wasm_opcode ) \
589+ static void \
590+ _mono_interp_simd_ ## id (gpointer res, gpointer v1) { \
591+ *((v128_t *)res) = c_intrinsic (*((v128_t *)v1)); \
592+ }
593+
594+ #define INTERP_WASM_SIMD_INTRINSIC_I_V (id , c_intrinsic , wasm_opcode ) \
595+ static void \
596+ _mono_interp_simd_ ## id (gpointer res, gpointer v1) { \
597+ *((int32_t *)res) = c_intrinsic (*((v128_t *)v1)); \
598+ }
599+
600+ #define INTERP_WASM_SIMD_INTRINSIC_V_VV (id , c_intrinsic , wasm_opcode ) \
601+ static void \
602+ _mono_interp_simd_ ## id (gpointer res, gpointer v1, gpointer v2) { \
603+ *((v128_t *)res) = c_intrinsic (*((v128_t *)v1), *((v128_t *)v2)); \
604+ }
605+
606+ #define INTERP_WASM_SIMD_INTRINSIC_V_VI (id , c_intrinsic , wasm_opcode ) \
607+ static void \
608+ _mono_interp_simd_ ## id (gpointer res, gpointer v1, gpointer v2) { \
609+ *((v128_t *)res) = c_intrinsic (*((v128_t *)v1), *((int *)v2)); \
610+ }
611+
612+ #define INTERP_WASM_SIMD_INTRINSIC_V_VVV (id , c_intrinsic , wasm_opcode ) \
613+ static void \
614+ _mono_interp_simd_ ## id (gpointer res, gpointer v1, gpointer v2, gpointer v3) { \
615+ *((v128_t *)res) = c_intrinsic (*((v128_t *)v1), *((v128_t *)v2), *((v128_t *)v3)); \
616+ }
617+
618+ #include "interp-simd-intrins.def"
619+
620+ #undef INTERP_WASM_SIMD_INTRINSIC_V_P
621+ #undef INTERP_WASM_SIMD_INTRINSIC_V_V
622+ #undef INTERP_WASM_SIMD_INTRINSIC_I_V
623+ #undef INTERP_WASM_SIMD_INTRINSIC_V_VV
624+ #undef INTERP_WASM_SIMD_INTRINSIC_V_VI
625+ #undef INTERP_WASM_SIMD_INTRINSIC_V_VVV
626+
627+ // Now generate the wasm opcode tables for the intrinsics
628+
629+ #undef INTERP_SIMD_INTRINSIC_P_P
630+ #define INTERP_SIMD_INTRINSIC_P_P (a ,b ,c ) c,
631+
632+ int interp_simd_p_p_wasm_opcode_table [] = {
633+ #include "interp-simd-intrins.def"
634+ };
635+
636+ #undef INTERP_SIMD_INTRINSIC_P_P
637+ #define INTERP_SIMD_INTRINSIC_P_P (a ,b ,c )
638+
639+ #undef INTERP_SIMD_INTRINSIC_P_PP
640+ #define INTERP_SIMD_INTRINSIC_P_PP (a ,b ,c ) c,
641+
642+ int interp_simd_p_pp_wasm_opcode_table [] = {
643+ #include "interp-simd-intrins.def"
644+ };
645+
646+ #undef INTERP_SIMD_INTRINSIC_P_PP
647+ #define INTERP_SIMD_INTRINSIC_P_PP (a ,b ,c )
648+
649+ #undef INTERP_SIMD_INTRINSIC_P_PPP
650+ #define INTERP_SIMD_INTRINSIC_P_PPP (a ,b ,c ) c,
651+
652+ int interp_simd_p_ppp_wasm_opcode_table [] = {
653+ #include "interp-simd-intrins.def"
654+ };
655+
656+ #undef INTERP_SIMD_INTRINSIC_P_PPP
657+ #define INTERP_SIMD_INTRINSIC_P_PPP (a ,b ,c )
658+
659+ #endif // HOST_BROWSER
541660
542661#undef INTERP_SIMD_INTRINSIC_P_P
543- #define INTERP_SIMD_INTRINSIC_P_P (a ,b ) b,
662+ #define INTERP_SIMD_INTRINSIC_P_P (a ,b , c ) b,
544663PP_SIMD_Method interp_simd_p_p_table [] = {
545664#include "interp-simd-intrins.def"
546665};
547666#undef INTERP_SIMD_INTRINSIC_P_P
548- #define INTERP_SIMD_INTRINSIC_P_P (a ,b )
667+ #define INTERP_SIMD_INTRINSIC_P_P (a ,b , c )
549668
550669#undef INTERP_SIMD_INTRINSIC_P_PP
551- #define INTERP_SIMD_INTRINSIC_P_PP (a ,b ) b,
670+ #define INTERP_SIMD_INTRINSIC_P_PP (a ,b , c ) b,
552671PPP_SIMD_Method interp_simd_p_pp_table [] = {
553672#include "interp-simd-intrins.def"
554673};
555674#undef INTERP_SIMD_INTRINSIC_P_PP
556- #define INTERP_SIMD_INTRINSIC_P_PP (a ,b )
675+ #define INTERP_SIMD_INTRINSIC_P_PP (a ,b , c )
557676
558677#undef INTERP_SIMD_INTRINSIC_P_PPP
559- #define INTERP_SIMD_INTRINSIC_P_PPP (a ,b ) b,
678+ #define INTERP_SIMD_INTRINSIC_P_PPP (a ,b , c ) b,
560679PPPP_SIMD_Method interp_simd_p_ppp_table [] = {
561680#include "interp-simd-intrins.def"
562681};
563682#undef INTERP_SIMD_INTRINSIC_P_PPP
564- #define INTERP_SIMD_INTRINSIC_P_PPP (a ,b )
683+ #define INTERP_SIMD_INTRINSIC_P_PPP (a ,b , c )
565684
566685#endif // INTERP_ENABLE_SIMD
0 commit comments