summaryrefslogtreecommitdiff
path: root/wasm2c
diff options
context:
space:
mode:
authorWilly R. Vasquez <wrv@utexas.edu>2023-01-29 10:48:56 -0600
committerGitHub <noreply@github.com>2023-01-29 08:48:56 -0800
commit8a7b7497bdf78f9099f8d5a3a2c9bde87ddd52da (patch)
tree1996c3154a28f875248d4fed6fdfe54cd1b6c856 /wasm2c
parentc831b98d2ed0571cda9b3ed7acaddd0df2c5a934 (diff)
downloadwabt-8a7b7497bdf78f9099f8d5a3a2c9bde87ddd52da.tar.gz
wabt-8a7b7497bdf78f9099f8d5a3a2c9bde87ddd52da.tar.bz2
wabt-8a7b7497bdf78f9099f8d5a3a2c9bde87ddd52da.zip
wasm2c: add SIMD support (#2119)
This change incorporates [simd-everywhere](https://github.com/simd-everywhere/simde) into the wasm2c output, which maps wasm SIMD C intrinsics to any supported target architecture.
Diffstat (limited to 'wasm2c')
-rw-r--r--wasm2c/examples/fac/fac.c121
-rw-r--r--wasm2c/examples/fac/fac.h9
-rw-r--r--wasm2c/wasm-rt-impl.c2
-rw-r--r--wasm2c/wasm-rt.h1
4 files changed, 133 insertions, 0 deletions
diff --git a/wasm2c/examples/fac/fac.c b/wasm2c/examples/fac/fac.c
index 0245c10d..c00a60d0 100644
--- a/wasm2c/examples/fac/fac.c
+++ b/wasm2c/examples/fac/fac.c
@@ -157,6 +157,127 @@ DEFINE_STORE(i64_store8, u8, u64)
DEFINE_STORE(i64_store16, u16, u64)
DEFINE_STORE(i64_store32, u32, u64)
+#if defined(WASM_RT_ENABLE_SIMD)
+
+#ifdef __x86_64__
+#define SIMD_FORCE_READ(var) wasm_asm("" ::"x"(var));
+#else
+#define SIMD_FORCE_READ(var)
+#endif
+// TODO: equivalent constraint for ARM and other architectures
+
+#define DEFINE_SIMD_LOAD_FUNC(name, func, t) \
+ static inline v128 name(wasm_rt_memory_t* mem, u64 addr) { \
+ MEMCHECK(mem, addr, t); \
+ v128 result = func((v128*)&mem->data[addr]); \
+ SIMD_FORCE_READ(result); \
+ return result; \
+ }
+
+#define DEFINE_SIMD_LOAD_LANE(name, func, t, lane) \
+ static inline v128 name(wasm_rt_memory_t* mem, u64 addr, v128 vec) { \
+ MEMCHECK(mem, addr, t); \
+ v128 result = func((v128*)&mem->data[addr], vec, lane); \
+ SIMD_FORCE_READ(result); \
+ return result; \
+ }
+
+#define DEFINE_SIMD_STORE(name, t) \
+ static inline void name(wasm_rt_memory_t* mem, u64 addr, v128 value) { \
+ MEMCHECK(mem, addr, t); \
+ simde_wasm_v128_store((v128*)&mem->data[addr], value); \
+ }
+
+#define DEFINE_SIMD_STORE_LANE(name, func, t, lane) \
+ static inline void name(wasm_rt_memory_t* mem, u64 addr, v128 value) { \
+ MEMCHECK(mem, addr, t); \
+ func((v128*)&mem->data[addr], value, lane); \
+ }
+
+// clang-format off
+DEFINE_SIMD_LOAD_FUNC(v128_load, simde_wasm_v128_load, v128)
+
+DEFINE_SIMD_LOAD_FUNC(v128_load8_splat, simde_wasm_v128_load8_splat, u8)
+DEFINE_SIMD_LOAD_FUNC(v128_load16_splat, simde_wasm_v128_load16_splat, u16)
+DEFINE_SIMD_LOAD_FUNC(v128_load32_splat, simde_wasm_v128_load32_splat, u32)
+DEFINE_SIMD_LOAD_FUNC(v128_load64_splat, simde_wasm_v128_load64_splat, u64)
+
+DEFINE_SIMD_LOAD_FUNC(i16x8_load8x8, simde_wasm_i16x8_load8x8, u64)
+DEFINE_SIMD_LOAD_FUNC(u16x8_load8x8, simde_wasm_u16x8_load8x8, u64)
+DEFINE_SIMD_LOAD_FUNC(i32x4_load16x4, simde_wasm_i32x4_load16x4, u64)
+DEFINE_SIMD_LOAD_FUNC(u32x4_load16x4, simde_wasm_u32x4_load16x4, u64)
+DEFINE_SIMD_LOAD_FUNC(i64x2_load32x2, simde_wasm_i64x2_load32x2, u64)
+DEFINE_SIMD_LOAD_FUNC(u64x2_load32x2, simde_wasm_u64x2_load32x2, u64)
+
+DEFINE_SIMD_LOAD_FUNC(v128_load32_zero, simde_wasm_v128_load32_zero, u32)
+DEFINE_SIMD_LOAD_FUNC(v128_load64_zero, simde_wasm_v128_load64_zero, u64)
+
+DEFINE_SIMD_LOAD_LANE(v128_load8_lane0, simde_wasm_v128_load8_lane, u8, 0)
+DEFINE_SIMD_LOAD_LANE(v128_load8_lane1, simde_wasm_v128_load8_lane, u8, 1)
+DEFINE_SIMD_LOAD_LANE(v128_load8_lane2, simde_wasm_v128_load8_lane, u8, 2)
+DEFINE_SIMD_LOAD_LANE(v128_load8_lane3, simde_wasm_v128_load8_lane, u8, 3)
+DEFINE_SIMD_LOAD_LANE(v128_load8_lane4, simde_wasm_v128_load8_lane, u8, 4)
+DEFINE_SIMD_LOAD_LANE(v128_load8_lane5, simde_wasm_v128_load8_lane, u8, 5)
+DEFINE_SIMD_LOAD_LANE(v128_load8_lane6, simde_wasm_v128_load8_lane, u8, 6)
+DEFINE_SIMD_LOAD_LANE(v128_load8_lane7, simde_wasm_v128_load8_lane, u8, 7)
+DEFINE_SIMD_LOAD_LANE(v128_load8_lane8, simde_wasm_v128_load8_lane, u8, 8)
+DEFINE_SIMD_LOAD_LANE(v128_load8_lane9, simde_wasm_v128_load8_lane, u8, 9)
+DEFINE_SIMD_LOAD_LANE(v128_load8_lane10, simde_wasm_v128_load8_lane, u8, 10)
+DEFINE_SIMD_LOAD_LANE(v128_load8_lane11, simde_wasm_v128_load8_lane, u8, 11)
+DEFINE_SIMD_LOAD_LANE(v128_load8_lane12, simde_wasm_v128_load8_lane, u8, 12)
+DEFINE_SIMD_LOAD_LANE(v128_load8_lane13, simde_wasm_v128_load8_lane, u8, 13)
+DEFINE_SIMD_LOAD_LANE(v128_load8_lane14, simde_wasm_v128_load8_lane, u8, 14)
+DEFINE_SIMD_LOAD_LANE(v128_load8_lane15, simde_wasm_v128_load8_lane, u8, 15)
+DEFINE_SIMD_LOAD_LANE(v128_load16_lane0, simde_wasm_v128_load16_lane, u16, 0)
+DEFINE_SIMD_LOAD_LANE(v128_load16_lane1, simde_wasm_v128_load16_lane, u16, 1)
+DEFINE_SIMD_LOAD_LANE(v128_load16_lane2, simde_wasm_v128_load16_lane, u16, 2)
+DEFINE_SIMD_LOAD_LANE(v128_load16_lane3, simde_wasm_v128_load16_lane, u16, 3)
+DEFINE_SIMD_LOAD_LANE(v128_load16_lane4, simde_wasm_v128_load16_lane, u16, 4)
+DEFINE_SIMD_LOAD_LANE(v128_load16_lane5, simde_wasm_v128_load16_lane, u16, 5)
+DEFINE_SIMD_LOAD_LANE(v128_load16_lane6, simde_wasm_v128_load16_lane, u16, 6)
+DEFINE_SIMD_LOAD_LANE(v128_load16_lane7, simde_wasm_v128_load16_lane, u16, 7)
+DEFINE_SIMD_LOAD_LANE(v128_load32_lane0, simde_wasm_v128_load32_lane, u32, 0)
+DEFINE_SIMD_LOAD_LANE(v128_load32_lane1, simde_wasm_v128_load32_lane, u32, 1)
+DEFINE_SIMD_LOAD_LANE(v128_load32_lane2, simde_wasm_v128_load32_lane, u32, 2)
+DEFINE_SIMD_LOAD_LANE(v128_load32_lane3, simde_wasm_v128_load32_lane, u32, 3)
+DEFINE_SIMD_LOAD_LANE(v128_load64_lane0, simde_wasm_v128_load64_lane, u64, 0)
+DEFINE_SIMD_LOAD_LANE(v128_load64_lane1, simde_wasm_v128_load64_lane, u64, 1)
+
+DEFINE_SIMD_STORE(v128_store, v128)
+
+DEFINE_SIMD_STORE_LANE(v128_store8_lane0, simde_wasm_v128_store8_lane, u8, 0)
+DEFINE_SIMD_STORE_LANE(v128_store8_lane1, simde_wasm_v128_store8_lane, u8, 1)
+DEFINE_SIMD_STORE_LANE(v128_store8_lane2, simde_wasm_v128_store8_lane, u8, 2)
+DEFINE_SIMD_STORE_LANE(v128_store8_lane3, simde_wasm_v128_store8_lane, u8, 3)
+DEFINE_SIMD_STORE_LANE(v128_store8_lane4, simde_wasm_v128_store8_lane, u8, 4)
+DEFINE_SIMD_STORE_LANE(v128_store8_lane5, simde_wasm_v128_store8_lane, u8, 5)
+DEFINE_SIMD_STORE_LANE(v128_store8_lane6, simde_wasm_v128_store8_lane, u8, 6)
+DEFINE_SIMD_STORE_LANE(v128_store8_lane7, simde_wasm_v128_store8_lane, u8, 7)
+DEFINE_SIMD_STORE_LANE(v128_store8_lane8, simde_wasm_v128_store8_lane, u8, 8)
+DEFINE_SIMD_STORE_LANE(v128_store8_lane9, simde_wasm_v128_store8_lane, u8, 9)
+DEFINE_SIMD_STORE_LANE(v128_store8_lane10, simde_wasm_v128_store8_lane, u8, 10)
+DEFINE_SIMD_STORE_LANE(v128_store8_lane11, simde_wasm_v128_store8_lane, u8, 11)
+DEFINE_SIMD_STORE_LANE(v128_store8_lane12, simde_wasm_v128_store8_lane, u8, 12)
+DEFINE_SIMD_STORE_LANE(v128_store8_lane13, simde_wasm_v128_store8_lane, u8, 13)
+DEFINE_SIMD_STORE_LANE(v128_store8_lane14, simde_wasm_v128_store8_lane, u8, 14)
+DEFINE_SIMD_STORE_LANE(v128_store8_lane15, simde_wasm_v128_store8_lane, u8, 15)
+DEFINE_SIMD_STORE_LANE(v128_store16_lane0, simde_wasm_v128_store16_lane, u16, 0)
+DEFINE_SIMD_STORE_LANE(v128_store16_lane1, simde_wasm_v128_store16_lane, u16, 1)
+DEFINE_SIMD_STORE_LANE(v128_store16_lane2, simde_wasm_v128_store16_lane, u16, 2)
+DEFINE_SIMD_STORE_LANE(v128_store16_lane3, simde_wasm_v128_store16_lane, u16, 3)
+DEFINE_SIMD_STORE_LANE(v128_store16_lane4, simde_wasm_v128_store16_lane, u16, 4)
+DEFINE_SIMD_STORE_LANE(v128_store16_lane5, simde_wasm_v128_store16_lane, u16, 5)
+DEFINE_SIMD_STORE_LANE(v128_store16_lane6, simde_wasm_v128_store16_lane, u16, 6)
+DEFINE_SIMD_STORE_LANE(v128_store16_lane7, simde_wasm_v128_store16_lane, u16, 7)
+DEFINE_SIMD_STORE_LANE(v128_store32_lane0, simde_wasm_v128_store32_lane, u32, 0)
+DEFINE_SIMD_STORE_LANE(v128_store32_lane1, simde_wasm_v128_store32_lane, u32, 1)
+DEFINE_SIMD_STORE_LANE(v128_store32_lane2, simde_wasm_v128_store32_lane, u32, 2)
+DEFINE_SIMD_STORE_LANE(v128_store32_lane3, simde_wasm_v128_store32_lane, u32, 3)
+DEFINE_SIMD_STORE_LANE(v128_store64_lane0, simde_wasm_v128_store64_lane, u64, 0)
+DEFINE_SIMD_STORE_LANE(v128_store64_lane1, simde_wasm_v128_store64_lane, u64, 1)
+// clang-format on
+#endif
+
#if defined(_MSC_VER)
// Adapted from
diff --git a/wasm2c/examples/fac/fac.h b/wasm2c/examples/fac/fac.h
index 7700bc42..1354411a 100644
--- a/wasm2c/examples/fac/fac.h
+++ b/wasm2c/examples/fac/fac.h
@@ -6,6 +6,10 @@
#include "wasm-rt.h"
+#if defined(WASM_RT_ENABLE_SIMD)
+#include "simde/wasm/simd128.h"
+#endif
+
/* TODO(binji): only use stdint.h types in header */
#ifndef WASM_RT_CORE_TYPES_DEFINED
#define WASM_RT_CORE_TYPES_DEFINED
@@ -19,6 +23,11 @@ typedef uint64_t u64;
typedef int64_t s64;
typedef float f32;
typedef double f64;
+
+#if defined(WASM_RT_ENABLE_SIMD)
+typedef simde_v128_t v128;
+#endif
+
#endif
#ifdef __cplusplus
diff --git a/wasm2c/wasm-rt-impl.c b/wasm2c/wasm-rt-impl.c
index 0430e5f3..14597d9c 100644
--- a/wasm2c/wasm-rt-impl.c
+++ b/wasm2c/wasm-rt-impl.c
@@ -234,6 +234,7 @@ static void os_install_signal_handler(void) {
}
struct sigaction sa;
+ memset(&sa , '\0', sizeof(sa));
sa.sa_flags = SA_SIGINFO | SA_ONSTACK;
sigemptyset(&sa.sa_mask);
sa.sa_sigaction = os_signal_handler;
@@ -248,6 +249,7 @@ static void os_install_signal_handler(void) {
static void os_cleanup_signal_handler(void) {
/* Undo what was done in os_install_signal_handler */
struct sigaction sa;
+ memset(&sa , '\0', sizeof(sa));
sa.sa_handler = SIG_DFL;
if (sigaction(SIGSEGV, &sa, NULL) != 0 || sigaction(SIGBUS, &sa, NULL)) {
perror("sigaction failed");
diff --git a/wasm2c/wasm-rt.h b/wasm2c/wasm-rt.h
index 871fb8ce..abdd0d0d 100644
--- a/wasm2c/wasm-rt.h
+++ b/wasm2c/wasm-rt.h
@@ -167,6 +167,7 @@ typedef enum {
WASM_RT_I64,
WASM_RT_F32,
WASM_RT_F64,
+ WASM_RT_V128,
WASM_RT_FUNCREF,
WASM_RT_EXTERNREF,
} wasm_rt_type_t;