authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-01-23 18:41:11+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2025-01-23 18:41:11+01:00
logd916954bee0f477bcada0693d4aa952197cf1eef
treea28e9b0f02df80b4c484119dffc48c8e5c16d7d2
parentf3c29dcb247be5e50d2d05f9fb2e814ebf115a86
parent68c6a88770420b897467073ec328ddc2bb3317d6
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #22098 from alexrp/wasm-generic-baseline

`std.Target`: Use `lime1` as wasm baseline model and `mvp` as generic model

8 files changed, 226 insertions(+), 20 deletions(-)

build.zig+8-7
...@@ -594,15 +594,14 @@ pub fn build(b: *std.Build) !void {...@@ -594,15 +594,14 @@ pub fn build(b: *std.Build) !void {
594fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void {594fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void {
595 const semver = try std.SemanticVersion.parse(version);595 const semver = try std.SemanticVersion.parse(version);
596596
597 var target_query: std.Target.Query = .{
598 .cpu_arch = .wasm32,
599 .os_tag = .wasi,
600 };
601 target_query.cpu_features_add.addFeature(@intFromEnum(std.Target.wasm.Feature.bulk_memory));
602
603 const exe = addCompilerStep(b, .{597 const exe = addCompilerStep(b, .{
604 .optimize = .ReleaseSmall,598 .optimize = .ReleaseSmall,
605 .target = b.resolveTargetQuery(target_query),599 .target = b.resolveTargetQuery(std.Target.Query.parse(.{
600 .arch_os_abi = "wasm32-wasi",
601 // * `extended_const` is not supported by the `wasm-opt` version in CI.
602 // * `nontrapping_bulk_memory_len0` is supported by `wasm2c`.
603 .cpu_features = "baseline-extended_const+nontrapping_bulk_memory_len0",
604 }) catch unreachable),
606 });605 });
607606
608 const exe_options = b.addOptions();607 const exe_options = b.addOptions();
...@@ -644,6 +643,8 @@ fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void {...@@ -644,6 +643,8 @@ fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void {
644 "wasm-opt",643 "wasm-opt",
645 "-Oz",644 "-Oz",
646 "--enable-bulk-memory",645 "--enable-bulk-memory",
646 "--enable-mutable-globals",
647 "--enable-nontrapping-float-to-int",
647 "--enable-sign-ext",648 "--enable-sign-ext",
648 });649 });
649 run_opt.addArtifactArg(exe);650 run_opt.addArtifactArg(exe);
lib/std/Target.zig+2-1
...@@ -1958,7 +1958,7 @@ pub const Cpu = struct {...@@ -1958,7 +1958,7 @@ pub const Cpu = struct {
1958 .x86_64 => &x86.cpu.x86_64,1958 .x86_64 => &x86.cpu.x86_64,
1959 .nvptx, .nvptx64 => &nvptx.cpu.sm_20,1959 .nvptx, .nvptx64 => &nvptx.cpu.sm_20,
1960 .ve => &ve.cpu.generic,1960 .ve => &ve.cpu.generic,
1961 .wasm32, .wasm64 => &wasm.cpu.generic,1961 .wasm32, .wasm64 => &wasm.cpu.mvp,
1962 .xcore => &xcore.cpu.generic,1962 .xcore => &xcore.cpu.generic,
1963 .xtensa => &xtensa.cpu.generic,1963 .xtensa => &xtensa.cpu.generic,
19641964
...@@ -2012,6 +2012,7 @@ pub const Cpu = struct {...@@ -2012,6 +2012,7 @@ pub const Cpu = struct {
2012 else => generic(arch),2012 else => generic(arch),
2013 },2013 },
2014 .xcore => &xcore.cpu.xs1b_generic,2014 .xcore => &xcore.cpu.xs1b_generic,
2015 .wasm32, .wasm64 => &wasm.cpu.lime1,
20152016
2016 else => generic(arch),2017 else => generic(arch),
2017 };2018 };
lib/std/Target/wasm.zig+20
...@@ -13,6 +13,7 @@ pub const Feature = enum {...@@ -13,6 +13,7 @@ pub const Feature = enum {
13 multimemory,13 multimemory,
14 multivalue,14 multivalue,
15 mutable_globals,15 mutable_globals,
16 nontrapping_bulk_memory_len0,
16 nontrapping_fptoint,17 nontrapping_fptoint,
17 reference_types,18 reference_types,
18 relaxed_simd,19 relaxed_simd,
...@@ -70,6 +71,13 @@ pub const all_features = blk: {...@@ -70,6 +71,13 @@ pub const all_features = blk: {
70 .description = "Enable mutable globals",71 .description = "Enable mutable globals",
71 .dependencies = featureSet(&[_]Feature{}),72 .dependencies = featureSet(&[_]Feature{}),
72 };73 };
74 result[@intFromEnum(Feature.nontrapping_bulk_memory_len0)] = .{
75 .llvm_name = null,
76 .description = "Bulk memory operations with a zero length do not trap",
77 .dependencies = featureSet(&[_]Feature{
78 .bulk_memory,
79 }),
80 };
73 result[@intFromEnum(Feature.nontrapping_fptoint)] = .{81 result[@intFromEnum(Feature.nontrapping_fptoint)] = .{
74 .llvm_name = "nontrapping-fptoint",82 .llvm_name = "nontrapping-fptoint",
75 .description = "Enable non-trapping float-to-int conversion operators",83 .description = "Enable non-trapping float-to-int conversion operators",
...@@ -139,6 +147,18 @@ pub const cpu = struct {...@@ -139,6 +147,18 @@ pub const cpu = struct {
139 .sign_ext,147 .sign_ext,
140 }),148 }),
141 };149 };
150 pub const lime1: CpuModel = .{
151 .name = "lime1",
152 .llvm_name = null,
153 .features = featureSet(&[_]Feature{
154 .bulk_memory,
155 .extended_const,
156 .multivalue,
157 .mutable_globals,
158 .nontrapping_fptoint,
159 .sign_ext,
160 }),
161 };
142 pub const mvp: CpuModel = .{162 pub const mvp: CpuModel = .{
143 .name = "mvp",163 .name = "mvp",
144 .llvm_name = "mvp",164 .llvm_name = "mvp",
src/Compilation.zig-5
...@@ -4150,14 +4150,9 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -4150,14 +4150,9 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye
4150 .os_tag = .freestanding,4150 .os_tag = .freestanding,
4151 .cpu_features_add = std.Target.wasm.featureSet(&.{4151 .cpu_features_add = std.Target.wasm.featureSet(&.{
4152 .atomics,4152 .atomics,
4153 .bulk_memory,
4154 // .extended_const, not supported by Safari4153 // .extended_const, not supported by Safari
4155 .multivalue,
4156 .mutable_globals,
4157 .nontrapping_fptoint,
4158 .reference_types,4154 .reference_types,
4159 //.relaxed_simd, not supported by Firefox or Safari4155 //.relaxed_simd, not supported by Firefox or Safari
4160 .sign_ext,
4161 // observed to cause Error occured during wast conversion :4156 // observed to cause Error occured during wast conversion :
4162 // Unknown operator: 0xfd058 in Firefox 1174157 // Unknown operator: 0xfd058 in Firefox 117
4163 //.simd128,4158 //.simd128,
src/arch/wasm/CodeGen.zig+48
...@@ -1591,10 +1591,35 @@ fn memcpy(cg: *CodeGen, dst: WValue, src: WValue, len: WValue) !void {...@@ -1591,10 +1591,35 @@ fn memcpy(cg: *CodeGen, dst: WValue, src: WValue, len: WValue) !void {
1591 // When bulk_memory is enabled, we lower it to wasm's memcpy instruction.1591 // When bulk_memory is enabled, we lower it to wasm's memcpy instruction.
1592 // If not, we lower it ourselves manually1592 // If not, we lower it ourselves manually
1593 if (std.Target.wasm.featureSetHas(cg.target.cpu.features, .bulk_memory)) {1593 if (std.Target.wasm.featureSetHas(cg.target.cpu.features, .bulk_memory)) {
1594 const len0_ok = std.Target.wasm.featureSetHas(cg.target.cpu.features, .nontrapping_bulk_memory_len0);
1595
1596 if (!len0_ok) {
1597 try cg.startBlock(.block, .empty);
1598
1599 // Even if `len` is zero, the spec requires an implementation to trap if `src + len` or
1600 // `dst + len` are out of memory bounds. This can easily happen in Zig in a case such
1601 // as:
1602 //
1603 // const dst: [*]u8 = undefined;
1604 // const src: [*]u8 = undefined;
1605 // var len: usize = runtime_zero();
1606 // @memcpy(dst[0..len], src[0..len]);
1607 //
1608 // So explicitly avoid using `memory.copy` in the `len == 0` case. Lovely design.
1609 try cg.emitWValue(len);
1610 try cg.addTag(.i32_eqz);
1611 try cg.addLabel(.br_if, 0);
1612 }
1613
1594 try cg.lowerToStack(dst);1614 try cg.lowerToStack(dst);
1595 try cg.lowerToStack(src);1615 try cg.lowerToStack(src);
1596 try cg.emitWValue(len);1616 try cg.emitWValue(len);
1597 try cg.addExtended(.memory_copy);1617 try cg.addExtended(.memory_copy);
1618
1619 if (!len0_ok) {
1620 try cg.endBlock();
1621 }
1622
1598 return;1623 return;
1599 }1624 }
16001625
...@@ -4782,10 +4807,33 @@ fn memset(cg: *CodeGen, elem_ty: Type, ptr: WValue, len: WValue, value: WValue)...@@ -4782,10 +4807,33 @@ fn memset(cg: *CodeGen, elem_ty: Type, ptr: WValue, len: WValue, value: WValue)
4782 // When bulk_memory is enabled, we lower it to wasm's memset instruction.4807 // When bulk_memory is enabled, we lower it to wasm's memset instruction.
4783 // If not, we lower it ourselves.4808 // If not, we lower it ourselves.
4784 if (std.Target.wasm.featureSetHas(cg.target.cpu.features, .bulk_memory) and abi_size == 1) {4809 if (std.Target.wasm.featureSetHas(cg.target.cpu.features, .bulk_memory) and abi_size == 1) {
4810 const len0_ok = std.Target.wasm.featureSetHas(cg.target.cpu.features, .nontrapping_bulk_memory_len0);
4811
4812 if (!len0_ok) {
4813 try cg.startBlock(.block, .empty);
4814
4815 // Even if `len` is zero, the spec requires an implementation to trap if `ptr + len` is
4816 // out of memory bounds. This can easily happen in Zig in a case such as:
4817 //
4818 // const ptr: [*]u8 = undefined;
4819 // var len: usize = runtime_zero();
4820 // @memset(ptr[0..len], 42);
4821 //
4822 // So explicitly avoid using `memory.fill` in the `len == 0` case. Lovely design.
4823 try cg.emitWValue(len);
4824 try cg.addTag(.i32_eqz);
4825 try cg.addLabel(.br_if, 0);
4826 }
4827
4785 try cg.lowerToStack(ptr);4828 try cg.lowerToStack(ptr);
4786 try cg.emitWValue(value);4829 try cg.emitWValue(value);
4787 try cg.emitWValue(len);4830 try cg.emitWValue(len);
4788 try cg.addExtended(.memory_fill);4831 try cg.addExtended(.memory_fill);
4832
4833 if (!len0_ok) {
4834 try cg.endBlock();
4835 }
4836
4789 return;4837 return;
4790 }4838 }
47914839
src/link/Wasm.zig+36-5
...@@ -2826,6 +2826,7 @@ pub const Feature = packed struct(u8) {...@@ -2826,6 +2826,7 @@ pub const Feature = packed struct(u8) {
2826 multimemory,2826 multimemory,
2827 multivalue,2827 multivalue,
2828 @"mutable-globals",2828 @"mutable-globals",
2829 @"nontrapping-bulk-memory-len0",
2829 @"nontrapping-fptoint",2830 @"nontrapping-fptoint",
2830 @"reference-types",2831 @"reference-types",
2831 @"relaxed-simd",2832 @"relaxed-simd",
...@@ -2835,14 +2836,44 @@ pub const Feature = packed struct(u8) {...@@ -2835,14 +2836,44 @@ pub const Feature = packed struct(u8) {
2835 @"shared-mem",2836 @"shared-mem",
28362837
2837 pub fn fromCpuFeature(feature: std.Target.wasm.Feature) Tag {2838 pub fn fromCpuFeature(feature: std.Target.wasm.Feature) Tag {
2838 return @enumFromInt(@intFromEnum(feature));2839 return switch (feature) {
2840 .atomics => .atomics,
2841 .bulk_memory => .@"bulk-memory",
2842 .exception_handling => .@"exception-handling",
2843 .extended_const => .@"extended-const",
2844 .half_precision => .@"half-precision",
2845 .multimemory => .multimemory,
2846 .multivalue => .multivalue,
2847 .mutable_globals => .@"mutable-globals",
2848 .nontrapping_bulk_memory_len0 => .@"nontrapping-bulk-memory-len0", // Zig extension.
2849 .nontrapping_fptoint => .@"nontrapping-fptoint",
2850 .reference_types => .@"reference-types",
2851 .relaxed_simd => .@"relaxed-simd",
2852 .sign_ext => .@"sign-ext",
2853 .simd128 => .simd128,
2854 .tail_call => .@"tail-call",
2855 };
2839 }2856 }
28402857
2841 pub fn toCpuFeature(tag: Tag) ?std.Target.wasm.Feature {2858 pub fn toCpuFeature(tag: Tag) ?std.Target.wasm.Feature {
2842 return if (@intFromEnum(tag) < @typeInfo(std.Target.wasm.Feature).@"enum".fields.len)2859 return switch (tag) {
2843 @enumFromInt(@intFromEnum(tag))2860 .atomics => .atomics,
2844 else2861 .@"bulk-memory" => .bulk_memory,
2845 null;2862 .@"exception-handling" => .exception_handling,
2863 .@"extended-const" => .extended_const,
2864 .@"half-precision" => .half_precision,
2865 .multimemory => .multimemory,
2866 .multivalue => .multivalue,
2867 .@"mutable-globals" => .mutable_globals,
2868 .@"nontrapping-bulk-memory-len0" => .nontrapping_bulk_memory_len0, // Zig extension.
2869 .@"nontrapping-fptoint" => .nontrapping_fptoint,
2870 .@"reference-types" => .reference_types,
2871 .@"relaxed-simd" => .relaxed_simd,
2872 .@"sign-ext" => .sign_ext,
2873 .simd128 => .simd128,
2874 .@"tail-call" => .tail_call,
2875 .@"shared-mem" => null, // Linker-only feature.
2876 };
2846 }2877 }
28472878
2848 pub const format = @compileError("use @tagName instead");2879 pub const format = @compileError("use @tagName instead");
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);
tools/update_cpu_features.zig+21
...@@ -1033,6 +1033,27 @@ const llvm_targets = [_]LlvmTarget{...@@ -1033,6 +1033,27 @@ const llvm_targets = [_]LlvmTarget{
1033 .zig_name = "wasm",1033 .zig_name = "wasm",
1034 .llvm_name = "WebAssembly",1034 .llvm_name = "WebAssembly",
1035 .td_name = "WebAssembly.td",1035 .td_name = "WebAssembly.td",
1036 .extra_features = &.{
1037 .{
1038 .zig_name = "nontrapping_bulk_memory_len0",
1039 .desc = "Bulk memory operations with a zero length do not trap",
1040 .deps = &.{"bulk_memory"},
1041 },
1042 },
1043 .extra_cpus = &.{
1044 .{
1045 .llvm_name = null,
1046 .zig_name = "lime1",
1047 .features = &.{
1048 "bulk_memory",
1049 "extended_const",
1050 "multivalue",
1051 "mutable_globals",
1052 "nontrapping_fptoint",
1053 "sign_ext",
1054 },
1055 },
1056 },
1036 },1057 },
1037 .{1058 .{
1038 .zig_name = "x86",1059 .zig_name = "x86",