| ... | @@ -109,7 +109,8 @@ int main(int argc, char **argv) { | ... | @@ -109,7 +109,8 @@ int main(int argc, char **argv) { |
| 109 | | 109 | |
| 110 | FILE *out = fopen(argv[2], "wb"); | 110 | FILE *out = fopen(argv[2], "wb"); |
| 111 | if (out == NULL) panic("unable to open output file"); | 111 | if (out == NULL) panic("unable to open output file"); |
| 112 | fputs("#include <math.h>\n" | 112 | fputs("#include <float.h>\n" |
| | 113 | "#include <math.h>\n" |
| 113 | "#include <stdint.h>\n" | 114 | "#include <stdint.h>\n" |
| 114 | "#include <stdlib.h>\n" | 115 | "#include <stdlib.h>\n" |
| 115 | "#include <string.h>\n" | 116 | "#include <string.h>\n" |
| ... | @@ -273,6 +274,47 @@ int main(int argc, char **argv) { | ... | @@ -273,6 +274,47 @@ int main(int argc, char **argv) { |
| 273 | " return dst;\n" | 274 | " return dst;\n" |
| 274 | "}\n" | 275 | "}\n" |
| 275 | "\n" | 276 | "\n" |
| | 277 | "static uint32_t i32_trunc_sat_f32(const float src) {\n" |
| | 278 | " if (isnan(src)) return 0;\n" |
| | 279 | " if (isinf(src)) return (uint32_t)(signbit(src) == 0 ? INT32_MAX : INT32_MIN);\n" |
| | 280 | " return (uint32_t)(int32_t)src;\n" |
| | 281 | "}\n" |
| | 282 | "static uint32_t u32_trunc_sat_f32(const float src) {\n" |
| | 283 | " if (isnan(src)) return 0;\n" |
| | 284 | " if (isinf(src)) return signbit(src) == 0 ? UINT32_MAX : 0;\n" |
| | 285 | " return (uint32_t)src;\n" |
| | 286 | "}\n" |
| | 287 | "static uint32_t i32_trunc_sat_f64(const double src) {\n" |
| | 288 | " if (isnan(src)) return 0;\n" |
| | 289 | " if (isinf(src)) return (uint32_t)(signbit(src) == 0 ? INT32_MAX : INT32_MIN);\n" |
| | 290 | " return (uint32_t)(int32_t)src;\n" |
| | 291 | "}\n" |
| | 292 | "static uint32_t u32_trunc_sat_f64(const double src) {\n" |
| | 293 | " if (isnan(src)) return 0;\n" |
| | 294 | " if (isinf(src)) return signbit(src) == 0 ? UINT32_MAX : 0;\n" |
| | 295 | " return (uint32_t)src;\n" |
| | 296 | "}\n" |
| | 297 | "static uint64_t i64_trunc_sat_f32(const float src) {\n" |
| | 298 | " if (isnan(src)) return 0;\n" |
| | 299 | " if (isinf(src)) return (uint64_t)(signbit(src) == 0 ? INT64_MAX : INT64_MIN);\n" |
| | 300 | " return (uint64_t)(int64_t)src;\n" |
| | 301 | "}\n" |
| | 302 | "static uint64_t u64_trunc_sat_f32(const float src) {\n" |
| | 303 | " if (isnan(src)) return 0;\n" |
| | 304 | " if (isinf(src)) return signbit(src) == 0 ? UINT64_MAX : 0;\n" |
| | 305 | " return (uint64_t)src;\n" |
| | 306 | "}\n" |
| | 307 | "static uint64_t i64_trunc_sat_f64(const double src) {\n" |
| | 308 | " if (isnan(src)) return 0;\n" |
| | 309 | " if (isinf(src)) return (uint64_t)(signbit(src) == 0 ? INT64_MAX : INT64_MIN);\n" |
| | 310 | " return (uint64_t)(int64_t)src;\n" |
| | 311 | "}\n" |
| | 312 | "static uint64_t u64_trunc_sat_f64(const double src) {\n" |
| | 313 | " if (isnan(src)) return 0;\n" |
| | 314 | " if (isinf(src)) return signbit(src) == 0 ? UINT64_MAX : 0;\n" |
| | 315 | " return (uint64_t)src;\n" |
| | 316 | "}\n" |
| | 317 | "\n" |
| 276 | "static uint32_t memory_grow(uint8_t **m, uint32_t *p, uint32_t *c, uint32_t n) {\n" | 318 | "static uint32_t memory_grow(uint8_t **m, uint32_t *p, uint32_t *c, uint32_t n) {\n" |
| 277 | " uint8_t *new_m = *m;\n" | 319 | " uint8_t *new_m = *m;\n" |
| 278 | " uint32_t r = *p;\n" | 320 | " uint32_t r = *p;\n" |
| ... | @@ -2074,14 +2116,61 @@ int main(int argc, char **argv) { | ... | @@ -2074,14 +2116,61 @@ int main(int argc, char **argv) { |
| 2074 | case WasmOpcode_prefixed: | 2116 | case WasmOpcode_prefixed: |
| 2075 | switch (InputStream_readLeb128_u32(&in)) { | 2117 | switch (InputStream_readLeb128_u32(&in)) { |
| 2076 | case WasmPrefixedOpcode_i32_trunc_sat_f32_s: | 2118 | case WasmPrefixedOpcode_i32_trunc_sat_f32_s: |
| | 2119 | if (unreachable_depth == 0) { |
| | 2120 | uint32_t lhs = FuncGen_stackPop(&fg); |
| | 2121 | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| | 2122 | fprintf(out, "i32_trunc_sat_f32(l%" PRIu32 ");\n", lhs); |
| | 2123 | } |
| | 2124 | break; |
| 2077 | case WasmPrefixedOpcode_i32_trunc_sat_f32_u: | 2125 | case WasmPrefixedOpcode_i32_trunc_sat_f32_u: |
| | 2126 | if (unreachable_depth == 0) { |
| | 2127 | uint32_t lhs = FuncGen_stackPop(&fg); |
| | 2128 | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| | 2129 | fprintf(out, "u32_trunc_sat_f32(l%" PRIu32 ");\n", lhs); |
| | 2130 | } |
| | 2131 | break; |
| 2078 | case WasmPrefixedOpcode_i32_trunc_sat_f64_s: | 2132 | case WasmPrefixedOpcode_i32_trunc_sat_f64_s: |
| | 2133 | if (unreachable_depth == 0) { |
| | 2134 | uint32_t lhs = FuncGen_stackPop(&fg); |
| | 2135 | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| | 2136 | fprintf(out, "i32_trunc_sat_f64(l%" PRIu32 ");\n", lhs); |
| | 2137 | } |
| | 2138 | break; |
| 2079 | case WasmPrefixedOpcode_i32_trunc_sat_f64_u: | 2139 | case WasmPrefixedOpcode_i32_trunc_sat_f64_u: |
| | 2140 | if (unreachable_depth == 0) { |
| | 2141 | uint32_t lhs = FuncGen_stackPop(&fg); |
| | 2142 | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| | 2143 | fprintf(out, "u32_trunc_sat_f64(l%" PRIu32 ");\n", lhs); |
| | 2144 | } |
| | 2145 | break; |
| 2080 | case WasmPrefixedOpcode_i64_trunc_sat_f32_s: | 2146 | case WasmPrefixedOpcode_i64_trunc_sat_f32_s: |
| | 2147 | if (unreachable_depth == 0) { |
| | 2148 | uint32_t lhs = FuncGen_stackPop(&fg); |
| | 2149 | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| | 2150 | fprintf(out, "i64_trunc_sat_f32(l%" PRIu32 ");\n", lhs); |
| | 2151 | } |
| | 2152 | break; |
| 2081 | case WasmPrefixedOpcode_i64_trunc_sat_f32_u: | 2153 | case WasmPrefixedOpcode_i64_trunc_sat_f32_u: |
| | 2154 | if (unreachable_depth == 0) { |
| | 2155 | uint32_t lhs = FuncGen_stackPop(&fg); |
| | 2156 | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| | 2157 | fprintf(out, "u64_trunc_sat_f32(l%" PRIu32 ");\n", lhs); |
| | 2158 | } |
| | 2159 | break; |
| 2082 | case WasmPrefixedOpcode_i64_trunc_sat_f64_s: | 2160 | case WasmPrefixedOpcode_i64_trunc_sat_f64_s: |
| | 2161 | if (unreachable_depth == 0) { |
| | 2162 | uint32_t lhs = FuncGen_stackPop(&fg); |
| | 2163 | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| | 2164 | fprintf(out, "i64_trunc_sat_f64(l%" PRIu32 ");\n", lhs); |
| | 2165 | } |
| | 2166 | break; |
| 2083 | case WasmPrefixedOpcode_i64_trunc_sat_f64_u: | 2167 | case WasmPrefixedOpcode_i64_trunc_sat_f64_u: |
| 2084 | if (unreachable_depth == 0) panic("unimplemented opcode"); | 2168 | if (unreachable_depth == 0) { |
| | 2169 | uint32_t lhs = FuncGen_stackPop(&fg); |
| | 2170 | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| | 2171 | fprintf(out, "u64_trunc_sat_f64(l%" PRIu32 ");\n", lhs); |
| | 2172 | } |
| | 2173 | break; |
| 2085 | | 2174 | |
| 2086 | case WasmPrefixedOpcode_memory_init: | 2175 | case WasmPrefixedOpcode_memory_init: |
| 2087 | (void)InputStream_readLeb128_u32(&in); | 2176 | (void)InputStream_readLeb128_u32(&in); |