authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-01-22 03:44:24+01:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-01-22 20:56:30+01:00
log35e804bfb8c57e29eda8ecb18f671b720f469af4
treeda47a3d5dd39978e4011f0a54719326c2f51e5f6
parentea1502974dd991c0ed4c58dd54fb96cf7080f293
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

wasm2c: Implement nontrapping_fptoint support.


2 files changed, 93 insertions(+), 4 deletions(-)

build.zig+2-2
...@@ -599,9 +599,8 @@ fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void {...@@ -599,9 +599,8 @@ fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void {
599 .target = b.resolveTargetQuery(std.Target.Query.parse(.{599 .target = b.resolveTargetQuery(std.Target.Query.parse(.{
600 .arch_os_abi = "wasm32-wasi",600 .arch_os_abi = "wasm32-wasi",
601 // * `extended_const` is not supported by the `wasm-opt` version in CI.601 // * `extended_const` is not supported by the `wasm-opt` version in CI.
602 // * `nontrapping_fptoint` is not supported by `wasm2c`.
603 // * `nontrapping_bulk_memory_len0` is supported by `wasm2c`.602 // * `nontrapping_bulk_memory_len0` is supported by `wasm2c`.
604 .cpu_features = "baseline-extended_const-nontrapping_fptoint+nontrapping_bulk_memory_len0",603 .cpu_features = "baseline-extended_const+nontrapping_bulk_memory_len0",
605 }) catch unreachable),604 }) catch unreachable),
606 });605 });
607606
...@@ -645,6 +644,7 @@ fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void {...@@ -645,6 +644,7 @@ fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void {
645 "-Oz",644 "-Oz",
646 "--enable-bulk-memory",645 "--enable-bulk-memory",
647 "--enable-mutable-globals",646 "--enable-mutable-globals",
647 "--enable-nontrapping-float-to-int",
648 "--enable-sign-ext",648 "--enable-sign-ext",
649 });649 });
650 run_opt.addArtifactArg(exe);650 run_opt.addArtifactArg(exe);
stage1/wasm2c.c+91-2
...@@ -109,7 +109,8 @@ int main(int argc, char **argv) {...@@ -109,7 +109,8 @@ int main(int argc, char **argv) {
109109
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;
20852174
2086 case WasmPrefixedOpcode_memory_init:2175 case WasmPrefixedOpcode_memory_init:
2087 (void)InputStream_readLeb128_u32(&in);2176 (void)InputStream_readLeb128_u32(&in);