diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/c-writer.cc | 12 | ||||
-rw-r--r-- | src/prebuilt/wasm2c.include.c | 128 | ||||
-rw-r--r-- | src/wasm2c.c.tmpl | 128 |
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) \ |