| ... | ... | @@ -109,7 +109,8 @@ int main(int argc, char **argv) { |
| 109 | 109 | |
| 110 | 110 | FILE *out = fopen(argv[2], "wb"); |
| 111 | 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 | 114 | "#include <stdint.h>\n" |
| 114 | 115 | "#include <stdlib.h>\n" |
| 115 | 116 | "#include <string.h>\n" |
| ... | ... | @@ -273,6 +274,47 @@ int main(int argc, char **argv) { |
| 273 | 274 | " return dst;\n" |
| 274 | 275 | "}\n" |
| 275 | 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 | 318 | "static uint32_t memory_grow(uint8_t **m, uint32_t *p, uint32_t *c, uint32_t n) {\n" |
| 277 | 319 | " uint8_t *new_m = *m;\n" |
| 278 | 320 | " uint32_t r = *p;\n" |
| ... | ... | @@ -2074,14 +2116,61 @@ int main(int argc, char **argv) { |
| 2074 | 2116 | case WasmOpcode_prefixed: |
| 2075 | 2117 | switch (InputStream_readLeb128_u32(&in)) { |
| 2076 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 2175 | case WasmPrefixedOpcode_memory_init: |
| 2087 | 2176 | (void)InputStream_readLeb128_u32(&in); |