zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 35e804bfb8c57e29eda8ecb18f671b720f469af4 (tree)
parent ea1502974dd991c0ed4c58dd54fb96cf7080f293
Author: Alex Rønne Petersen <alex@alexrp.com>
Date:   Wed, 22 Jan 2025 03:44:24 +0100

wasm2c: Implement nontrapping_fptoint support.

Diffstat:
Mbuild.zig | 4++--
Mstage1/wasm2c.c | 93+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 93 insertions(+), 4 deletions(-)

diff --git a/build.zig b/build.zig @@ -599,9 +599,8 @@ fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void { .target = b.resolveTargetQuery(std.Target.Query.parse(.{ .arch_os_abi = "wasm32-wasi", // * `extended_const` is not supported by the `wasm-opt` version in CI. - // * `nontrapping_fptoint` is not supported by `wasm2c`. // * `nontrapping_bulk_memory_len0` is supported by `wasm2c`. - .cpu_features = "baseline-extended_const-nontrapping_fptoint+nontrapping_bulk_memory_len0", + .cpu_features = "baseline-extended_const+nontrapping_bulk_memory_len0", }) catch unreachable), }); @@ -645,6 +644,7 @@ fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void { "-Oz", "--enable-bulk-memory", "--enable-mutable-globals", + "--enable-nontrapping-float-to-int", "--enable-sign-ext", }); run_opt.addArtifactArg(exe); diff --git a/stage1/wasm2c.c b/stage1/wasm2c.c @@ -109,7 +109,8 @@ int main(int argc, char **argv) { FILE *out = fopen(argv[2], "wb"); if (out == NULL) panic("unable to open output file"); - fputs("#include <math.h>\n" + fputs("#include <float.h>\n" + "#include <math.h>\n" "#include <stdint.h>\n" "#include <stdlib.h>\n" "#include <string.h>\n" @@ -273,6 +274,47 @@ int main(int argc, char **argv) { " return dst;\n" "}\n" "\n" + "static uint32_t i32_trunc_sat_f32(const float src) {\n" + " if (isnan(src)) return 0;\n" + " if (isinf(src)) return (uint32_t)(signbit(src) == 0 ? INT32_MAX : INT32_MIN);\n" + " return (uint32_t)(int32_t)src;\n" + "}\n" + "static uint32_t u32_trunc_sat_f32(const float src) {\n" + " if (isnan(src)) return 0;\n" + " if (isinf(src)) return signbit(src) == 0 ? UINT32_MAX : 0;\n" + " return (uint32_t)src;\n" + "}\n" + "static uint32_t i32_trunc_sat_f64(const double src) {\n" + " if (isnan(src)) return 0;\n" + " if (isinf(src)) return (uint32_t)(signbit(src) == 0 ? INT32_MAX : INT32_MIN);\n" + " return (uint32_t)(int32_t)src;\n" + "}\n" + "static uint32_t u32_trunc_sat_f64(const double src) {\n" + " if (isnan(src)) return 0;\n" + " if (isinf(src)) return signbit(src) == 0 ? UINT32_MAX : 0;\n" + " return (uint32_t)src;\n" + "}\n" + "static uint64_t i64_trunc_sat_f32(const float src) {\n" + " if (isnan(src)) return 0;\n" + " if (isinf(src)) return (uint64_t)(signbit(src) == 0 ? INT64_MAX : INT64_MIN);\n" + " return (uint64_t)(int64_t)src;\n" + "}\n" + "static uint64_t u64_trunc_sat_f32(const float src) {\n" + " if (isnan(src)) return 0;\n" + " if (isinf(src)) return signbit(src) == 0 ? UINT64_MAX : 0;\n" + " return (uint64_t)src;\n" + "}\n" + "static uint64_t i64_trunc_sat_f64(const double src) {\n" + " if (isnan(src)) return 0;\n" + " if (isinf(src)) return (uint64_t)(signbit(src) == 0 ? INT64_MAX : INT64_MIN);\n" + " return (uint64_t)(int64_t)src;\n" + "}\n" + "static uint64_t u64_trunc_sat_f64(const double src) {\n" + " if (isnan(src)) return 0;\n" + " if (isinf(src)) return signbit(src) == 0 ? UINT64_MAX : 0;\n" + " return (uint64_t)src;\n" + "}\n" + "\n" "static uint32_t memory_grow(uint8_t **m, uint32_t *p, uint32_t *c, uint32_t n) {\n" " uint8_t *new_m = *m;\n" " uint32_t r = *p;\n" @@ -2074,14 +2116,61 @@ int main(int argc, char **argv) { case WasmOpcode_prefixed: switch (InputStream_readLeb128_u32(&in)) { case WasmPrefixedOpcode_i32_trunc_sat_f32_s: + if (unreachable_depth == 0) { + uint32_t lhs = FuncGen_stackPop(&fg); + FuncGen_stackPush(&fg, out, WasmValType_i32); + fprintf(out, "i32_trunc_sat_f32(l%" PRIu32 ");\n", lhs); + } + break; case WasmPrefixedOpcode_i32_trunc_sat_f32_u: + if (unreachable_depth == 0) { + uint32_t lhs = FuncGen_stackPop(&fg); + FuncGen_stackPush(&fg, out, WasmValType_i32); + fprintf(out, "u32_trunc_sat_f32(l%" PRIu32 ");\n", lhs); + } + break; case WasmPrefixedOpcode_i32_trunc_sat_f64_s: + if (unreachable_depth == 0) { + uint32_t lhs = FuncGen_stackPop(&fg); + FuncGen_stackPush(&fg, out, WasmValType_i32); + fprintf(out, "i32_trunc_sat_f64(l%" PRIu32 ");\n", lhs); + } + break; case WasmPrefixedOpcode_i32_trunc_sat_f64_u: + if (unreachable_depth == 0) { + uint32_t lhs = FuncGen_stackPop(&fg); + FuncGen_stackPush(&fg, out, WasmValType_i32); + fprintf(out, "u32_trunc_sat_f64(l%" PRIu32 ");\n", lhs); + } + break; case WasmPrefixedOpcode_i64_trunc_sat_f32_s: + if (unreachable_depth == 0) { + uint32_t lhs = FuncGen_stackPop(&fg); + FuncGen_stackPush(&fg, out, WasmValType_i32); + fprintf(out, "i64_trunc_sat_f32(l%" PRIu32 ");\n", lhs); + } + break; case WasmPrefixedOpcode_i64_trunc_sat_f32_u: + if (unreachable_depth == 0) { + uint32_t lhs = FuncGen_stackPop(&fg); + FuncGen_stackPush(&fg, out, WasmValType_i32); + fprintf(out, "u64_trunc_sat_f32(l%" PRIu32 ");\n", lhs); + } + break; case WasmPrefixedOpcode_i64_trunc_sat_f64_s: + if (unreachable_depth == 0) { + uint32_t lhs = FuncGen_stackPop(&fg); + FuncGen_stackPush(&fg, out, WasmValType_i32); + fprintf(out, "i64_trunc_sat_f64(l%" PRIu32 ");\n", lhs); + } + break; case WasmPrefixedOpcode_i64_trunc_sat_f64_u: - if (unreachable_depth == 0) panic("unimplemented opcode"); + if (unreachable_depth == 0) { + uint32_t lhs = FuncGen_stackPop(&fg); + FuncGen_stackPush(&fg, out, WasmValType_i32); + fprintf(out, "u64_trunc_sat_f64(l%" PRIu32 ");\n", lhs); + } + break; case WasmPrefixedOpcode_memory_init: (void)InputStream_readLeb128_u32(&in);