summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/c-writer.cc12
-rw-r--r--src/prebuilt/wasm2c.include.c128
-rw-r--r--src/wasm2c.c.tmpl128
3 files changed, 210 insertions, 58 deletions
diff --git a/src/c-writer.cc b/src/c-writer.cc
index de34cb61..e2bef4a3 100644
--- a/src/c-writer.cc
+++ b/src/c-writer.cc
@@ -2214,11 +2214,11 @@ void CWriter::Write(const UnaryExpr& expr) {
break;
case Opcode::F32Abs:
- WriteSimpleUnaryExpr(expr.opcode, "fabsf");
+ WriteSimpleUnaryExpr(expr.opcode, "wasm_rt_fabsf");
break;
case Opcode::F64Abs:
- WriteSimpleUnaryExpr(expr.opcode, "fabs");
+ WriteSimpleUnaryExpr(expr.opcode, "wasm_rt_fabs");
break;
case Opcode::F32Sqrt:
@@ -2246,19 +2246,19 @@ void CWriter::Write(const UnaryExpr& expr) {
break;
case Opcode::F32Trunc:
- WriteSimpleUnaryExpr(expr.opcode, "truncf");
+ WriteSimpleUnaryExpr(expr.opcode, "wasm_rt_truncf");
break;
case Opcode::F64Trunc:
- WriteSimpleUnaryExpr(expr.opcode, "trunc");
+ WriteSimpleUnaryExpr(expr.opcode, "wasm_rt_trunc");
break;
case Opcode::F32Nearest:
- WriteSimpleUnaryExpr(expr.opcode, "nearbyintf");
+ WriteSimpleUnaryExpr(expr.opcode, "wasm_rt_nearbyintf");
break;
case Opcode::F64Nearest:
- WriteSimpleUnaryExpr(expr.opcode, "nearbyint");
+ WriteSimpleUnaryExpr(expr.opcode, "wasm_rt_nearbyint");
break;
case Opcode::I32Extend8S:
diff --git a/src/prebuilt/wasm2c.include.c b/src/prebuilt/wasm2c.include.c
index bb23139b..cf511212 100644
--- a/src/prebuilt/wasm2c.include.c
+++ b/src/prebuilt/wasm2c.include.c
@@ -6,8 +6,6 @@ const char SECTION_NAME(includes)[] =
;
const char SECTION_NAME(declarations)[] =
-"#define UNLIKELY(x) __builtin_expect(!!(x), 0)\n"
-"#define LIKELY(x) __builtin_expect(!!(x), 1)\n"
"\n"
"#define TRAP(x) (wasm_rt_trap(WASM_RT_TRAP_##x), 0)\n"
"\n"
@@ -25,13 +23,13 @@ const char SECTION_NAME(declarations)[] =
" || TRAP(CALL_INDIRECT) \\\n"
" , ((t)table.data[x].func)(__VA_ARGS__))\n"
"\n"
-"#define RANGE_CHECK(mem, a, t) \\\n"
-" if (UNLIKELY((a) + sizeof(t) > mem->size)) TRAP(OOB)\n"
+"#define RANGE_CHECK(mem, offset, len) \\\n"
+" if (UNLIKELY(offset + (uint64_t)len > mem->size)) TRAP(OOB)\n"
"\n"
"#if WASM_RT_MEMCHECK_SIGNAL_HANDLER\n"
"#define MEMCHECK(mem, a, t)\n"
"#else\n"
-"#define MEMCHECK(mem, a, t) RANGE_CHECK(mem, a, t)\n"
+"#define MEMCHECK(mem, a, t) RANGE_CHECK(mem, a, sizeof(t))\n"
"#endif\n"
"\n"
"#if WABT_BIG_ENDIAN\n"
@@ -45,45 +43,48 @@ const char SECTION_NAME(declarations)[] =
" dest_chars[n - i - 1] = cursor;\n"
" }\n"
"}\n"
-"#define LOAD_DATA(m, o, i, s) do { \\\n"
-" RANGE_CHECK((&m), m.size - o - s, char[s]); \\\n"
+"#define LOAD_DATA(m, o, i, s) \\\n"
+" do { \\\n"
+" RANGE_CHECK((&m), m.size - o - s, s); \\\n"
" load_data(&(m.data[m.size - o - s]), i, s); \\\n"
" } while (0)\n"
-"#define DEFINE_LOAD(name, t1, t2, t3) \\\n"
-" static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \\\n"
-" MEMCHECK(mem, addr, t1); \\\n"
-" t1 result; \\\n"
-" __builtin_memcpy(&result, &mem->data[mem->size - addr - sizeof(t1)], sizeof(t1)); \\\n"
-" return (t3)(t2)result; \\\n"
+"#define DEFINE_LOAD(name, t1, t2, t3) \\\n"
+" static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \\\n"
+" MEMCHECK(mem, addr, t1); \\\n"
+" t1 result; \\\n"
+" wasm_rt_memcpy(&result, &mem->data[mem->size - addr - sizeof(t1)], \\\n"
+" sizeof(t1)); \\\n"
+" return (t3)(t2)result; \\\n"
" }\n"
"\n"
-"#define DEFINE_STORE(name, t1, t2) \\\n"
-" static inline void name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \\\n"
-" MEMCHECK(mem, addr, t1); \\\n"
-" t1 wrapped = (t1)value; \\\n"
-" __builtin_memcpy(&mem->data[mem->size - addr - sizeof(t1)], &wrapped, sizeof(t1)); \\\n"
+"#define DEFINE_STORE(name, t1, t2) \\\n"
+" static inline void name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \\\n"
+" MEMCHECK(mem, addr, t1); \\\n"
+" t1 wrapped = (t1)value; \\\n"
+" wasm_rt_memcpy(&mem->data[mem->size - addr - sizeof(t1)], &wrapped, \\\n"
+" sizeof(t1)); \\\n"
" }\n"
"#else\n"
"static inline void load_data(void *dest, const void *src, size_t n) {\n"
" memcpy(dest, src, n);\n"
"}\n"
"#define LOAD_DATA(m, o, i, s) do { \\\n"
-" RANGE_CHECK((&m), o, char[s]); \\\n"
+" RANGE_CHECK((&m), o, s); \\\n"
" load_data(&(m.data[o]), i, s); \\\n"
" } while (0)\n"
-"#define DEFINE_LOAD(name, t1, t2, t3) \\\n"
-" static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \\\n"
-" MEMCHECK(mem, addr, t1); \\\n"
-" t1 result; \\\n"
-" __builtin_memcpy(&result, &mem->data[addr], sizeof(t1)); \\\n"
-" return (t3)(t2)result; \\\n"
+"#define DEFINE_LOAD(name, t1, t2, t3) \\\n"
+" static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \\\n"
+" MEMCHECK(mem, addr, t1); \\\n"
+" t1 result; \\\n"
+" wasm_rt_memcpy(&result, &mem->data[addr], sizeof(t1)); \\\n"
+" return (t3)(t2)result; \\\n"
" }\n"
"\n"
"#define DEFINE_STORE(name, t1, t2) \\\n"
" static inline void name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \\\n"
" MEMCHECK(mem, addr, t1); \\\n"
" t1 wrapped = (t1)value; \\\n"
-" __builtin_memcpy(&mem->data[addr], &wrapped, sizeof(t1)); \\\n"
+" wasm_rt_memcpy(&mem->data[addr], &wrapped, sizeof(t1)); \\\n"
" }\n"
"#endif\n"
"\n"
@@ -111,6 +112,79 @@ const char SECTION_NAME(declarations)[] =
"DEFINE_STORE(i64_store16, u16, u64)\n"
"DEFINE_STORE(i64_store32, u32, u64)\n"
"\n"
+"#if defined(_MSC_VER)\n"
+"\n"
+"#include <intrin.h>\n"
+"\n"
+"// Adapted from\n"
+"// https://github.com/nemequ/portable-snippets/blob/master/builtin/builtin.h\n"
+"\n"
+"static inline int I64_CLZ(unsigned long long v) {\n"
+" unsigned long r = 0;\n"
+"#if defined(_M_AMD64) || defined(_M_ARM)\n"
+" if (_BitScanReverse64(&r, v)) {\n"
+" return 63 - r;\n"
+" }\n"
+"#else\n"
+" if (_BitScanReverse(&r, (unsigned long) (v >> 32))) {\n"
+" return 31 - r;\n"
+" } else if (_BitScanReverse(&r, (unsigned long) v)) {\n"
+" return 63 - r;\n"
+" }\n"
+"#endif\n"
+" return 64;\n"
+"}\n"
+"\n"
+"static inline int I32_CLZ(unsigned long v) {\n"
+" unsigned long r = 0;\n"
+" if (_BitScanReverse(&r, v)) {\n"
+" return 31 - r;\n"
+" }\n"
+" return 32;\n"
+"}\n"
+"\n"
+"static inline int I64_CTZ(unsigned long long v) {\n"
+" if (!v) {\n"
+" return 64;\n"
+" }\n"
+" unsigned long r = 0;\n"
+"#if defined(_M_AMD64) || defined(_M_ARM)\n"
+" _BitScanForward64(&r, v);\n"
+" return (int) r;\n"
+"#else\n"
+" if (_BitScanForward(&r, (unsigned int) (v))) {\n"
+" return (int) (r);\n"
+" }\n"
+"\n"
+" _BitScanForward(&r, (unsigned int) (v >> 32));\n"
+" return (int) (r + 32);\n"
+"#endif\n"
+"}\n"
+"\n"
+"static inline int I32_CTZ(unsigned long v) {\n"
+" if (!v) {\n"
+" return 32;\n"
+" }\n"
+" unsigned long r = 0;\n"
+" _BitScanForward(&r, v);\n"
+" return (int) r;\n"
+"}\n"
+"\n"
+"#define POPCOUNT_DEFINE_PORTABLE(f_n, T) \\\n"
+" static inline u32 f_n(T x) { \\\n"
+" x = x - ((x >> 1) & (T)~(T)0/3); \\\n"
+" x = (x & (T)~(T)0/15*3) + ((x >> 2) & (T)~(T)0/15*3); \\\n"
+" x = (x + (x >> 4)) & (T)~(T)0/255*15; \\\n"
+" return (T)(x * ((T)~(T)0/255)) >> (sizeof(T) - 1) * 8; \\\n"
+" }\n"
+"\n"
+"POPCOUNT_DEFINE_PORTABLE(I32_POPCNT, u32)\n"
+"POPCOUNT_DEFINE_PORTABLE(I64_POPCNT, u64)\n"
+"\n"
+"#undef POPCOUNT_DEFINE_PORTABLE\n"
+"\n"
+"#else\n"
+"\n"
"#define I32_CLZ(x) ((x) ? __builtin_clz(x) : 32)\n"
"#define I64_CLZ(x) ((x) ? __builtin_clzll(x) : 64)\n"
"#define I32_CTZ(x) ((x) ? __builtin_ctz(x) : 32)\n"
@@ -118,6 +192,8 @@ const char SECTION_NAME(declarations)[] =
"#define I32_POPCNT(x) (__builtin_popcount(x))\n"
"#define I64_POPCNT(x) (__builtin_popcountll(x))\n"
"\n"
+"#endif\n"
+"\n"
"#define DIV_S(ut, min, x, y) \\\n"
" ((UNLIKELY((y) == 0)) ? TRAP(DIV_BY_ZERO) \\\n"
" : (UNLIKELY((x) == min && (y) == -1)) ? TRAP(INT_OVERFLOW) \\\n"
diff --git a/src/wasm2c.c.tmpl b/src/wasm2c.c.tmpl
index f6bcc941..d7ba6831 100644
--- a/src/wasm2c.c.tmpl
+++ b/src/wasm2c.c.tmpl
@@ -3,8 +3,6 @@
#include <math.h>
#include <string.h>
%%declarations
-#define UNLIKELY(x) __builtin_expect(!!(x), 0)
-#define LIKELY(x) __builtin_expect(!!(x), 1)
#define TRAP(x) (wasm_rt_trap(WASM_RT_TRAP_##x), 0)
@@ -22,13 +20,13 @@
|| TRAP(CALL_INDIRECT) \
, ((t)table.data[x].func)(__VA_ARGS__))
-#define RANGE_CHECK(mem, a, t) \
- if (UNLIKELY((a) + sizeof(t) > mem->size)) TRAP(OOB)
+#define RANGE_CHECK(mem, offset, len) \
+ if (UNLIKELY(offset + (uint64_t)len > mem->size)) TRAP(OOB)
#if WASM_RT_MEMCHECK_SIGNAL_HANDLER
#define MEMCHECK(mem, a, t)
#else
-#define MEMCHECK(mem, a, t) RANGE_CHECK(mem, a, t)
+#define MEMCHECK(mem, a, t) RANGE_CHECK(mem, a, sizeof(t))
#endif
#if WABT_BIG_ENDIAN
@@ -42,45 +40,48 @@ static inline void load_data(void *dest, const void *src, size_t n) {
dest_chars[n - i - 1] = cursor;
}
}
-#define LOAD_DATA(m, o, i, s) do { \
- RANGE_CHECK((&m), m.size - o - s, char[s]); \
+#define LOAD_DATA(m, o, i, s) \
+ do { \
+ RANGE_CHECK((&m), m.size - o - s, s); \
load_data(&(m.data[m.size - o - s]), i, s); \
} while (0)
-#define DEFINE_LOAD(name, t1, t2, t3) \
- static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \
- MEMCHECK(mem, addr, t1); \
- t1 result; \
- __builtin_memcpy(&result, &mem->data[mem->size - addr - sizeof(t1)], sizeof(t1)); \
- return (t3)(t2)result; \
+#define DEFINE_LOAD(name, t1, t2, t3) \
+ static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \
+ MEMCHECK(mem, addr, t1); \
+ t1 result; \
+ wasm_rt_memcpy(&result, &mem->data[mem->size - addr - sizeof(t1)], \
+ sizeof(t1)); \
+ return (t3)(t2)result; \
}
-#define DEFINE_STORE(name, t1, t2) \
- static inline void name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \
- MEMCHECK(mem, addr, t1); \
- t1 wrapped = (t1)value; \
- __builtin_memcpy(&mem->data[mem->size - addr - sizeof(t1)], &wrapped, sizeof(t1)); \
+#define DEFINE_STORE(name, t1, t2) \
+ static inline void name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \
+ MEMCHECK(mem, addr, t1); \
+ t1 wrapped = (t1)value; \
+ wasm_rt_memcpy(&mem->data[mem->size - addr - sizeof(t1)], &wrapped, \
+ sizeof(t1)); \
}
#else
static inline void load_data(void *dest, const void *src, size_t n) {
memcpy(dest, src, n);
}
#define LOAD_DATA(m, o, i, s) do { \
- RANGE_CHECK((&m), o, char[s]); \
+ RANGE_CHECK((&m), o, s); \
load_data(&(m.data[o]), i, s); \
} while (0)
-#define DEFINE_LOAD(name, t1, t2, t3) \
- static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \
- MEMCHECK(mem, addr, t1); \
- t1 result; \
- __builtin_memcpy(&result, &mem->data[addr], sizeof(t1)); \
- return (t3)(t2)result; \
+#define DEFINE_LOAD(name, t1, t2, t3) \
+ static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \
+ MEMCHECK(mem, addr, t1); \
+ t1 result; \
+ wasm_rt_memcpy(&result, &mem->data[addr], sizeof(t1)); \
+ return (t3)(t2)result; \
}
#define DEFINE_STORE(name, t1, t2) \
static inline void name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \
MEMCHECK(mem, addr, t1); \
t1 wrapped = (t1)value; \
- __builtin_memcpy(&mem->data[addr], &wrapped, sizeof(t1)); \
+ wasm_rt_memcpy(&mem->data[addr], &wrapped, sizeof(t1)); \
}
#endif
@@ -108,6 +109,79 @@ DEFINE_STORE(i64_store8, u8, u64)
DEFINE_STORE(i64_store16, u16, u64)
DEFINE_STORE(i64_store32, u32, u64)
+#if defined(_MSC_VER)
+
+#include <intrin.h>
+
+// Adapted from
+// https://github.com/nemequ/portable-snippets/blob/master/builtin/builtin.h
+
+static inline int I64_CLZ(unsigned long long v) {
+ unsigned long r = 0;
+#if defined(_M_AMD64) || defined(_M_ARM)
+ if (_BitScanReverse64(&r, v)) {
+ return 63 - r;
+ }
+#else
+ if (_BitScanReverse(&r, (unsigned long) (v >> 32))) {
+ return 31 - r;
+ } else if (_BitScanReverse(&r, (unsigned long) v)) {
+ return 63 - r;
+ }
+#endif
+ return 64;
+}
+
+static inline int I32_CLZ(unsigned long v) {
+ unsigned long r = 0;
+ if (_BitScanReverse(&r, v)) {
+ return 31 - r;
+ }
+ return 32;
+}
+
+static inline int I64_CTZ(unsigned long long v) {
+ if (!v) {
+ return 64;
+ }
+ unsigned long r = 0;
+#if defined(_M_AMD64) || defined(_M_ARM)
+ _BitScanForward64(&r, v);
+ return (int) r;
+#else
+ if (_BitScanForward(&r, (unsigned int) (v))) {
+ return (int) (r);
+ }
+
+ _BitScanForward(&r, (unsigned int) (v >> 32));
+ return (int) (r + 32);
+#endif
+}
+
+static inline int I32_CTZ(unsigned long v) {
+ if (!v) {
+ return 32;
+ }
+ unsigned long r = 0;
+ _BitScanForward(&r, v);
+ return (int) r;
+}
+
+#define POPCOUNT_DEFINE_PORTABLE(f_n, T) \
+ static inline u32 f_n(T x) { \
+ x = x - ((x >> 1) & (T)~(T)0/3); \
+ x = (x & (T)~(T)0/15*3) + ((x >> 2) & (T)~(T)0/15*3); \
+ x = (x + (x >> 4)) & (T)~(T)0/255*15; \
+ return (T)(x * ((T)~(T)0/255)) >> (sizeof(T) - 1) * 8; \
+ }
+
+POPCOUNT_DEFINE_PORTABLE(I32_POPCNT, u32)
+POPCOUNT_DEFINE_PORTABLE(I64_POPCNT, u64)
+
+#undef POPCOUNT_DEFINE_PORTABLE
+
+#else
+
#define I32_CLZ(x) ((x) ? __builtin_clz(x) : 32)
#define I64_CLZ(x) ((x) ? __builtin_clzll(x) : 64)
#define I32_CTZ(x) ((x) ? __builtin_ctz(x) : 32)
@@ -115,6 +189,8 @@ DEFINE_STORE(i64_store32, u32, u64)
#define I32_POPCNT(x) (__builtin_popcount(x))
#define I64_POPCNT(x) (__builtin_popcountll(x))
+#endif
+
#define DIV_S(ut, min, x, y) \
((UNLIKELY((y) == 0)) ? TRAP(DIV_BY_ZERO) \
: (UNLIKELY((x) == min && (y) == -1)) ? TRAP(INT_OVERFLOW) \