authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-12-07 14:04:30-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-01-15 15:11:35-08:00
log4a1447d1dbdc5638d94359d731379eba428a016d
tree118a9b60b35782de04f752366827f2348473bf4f
parente24f635c758242b9c8d8aacac668d31dead7623e

wasm codegen: switch on bool instead of int


1 files changed, 24 insertions(+), 39 deletions(-)

src/arch/wasm/CodeGen.zig+24-39
......@@ -64,6 +64,7 @@ arg_index: u32 = 0,
6464simd_immediates: std.ArrayListUnmanaged([16]u8) = .empty,
6565/// The Target we're emitting (used to call intInfo)
6666target: *const std.Target,
67ptr_size: enum { wasm32, wasm64 },
6768wasm: *link.File.Wasm,
6869pt: Zcu.PerThread,
6970/// List of MIR Instructions
......@@ -1310,6 +1311,11 @@ pub fn function(
13101311 .liveness = liveness,
13111312 .owner_nav = func.owner_nav,
13121313 .target = target,
1314 .ptr_size = switch (target.cpu.arch) {
1315 .wasm32 => .wasm32,
1316 .wasm64 => .wasm64,
1317 else => unreachable,
1318 },
13131319 .wasm = wasm,
13141320 .func_index = func_index,
13151321 .args = cc_result.args,
......@@ -1510,7 +1516,7 @@ fn lowerToStack(func: *CodeGen, value: WValue) !void {
15101516 .stack_offset => |offset| {
15111517 try func.emitWValue(value);
15121518 if (offset.value > 0) {
1513 switch (func.arch()) {
1519 switch (func.ptr_size) {
15141520 .wasm32 => {
15151521 try func.addImm32(offset.value);
15161522 try func.addTag(.i32_add);
......@@ -1519,7 +1525,6 @@ fn lowerToStack(func: *CodeGen, value: WValue) !void {
15191525 try func.addImm64(offset.value);
15201526 try func.addTag(.i64_add);
15211527 },
1522 else => unreachable,
15231528 }
15241529 }
15251530 },
......@@ -1650,7 +1655,7 @@ fn memcpy(func: *CodeGen, dst: WValue, src: WValue, len: WValue) !void {
16501655 try func.emitWValue(dst);
16511656 // load byte from src's address
16521657 try func.emitWValue(src);
1653 switch (func.arch()) {
1658 switch (func.ptr_size) {
16541659 .wasm32 => {
16551660 try func.addMemArg(.i32_load8_u, .{ .offset = rhs_base + offset, .alignment = 1 });
16561661 try func.addMemArg(.i32_store8, .{ .offset = lhs_base + offset, .alignment = 1 });
......@@ -1659,7 +1664,6 @@ fn memcpy(func: *CodeGen, dst: WValue, src: WValue, len: WValue) !void {
16591664 try func.addMemArg(.i64_load8_u, .{ .offset = rhs_base + offset, .alignment = 1 });
16601665 try func.addMemArg(.i64_store8, .{ .offset = lhs_base + offset, .alignment = 1 });
16611666 },
1662 else => unreachable,
16631667 }
16641668 }
16651669 return;
......@@ -1671,10 +1675,9 @@ fn memcpy(func: *CodeGen, dst: WValue, src: WValue, len: WValue) !void {
16711675 // This to ensure that inside loops we correctly re-set the counter.
16721676 var offset = try func.allocLocal(Type.usize); // local for counter
16731677 defer offset.free(func);
1674 switch (func.arch()) {
1678 switch (func.ptr_size) {
16751679 .wasm32 => try func.addImm32(0),
16761680 .wasm64 => try func.addImm64(0),
1677 else => unreachable,
16781681 }
16791682 try func.addLabel(.local_set, offset.local.value);
16801683
......@@ -1686,10 +1689,9 @@ fn memcpy(func: *CodeGen, dst: WValue, src: WValue, len: WValue) !void {
16861689 {
16871690 try func.emitWValue(offset);
16881691 try func.emitWValue(len);
1689 switch (func.arch()) {
1692 switch (func.ptr_size) {
16901693 .wasm32 => try func.addTag(.i32_eq),
16911694 .wasm64 => try func.addTag(.i64_eq),
1692 else => unreachable,
16931695 }
16941696 try func.addLabel(.br_if, 1); // jump out of loop into outer block (finished)
16951697 }
......@@ -1698,10 +1700,9 @@ fn memcpy(func: *CodeGen, dst: WValue, src: WValue, len: WValue) !void {
16981700 {
16991701 try func.emitWValue(dst);
17001702 try func.emitWValue(offset);
1701 switch (func.arch()) {
1703 switch (func.ptr_size) {
17021704 .wasm32 => try func.addTag(.i32_add),
17031705 .wasm64 => try func.addTag(.i64_add),
1704 else => unreachable,
17051706 }
17061707 }
17071708
......@@ -1709,7 +1710,7 @@ fn memcpy(func: *CodeGen, dst: WValue, src: WValue, len: WValue) !void {
17091710 {
17101711 try func.emitWValue(src);
17111712 try func.emitWValue(offset);
1712 switch (func.arch()) {
1713 switch (func.ptr_size) {
17131714 .wasm32 => {
17141715 try func.addTag(.i32_add);
17151716 try func.addMemArg(.i32_load8_u, .{ .offset = src.offset(), .alignment = 1 });
......@@ -1720,14 +1721,13 @@ fn memcpy(func: *CodeGen, dst: WValue, src: WValue, len: WValue) !void {
17201721 try func.addMemArg(.i64_load8_u, .{ .offset = src.offset(), .alignment = 1 });
17211722 try func.addMemArg(.i64_store8, .{ .offset = dst.offset(), .alignment = 1 });
17221723 },
1723 else => unreachable,
17241724 }
17251725 }
17261726
17271727 // increment loop counter
17281728 {
17291729 try func.emitWValue(offset);
1730 switch (func.arch()) {
1730 switch (func.ptr_size) {
17311731 .wasm32 => {
17321732 try func.addImm32(1);
17331733 try func.addTag(.i32_add);
......@@ -1736,7 +1736,6 @@ fn memcpy(func: *CodeGen, dst: WValue, src: WValue, len: WValue) !void {
17361736 try func.addImm64(1);
17371737 try func.addTag(.i64_add);
17381738 },
1739 else => unreachable,
17401739 }
17411740 try func.addLabel(.local_set, offset.local.value);
17421741 try func.addLabel(.br, 0); // jump to start of loop
......@@ -1749,10 +1748,6 @@ fn ptrSize(func: *const CodeGen) u16 {
17491748 return @divExact(func.target.ptrBitWidth(), 8);
17501749}
17511750
1752fn arch(func: *const CodeGen) std.Target.Cpu.Arch {
1753 return func.target.cpu.arch;
1754}
1755
17561751/// For a given `Type`, will return true when the type will be passed
17571752/// by reference, rather than by value
17581753fn isByRef(ty: Type, pt: Zcu.PerThread, target: *const std.Target) bool {
......@@ -1851,7 +1846,7 @@ fn buildPointerOffset(func: *CodeGen, ptr_value: WValue, offset: u64, action: en
18511846 };
18521847 try func.emitWValue(ptr_value);
18531848 if (offset + ptr_value.offset() > 0) {
1854 switch (func.arch()) {
1849 switch (func.ptr_size) {
18551850 .wasm32 => {
18561851 try func.addImm32(@intCast(offset + ptr_value.offset()));
18571852 try func.addTag(.i32_add);
......@@ -1860,7 +1855,6 @@ fn buildPointerOffset(func: *CodeGen, ptr_value: WValue, offset: u64, action: en
18601855 try func.addImm64(offset + ptr_value.offset());
18611856 try func.addTag(.i64_add);
18621857 },
1863 else => unreachable,
18641858 }
18651859 }
18661860 try func.addLabel(.local_set, result_ptr.local.value);
......@@ -3350,10 +3344,9 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {
33503344 64 => return .{ .float64 = @as(f64, @bitCast(@as(u64, 0xaaaaaaaaaaaaaaaa))) },
33513345 else => unreachable,
33523346 },
3353 .pointer => switch (func.arch()) {
3347 .pointer => switch (func.ptr_size) {
33543348 .wasm32 => return .{ .imm32 = 0xaaaaaaaa },
33553349 .wasm64 => return .{ .imm64 = 0xaaaaaaaaaaaaaaaa },
3356 else => unreachable,
33573350 },
33583351 .optional => {
33593352 const pl_ty = ty.optionalChild(zcu);
......@@ -4428,10 +4421,9 @@ fn isNull(func: *CodeGen, operand: WValue, optional_ty: Type, opcode: std.wasm.O
44284421 try func.addMemArg(.i32_load8_u, .{ .offset = operand.offset() + offset, .alignment = 1 });
44294422 }
44304423 } else if (payload_ty.isSlice(zcu)) {
4431 switch (func.arch()) {
4424 switch (func.ptr_size) {
44324425 .wasm32 => try func.addMemArg(.i32_load, .{ .offset = operand.offset(), .alignment = 4 }),
44334426 .wasm64 => try func.addMemArg(.i64_load, .{ .offset = operand.offset(), .alignment = 8 }),
4434 else => unreachable,
44354427 }
44364428 }
44374429
......@@ -4867,7 +4859,7 @@ fn memset(func: *CodeGen, elem_ty: Type, ptr: WValue, len: WValue, value: WValue
48674859 else => if (abi_size != 1) blk: {
48684860 const new_len = try func.ensureAllocLocal(Type.usize);
48694861 try func.emitWValue(len);
4870 switch (func.arch()) {
4862 switch (func.ptr_size) {
48714863 .wasm32 => {
48724864 try func.emitWValue(.{ .imm32 = abi_size });
48734865 try func.addTag(.i32_mul);
......@@ -4876,7 +4868,6 @@ fn memset(func: *CodeGen, elem_ty: Type, ptr: WValue, len: WValue, value: WValue
48764868 try func.emitWValue(.{ .imm64 = abi_size });
48774869 try func.addTag(.i64_mul);
48784870 },
4879 else => unreachable,
48804871 }
48814872 try func.addLabel(.local_set, new_len.local.value);
48824873 break :blk new_len;
......@@ -4891,10 +4882,9 @@ fn memset(func: *CodeGen, elem_ty: Type, ptr: WValue, len: WValue, value: WValue
48914882 // get the loop conditional: if current pointer address equals final pointer's address
48924883 try func.lowerToStack(ptr);
48934884 try func.emitWValue(final_len);
4894 switch (func.arch()) {
4885 switch (func.ptr_size) {
48954886 .wasm32 => try func.addTag(.i32_add),
48964887 .wasm64 => try func.addTag(.i64_add),
4897 else => unreachable,
48984888 }
48994889 try func.addLabel(.local_set, end_ptr.local.value);
49004890
......@@ -4905,10 +4895,9 @@ fn memset(func: *CodeGen, elem_ty: Type, ptr: WValue, len: WValue, value: WValue
49054895 // check for condition for loop end
49064896 try func.emitWValue(new_ptr);
49074897 try func.emitWValue(end_ptr);
4908 switch (func.arch()) {
4898 switch (func.ptr_size) {
49094899 .wasm32 => try func.addTag(.i32_eq),
49104900 .wasm64 => try func.addTag(.i64_eq),
4911 else => unreachable,
49124901 }
49134902 try func.addLabel(.br_if, 1); // jump out of loop into outer block (finished)
49144903
......@@ -4917,7 +4906,7 @@ fn memset(func: *CodeGen, elem_ty: Type, ptr: WValue, len: WValue, value: WValue
49174906
49184907 // move the pointer to the next element
49194908 try func.emitWValue(new_ptr);
4920 switch (func.arch()) {
4909 switch (func.ptr_size) {
49214910 .wasm32 => {
49224911 try func.emitWValue(.{ .imm32 = abi_size });
49234912 try func.addTag(.i32_add);
......@@ -4926,7 +4915,6 @@ fn memset(func: *CodeGen, elem_ty: Type, ptr: WValue, len: WValue, value: WValue
49264915 try func.emitWValue(.{ .imm64 = abi_size });
49274916 try func.addTag(.i64_add);
49284917 },
4929 else => unreachable,
49304918 }
49314919 try func.addLabel(.local_set, new_ptr.local.value);
49324920
......@@ -5101,7 +5089,7 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
51015089 // when the operand lives in the linear memory section, we can directly
51025090 // load and splat the value at once. Meaning we do not first have to load
51035091 // the scalar value onto the stack.
5104 .stack_offset, .memory, .memory_offset => {
5092 .stack_offset, .nav_ref, .uav_ref => {
51055093 const opcode = switch (elem_ty.bitSize(zcu)) {
51065094 8 => @intFromEnum(std.wasm.SimdOpcode.v128_load8_splat),
51075095 16 => @intFromEnum(std.wasm.SimdOpcode.v128_load16_splat),
......@@ -5110,8 +5098,7 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
51105098 else => break :blk, // Cannot make use of simd-instructions
51115099 };
51125100 try func.emitWValue(operand);
5113 // TODO: Add helper functions for simd opcodes
5114 const extra_index = @as(u32, @intCast(func.mir_extra.items.len));
5101 const extra_index: u32 = @intCast(func.mir_extra.items.len);
51155102 // stores as := opcode, offset, alignment (opcode::memarg)
51165103 try func.mir_extra.appendSlice(func.gpa, &[_]u32{
51175104 opcode,
......@@ -5759,10 +5746,9 @@ fn airMemcpy(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
57595746
57605747fn airRetAddr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
57615748 // TODO: Implement this properly once stack serialization is solved
5762 return func.finishAir(inst, switch (func.arch()) {
5749 return func.finishAir(inst, switch (func.ptr_size) {
57635750 .wasm32 => .{ .imm32 = 0 },
57645751 .wasm64 => .{ .imm64 = 0 },
5765 else => unreachable,
57665752 }, &.{});
57675753}
57685754
......@@ -5937,7 +5923,7 @@ fn airErrorName(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
59375923 const error_name_value: WValue = .{ .memory = error_table_symbol }; // emitting this will create a relocation
59385924 try func.emitWValue(error_name_value);
59395925 try func.emitWValue(operand);
5940 switch (func.arch()) {
5926 switch (func.ptr_size) {
59415927 .wasm32 => {
59425928 try func.addImm32(@intCast(abi_size));
59435929 try func.addTag(.i32_mul);
......@@ -5948,7 +5934,6 @@ fn airErrorName(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
59485934 try func.addTag(.i64_mul);
59495935 try func.addTag(.i64_add);
59505936 },
5951 else => unreachable,
59525937 }
59535938
59545939 return func.finishAir(inst, .stack, &.{un_op});