authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-07-17 22:33:29-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-07-17 22:33:29-07:00
loga57479afc2cea1b7c2c6802b7e8a1a7db973a3a3
tree80c37854ba226b83a1ffd964d101178039fe2946
parent8ab70f80cb8943dde41a5e4a8ca73631d44643a2
parent31706dc31acdc875899ca18cf92a2fccb3a2f0c7
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #20652 from pavelverigo/stage2-wasm-finishAir

stage2-wasm: finishAir enhancement

1 files changed, 346 insertions(+), 454 deletions(-)

src/arch/wasm/CodeGen.zig+346-454
......@@ -793,7 +793,7 @@ fn resolveInst(func: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue {
793793 const val = (try func.air.value(ref, pt)).?;
794794 const ty = func.typeOf(ref);
795795 if (!ty.hasRuntimeBitsIgnoreComptime(pt) and !ty.isInt(mod) and !ty.isError(mod)) {
796 gop.value_ptr.* = WValue{ .none = {} };
796 gop.value_ptr.* = .none;
797797 return gop.value_ptr.*;
798798 }
799799
......@@ -803,16 +803,17 @@ fn resolveInst(func: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue {
803803 //
804804 // In the other cases, we will simply lower the constant to a value that fits
805805 // into a single local (such as a pointer, integer, bool, etc).
806 const result = if (isByRef(ty, pt)) blk: {
807 const sym_index = try func.bin_file.lowerUnnamedConst(pt, val, func.decl_index);
808 break :blk WValue{ .memory = sym_index };
809 } else try func.lowerConstant(val, ty);
806 const result: WValue = if (isByRef(ty, pt))
807 .{ .memory = try func.bin_file.lowerUnnamedConst(pt, val, func.decl_index) }
808 else
809 try func.lowerConstant(val, ty);
810810
811811 gop.value_ptr.* = result;
812812 return result;
813813}
814814
815fn finishAir(func: *CodeGen, inst: Air.Inst.Index, result: WValue, operands: []const Air.Inst.Ref) void {
815/// NOTE: if result == .stack, it will be stored in .local
816fn finishAir(func: *CodeGen, inst: Air.Inst.Index, result: WValue, operands: []const Air.Inst.Ref) InnerError!void {
816817 assert(operands.len <= Liveness.bpi - 1);
817818 var tomb_bits = func.liveness.getTombBits(inst);
818819 for (operands) |operand| {
......@@ -824,9 +825,12 @@ fn finishAir(func: *CodeGen, inst: Air.Inst.Index, result: WValue, operands: []c
824825
825826 // results of `none` can never be referenced.
826827 if (result != .none) {
827 assert(result != .stack); // it's illegal to store a stack value as we cannot track its position
828 const trackable_result = if (result != .stack)
829 result
830 else
831 try result.toLocal(func, func.typeOfIndex(inst));
828832 const branch = func.currentBranch();
829 branch.values.putAssumeCapacityNoClobber(inst.toRef(), result);
833 branch.values.putAssumeCapacityNoClobber(inst.toRef(), trackable_result);
830834 }
831835
832836 if (std.debug.runtime_safety) {
......@@ -990,44 +994,44 @@ fn addExtraAssumeCapacity(func: *CodeGen, extra: anytype) error{OutOfMemory}!u32
990994 return result;
991995}
992996
993/// Using a given `Type`, returns the corresponding type
997/// Using a given `Type`, returns the corresponding valtype for .auto callconv
994998fn typeToValtype(ty: Type, pt: Zcu.PerThread) wasm.Valtype {
995999 const mod = pt.zcu;
9961000 const target = mod.getTarget();
9971001 const ip = &mod.intern_pool;
9981002 return switch (ty.zigTypeTag(mod)) {
9991003 .Float => switch (ty.floatBits(target)) {
1000 16 => wasm.Valtype.i32, // stored/loaded as u16
1001 32 => wasm.Valtype.f32,
1002 64 => wasm.Valtype.f64,
1003 80, 128 => wasm.Valtype.i64,
1004 16 => .i32, // stored/loaded as u16
1005 32 => .f32,
1006 64 => .f64,
1007 80, 128 => .i32,
10041008 else => unreachable,
10051009 },
1006 .Int, .Enum => blk: {
1007 const info = ty.intInfo(pt.zcu);
1008 if (info.bits <= 32) break :blk wasm.Valtype.i32;
1009 if (info.bits > 32 and info.bits <= 128) break :blk wasm.Valtype.i64;
1010 break :blk wasm.Valtype.i32; // represented as pointer to stack
1010 .Int, .Enum => switch (ty.intInfo(pt.zcu).bits) {
1011 0...32 => .i32,
1012 33...64 => .i64,
1013 else => .i32,
10111014 },
1012 .Struct => {
1015 .Struct => blk: {
10131016 if (pt.zcu.typeToPackedStruct(ty)) |packed_struct| {
1014 return typeToValtype(Type.fromInterned(packed_struct.backingIntTypeUnordered(ip)), pt);
1017 const backing_int_ty = Type.fromInterned(packed_struct.backingIntTypeUnordered(ip));
1018 break :blk typeToValtype(backing_int_ty, pt);
10151019 } else {
1016 return wasm.Valtype.i32;
1020 break :blk .i32;
10171021 }
10181022 },
10191023 .Vector => switch (determineSimdStoreStrategy(ty, pt)) {
1020 .direct => wasm.Valtype.v128,
1021 .unrolled => wasm.Valtype.i32,
1024 .direct => .v128,
1025 .unrolled => .i32,
10221026 },
10231027 .Union => switch (ty.containerLayout(pt.zcu)) {
1024 .@"packed" => {
1028 .@"packed" => blk: {
10251029 const int_ty = pt.intType(.unsigned, @as(u16, @intCast(ty.bitSize(pt)))) catch @panic("out of memory");
1026 return typeToValtype(int_ty, pt);
1030 break :blk typeToValtype(int_ty, pt);
10271031 },
1028 else => wasm.Valtype.i32,
1032 else => .i32,
10291033 },
1030 else => wasm.Valtype.i32, // all represented as reference/immediate
1034 else => .i32, // all represented as reference/immediate
10311035 };
10321036}
10331037
......@@ -1105,30 +1109,18 @@ fn getResolvedInst(func: *CodeGen, ref: Air.Inst.Ref) *WValue {
11051109fn allocLocal(func: *CodeGen, ty: Type) InnerError!WValue {
11061110 const pt = func.pt;
11071111 const valtype = typeToValtype(ty, pt);
1108 switch (valtype) {
1109 .i32 => if (func.free_locals_i32.popOrNull()) |index| {
1110 log.debug("reusing local ({d}) of type {}", .{ index, valtype });
1111 return WValue{ .local = .{ .value = index, .references = 1 } };
1112 },
1113 .i64 => if (func.free_locals_i64.popOrNull()) |index| {
1114 log.debug("reusing local ({d}) of type {}", .{ index, valtype });
1115 return WValue{ .local = .{ .value = index, .references = 1 } };
1116 },
1117 .f32 => if (func.free_locals_f32.popOrNull()) |index| {
1118 log.debug("reusing local ({d}) of type {}", .{ index, valtype });
1119 return WValue{ .local = .{ .value = index, .references = 1 } };
1120 },
1121 .f64 => if (func.free_locals_f64.popOrNull()) |index| {
1122 log.debug("reusing local ({d}) of type {}", .{ index, valtype });
1123 return WValue{ .local = .{ .value = index, .references = 1 } };
1124 },
1125 .v128 => if (func.free_locals_v128.popOrNull()) |index| {
1126 log.debug("reusing local ({d}) of type {}", .{ index, valtype });
1127 return WValue{ .local = .{ .value = index, .references = 1 } };
1128 },
1112 const index_or_null = switch (valtype) {
1113 .i32 => func.free_locals_i32.popOrNull(),
1114 .i64 => func.free_locals_i64.popOrNull(),
1115 .f32 => func.free_locals_f32.popOrNull(),
1116 .f64 => func.free_locals_f64.popOrNull(),
1117 .v128 => func.free_locals_v128.popOrNull(),
1118 };
1119 if (index_or_null) |index| {
1120 log.debug("reusing local ({d}) of type {}", .{ index, valtype });
1121 return .{ .local = .{ .value = index, .references = 1 } };
11291122 }
11301123 log.debug("new local of type {}", .{valtype});
1131 // no local was free to be re-used, so allocate a new local instead
11321124 return func.ensureAllocLocal(ty);
11331125}
11341126
......@@ -1139,7 +1131,7 @@ fn ensureAllocLocal(func: *CodeGen, ty: Type) InnerError!WValue {
11391131 try func.locals.append(func.gpa, genValtype(ty, pt));
11401132 const initial_index = func.local_index;
11411133 func.local_index += 1;
1142 return WValue{ .local = .{ .value = initial_index, .references = 1 } };
1134 return .{ .local = .{ .value = initial_index, .references = 1 } };
11431135}
11441136
11451137/// Generates a `wasm.Type` from a given function type.
......@@ -1180,20 +1172,20 @@ fn genFunctype(
11801172 switch (cc) {
11811173 .C => {
11821174 const param_classes = abi.classifyType(param_type, pt);
1183 for (param_classes) |class| {
1184 if (class == .none) continue;
1185 if (class == .direct) {
1175 if (param_classes[1] == .none) {
1176 if (param_classes[0] == .direct) {
11861177 const scalar_type = abi.scalarType(param_type, pt);
11871178 try temp_params.append(typeToValtype(scalar_type, pt));
11881179 } else {
11891180 try temp_params.append(typeToValtype(param_type, pt));
11901181 }
1182 } else {
1183 // i128/f128
1184 try temp_params.append(.i64);
1185 try temp_params.append(.i64);
11911186 }
11921187 },
1193 else => if (isByRef(param_type, pt))
1194 try temp_params.append(.i32)
1195 else
1196 try temp_params.append(typeToValtype(param_type, pt)),
1188 else => try temp_params.append(typeToValtype(param_type, pt)),
11971189 }
11981190 }
11991191
......@@ -1539,7 +1531,7 @@ fn allocStack(func: *CodeGen, ty: Type) !WValue {
15391531 const offset: u32 = @intCast(abi_align.forward(func.stack_size));
15401532 defer func.stack_size = offset + abi_size;
15411533
1542 return WValue{ .stack_offset = .{ .value = offset, .references = 1 } };
1534 return .{ .stack_offset = .{ .value = offset, .references = 1 } };
15431535}
15441536
15451537/// From a given AIR instruction generates a pointer to the stack where
......@@ -1571,7 +1563,7 @@ fn allocStackPtr(func: *CodeGen, inst: Air.Inst.Index) !WValue {
15711563 const offset: u32 = @intCast(abi_alignment.forward(func.stack_size));
15721564 defer func.stack_size = offset + abi_size;
15731565
1574 return WValue{ .stack_offset = .{ .value = offset, .references = 1 } };
1566 return .{ .stack_offset = .{ .value = offset, .references = 1 } };
15751567}
15761568
15771569/// From given zig bitsize, returns the wasm bitsize
......@@ -2135,7 +2127,7 @@ fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
21352127 try func.restoreStackPointer();
21362128 try func.addTag(.@"return");
21372129
2138 func.finishAir(inst, .none, &.{un_op});
2130 return func.finishAir(inst, .none, &.{un_op});
21392131}
21402132
21412133fn airRetPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -2156,7 +2148,7 @@ fn airRetPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
21562148 break :result try func.allocStackPtr(inst);
21572149 };
21582150
2159 func.finishAir(inst, result, &.{});
2151 return func.finishAir(inst, result, &.{});
21602152}
21612153
21622154fn airRetLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -2234,11 +2226,11 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
22342226 return func.fail("Expected a function, but instead found '{s}'", .{@tagName(ip.indexToKey(func_val.toIntern()))});
22352227 };
22362228
2237 const sret = if (first_param_sret) blk: {
2229 const sret: WValue = if (first_param_sret) blk: {
22382230 const sret_local = try func.allocStack(ret_ty);
22392231 try func.lowerToStack(sret_local);
22402232 break :blk sret_local;
2241 } else WValue{ .none = {} };
2233 } else .none;
22422234
22432235 for (args) |arg| {
22442236 const arg_val = try func.resolveInst(arg);
......@@ -2268,10 +2260,10 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
22682260
22692261 const result_value = result_value: {
22702262 if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt) and !ret_ty.isError(mod)) {
2271 break :result_value WValue{ .none = {} };
2263 break :result_value .none;
22722264 } else if (ret_ty.isNoReturn(mod)) {
22732265 try func.addTag(.@"unreachable");
2274 break :result_value WValue{ .none = {} };
2266 break :result_value .none;
22752267 } else if (first_param_sret) {
22762268 break :result_value sret;
22772269 // TODO: Make this less fragile and optimize
......@@ -2297,7 +2289,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
22972289
22982290fn airAlloc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
22992291 const value = try func.allocStackPtr(inst);
2300 func.finishAir(inst, value, &.{});
2292 return func.finishAir(inst, value, &.{});
23012293}
23022294
23032295fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void {
......@@ -2330,18 +2322,18 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void
23302322 var mask = @as(u64, @intCast((@as(u65, 1) << @as(u7, @intCast(ty.bitSize(pt)))) - 1));
23312323 mask <<= @as(u6, @intCast(ptr_info.packed_offset.bit_offset));
23322324 mask ^= ~@as(u64, 0);
2333 const shift_val = if (ptr_info.packed_offset.host_size <= 4)
2334 WValue{ .imm32 = ptr_info.packed_offset.bit_offset }
2325 const shift_val: WValue = if (ptr_info.packed_offset.host_size <= 4)
2326 .{ .imm32 = ptr_info.packed_offset.bit_offset }
23352327 else
2336 WValue{ .imm64 = ptr_info.packed_offset.bit_offset };
2337 const mask_val = if (ptr_info.packed_offset.host_size <= 4)
2338 WValue{ .imm32 = @as(u32, @truncate(mask)) }
2328 .{ .imm64 = ptr_info.packed_offset.bit_offset };
2329 const mask_val: WValue = if (ptr_info.packed_offset.host_size <= 4)
2330 .{ .imm32 = @as(u32, @truncate(mask)) }
23392331 else
2340 WValue{ .imm64 = mask };
2341 const wrap_mask_val = if (ptr_info.packed_offset.host_size <= 4)
2342 WValue{ .imm32 = @truncate(~@as(u64, 0) >> @intCast(64 - ty.bitSize(pt))) }
2332 .{ .imm64 = mask };
2333 const wrap_mask_val: WValue = if (ptr_info.packed_offset.host_size <= 4)
2334 .{ .imm32 = @truncate(~@as(u64, 0) >> @intCast(64 - ty.bitSize(pt))) }
23432335 else
2344 WValue{ .imm64 = ~@as(u64, 0) >> @intCast(64 - ty.bitSize(pt)) };
2336 .{ .imm64 = ~@as(u64, 0) >> @intCast(64 - ty.bitSize(pt)) };
23452337
23462338 try func.emitWValue(lhs);
23472339 const loaded = try func.load(lhs, int_elem_ty, 0);
......@@ -2356,7 +2348,7 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void
23562348 try func.store(.stack, result, int_elem_ty, lhs.offset());
23572349 }
23582350
2359 func.finishAir(inst, .none, &.{ bin_op.lhs, bin_op.rhs });
2351 return func.finishAir(inst, .none, &.{ bin_op.lhs, bin_op.rhs });
23602352}
23612353
23622354fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerError!void {
......@@ -2418,23 +2410,23 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE
24182410 // lower it to the stack so we do not have to store rhs into a local first
24192411 try func.emitWValue(lhs);
24202412 const ptr_local = try func.load(rhs, Type.usize, 0);
2421 try func.store(.{ .stack = {} }, ptr_local, Type.usize, 0 + lhs.offset());
2413 try func.store(.stack, ptr_local, Type.usize, 0 + lhs.offset());
24222414
24232415 // retrieve length from rhs, and store that alongside lhs as well
24242416 try func.emitWValue(lhs);
24252417 const len_local = try func.load(rhs, Type.usize, func.ptrSize());
2426 try func.store(.{ .stack = {} }, len_local, Type.usize, func.ptrSize() + lhs.offset());
2418 try func.store(.stack, len_local, Type.usize, func.ptrSize() + lhs.offset());
24272419 return;
24282420 }
24292421 },
24302422 .Int, .Enum, .Float => if (abi_size > 8 and abi_size <= 16) {
24312423 try func.emitWValue(lhs);
24322424 const lsb = try func.load(rhs, Type.u64, 0);
2433 try func.store(.{ .stack = {} }, lsb, Type.u64, 0 + lhs.offset());
2425 try func.store(.stack, lsb, Type.u64, 0 + lhs.offset());
24342426
24352427 try func.emitWValue(lhs);
24362428 const msb = try func.load(rhs, Type.u64, 8);
2437 try func.store(.{ .stack = {} }, msb, Type.u64, 8 + lhs.offset());
2429 try func.store(.stack, msb, Type.u64, 8 + lhs.offset());
24382430 return;
24392431 } else if (abi_size > 16) {
24402432 try func.memcpy(lhs, rhs, .{ .imm32 = @as(u32, @intCast(ty.abiSize(pt))) });
......@@ -2487,27 +2479,24 @@ fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
24872479 }
24882480
24892481 if (ptr_info.packed_offset.host_size == 0) {
2490 const stack_loaded = try func.load(operand, ty, 0);
2491 break :result try stack_loaded.toLocal(func, ty);
2482 break :result try func.load(operand, ty, 0);
24922483 }
24932484
24942485 // at this point we have a non-natural alignment, we must
24952486 // shift the value to obtain the correct bit.
24962487 const int_elem_ty = try pt.intType(.unsigned, ptr_info.packed_offset.host_size * 8);
2497 const shift_val = if (ptr_info.packed_offset.host_size <= 4)
2498 WValue{ .imm32 = ptr_info.packed_offset.bit_offset }
2488 const shift_val: WValue = if (ptr_info.packed_offset.host_size <= 4)
2489 .{ .imm32 = ptr_info.packed_offset.bit_offset }
24992490 else if (ptr_info.packed_offset.host_size <= 8)
2500 WValue{ .imm64 = ptr_info.packed_offset.bit_offset }
2491 .{ .imm64 = ptr_info.packed_offset.bit_offset }
25012492 else
25022493 return func.fail("TODO: airLoad where ptr to bitfield exceeds 64 bits", .{});
25032494
25042495 const stack_loaded = try func.load(operand, int_elem_ty, 0);
25052496 const shifted = try func.binOp(stack_loaded, shift_val, int_elem_ty, .shr);
2506 const result = try func.trunc(shifted, ty, int_elem_ty);
2507 // const wrapped = try func.wrapOperand(shifted, ty);
2508 break :result try result.toLocal(func, ty);
2497 break :result try func.trunc(shifted, ty, int_elem_ty);
25092498 };
2510 func.finishAir(inst, result, &.{ty_op.operand});
2499 return func.finishAir(inst, result, &.{ty_op.operand});
25112500}
25122501
25132502/// Loads an operand from the linear memory section.
......@@ -2528,7 +2517,7 @@ fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValu
25282517 @intCast(ty.abiAlignment(pt).toByteUnits().?),
25292518 });
25302519 try func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } });
2531 return WValue{ .stack = {} };
2520 return .stack;
25322521 }
25332522
25342523 const abi_size: u8 = @intCast(ty.abiSize(pt));
......@@ -2547,7 +2536,7 @@ fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValu
25472536 },
25482537 );
25492538
2550 return WValue{ .stack = {} };
2539 return .stack;
25512540}
25522541
25532542fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -2596,7 +2585,7 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
25962585 else => {},
25972586 }
25982587
2599 func.finishAir(inst, arg, &.{});
2588 return func.finishAir(inst, arg, &.{});
26002589}
26012590
26022591fn airBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
......@@ -2613,25 +2602,21 @@ fn airBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
26132602 // case we first coerce the operands to the same type before performing the operation.
26142603 // For big integers we can ignore this as we will call into compiler-rt which handles this.
26152604 const result = switch (op) {
2616 .shr, .shl => res: {
2605 .shr, .shl => result: {
26172606 const lhs_wasm_bits = toWasmBits(@intCast(lhs_ty.bitSize(pt))) orelse {
26182607 return func.fail("TODO: implement '{s}' for types larger than 128 bits", .{@tagName(op)});
26192608 };
26202609 const rhs_wasm_bits = toWasmBits(@intCast(rhs_ty.bitSize(pt))).?;
2621 const new_rhs = if (lhs_wasm_bits != rhs_wasm_bits and lhs_wasm_bits != 128) blk: {
2622 const tmp = try func.intcast(rhs, rhs_ty, lhs_ty);
2623 break :blk try tmp.toLocal(func, lhs_ty);
2624 } else rhs;
2625 const stack_result = try func.binOp(lhs, new_rhs, lhs_ty, op);
2626 break :res try stack_result.toLocal(func, lhs_ty);
2627 },
2628 else => res: {
2629 const stack_result = try func.binOp(lhs, rhs, lhs_ty, op);
2630 break :res try stack_result.toLocal(func, lhs_ty);
2610 const new_rhs = if (lhs_wasm_bits != rhs_wasm_bits and lhs_wasm_bits != 128)
2611 try (try func.intcast(rhs, rhs_ty, lhs_ty)).toLocal(func, lhs_ty)
2612 else
2613 rhs;
2614 break :result try func.binOp(lhs, new_rhs, lhs_ty, op);
26312615 },
2616 else => try func.binOp(lhs, rhs, lhs_ty, op),
26322617 };
26332618
2634 func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
2619 return func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
26352620}
26362621
26372622/// Performs a binary operation on the given `WValue`'s
......@@ -2667,7 +2652,7 @@ fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!
26672652
26682653 try func.addTag(Mir.Inst.Tag.fromOpcode(opcode));
26692654
2670 return WValue{ .stack = {} };
2655 return .stack;
26712656}
26722657
26732658fn binOpBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!WValue {
......@@ -2839,6 +2824,7 @@ fn airAbs(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
28392824 try func.addTag(.i32_xor);
28402825 try func.emitWValue(tmp);
28412826 try func.addTag(.i32_sub);
2827 return func.finishAir(inst, .stack, &.{ty_op.operand});
28422828 },
28432829 64 => {
28442830 try func.emitWValue(operand);
......@@ -2854,6 +2840,7 @@ fn airAbs(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
28542840 try func.addTag(.i64_xor);
28552841 try func.emitWValue(tmp);
28562842 try func.addTag(.i64_sub);
2843 return func.finishAir(inst, .stack, &.{ty_op.operand});
28572844 },
28582845 128 => {
28592846 const mask = try func.allocStack(Type.u128);
......@@ -2874,18 +2861,14 @@ fn airAbs(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
28742861 const a = try func.binOpBigInt(operand, mask, Type.u128, .xor);
28752862 const b = try func.binOpBigInt(a, mask, Type.u128, .sub);
28762863
2877 func.finishAir(inst, b, &.{ty_op.operand});
2878 return;
2864 return func.finishAir(inst, b, &.{ty_op.operand});
28792865 },
28802866 else => unreachable,
28812867 }
2882
2883 const result = try (WValue{ .stack = {} }).toLocal(func, ty);
2884 func.finishAir(inst, result, &.{ty_op.operand});
28852868 },
28862869 .Float => {
2887 const result = try (try func.floatOp(.fabs, ty, &.{operand})).toLocal(func, ty);
2888 func.finishAir(inst, result, &.{ty_op.operand});
2870 const result = try func.floatOp(.fabs, ty, &.{operand});
2871 return func.finishAir(inst, result, &.{ty_op.operand});
28892872 },
28902873 else => unreachable,
28912874 }
......@@ -2896,8 +2879,8 @@ fn airUnaryFloatOp(func: *CodeGen, inst: Air.Inst.Index, op: FloatOp) InnerError
28962879 const operand = try func.resolveInst(un_op);
28972880 const ty = func.typeOf(un_op);
28982881
2899 const result = try (try func.floatOp(op, ty, &.{operand})).toLocal(func, ty);
2900 func.finishAir(inst, result, &.{un_op});
2882 const result = try func.floatOp(op, ty, &.{operand});
2883 return func.finishAir(inst, result, &.{un_op});
29012884}
29022885
29032886fn floatOp(func: *CodeGen, float_op: FloatOp, ty: Type, args: []const WValue) InnerError!WValue {
......@@ -3027,22 +3010,18 @@ fn airWrapBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
30273010 // case we first coerce the operands to the same type before performing the operation.
30283011 // For big integers we can ignore this as we will call into compiler-rt which handles this.
30293012 const result = switch (op) {
3030 .shr, .shl => res: {
3013 .shr, .shl => result: {
30313014 const lhs_wasm_bits = toWasmBits(@intCast(lhs_ty.bitSize(pt))) orelse {
30323015 return func.fail("TODO: implement '{s}' for types larger than 128 bits", .{@tagName(op)});
30333016 };
30343017 const rhs_wasm_bits = toWasmBits(@intCast(rhs_ty.bitSize(pt))).?;
3035 const new_rhs = if (lhs_wasm_bits != rhs_wasm_bits and lhs_wasm_bits != 128) blk: {
3036 const tmp = try func.intcast(rhs, rhs_ty, lhs_ty);
3037 break :blk try tmp.toLocal(func, lhs_ty);
3038 } else rhs;
3039 const stack_result = try func.wrapBinOp(lhs, new_rhs, lhs_ty, op);
3040 break :res try stack_result.toLocal(func, lhs_ty);
3041 },
3042 else => res: {
3043 const stack_result = try func.wrapBinOp(lhs, rhs, lhs_ty, op);
3044 break :res try stack_result.toLocal(func, lhs_ty);
3018 const new_rhs = if (lhs_wasm_bits != rhs_wasm_bits and lhs_wasm_bits != 128)
3019 try (try func.intcast(rhs, rhs_ty, lhs_ty)).toLocal(func, lhs_ty)
3020 else
3021 rhs;
3022 break :result try func.wrapBinOp(lhs, new_rhs, lhs_ty, op);
30453023 },
3024 else => try func.wrapBinOp(lhs, rhs, lhs_ty, op),
30463025 };
30473026
30483027 return func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
......@@ -3187,7 +3166,7 @@ fn lowerAnonDeclRef(
31873166
31883167 const is_fn_body = ty.zigTypeTag(mod) == .Fn;
31893168 if (!is_fn_body and !ty.hasRuntimeBitsIgnoreComptime(pt)) {
3190 return WValue{ .imm32 = 0xaaaaaaaa };
3169 return .{ .imm32 = 0xaaaaaaaa };
31913170 }
31923171
31933172 const decl_align = mod.intern_pool.indexToKey(anon_decl.orig_ty).ptr_type.flags.alignment;
......@@ -3202,10 +3181,10 @@ fn lowerAnonDeclRef(
32023181 const target_atom_index = func.bin_file.zigObjectPtr().?.anon_decls.get(decl_val).?;
32033182 const target_sym_index = @intFromEnum(func.bin_file.getAtom(target_atom_index).sym_index);
32043183 if (is_fn_body) {
3205 return WValue{ .function_index = target_sym_index };
3184 return .{ .function_index = target_sym_index };
32063185 } else if (offset == 0) {
3207 return WValue{ .memory = target_sym_index };
3208 } else return WValue{ .memory_offset = .{ .pointer = target_sym_index, .offset = offset } };
3186 return .{ .memory = target_sym_index };
3187 } else return .{ .memory_offset = .{ .pointer = target_sym_index, .offset = offset } };
32093188}
32103189
32113190fn lowerDeclRefValue(func: *CodeGen, decl_index: InternPool.DeclIndex, offset: u32) InnerError!WValue {
......@@ -3226,7 +3205,7 @@ fn lowerDeclRefValue(func: *CodeGen, decl_index: InternPool.DeclIndex, offset: u
32263205 }
32273206 const decl_ty = decl.typeOf(mod);
32283207 if (decl_ty.zigTypeTag(mod) != .Fn and !decl_ty.hasRuntimeBitsIgnoreComptime(pt)) {
3229 return WValue{ .imm32 = 0xaaaaaaaa };
3208 return .{ .imm32 = 0xaaaaaaaa };
32303209 }
32313210
32323211 const atom_index = try func.bin_file.getOrCreateAtomForDecl(pt, decl_index);
......@@ -3234,10 +3213,10 @@ fn lowerDeclRefValue(func: *CodeGen, decl_index: InternPool.DeclIndex, offset: u
32343213
32353214 const target_sym_index = @intFromEnum(atom.sym_index);
32363215 if (decl_ty.zigTypeTag(mod) == .Fn) {
3237 return WValue{ .function_index = target_sym_index };
3216 return .{ .function_index = target_sym_index };
32383217 } else if (offset == 0) {
3239 return WValue{ .memory = target_sym_index };
3240 } else return WValue{ .memory_offset = .{ .pointer = target_sym_index, .offset = offset } };
3218 return .{ .memory = target_sym_index };
3219 } else return .{ .memory_offset = .{ .pointer = target_sym_index, .offset = offset } };
32413220}
32423221
32433222/// Asserts that `isByRef` returns `false` for `ty`.
......@@ -3276,7 +3255,7 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
32763255 .@"unreachable",
32773256 .generic_poison,
32783257 => unreachable, // non-runtime values
3279 .false, .true => return WValue{ .imm32 = switch (simple_value) {
3258 .false, .true => return .{ .imm32 = switch (simple_value) {
32803259 .false => 0,
32813260 .true => 1,
32823261 else => unreachable,
......@@ -3292,20 +3271,20 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
32923271 const int_info = ty.intInfo(mod);
32933272 switch (int_info.signedness) {
32943273 .signed => switch (int_info.bits) {
3295 0...32 => return WValue{ .imm32 = @bitCast(@as(i32, @intCast(val.toSignedInt(pt)))) },
3296 33...64 => return WValue{ .imm64 = @bitCast(val.toSignedInt(pt)) },
3274 0...32 => return .{ .imm32 = @bitCast(@as(i32, @intCast(val.toSignedInt(pt)))) },
3275 33...64 => return .{ .imm64 = @bitCast(val.toSignedInt(pt)) },
32973276 else => unreachable,
32983277 },
32993278 .unsigned => switch (int_info.bits) {
3300 0...32 => return WValue{ .imm32 = @intCast(val.toUnsignedInt(pt)) },
3301 33...64 => return WValue{ .imm64 = val.toUnsignedInt(pt) },
3279 0...32 => return .{ .imm32 = @intCast(val.toUnsignedInt(pt)) },
3280 33...64 => return .{ .imm64 = val.toUnsignedInt(pt) },
33023281 else => unreachable,
33033282 },
33043283 }
33053284 },
33063285 .err => |err| {
33073286 const int = try pt.getErrorValue(err.name);
3308 return WValue{ .imm32 = int };
3287 return .{ .imm32 = int };
33093288 },
33103289 .error_union => |error_union| {
33113290 const err_int_ty = try pt.errorIntType();
......@@ -3335,9 +3314,9 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
33353314 return func.lowerConstant(Value.fromInterned(enum_tag.int), Type.fromInterned(int_tag_ty));
33363315 },
33373316 .float => |float| switch (float.storage) {
3338 .f16 => |f16_val| return WValue{ .imm32 = @as(u16, @bitCast(f16_val)) },
3339 .f32 => |f32_val| return WValue{ .float32 = f32_val },
3340 .f64 => |f64_val| return WValue{ .float64 = f64_val },
3317 .f16 => |f16_val| return .{ .imm32 = @as(u16, @bitCast(f16_val)) },
3318 .f32 => |f32_val| return .{ .float32 = f32_val },
3319 .f64 => |f64_val| return .{ .float64 = f64_val },
33413320 else => unreachable,
33423321 },
33433322 .slice => |slice| {
......@@ -3357,10 +3336,10 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
33573336 if (val.optionalValue(mod)) |payload| {
33583337 return func.lowerConstant(payload, pl_ty);
33593338 } else {
3360 return WValue{ .imm32 = 0 };
3339 return .{ .imm32 = 0 };
33613340 }
33623341 } else {
3363 return WValue{ .imm32 = @intFromBool(!val.isNull(mod)) };
3342 return .{ .imm32 = @intFromBool(!val.isNull(mod)) };
33643343 },
33653344 .aggregate => switch (ip.indexToKey(ty.ip_index)) {
33663345 .array_type => return func.fail("Wasm TODO: LowerConstant for {}", .{ty.fmt(pt)}),
......@@ -3406,7 +3385,7 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
34063385fn storeSimdImmd(func: *CodeGen, value: [16]u8) !WValue {
34073386 const index = @as(u32, @intCast(func.simd_immediates.items.len));
34083387 try func.simd_immediates.append(func.gpa, value);
3409 return WValue{ .imm128 = index };
3388 return .{ .imm128 = index };
34103389}
34113390
34123391fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {
......@@ -3414,21 +3393,21 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {
34143393 const mod = pt.zcu;
34153394 const ip = &mod.intern_pool;
34163395 switch (ty.zigTypeTag(mod)) {
3417 .Bool, .ErrorSet => return WValue{ .imm32 = 0xaaaaaaaa },
3396 .Bool, .ErrorSet => return .{ .imm32 = 0xaaaaaaaa },
34183397 .Int, .Enum => switch (ty.intInfo(mod).bits) {
3419 0...32 => return WValue{ .imm32 = 0xaaaaaaaa },
3420 33...64 => return WValue{ .imm64 = 0xaaaaaaaaaaaaaaaa },
3398 0...32 => return .{ .imm32 = 0xaaaaaaaa },
3399 33...64 => return .{ .imm64 = 0xaaaaaaaaaaaaaaaa },
34213400 else => unreachable,
34223401 },
34233402 .Float => switch (ty.floatBits(func.target)) {
3424 16 => return WValue{ .imm32 = 0xaaaaaaaa },
3425 32 => return WValue{ .float32 = @as(f32, @bitCast(@as(u32, 0xaaaaaaaa))) },
3426 64 => return WValue{ .float64 = @as(f64, @bitCast(@as(u64, 0xaaaaaaaaaaaaaaaa))) },
3403 16 => return .{ .imm32 = 0xaaaaaaaa },
3404 32 => return .{ .float32 = @as(f32, @bitCast(@as(u32, 0xaaaaaaaa))) },
3405 64 => return .{ .float64 = @as(f64, @bitCast(@as(u64, 0xaaaaaaaaaaaaaaaa))) },
34273406 else => unreachable,
34283407 },
34293408 .Pointer => switch (func.arch()) {
3430 .wasm32 => return WValue{ .imm32 = 0xaaaaaaaa },
3431 .wasm64 => return WValue{ .imm64 = 0xaaaaaaaaaaaaaaaa },
3409 .wasm32 => return .{ .imm32 = 0xaaaaaaaa },
3410 .wasm64 => return .{ .imm64 = 0xaaaaaaaaaaaaaaaa },
34323411 else => unreachable,
34333412 },
34343413 .Optional => {
......@@ -3436,10 +3415,10 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {
34363415 if (ty.optionalReprIsPayload(mod)) {
34373416 return func.emitUndefined(pl_ty);
34383417 }
3439 return WValue{ .imm32 = 0xaaaaaaaa };
3418 return .{ .imm32 = 0xaaaaaaaa };
34403419 },
34413420 .ErrorUnion => {
3442 return WValue{ .imm32 = 0xaaaaaaaa };
3421 return .{ .imm32 = 0xaaaaaaaa };
34433422 },
34443423 .Struct => {
34453424 const packed_struct = mod.typeToPackedStruct(ty).?;
......@@ -3501,7 +3480,7 @@ fn lowerBlock(func: *CodeGen, inst: Air.Inst.Index, block_ty: Type, body: []cons
35013480 const block_result: WValue = if (wasm_block_ty != wasm.block_empty) blk: {
35023481 const ty: Type = if (isByRef(block_ty, pt)) Type.u32 else block_ty;
35033482 break :blk try func.ensureAllocLocal(ty); // make sure it's a clean local as it may never get overwritten
3504 } else WValue.none;
3483 } else .none;
35053484
35063485 try func.startBlock(.block, wasm.block_empty);
35073486 // Here we set the current block idx, so breaks know the depth to jump
......@@ -3517,7 +3496,7 @@ fn lowerBlock(func: *CodeGen, inst: Air.Inst.Index, block_ty: Type, body: []cons
35173496 const liveness = func.liveness.getBlock(inst);
35183497 try func.currentBranch().values.ensureUnusedCapacity(func.gpa, liveness.deaths.len);
35193498
3520 func.finishAir(inst, block_result, &.{});
3499 return func.finishAir(inst, block_result, &.{});
35213500}
35223501
35233502/// appends a new wasm block to the code section and increases the `block_depth` by 1
......@@ -3549,7 +3528,7 @@ fn airLoop(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
35493528 try func.addLabel(.br, 0);
35503529 try func.endBlock();
35513530
3552 func.finishAir(inst, .none, &.{});
3531 return func.finishAir(inst, .none, &.{});
35533532}
35543533
35553534fn airCondBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -3593,7 +3572,7 @@ fn airCondBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
35933572 try func.genBody(then_body);
35943573 }
35953574
3596 func.finishAir(inst, .none, &.{});
3575 return func.finishAir(inst, .none, &.{});
35973576}
35983577
35993578fn airCmp(func: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) InnerError!void {
......@@ -3602,8 +3581,8 @@ fn airCmp(func: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) In
36023581 const lhs = try func.resolveInst(bin_op.lhs);
36033582 const rhs = try func.resolveInst(bin_op.rhs);
36043583 const operand_ty = func.typeOf(bin_op.lhs);
3605 const result = try (try func.cmp(lhs, rhs, operand_ty, op)).toLocal(func, Type.u32); // comparison result is always 32 bits
3606 func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
3584 const result = try func.cmp(lhs, rhs, operand_ty, op);
3585 return func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
36073586}
36083587
36093588/// Compares two operands.
......@@ -3654,7 +3633,7 @@ fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareO
36543633 });
36553634 try func.addTag(Mir.Inst.Tag.fromOpcode(opcode));
36563635
3657 return WValue{ .stack = {} };
3636 return .stack;
36583637}
36593638
36603639/// Compares two floats.
......@@ -3694,7 +3673,7 @@ fn cmpFloat(func: *CodeGen, ty: Type, lhs: WValue, rhs: WValue, cmp_op: std.math
36943673 }) catch unreachable;
36953674
36963675 const result = try func.callIntrinsic(fn_name, &.{ ty.ip_index, ty.ip_index }, Type.bool, &.{ lhs, rhs });
3697 return func.cmp(result, WValue{ .imm32 = 0 }, Type.i32, cmp_op);
3676 return func.cmp(result, .{ .imm32 = 0 }, Type.i32, cmp_op);
36983677 },
36993678 else => unreachable,
37003679 }
......@@ -3709,7 +3688,7 @@ fn airCmpLtErrorsLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
37093688 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
37103689 const operand = try func.resolveInst(un_op);
37113690 const sym_index = try func.bin_file.getGlobalSymbol("__zig_errors_len", null);
3712 const errors_len = WValue{ .memory = @intFromEnum(sym_index) };
3691 const errors_len = .{ .memory = @intFromEnum(sym_index) };
37133692
37143693 try func.emitWValue(operand);
37153694 const pt = func.pt;
......@@ -3717,7 +3696,7 @@ fn airCmpLtErrorsLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
37173696 const errors_len_val = try func.load(errors_len, err_int_ty, 0);
37183697 const result = try func.cmp(.stack, errors_len_val, err_int_ty, .lt);
37193698
3720 return func.finishAir(inst, try result.toLocal(func, Type.bool), &.{un_op});
3699 return func.finishAir(inst, result, &.{un_op});
37213700}
37223701
37233702fn airBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -3740,7 +3719,7 @@ fn airBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
37403719 const idx: u32 = func.block_depth - block.label;
37413720 try func.addLabel(.br, idx);
37423721
3743 func.finishAir(inst, .none, &.{br.operand});
3722 return func.finishAir(inst, .none, &.{br.operand});
37443723}
37453724
37463725fn airNot(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -3772,7 +3751,7 @@ fn airNot(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
37723751 .signed => ~@as(u32, 0),
37733752 });
37743753 try func.addTag(.i32_xor);
3775 break :result try @as(WValue, .stack).toLocal(func, operand_ty);
3754 break :result .stack;
37763755 },
37773756 64 => {
37783757 try func.emitWValue(operand);
......@@ -3781,7 +3760,7 @@ fn airNot(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
37813760 .signed => ~@as(u64, 0),
37823761 });
37833762 try func.addTag(.i64_xor);
3784 break :result try @as(WValue, .stack).toLocal(func, operand_ty);
3763 break :result .stack;
37853764 },
37863765 128 => {
37873766 const ptr = try func.allocStack(operand_ty);
......@@ -3807,24 +3786,24 @@ fn airNot(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
38073786 }
38083787 }
38093788 };
3810 func.finishAir(inst, result, &.{ty_op.operand});
3789 return func.finishAir(inst, result, &.{ty_op.operand});
38113790}
38123791
38133792fn airTrap(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
38143793 try func.addTag(.@"unreachable");
3815 func.finishAir(inst, .none, &.{});
3794 return func.finishAir(inst, .none, &.{});
38163795}
38173796
38183797fn airBreakpoint(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
38193798 // unsupported by wasm itfunc. Can be implemented once we support DWARF
38203799 // for wasm
38213800 try func.addTag(.@"unreachable");
3822 func.finishAir(inst, .none, &.{});
3801 return func.finishAir(inst, .none, &.{});
38233802}
38243803
38253804fn airUnreachable(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
38263805 try func.addTag(.@"unreachable");
3827 func.finishAir(inst, .none, &.{});
3806 return func.finishAir(inst, .none, &.{});
38283807}
38293808
38303809fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -3841,35 +3820,34 @@ fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
38413820
38423821 const result = result: {
38433822 if (given_ty.isAnyFloat() or wanted_ty.isAnyFloat()) {
3844 const bitcast_result = try func.bitcast(wanted_ty, given_ty, operand);
3845 break :result try bitcast_result.toLocal(func, wanted_ty);
3823 break :result try func.bitcast(wanted_ty, given_ty, operand);
38463824 }
38473825
38483826 if (isByRef(given_ty, pt) and !isByRef(wanted_ty, pt)) {
38493827 const loaded_memory = try func.load(operand, wanted_ty, 0);
38503828 if (needs_wrapping) {
3851 break :result try (try func.wrapOperand(loaded_memory, wanted_ty)).toLocal(func, wanted_ty);
3829 break :result try func.wrapOperand(loaded_memory, wanted_ty);
38523830 } else {
3853 break :result try loaded_memory.toLocal(func, wanted_ty);
3831 break :result loaded_memory;
38543832 }
38553833 }
38563834 if (!isByRef(given_ty, pt) and isByRef(wanted_ty, pt)) {
38573835 const stack_memory = try func.allocStack(wanted_ty);
38583836 try func.store(stack_memory, operand, given_ty, 0);
38593837 if (needs_wrapping) {
3860 break :result try (try func.wrapOperand(stack_memory, wanted_ty)).toLocal(func, wanted_ty);
3838 break :result try func.wrapOperand(stack_memory, wanted_ty);
38613839 } else {
38623840 break :result stack_memory;
38633841 }
38643842 }
38653843
38663844 if (needs_wrapping) {
3867 break :result try (try func.wrapOperand(operand, wanted_ty)).toLocal(func, wanted_ty);
3845 break :result try func.wrapOperand(operand, wanted_ty);
38683846 }
38693847
38703848 break :result func.reuseOperand(ty_op.operand, operand);
38713849 };
3872 func.finishAir(inst, result, &.{ty_op.operand});
3850 return func.finishAir(inst, result, &.{ty_op.operand});
38733851}
38743852
38753853fn bitcast(func: *CodeGen, wanted_ty: Type, given_ty: Type, operand: WValue) InnerError!WValue {
......@@ -3888,7 +3866,7 @@ fn bitcast(func: *CodeGen, wanted_ty: Type, given_ty: Type, operand: WValue) Inn
38883866 });
38893867 try func.emitWValue(operand);
38903868 try func.addTag(Mir.Inst.Tag.fromOpcode(opcode));
3891 return WValue{ .stack = {} };
3869 return .stack;
38923870}
38933871
38943872fn airStructFieldPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -3901,7 +3879,7 @@ fn airStructFieldPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
39013879 const struct_ptr_ty = func.typeOf(extra.data.struct_operand);
39023880 const struct_ty = struct_ptr_ty.childType(mod);
39033881 const result = try func.structFieldPtr(inst, extra.data.struct_operand, struct_ptr, struct_ptr_ty, struct_ty, extra.data.field_index);
3904 func.finishAir(inst, result, &.{extra.data.struct_operand});
3882 return func.finishAir(inst, result, &.{extra.data.struct_operand});
39053883}
39063884
39073885fn airStructFieldPtrIndex(func: *CodeGen, inst: Air.Inst.Index, index: u32) InnerError!void {
......@@ -3913,7 +3891,7 @@ fn airStructFieldPtrIndex(func: *CodeGen, inst: Air.Inst.Index, index: u32) Inne
39133891 const struct_ty = struct_ptr_ty.childType(mod);
39143892
39153893 const result = try func.structFieldPtr(inst, ty_op.operand, struct_ptr, struct_ptr_ty, struct_ty, index);
3916 func.finishAir(inst, result, &.{ty_op.operand});
3894 return func.finishAir(inst, result, &.{ty_op.operand});
39173895}
39183896
39193897fn structFieldPtr(
......@@ -3950,7 +3928,7 @@ fn structFieldPtr(
39503928 }
39513929 switch (struct_ptr) {
39523930 .stack_offset => |stack_offset| {
3953 return WValue{ .stack_offset = .{ .value = stack_offset.value + @as(u32, @intCast(offset)), .references = 1 } };
3931 return .{ .stack_offset = .{ .value = stack_offset.value + @as(u32, @intCast(offset)), .references = 1 } };
39543932 },
39553933 else => return func.buildPointerOffset(struct_ptr, offset, .new),
39563934 }
......@@ -3969,7 +3947,7 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
39693947 const field_ty = struct_ty.structFieldType(field_index, mod);
39703948 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) return func.finishAir(inst, .none, &.{struct_field.struct_operand});
39713949
3972 const result = switch (struct_ty.containerLayout(mod)) {
3950 const result: WValue = switch (struct_ty.containerLayout(mod)) {
39733951 .@"packed" => switch (struct_ty.zigTypeTag(mod)) {
39743952 .Struct => result: {
39753953 const packed_struct = mod.typeToPackedStruct(struct_ty).?;
......@@ -3978,10 +3956,10 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
39783956 const wasm_bits = toWasmBits(backing_ty.intInfo(mod).bits) orelse {
39793957 return func.fail("TODO: airStructFieldVal for packed structs larger than 128 bits", .{});
39803958 };
3981 const const_wvalue = if (wasm_bits == 32)
3982 WValue{ .imm32 = offset }
3959 const const_wvalue: WValue = if (wasm_bits == 32)
3960 .{ .imm32 = offset }
39833961 else if (wasm_bits == 64)
3984 WValue{ .imm64 = offset }
3962 .{ .imm64 = offset }
39853963 else
39863964 return func.fail("TODO: airStructFieldVal for packed structs larger than 64 bits", .{});
39873965
......@@ -3994,25 +3972,21 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
39943972 if (field_ty.zigTypeTag(mod) == .Float) {
39953973 const int_type = try pt.intType(.unsigned, @as(u16, @intCast(field_ty.bitSize(pt))));
39963974 const truncated = try func.trunc(shifted_value, int_type, backing_ty);
3997 const bitcasted = try func.bitcast(field_ty, int_type, truncated);
3998 break :result try bitcasted.toLocal(func, field_ty);
3975 break :result try func.bitcast(field_ty, int_type, truncated);
39993976 } else if (field_ty.isPtrAtRuntime(mod) and packed_struct.field_types.len == 1) {
40003977 // In this case we do not have to perform any transformations,
40013978 // we can simply reuse the operand.
40023979 break :result func.reuseOperand(struct_field.struct_operand, operand);
40033980 } else if (field_ty.isPtrAtRuntime(mod)) {
40043981 const int_type = try pt.intType(.unsigned, @as(u16, @intCast(field_ty.bitSize(pt))));
4005 const truncated = try func.trunc(shifted_value, int_type, backing_ty);
4006 break :result try truncated.toLocal(func, field_ty);
3982 break :result try func.trunc(shifted_value, int_type, backing_ty);
40073983 }
4008 const truncated = try func.trunc(shifted_value, field_ty, backing_ty);
4009 break :result try truncated.toLocal(func, field_ty);
3984 break :result try func.trunc(shifted_value, field_ty, backing_ty);
40103985 },
40113986 .Union => result: {
40123987 if (isByRef(struct_ty, pt)) {
40133988 if (!isByRef(field_ty, pt)) {
4014 const val = try func.load(operand, field_ty, 0);
4015 break :result try val.toLocal(func, field_ty);
3989 break :result try func.load(operand, field_ty, 0);
40163990 } else {
40173991 const new_stack_val = try func.allocStack(field_ty);
40183992 try func.store(new_stack_val, operand, field_ty, 0);
......@@ -4024,15 +3998,12 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
40243998 if (field_ty.zigTypeTag(mod) == .Float) {
40253999 const int_type = try pt.intType(.unsigned, @as(u16, @intCast(field_ty.bitSize(pt))));
40264000 const truncated = try func.trunc(operand, int_type, union_int_type);
4027 const bitcasted = try func.bitcast(field_ty, int_type, truncated);
4028 break :result try bitcasted.toLocal(func, field_ty);
4001 break :result try func.bitcast(field_ty, int_type, truncated);
40294002 } else if (field_ty.isPtrAtRuntime(mod)) {
40304003 const int_type = try pt.intType(.unsigned, @as(u16, @intCast(field_ty.bitSize(pt))));
4031 const truncated = try func.trunc(operand, int_type, union_int_type);
4032 break :result try truncated.toLocal(func, field_ty);
4004 break :result try func.trunc(operand, int_type, union_int_type);
40334005 }
4034 const truncated = try func.trunc(operand, field_ty, union_int_type);
4035 break :result try truncated.toLocal(func, field_ty);
4006 break :result try func.trunc(operand, field_ty, union_int_type);
40364007 },
40374008 else => unreachable,
40384009 },
......@@ -4043,17 +4014,16 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
40434014 if (isByRef(field_ty, pt)) {
40444015 switch (operand) {
40454016 .stack_offset => |stack_offset| {
4046 break :result WValue{ .stack_offset = .{ .value = stack_offset.value + offset, .references = 1 } };
4017 break :result .{ .stack_offset = .{ .value = stack_offset.value + offset, .references = 1 } };
40474018 },
40484019 else => break :result try func.buildPointerOffset(operand, offset, .new),
40494020 }
40504021 }
4051 const field = try func.load(operand, field_ty, offset);
4052 break :result try field.toLocal(func, field_ty);
4022 break :result try func.load(operand, field_ty, offset);
40534023 },
40544024 };
40554025
4056 func.finishAir(inst, result, &.{struct_field.struct_operand});
4026 return func.finishAir(inst, result, &.{struct_field.struct_operand});
40574027}
40584028
40594029fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -4234,7 +4204,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
42344204 try func.genBody(else_body);
42354205 try func.endBlock();
42364206 }
4237 func.finishAir(inst, .none, &.{});
4207 return func.finishAir(inst, .none, &.{});
42384208}
42394209
42404210fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerError!void {
......@@ -4245,11 +4215,11 @@ fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerErro
42454215 const err_union_ty = func.typeOf(un_op);
42464216 const pl_ty = err_union_ty.errorUnionPayload(mod);
42474217
4248 const result = result: {
4218 const result: WValue = result: {
42494219 if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
42504220 switch (opcode) {
4251 .i32_ne => break :result WValue{ .imm32 = 0 },
4252 .i32_eq => break :result WValue{ .imm32 = 1 },
4221 .i32_ne => break :result .{ .imm32 = 0 },
4222 .i32_eq => break :result .{ .imm32 = 1 },
42534223 else => unreachable,
42544224 }
42554225 }
......@@ -4265,12 +4235,9 @@ fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerErro
42654235 // Compare the error value with '0'
42664236 try func.addImm32(0);
42674237 try func.addTag(Mir.Inst.Tag.fromOpcode(opcode));
4268
4269 const is_err_tmp = try func.allocLocal(Type.i32);
4270 try func.addLabel(.local_set, is_err_tmp.local.value);
4271 break :result is_err_tmp;
4238 break :result .stack;
42724239 };
4273 func.finishAir(inst, result, &.{un_op});
4240 return func.finishAir(inst, result, &.{un_op});
42744241}
42754242
42764243fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!void {
......@@ -4283,12 +4250,12 @@ fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: boo
42834250 const err_ty = if (op_is_ptr) op_ty.childType(mod) else op_ty;
42844251 const payload_ty = err_ty.errorUnionPayload(mod);
42854252
4286 const result = result: {
4253 const result: WValue = result: {
42874254 if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
42884255 if (op_is_ptr) {
42894256 break :result func.reuseOperand(ty_op.operand, operand);
42904257 }
4291 break :result WValue{ .none = {} };
4258 break :result .none;
42924259 }
42934260
42944261 const pl_offset = @as(u32, @intCast(errUnionPayloadOffset(payload_ty, pt)));
......@@ -4296,10 +4263,9 @@ fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: boo
42964263 break :result try func.buildPointerOffset(operand, pl_offset, .new);
42974264 }
42984265
4299 const payload = try func.load(operand, payload_ty, pl_offset);
4300 break :result try payload.toLocal(func, payload_ty);
4266 break :result try func.load(operand, payload_ty, pl_offset);
43014267 };
4302 func.finishAir(inst, result, &.{ty_op.operand});
4268 return func.finishAir(inst, result, &.{ty_op.operand});
43034269}
43044270
43054271fn airUnwrapErrUnionError(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!void {
......@@ -4312,19 +4278,18 @@ fn airUnwrapErrUnionError(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool)
43124278 const err_ty = if (op_is_ptr) op_ty.childType(mod) else op_ty;
43134279 const payload_ty = err_ty.errorUnionPayload(mod);
43144280
4315 const result = result: {
4281 const result: WValue = result: {
43164282 if (err_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
4317 break :result WValue{ .imm32 = 0 };
4283 break :result .{ .imm32 = 0 };
43184284 }
43194285
43204286 if (op_is_ptr or !payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
43214287 break :result func.reuseOperand(ty_op.operand, operand);
43224288 }
43234289
4324 const error_val = try func.load(operand, Type.anyerror, @intCast(errUnionErrorOffset(payload_ty, pt)));
4325 break :result try error_val.toLocal(func, Type.anyerror);
4290 break :result try func.load(operand, Type.anyerror, @intCast(errUnionErrorOffset(payload_ty, pt)));
43264291 };
4327 func.finishAir(inst, result, &.{ty_op.operand});
4292 return func.finishAir(inst, result, &.{ty_op.operand});
43284293}
43294294
43304295fn airWrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -4354,7 +4319,7 @@ fn airWrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void
43544319 });
43554320 break :result err_union;
43564321 };
4357 func.finishAir(inst, result, &.{ty_op.operand});
4322 return func.finishAir(inst, result, &.{ty_op.operand});
43584323}
43594324
43604325fn airWrapErrUnionErr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -4382,7 +4347,7 @@ fn airWrapErrUnionErr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
43824347
43834348 break :result err_union;
43844349 };
4385 func.finishAir(inst, result, &.{ty_op.operand});
4350 return func.finishAir(inst, result, &.{ty_op.operand});
43864351}
43874352
43884353fn airIntcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -4405,9 +4370,9 @@ fn airIntcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
44054370 const result = if (op_bits == wanted_bits)
44064371 func.reuseOperand(ty_op.operand, operand)
44074372 else
4408 try (try func.intcast(operand, operand_ty, ty)).toLocal(func, ty);
4373 try func.intcast(operand, operand_ty, ty);
44094374
4410 func.finishAir(inst, result, &.{});
4375 return func.finishAir(inst, result, &.{});
44114376}
44124377
44134378/// Upcasts or downcasts an integer based on the given and wanted types,
......@@ -4472,9 +4437,8 @@ fn airIsNull(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode, op_kind:
44724437
44734438 const op_ty = func.typeOf(un_op);
44744439 const optional_ty = if (op_kind == .ptr) op_ty.childType(mod) else op_ty;
4475 const is_null = try func.isNull(operand, optional_ty, opcode);
4476 const result = try is_null.toLocal(func, optional_ty);
4477 func.finishAir(inst, result, &.{un_op});
4440 const result = try func.isNull(operand, optional_ty, opcode);
4441 return func.finishAir(inst, result, &.{un_op});
44784442}
44794443
44804444/// For a given type and operand, checks if it's considered `null`.
......@@ -4505,7 +4469,7 @@ fn isNull(func: *CodeGen, operand: WValue, optional_ty: Type, opcode: wasm.Opcod
45054469 try func.addImm32(0);
45064470 try func.addTag(Mir.Inst.Tag.fromOpcode(opcode));
45074471
4508 return WValue{ .stack = {} };
4472 return .stack;
45094473}
45104474
45114475fn airOptionalPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -4526,10 +4490,9 @@ fn airOptionalPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
45264490 break :result try func.buildPointerOffset(operand, 0, .new);
45274491 }
45284492
4529 const payload = try func.load(operand, payload_ty, 0);
4530 break :result try payload.toLocal(func, payload_ty);
4493 break :result try func.load(operand, payload_ty, 0);
45314494 };
4532 func.finishAir(inst, result, &.{ty_op.operand});
4495 return func.finishAir(inst, result, &.{ty_op.operand});
45334496}
45344497
45354498fn airOptionalPayloadPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -4547,7 +4510,7 @@ fn airOptionalPayloadPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
45474510
45484511 break :result try func.buildPointerOffset(operand, 0, .new);
45494512 };
4550 func.finishAir(inst, result, &.{ty_op.operand});
4513 return func.finishAir(inst, result, &.{ty_op.operand});
45514514}
45524515
45534516fn airOptionalPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -4612,7 +4575,7 @@ fn airWrapOptional(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
46124575 break :result result_ptr;
46134576 };
46144577
4615 func.finishAir(inst, result, &.{ty_op.operand});
4578 return func.finishAir(inst, result, &.{ty_op.operand});
46164579}
46174580
46184581fn airSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -4627,14 +4590,14 @@ fn airSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
46274590 try func.store(slice, lhs, Type.usize, 0);
46284591 try func.store(slice, rhs, Type.usize, func.ptrSize());
46294592
4630 func.finishAir(inst, slice, &.{ bin_op.lhs, bin_op.rhs });
4593 return func.finishAir(inst, slice, &.{ bin_op.lhs, bin_op.rhs });
46314594}
46324595
46334596fn airSliceLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
46344597 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
46354598
46364599 const operand = try func.resolveInst(ty_op.operand);
4637 func.finishAir(inst, try func.sliceLen(operand), &.{ty_op.operand});
4600 return func.finishAir(inst, try func.sliceLen(operand), &.{ty_op.operand});
46384601}
46394602
46404603fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -4657,15 +4620,12 @@ fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
46574620 try func.addTag(.i32_mul);
46584621 try func.addTag(.i32_add);
46594622
4660 const result_ptr = try func.allocLocal(Type.usize);
4661 try func.addLabel(.local_set, result_ptr.local.value);
4662
4663 const result = if (!isByRef(elem_ty, pt)) result: {
4664 const elem_val = try func.load(result_ptr, elem_ty, 0);
4665 break :result try elem_val.toLocal(func, elem_ty);
4666 } else result_ptr;
4623 const elem_result = if (isByRef(elem_ty, pt))
4624 .stack
4625 else
4626 try func.load(.stack, elem_ty, 0);
46674627
4668 func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
4628 return func.finishAir(inst, elem_result, &.{ bin_op.lhs, bin_op.rhs });
46694629}
46704630
46714631fn airSliceElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -4688,15 +4648,13 @@ fn airSliceElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
46884648 try func.addTag(.i32_mul);
46894649 try func.addTag(.i32_add);
46904650
4691 const result = try func.allocLocal(Type.i32);
4692 try func.addLabel(.local_set, result.local.value);
4693 func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
4651 return func.finishAir(inst, .stack, &.{ bin_op.lhs, bin_op.rhs });
46944652}
46954653
46964654fn airSlicePtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
46974655 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
46984656 const operand = try func.resolveInst(ty_op.operand);
4699 func.finishAir(inst, try func.slicePtr(operand), &.{ty_op.operand});
4657 return func.finishAir(inst, try func.slicePtr(operand), &.{ty_op.operand});
47004658}
47014659
47024660fn slicePtr(func: *CodeGen, operand: WValue) InnerError!WValue {
......@@ -4717,7 +4675,7 @@ fn airTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
47174675 const op_ty = func.typeOf(ty_op.operand);
47184676
47194677 const result = try func.trunc(operand, wanted_ty, op_ty);
4720 func.finishAir(inst, try result.toLocal(func, wanted_ty), &.{ty_op.operand});
4678 return func.finishAir(inst, result, &.{ty_op.operand});
47214679}
47224680
47234681/// Truncates a given operand to a given type, discarding any overflown bits.
......@@ -4743,7 +4701,7 @@ fn airIntFromBool(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
47434701 const operand = try func.resolveInst(un_op);
47444702 const result = func.reuseOperand(un_op, operand);
47454703
4746 func.finishAir(inst, result, &.{un_op});
4704 return func.finishAir(inst, result, &.{un_op});
47474705}
47484706
47494707fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -4764,10 +4722,10 @@ fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
47644722 }
47654723
47664724 // store the length of the array in the slice
4767 const len = WValue{ .imm32 = @as(u32, @intCast(array_ty.arrayLen(mod))) };
4768 try func.store(slice_local, len, Type.usize, func.ptrSize());
4725 const array_len: u32 = @intCast(array_ty.arrayLen(mod));
4726 try func.store(slice_local, .{ .imm32 = array_len }, Type.usize, func.ptrSize());
47694727
4770 func.finishAir(inst, slice_local, &.{ty_op.operand});
4728 return func.finishAir(inst, slice_local, &.{ty_op.operand});
47714729}
47724730
47734731fn airIntFromPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -4783,7 +4741,7 @@ fn airIntFromPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
47834741 .stack_offset => try func.buildPointerOffset(operand, 0, .new),
47844742 else => func.reuseOperand(un_op, operand),
47854743 };
4786 func.finishAir(inst, result, &.{un_op});
4744 return func.finishAir(inst, result, &.{un_op});
47874745}
47884746
47894747fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -4810,18 +4768,12 @@ fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
48104768 try func.addTag(.i32_mul);
48114769 try func.addTag(.i32_add);
48124770
4813 const elem_result = val: {
4814 var result = try func.allocLocal(Type.usize);
4815 try func.addLabel(.local_set, result.local.value);
4816 if (isByRef(elem_ty, pt)) {
4817 break :val result;
4818 }
4819 defer result.free(func); // only free if it's not returned like above
4771 const elem_result = if (isByRef(elem_ty, pt))
4772 .stack
4773 else
4774 try func.load(.stack, elem_ty, 0);
48204775
4821 const elem_val = try func.load(result, elem_ty, 0);
4822 break :val try elem_val.toLocal(func, elem_ty);
4823 };
4824 func.finishAir(inst, elem_result, &.{ bin_op.lhs, bin_op.rhs });
4776 return func.finishAir(inst, elem_result, &.{ bin_op.lhs, bin_op.rhs });
48254777}
48264778
48274779fn airPtrElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -4850,9 +4802,7 @@ fn airPtrElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
48504802 try func.addTag(.i32_mul);
48514803 try func.addTag(.i32_add);
48524804
4853 const result = try func.allocLocal(Type.i32);
4854 try func.addLabel(.local_set, result.local.value);
4855 func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
4805 return func.finishAir(inst, .stack, &.{ bin_op.lhs, bin_op.rhs });
48564806}
48574807
48584808fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
......@@ -4879,9 +4829,7 @@ fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
48794829 try func.addTag(Mir.Inst.Tag.fromOpcode(mul_opcode));
48804830 try func.addTag(Mir.Inst.Tag.fromOpcode(bin_opcode));
48814831
4882 const result = try func.allocLocal(Type.usize);
4883 try func.addLabel(.local_set, result.local.value);
4884 func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
4832 return func.finishAir(inst, .stack, &.{ bin_op.lhs, bin_op.rhs });
48854833}
48864834
48874835fn airMemset(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void {
......@@ -4911,7 +4859,7 @@ fn airMemset(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void
49114859 const dst_ptr = try func.sliceOrArrayPtr(ptr, ptr_ty);
49124860 try func.memset(elem_ty, dst_ptr, len, value);
49134861
4914 func.finishAir(inst, .none, &.{ bin_op.lhs, bin_op.rhs });
4862 return func.finishAir(inst, .none, &.{ bin_op.lhs, bin_op.rhs });
49154863}
49164864
49174865/// Sets a region of memory at `ptr` to the value of `value`
......@@ -4932,9 +4880,9 @@ fn memset(func: *CodeGen, elem_ty: Type, ptr: WValue, len: WValue, value: WValue
49324880 return;
49334881 }
49344882
4935 const final_len = switch (len) {
4936 .imm32 => |val| WValue{ .imm32 = val * abi_size },
4937 .imm64 => |val| WValue{ .imm64 = val * abi_size },
4883 const final_len: WValue = switch (len) {
4884 .imm32 => |val| .{ .imm32 = val * abi_size },
4885 .imm64 => |val| .{ .imm64 = val * abi_size },
49384886 else => if (abi_size != 1) blk: {
49394887 const new_len = try func.ensureAllocLocal(Type.usize);
49404888 try func.emitWValue(len);
......@@ -5045,7 +4993,7 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
50454993 try func.mir_extra.appendSlice(func.gpa, &operands);
50464994 try func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } });
50474995
5048 return func.finishAir(inst, try WValue.toLocal(.stack, func, elem_ty), &.{ bin_op.lhs, bin_op.rhs });
4996 return func.finishAir(inst, .stack, &.{ bin_op.lhs, bin_op.rhs });
50494997 },
50504998 else => {
50514999 const stack_vec = try func.allocStack(array_ty);
......@@ -5061,20 +5009,12 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
50615009 }
50625010 }
50635011
5064 const elem_result = val: {
5065 var result = try func.allocLocal(Type.usize);
5066 try func.addLabel(.local_set, result.local.value);
5067
5068 if (isByRef(elem_ty, pt)) {
5069 break :val result;
5070 }
5071 defer result.free(func); // only free if no longer needed and not returned like above
5072
5073 const elem_val = try func.load(result, elem_ty, 0);
5074 break :val try elem_val.toLocal(func, elem_ty);
5075 };
5012 const elem_result = if (isByRef(elem_ty, pt))
5013 .stack
5014 else
5015 try func.load(.stack, elem_ty, 0);
50765016
5077 func.finishAir(inst, elem_result, &.{ bin_op.lhs, bin_op.rhs });
5017 return func.finishAir(inst, elem_result, &.{ bin_op.lhs, bin_op.rhs });
50785018}
50795019
50805020fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -5106,7 +5046,7 @@ fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
51065046 target_util.compilerRtIntAbbrev(dest_bitsize),
51075047 }) catch unreachable;
51085048
5109 const result = try (try func.callIntrinsic(fn_name, &.{op_ty.ip_index}, dest_ty, &.{operand})).toLocal(func, dest_ty);
5049 const result = try func.callIntrinsic(fn_name, &.{op_ty.ip_index}, dest_ty, &.{operand});
51105050 return func.finishAir(inst, result, &.{ty_op.operand});
51115051 }
51125052
......@@ -5118,9 +5058,8 @@ fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
51185058 .signedness = dest_info.signedness,
51195059 });
51205060 try func.addTag(Mir.Inst.Tag.fromOpcode(op));
5121 const wrapped = try func.wrapOperand(.{ .stack = {} }, dest_ty);
5122 const result = try wrapped.toLocal(func, dest_ty);
5123 func.finishAir(inst, result, &.{ty_op.operand});
5061 const result = try func.wrapOperand(.stack, dest_ty);
5062 return func.finishAir(inst, result, &.{ty_op.operand});
51245063}
51255064
51265065fn airFloatFromInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -5152,7 +5091,7 @@ fn airFloatFromInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
51525091 target_util.compilerRtFloatAbbrev(dest_bits),
51535092 }) catch unreachable;
51545093
5155 const result = try (try func.callIntrinsic(fn_name, &.{op_ty.ip_index}, dest_ty, &.{operand})).toLocal(func, dest_ty);
5094 const result = try func.callIntrinsic(fn_name, &.{op_ty.ip_index}, dest_ty, &.{operand});
51565095 return func.finishAir(inst, result, &.{ty_op.operand});
51575096 }
51585097
......@@ -5165,9 +5104,7 @@ fn airFloatFromInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
51655104 });
51665105 try func.addTag(Mir.Inst.Tag.fromOpcode(op));
51675106
5168 const result = try func.allocLocal(dest_ty);
5169 try func.addLabel(.local_set, result.local.value);
5170 func.finishAir(inst, result, &.{ty_op.operand});
5107 return func.finishAir(inst, .stack, &.{ty_op.operand});
51715108}
51725109
51735110fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -5191,7 +5128,6 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
51915128 64 => std.wasm.simdOpcode(.v128_load64_splat),
51925129 else => break :blk, // Cannot make use of simd-instructions
51935130 };
5194 const result = try func.allocLocal(ty);
51955131 try func.emitWValue(operand);
51965132 // TODO: Add helper functions for simd opcodes
51975133 const extra_index = @as(u32, @intCast(func.mir_extra.items.len));
......@@ -5202,8 +5138,7 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
52025138 @intCast(elem_ty.abiAlignment(pt).toByteUnits().?),
52035139 });
52045140 try func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } });
5205 try func.addLabel(.local_set, result.local.value);
5206 return func.finishAir(inst, result, &.{ty_op.operand});
5141 return func.finishAir(inst, .stack, &.{ty_op.operand});
52075142 },
52085143 .local => {
52095144 const opcode = switch (elem_ty.bitSize(pt)) {
......@@ -5213,13 +5148,11 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
52135148 64 => if (elem_ty.isInt(mod)) std.wasm.simdOpcode(.i64x2_splat) else std.wasm.simdOpcode(.f64x2_splat),
52145149 else => break :blk, // Cannot make use of simd-instructions
52155150 };
5216 const result = try func.allocLocal(ty);
52175151 try func.emitWValue(operand);
52185152 const extra_index = @as(u32, @intCast(func.mir_extra.items.len));
52195153 try func.mir_extra.append(func.gpa, opcode);
52205154 try func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } });
5221 try func.addLabel(.local_set, result.local.value);
5222 return func.finishAir(inst, result, &.{ty_op.operand});
5155 return func.finishAir(inst, .stack, &.{ty_op.operand});
52235156 },
52245157 else => unreachable,
52255158 }
......@@ -5308,7 +5241,7 @@ fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
53085241 try func.mir_extra.appendSlice(func.gpa, &operands);
53095242 try func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } });
53105243
5311 return func.finishAir(inst, try WValue.toLocal(.stack, func, inst_ty), &.{ extra.a, extra.b });
5244 return func.finishAir(inst, .stack, &.{ extra.a, extra.b });
53125245 }
53135246}
53145247
......@@ -5392,10 +5325,10 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
53925325 const field_ty = Type.fromInterned(field_types.get(ip)[elem_index]);
53935326 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue;
53945327
5395 const shift_val = if (backing_type.bitSize(pt) <= 32)
5396 WValue{ .imm32 = current_bit }
5328 const shift_val: WValue = if (backing_type.bitSize(pt) <= 32)
5329 .{ .imm32 = current_bit }
53975330 else
5398 WValue{ .imm64 = current_bit };
5331 .{ .imm64 = current_bit };
53995332
54005333 const value = try func.resolveInst(elem);
54015334 const value_bit_size: u16 = @intCast(field_ty.bitSize(pt));
......@@ -5473,7 +5406,7 @@ fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
54735406 };
54745407 if (layout.payload_size == 0) {
54755408 if (layout.tag_size == 0) {
5476 break :result WValue{ .none = {} };
5409 break :result .none;
54775410 }
54785411 assert(!isByRef(union_ty, pt));
54795412 break :result tag_int;
......@@ -5511,15 +5444,12 @@ fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
55115444 if (field_ty.zigTypeTag(mod) == .Float) {
55125445 const int_type = try pt.intType(.unsigned, @intCast(field_ty.bitSize(pt)));
55135446 const bitcasted = try func.bitcast(field_ty, int_type, operand);
5514 const casted = try func.trunc(bitcasted, int_type, union_int_type);
5515 break :result try casted.toLocal(func, field_ty);
5447 break :result try func.trunc(bitcasted, int_type, union_int_type);
55165448 } else if (field_ty.isPtrAtRuntime(mod)) {
55175449 const int_type = try pt.intType(.unsigned, @intCast(field_ty.bitSize(pt)));
5518 const casted = try func.intcast(operand, int_type, union_int_type);
5519 break :result try casted.toLocal(func, field_ty);
5450 break :result try func.intcast(operand, int_type, union_int_type);
55205451 }
5521 const casted = try func.intcast(operand, field_ty, union_int_type);
5522 break :result try casted.toLocal(func, field_ty);
5452 break :result try func.intcast(operand, field_ty, union_int_type);
55235453 }
55245454 };
55255455
......@@ -5528,27 +5458,23 @@ fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
55285458
55295459fn airPrefetch(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
55305460 const prefetch = func.air.instructions.items(.data)[@intFromEnum(inst)].prefetch;
5531 func.finishAir(inst, .none, &.{prefetch.ptr});
5461 return func.finishAir(inst, .none, &.{prefetch.ptr});
55325462}
55335463
55345464fn airWasmMemorySize(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
55355465 const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
55365466
5537 const result = try func.allocLocal(func.typeOfIndex(inst));
55385467 try func.addLabel(.memory_size, pl_op.payload);
5539 try func.addLabel(.local_set, result.local.value);
5540 func.finishAir(inst, result, &.{pl_op.operand});
5468 return func.finishAir(inst, .stack, &.{pl_op.operand});
55415469}
55425470
55435471fn airWasmMemoryGrow(func: *CodeGen, inst: Air.Inst.Index) !void {
55445472 const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
55455473
55465474 const operand = try func.resolveInst(pl_op.operand);
5547 const result = try func.allocLocal(func.typeOfIndex(inst));
55485475 try func.emitWValue(operand);
55495476 try func.addLabel(.memory_grow, pl_op.payload);
5550 try func.addLabel(.local_set, result.local.value);
5551 func.finishAir(inst, result, &.{pl_op.operand});
5477 return func.finishAir(inst, .stack, &.{pl_op.operand});
55525478}
55535479
55545480fn cmpOptionals(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std.math.CompareOperator) InnerError!WValue {
......@@ -5582,7 +5508,7 @@ fn cmpOptionals(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op:
55825508 try func.emitWValue(result);
55835509 try func.addImm32(0);
55845510 try func.addTag(if (op == .eq) .i32_ne else .i32_eq);
5585 return WValue{ .stack = {} };
5511 return .stack;
55865512}
55875513
55885514/// Compares big integers by checking both its high bits and low bits.
......@@ -5628,7 +5554,7 @@ fn cmpBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std
56285554 },
56295555 }
56305556
5631 return WValue{ .stack = {} };
5557 return .stack;
56325558}
56335559
56345560fn airSetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -5653,7 +5579,7 @@ fn airSetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
56535579 break :blk @intCast(layout.payload_size);
56545580 } else 0;
56555581 try func.store(union_ptr, new_tag, tag_ty, offset);
5656 func.finishAir(inst, .none, &.{ bin_op.lhs, bin_op.rhs });
5582 return func.finishAir(inst, .none, &.{ bin_op.lhs, bin_op.rhs });
56575583}
56585584
56595585fn airGetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -5668,12 +5594,12 @@ fn airGetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
56685594 const operand = try func.resolveInst(ty_op.operand);
56695595 // when the tag alignment is smaller than the payload, the field will be stored
56705596 // after the payload.
5671 const offset: u32 = if (layout.tag_align.compare(.lt, layout.payload_align)) blk: {
5672 break :blk @intCast(layout.payload_size);
5673 } else 0;
5674 const tag = try func.load(operand, tag_ty, offset);
5675 const result = try tag.toLocal(func, tag_ty);
5676 func.finishAir(inst, result, &.{ty_op.operand});
5597 const offset: u32 = if (layout.tag_align.compare(.lt, layout.payload_align))
5598 @intCast(layout.payload_size)
5599 else
5600 0;
5601 const result = try func.load(operand, tag_ty, offset);
5602 return func.finishAir(inst, result, &.{ty_op.operand});
56775603}
56785604
56795605fn airFpext(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -5681,9 +5607,8 @@ fn airFpext(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
56815607
56825608 const dest_ty = func.typeOfIndex(inst);
56835609 const operand = try func.resolveInst(ty_op.operand);
5684 const extended = try func.fpext(operand, func.typeOf(ty_op.operand), dest_ty);
5685 const result = try extended.toLocal(func, dest_ty);
5686 func.finishAir(inst, result, &.{ty_op.operand});
5610 const result = try func.fpext(operand, func.typeOf(ty_op.operand), dest_ty);
5611 return func.finishAir(inst, result, &.{ty_op.operand});
56875612}
56885613
56895614/// Extends a float from a given `Type` to a larger wanted `Type`
......@@ -5695,7 +5620,7 @@ fn fpext(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerError!
56955620 if (wanted_bits == 64 and given_bits == 32) {
56965621 try func.emitWValue(operand);
56975622 try func.addTag(.f64_promote_f32);
5698 return WValue{ .stack = {} };
5623 return .stack;
56995624 } else if (given_bits == 16 and wanted_bits <= 64) {
57005625 // call __extendhfsf2(f16) f32
57015626 const f32_result = try func.callIntrinsic(
......@@ -5709,7 +5634,7 @@ fn fpext(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerError!
57095634 if (wanted_bits == 64) {
57105635 try func.addTag(.f64_promote_f32);
57115636 }
5712 return WValue{ .stack = {} };
5637 return .stack;
57135638 }
57145639
57155640 var fn_name_buf: [13]u8 = undefined;
......@@ -5726,9 +5651,8 @@ fn airFptrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
57265651
57275652 const dest_ty = func.typeOfIndex(inst);
57285653 const operand = try func.resolveInst(ty_op.operand);
5729 const truncated = try func.fptrunc(operand, func.typeOf(ty_op.operand), dest_ty);
5730 const result = try truncated.toLocal(func, dest_ty);
5731 func.finishAir(inst, result, &.{ty_op.operand});
5654 const result = try func.fptrunc(operand, func.typeOf(ty_op.operand), dest_ty);
5655 return func.finishAir(inst, result, &.{ty_op.operand});
57325656}
57335657
57345658/// Truncates a float from a given `Type` to its wanted `Type`
......@@ -5740,12 +5664,12 @@ fn fptrunc(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerErro
57405664 if (wanted_bits == 32 and given_bits == 64) {
57415665 try func.emitWValue(operand);
57425666 try func.addTag(.f32_demote_f64);
5743 return WValue{ .stack = {} };
5667 return .stack;
57445668 } else if (wanted_bits == 16 and given_bits <= 64) {
57455669 const op: WValue = if (given_bits == 64) blk: {
57465670 try func.emitWValue(operand);
57475671 try func.addTag(.f32_demote_f64);
5748 break :blk WValue{ .stack = {} };
5672 break :blk .stack;
57495673 } else operand;
57505674
57515675 // call __truncsfhf2(f32) f16
......@@ -5785,7 +5709,7 @@ fn airErrUnionPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi
57855709
57865710 break :result try func.buildPointerOffset(operand, @as(u32, @intCast(errUnionPayloadOffset(payload_ty, pt))), .new);
57875711 };
5788 func.finishAir(inst, result, &.{ty_op.operand});
5712 return func.finishAir(inst, result, &.{ty_op.operand});
57895713}
57905714
57915715fn airFieldParentPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -5807,7 +5731,7 @@ fn airFieldParentPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
58075731 break :result base;
58085732 } else func.reuseOperand(extra.field_ptr, field_ptr);
58095733
5810 func.finishAir(inst, result, &.{extra.field_ptr});
5734 return func.finishAir(inst, result, &.{extra.field_ptr});
58115735}
58125736
58135737fn sliceOrArrayPtr(func: *CodeGen, ptr: WValue, ptr_ty: Type) InnerError!WValue {
......@@ -5849,12 +5773,12 @@ fn airMemcpy(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
58495773 const src_ptr = try func.sliceOrArrayPtr(src, src_ty);
58505774 try func.memcpy(dst_ptr, src_ptr, len);
58515775
5852 func.finishAir(inst, .none, &.{ bin_op.lhs, bin_op.rhs });
5776 return func.finishAir(inst, .none, &.{ bin_op.lhs, bin_op.rhs });
58535777}
58545778
58555779fn airRetAddr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
58565780 // TODO: Implement this properly once stack serialization is solved
5857 func.finishAir(inst, switch (func.arch()) {
5781 return func.finishAir(inst, switch (func.arch()) {
58585782 .wasm32 => .{ .imm32 = 0 },
58595783 .wasm64 => .{ .imm64 = 0 },
58605784 else => unreachable,
......@@ -5868,7 +5792,6 @@ fn airPopcount(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
58685792
58695793 const operand = try func.resolveInst(ty_op.operand);
58705794 const op_ty = func.typeOf(ty_op.operand);
5871 const result_ty = func.typeOfIndex(inst);
58725795
58735796 if (op_ty.zigTypeTag(mod) == .Vector) {
58745797 return func.fail("TODO: Implement @popCount for vectors", .{});
......@@ -5911,9 +5834,7 @@ fn airPopcount(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
59115834 else => unreachable,
59125835 }
59135836
5914 const result = try func.allocLocal(result_ty);
5915 try func.addLabel(.local_set, result.local.value);
5916 func.finishAir(inst, result, &.{ty_op.operand});
5837 return func.finishAir(inst, .stack, &.{ty_op.operand});
59175838}
59185839
59195840fn airBitReverse(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -5942,12 +5863,11 @@ fn airBitReverse(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
59425863 Type.u32,
59435864 &.{operand},
59445865 );
5945 const reversed = if (bits == 32)
5866 const result = if (bits == 32)
59465867 intrin_ret
59475868 else
59485869 try func.binOp(intrin_ret, .{ .imm32 = 32 - bits }, ty, .shr);
5949 const result = try reversed.toLocal(func, ty);
5950 func.finishAir(inst, result, &.{ty_op.operand});
5870 return func.finishAir(inst, result, &.{ty_op.operand});
59515871 },
59525872 64 => {
59535873 const intrin_ret = try func.callIntrinsic(
......@@ -5956,12 +5876,11 @@ fn airBitReverse(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
59565876 Type.u64,
59575877 &.{operand},
59585878 );
5959 const reversed = if (bits == 64)
5879 const result = if (bits == 64)
59605880 intrin_ret
59615881 else
59625882 try func.binOp(intrin_ret, .{ .imm64 = 64 - bits }, ty, .shr);
5963 const result = try reversed.toLocal(func, ty);
5964 func.finishAir(inst, result, &.{ty_op.operand});
5883 return func.finishAir(inst, result, &.{ty_op.operand});
59655884 },
59665885 128 => {
59675886 const result = try func.allocStack(ty);
......@@ -6008,7 +5927,7 @@ fn airBitReverse(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
60085927 try func.addTag(.i64_or);
60095928 try func.store(.stack, .stack, Type.u64, result.offset());
60105929 }
6011 func.finishAir(inst, result, &.{ty_op.operand});
5930 return func.finishAir(inst, result, &.{ty_op.operand});
60125931 },
60135932 else => unreachable,
60145933 }
......@@ -6051,16 +5970,14 @@ fn airErrorName(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
60515970 else => unreachable,
60525971 }
60535972
6054 const result_ptr = try func.allocLocal(Type.usize);
6055 try func.addLabel(.local_set, result_ptr.local.value);
6056 func.finishAir(inst, result_ptr, &.{un_op});
5973 return func.finishAir(inst, .stack, &.{un_op});
60575974}
60585975
60595976fn airPtrSliceFieldPtr(func: *CodeGen, inst: Air.Inst.Index, offset: u32) InnerError!void {
60605977 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
60615978 const slice_ptr = try func.resolveInst(ty_op.operand);
60625979 const result = try func.buildPointerOffset(slice_ptr, offset, .new);
6063 func.finishAir(inst, result, &.{ty_op.operand});
5980 return func.finishAir(inst, result, &.{ty_op.operand});
60645981}
60655982
60665983fn airAddSubWithOverflow(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
......@@ -6089,9 +6006,9 @@ fn airAddSubWithOverflow(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerErro
60896006 return func.finishAir(inst, result, &.{ extra.lhs, extra.rhs });
60906007 }
60916008
6092 const zero = switch (wasm_bits) {
6093 32 => WValue{ .imm32 = 0 },
6094 64 => WValue{ .imm64 = 0 },
6009 const zero: WValue = switch (wasm_bits) {
6010 32 => .{ .imm32 = 0 },
6011 64 => .{ .imm64 = 0 },
60956012 else => unreachable,
60966013 };
60976014
......@@ -6121,7 +6038,7 @@ fn airAddSubWithOverflow(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerErro
61216038 const offset = @as(u32, @intCast(lhs_ty.abiSize(pt)));
61226039 try func.store(result_ptr, overflow_local, Type.u1, offset);
61236040
6124 func.finishAir(inst, result_ptr, &.{ extra.lhs, extra.rhs });
6041 return func.finishAir(inst, result_ptr, &.{ extra.lhs, extra.rhs });
61256042}
61266043
61276044fn addSubWithOverflowBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, result_ty: Type, op: Op) InnerError!WValue {
......@@ -6177,7 +6094,7 @@ fn addSubWithOverflowBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type,
61776094 _ = try func.cmp(tmp_op, lhs_low_bit, Type.u64, .eq);
61786095 try func.addTag(.select);
61796096
6180 break :blk WValue{ .stack = {} };
6097 break :blk .stack;
61816098 };
61826099 var overflow_local = try overflow_bit.toLocal(func, Type.u1);
61836100 defer overflow_local.free(func);
......@@ -6228,7 +6145,7 @@ fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
62286145 const overflow_bit = blk: {
62296146 try func.emitWValue(lhs);
62306147 const shr = try func.binOp(result, rhs_final, lhs_ty, .shr);
6231 break :blk try func.cmp(.{ .stack = {} }, shr, lhs_ty, .neq);
6148 break :blk try func.cmp(.stack, shr, lhs_ty, .neq);
62326149 };
62336150 var overflow_local = try overflow_bit.toLocal(func, Type.u1);
62346151 defer overflow_local.free(func);
......@@ -6238,7 +6155,7 @@ fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
62386155 const offset = @as(u32, @intCast(lhs_ty.abiSize(pt)));
62396156 try func.store(result_ptr, overflow_local, Type.u1, offset);
62406157
6241 func.finishAir(inst, result_ptr, &.{ extra.lhs, extra.rhs });
6158 return func.finishAir(inst, result_ptr, &.{ extra.lhs, extra.rhs });
62426159}
62436160
62446161fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -6265,9 +6182,9 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
62656182 return func.fail("TODO: Implement `@mulWithOverflow` for integer bitsize: {d}", .{int_info.bits});
62666183 };
62676184
6268 const zero = switch (wasm_bits) {
6269 32 => WValue{ .imm32 = 0 },
6270 64, 128 => WValue{ .imm64 = 0 },
6185 const zero: WValue = switch (wasm_bits) {
6186 32 => .{ .imm32 = 0 },
6187 64, 128 => .{ .imm64 = 0 },
62716188 else => unreachable,
62726189 };
62736190
......@@ -6303,10 +6220,10 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
63036220 } else if (wasm_bits == 32) blk: {
63046221 var bin_op = try (try func.binOp(lhs, rhs, lhs_ty, .mul)).toLocal(func, lhs_ty);
63056222 defer bin_op.free(func);
6306 const shift_imm = if (wasm_bits == 32)
6307 WValue{ .imm32 = int_info.bits }
6223 const shift_imm: WValue = if (wasm_bits == 32)
6224 .{ .imm32 = int_info.bits }
63086225 else
6309 WValue{ .imm64 = int_info.bits };
6226 .{ .imm64 = int_info.bits };
63106227 const shr = try func.binOp(bin_op, shift_imm, lhs_ty, .shr);
63116228 _ = try func.cmp(shr, zero, lhs_ty, .neq);
63126229 try func.addLabel(.local_set, overflow_bit.local.value);
......@@ -6412,7 +6329,7 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
64126329 const offset = @as(u32, @intCast(lhs_ty.abiSize(pt)));
64136330 try func.store(result_ptr, overflow_bit, Type.u1, offset);
64146331
6415 func.finishAir(inst, result_ptr, &.{ extra.lhs, extra.rhs });
6332 return func.finishAir(inst, result_ptr, &.{ extra.lhs, extra.rhs });
64166333}
64176334
64186335fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
......@@ -6454,11 +6371,7 @@ fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
64546371 try func.addTag(.select);
64556372 }
64566373
6457 // store result in local
6458 const result_ty = if (isByRef(ty, pt)) Type.u32 else ty;
6459 const result = try func.allocLocal(result_ty);
6460 try func.addLabel(.local_set, result.local.value);
6461 func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
6374 return func.finishAir(inst, .stack, &.{ bin_op.lhs, bin_op.rhs });
64626375}
64636376
64646377fn airMulAdd(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -6487,13 +6400,13 @@ fn airMulAdd(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
64876400 Type.f32,
64886401 &.{ rhs_ext, lhs_ext, addend_ext },
64896402 );
6490 break :fl_result try (try func.fptrunc(result, Type.f32, ty)).toLocal(func, ty);
6403 break :fl_result try func.fptrunc(result, Type.f32, ty);
64916404 } else result: {
64926405 const mul_result = try func.binOp(lhs, rhs, ty, .mul);
6493 break :result try (try func.binOp(mul_result, addend, ty, .add)).toLocal(func, ty);
6406 break :result try func.binOp(mul_result, addend, ty, .add);
64946407 };
64956408
6496 func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs, pl_op.operand });
6409 return func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs, pl_op.operand });
64976410}
64986411
64996412fn airClz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -6502,7 +6415,6 @@ fn airClz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
65026415 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
65036416
65046417 const ty = func.typeOf(ty_op.operand);
6505 const result_ty = func.typeOfIndex(inst);
65066418 if (ty.zigTypeTag(mod) == .Vector) {
65076419 return func.fail("TODO: `@clz` for vectors", .{});
65086420 }
......@@ -6545,9 +6457,7 @@ fn airClz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
65456457 try func.addTag(.i32_sub);
65466458 }
65476459
6548 const result = try func.allocLocal(result_ty);
6549 try func.addLabel(.local_set, result.local.value);
6550 func.finishAir(inst, result, &.{ty_op.operand});
6460 return func.finishAir(inst, .stack, &.{ty_op.operand});
65516461}
65526462
65536463fn airCtz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -6556,7 +6466,6 @@ fn airCtz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
65566466 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
65576467
65586468 const ty = func.typeOf(ty_op.operand);
6559 const result_ty = func.typeOfIndex(inst);
65606469
65616470 if (ty.zigTypeTag(mod) == .Vector) {
65626471 return func.fail("TODO: `@ctz` for vectors", .{});
......@@ -6611,9 +6520,7 @@ fn airCtz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
66116520 else => unreachable,
66126521 }
66136522
6614 const result = try func.allocLocal(result_ty);
6615 try func.addLabel(.local_set, result.local.value);
6616 func.finishAir(inst, result, &.{ty_op.operand});
6523 return func.finishAir(inst, .stack, &.{ty_op.operand});
66176524}
66186525
66196526fn airDbgStmt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -6626,7 +6533,7 @@ fn airDbgStmt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
66266533 .column = dbg_stmt.column,
66276534 }),
66286535 } });
6629 func.finishAir(inst, .none, &.{});
6536 return func.finishAir(inst, .none, &.{});
66306537}
66316538
66326539fn airDbgInlineBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -6659,7 +6566,7 @@ fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) InnerError!void
66596566 };
66606567 try func.debug_output.dwarf.genVarDbgInfo(name, ty, mod.funcOwnerDeclIndex(func.func_index), is_ptr, loc);
66616568
6662 func.finishAir(inst, .none, &.{});
6569 return func.finishAir(inst, .none, &.{});
66636570}
66646571
66656572fn airTry(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -6669,7 +6576,7 @@ fn airTry(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
66696576 const body: []const Air.Inst.Index = @ptrCast(func.air.extra[extra.end..][0..extra.data.body_len]);
66706577 const err_union_ty = func.typeOf(pl_op.operand);
66716578 const result = try lowerTry(func, inst, err_union, body, err_union_ty, false);
6672 func.finishAir(inst, result, &.{pl_op.operand});
6579 return func.finishAir(inst, result, &.{pl_op.operand});
66736580}
66746581
66756582fn airTryPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -6681,7 +6588,7 @@ fn airTryPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
66816588 const body: []const Air.Inst.Index = @ptrCast(func.air.extra[extra.end..][0..extra.data.body_len]);
66826589 const err_union_ty = func.typeOf(extra.data.ptr).childType(mod);
66836590 const result = try lowerTry(func, inst, err_union_ptr, body, err_union_ty, true);
6684 func.finishAir(inst, result, &.{extra.data.ptr});
6591 return func.finishAir(inst, result, &.{extra.data.ptr});
66856592}
66866593
66876594fn lowerTry(
......@@ -6730,7 +6637,7 @@ fn lowerTry(
67306637
67316638 // if we reach here it means error was not set, and we want the payload
67326639 if (!pl_has_bits) {
6733 return WValue{ .none = {} };
6640 return .none;
67346641 }
67356642
67366643 const pl_offset: u32 = @intCast(errUnionPayloadOffset(pl_ty, pt));
......@@ -6771,12 +6678,10 @@ fn airByteSwap(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
67716678 Type.u32,
67726679 &.{operand},
67736680 );
6774 const swapped = if (int_info.bits == 32)
6681 break :result if (int_info.bits == 32)
67756682 intrin_ret
67766683 else
67776684 try func.binOp(intrin_ret, .{ .imm32 = 32 - int_info.bits }, ty, .shr);
6778
6779 break :result try swapped.toLocal(func, ty);
67806685 },
67816686 64 => {
67826687 const intrin_ret = try func.callIntrinsic(
......@@ -6785,17 +6690,15 @@ fn airByteSwap(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
67856690 Type.u64,
67866691 &.{operand},
67876692 );
6788 const swapped = if (int_info.bits == 64)
6693 break :result if (int_info.bits == 64)
67896694 intrin_ret
67906695 else
67916696 try func.binOp(intrin_ret, .{ .imm64 = 64 - int_info.bits }, ty, .shr);
6792
6793 break :result try swapped.toLocal(func, ty);
67946697 },
67956698 else => return func.fail("TODO: @byteSwap for integers with bitsize {d}", .{int_info.bits}),
67966699 }
67976700 };
6798 func.finishAir(inst, result, &.{ty_op.operand});
6701 return func.finishAir(inst, result, &.{ty_op.operand});
67996702}
68006703
68016704fn airDiv(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -6805,8 +6708,8 @@ fn airDiv(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
68056708 const lhs = try func.resolveInst(bin_op.lhs);
68066709 const rhs = try func.resolveInst(bin_op.rhs);
68076710
6808 const result = try (try func.binOp(lhs, rhs, ty, .div)).toLocal(func, ty);
6809 func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
6711 const result = try func.binOp(lhs, rhs, ty, .div);
6712 return func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
68106713}
68116714
68126715fn airDivTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -6816,10 +6719,10 @@ fn airDivTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
68166719 const lhs = try func.resolveInst(bin_op.lhs);
68176720 const rhs = try func.resolveInst(bin_op.rhs);
68186721
6819 const div_result = try (try func.binOp(lhs, rhs, ty, .div)).toLocal(func, ty);
6722 const div_result = try func.binOp(lhs, rhs, ty, .div);
68206723
68216724 if (ty.isAnyFloat()) {
6822 const trunc_result = try (try func.floatOp(.trunc, ty, &.{div_result})).toLocal(func, ty);
6725 const trunc_result = try func.floatOp(.trunc, ty, &.{div_result});
68236726 return func.finishAir(inst, trunc_result, &.{ bin_op.lhs, bin_op.rhs });
68246727 }
68256728
......@@ -6847,9 +6750,9 @@ fn airDivFloor(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
68476750 return func.fail("TODO: `@divFloor` for signed integers larger than 64 bits ({d} bits requested)", .{int_bits});
68486751 }
68496752
6850 const zero = switch (wasm_bits) {
6851 32 => WValue{ .imm32 = 0 },
6852 64 => WValue{ .imm64 = 0 },
6753 const zero: WValue = switch (wasm_bits) {
6754 32 => .{ .imm32 = 0 },
6755 64 => .{ .imm64 = 0 },
68536756 else => unreachable,
68546757 };
68556758
......@@ -6895,7 +6798,7 @@ fn airDivFloor(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
68956798 // TODO: Should we be zeroing the high bits here or should we be ignoring the high bits
68966799 // when performing comparisons?
68976800 if (int_bits != wasm_bits) {
6898 _ = try func.wrapOperand(.{ .stack = {} }, ty);
6801 _ = try func.wrapOperand(.stack, ty);
68996802 }
69006803 } else {
69016804 const float_bits = ty.floatBits(func.target);
......@@ -6923,13 +6826,11 @@ fn airDivFloor(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
69236826 }
69246827
69256828 if (is_f16) {
6926 _ = try func.fptrunc(.{ .stack = {} }, Type.f32, Type.f16);
6829 _ = try func.fptrunc(.stack, Type.f32, Type.f16);
69276830 }
69286831 }
69296832
6930 const result = try func.allocLocal(ty);
6931 try func.addLabel(.local_set, result.local.value);
6932 func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
6833 return func.finishAir(inst, .stack, &.{ bin_op.lhs, bin_op.rhs });
69336834}
69346835
69356836fn airRem(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -6941,8 +6842,7 @@ fn airRem(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
69416842
69426843 const result = try func.binOp(lhs, rhs, ty, .rem);
69436844
6944 const return_local = try result.toLocal(func, ty);
6945 func.finishAir(inst, return_local, &.{ bin_op.lhs, bin_op.rhs });
6845 return func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
69466846}
69476847
69486848/// Remainder after floor division, defined by:
......@@ -6979,9 +6879,7 @@ fn airMod(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
69796879 return func.fail("TODO: implement `@mod` on floating point types for {}", .{func.target.cpu.arch});
69806880 }
69816881
6982 const result = try func.allocLocal(ty);
6983 try func.addLabel(.local_set, result.local.value);
6984 func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
6882 return func.finishAir(inst, .stack, &.{ bin_op.lhs, bin_op.rhs });
69856883}
69866884
69876885fn airSatBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
......@@ -7011,9 +6909,9 @@ fn airSatBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
70116909 defer bin_result.free(func);
70126910 if (wasm_bits != int_info.bits and op == .add) {
70136911 const val: u64 = @as(u64, @intCast((@as(u65, 1) << @as(u7, @intCast(int_info.bits))) - 1));
7014 const imm_val = switch (wasm_bits) {
7015 32 => WValue{ .imm32 = @intCast(val) },
7016 64 => WValue{ .imm64 = val },
6912 const imm_val: WValue = switch (wasm_bits) {
6913 32 => .{ .imm32 = @intCast(val) },
6914 64 => .{ .imm64 = val },
70176915 else => unreachable,
70186916 };
70196917
......@@ -7031,9 +6929,7 @@ fn airSatBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
70316929 }
70326930
70336931 try func.addTag(.select);
7034 const result = try func.allocLocal(ty);
7035 try func.addLabel(.local_set, result.local.value);
7036 return func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
6932 return func.finishAir(inst, .stack, &.{ bin_op.lhs, bin_op.rhs });
70376933}
70386934
70396935fn signedSat(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!WValue {
......@@ -7046,14 +6942,14 @@ fn signedSat(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerEr
70466942
70476943 const max_val: u64 = @as(u64, @intCast((@as(u65, 1) << @as(u7, @intCast(int_info.bits - 1))) - 1));
70486944 const min_val: i64 = (-@as(i64, @intCast(@as(u63, @intCast(max_val))))) - 1;
7049 const max_wvalue = switch (wasm_bits) {
7050 32 => WValue{ .imm32 = @as(u32, @truncate(max_val)) },
7051 64 => WValue{ .imm64 = max_val },
6945 const max_wvalue: WValue = switch (wasm_bits) {
6946 32 => .{ .imm32 = @truncate(max_val) },
6947 64 => .{ .imm64 = max_val },
70526948 else => unreachable,
70536949 };
7054 const min_wvalue = switch (wasm_bits) {
7055 32 => WValue{ .imm32 = @as(u32, @bitCast(@as(i32, @truncate(min_val)))) },
7056 64 => WValue{ .imm64 = @as(u64, @bitCast(min_val)) },
6950 const min_wvalue: WValue = switch (wasm_bits) {
6951 32 => .{ .imm32 = @bitCast(@as(i32, @truncate(min_val))) },
6952 64 => .{ .imm64 = @bitCast(min_val) },
70576953 else => unreachable,
70586954 };
70596955
......@@ -7073,9 +6969,9 @@ fn signedSat(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerEr
70736969 try func.addLabel(.local_set, bin_result.local.value); // re-use local
70746970 return (try func.wrapOperand(bin_result, ty)).toLocal(func, ty);
70756971 } else {
7076 const zero = switch (wasm_bits) {
7077 32 => WValue{ .imm32 = 0 },
7078 64 => WValue{ .imm64 = 0 },
6972 const zero: WValue = switch (wasm_bits) {
6973 32 => .{ .imm32 = 0 },
6974 64 => .{ .imm64 = 0 },
70796975 else => unreachable,
70806976 };
70816977 try func.emitWValue(max_wvalue);
......@@ -7110,7 +7006,7 @@ fn airShlSat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
71107006 const wasm_bits = toWasmBits(int_info.bits).?;
71117007 const result = try func.allocLocal(ty);
71127008
7113 if (wasm_bits == int_info.bits) outer_blk: {
7009 if (wasm_bits == int_info.bits) {
71147010 var shl = try (try func.binOp(lhs, rhs, ty, .shl)).toLocal(func, ty);
71157011 defer shl.free(func);
71167012 var shr = try (try func.binOp(shl, rhs, ty, .shr)).toLocal(func, ty);
......@@ -7143,12 +7039,11 @@ fn airShlSat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
71437039 _ = try func.cmp(lhs, shr, ty, .neq);
71447040 try func.addTag(.select);
71457041 try func.addLabel(.local_set, result.local.value);
7146 break :outer_blk;
71477042 } else {
71487043 const shift_size = wasm_bits - int_info.bits;
7149 const shift_value = switch (wasm_bits) {
7150 32 => WValue{ .imm32 = shift_size },
7151 64 => WValue{ .imm64 = shift_size },
7044 const shift_value: WValue = switch (wasm_bits) {
7045 32 => .{ .imm32 = shift_size },
7046 64 => .{ .imm64 = shift_size },
71527047 else => unreachable,
71537048 };
71547049 const ext_ty = try pt.intType(int_info.signedness, wasm_bits);
......@@ -7232,7 +7127,7 @@ fn callIntrinsic(
72327127 const sret_local = try func.allocStack(return_type);
72337128 try func.lowerToStack(sret_local);
72347129 break :blk sret_local;
7235 } else WValue{ .none = {} };
7130 } else .none;
72367131
72377132 // Lower all arguments to the stack before we call our function
72387133 for (args, 0..) |arg, arg_i| {
......@@ -7245,14 +7140,14 @@ fn callIntrinsic(
72457140 try func.addLabel(.call, @intFromEnum(symbol_index));
72467141
72477142 if (!return_type.hasRuntimeBitsIgnoreComptime(pt)) {
7248 return WValue.none;
7143 return .none;
72497144 } else if (return_type.isNoReturn(mod)) {
72507145 try func.addTag(.@"unreachable");
7251 return WValue.none;
7146 return .none;
72527147 } else if (want_sret_param) {
72537148 return sret;
72547149 } else {
7255 return WValue{ .stack = {} };
7150 return .stack;
72567151 }
72577152}
72587153
......@@ -7571,7 +7466,7 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
75717466 break :val ptr_val;
75727467 };
75737468
7574 const result_ptr = if (isByRef(result_ty, pt)) val: {
7469 const result = if (isByRef(result_ty, pt)) val: {
75757470 try func.emitWValue(cmp_result);
75767471 try func.addImm32(~@as(u32, 0));
75777472 try func.addTag(.i32_xor);
......@@ -7587,10 +7482,10 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
75877482 try func.emitWValue(ptr_val);
75887483 try func.emitWValue(cmp_result);
75897484 try func.addTag(.select);
7590 break :val try WValue.toLocal(.stack, func, result_ty);
7485 break :val .stack;
75917486 };
75927487
7593 return func.finishAir(inst, result_ptr, &.{ extra.ptr, extra.expected_value, extra.new_value });
7488 return func.finishAir(inst, result, &.{ extra.ptr, extra.expected_value, extra.new_value });
75947489}
75957490
75967491fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -7616,8 +7511,7 @@ fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
76167511 _ = try func.load(ptr, ty, 0);
76177512 }
76187513
7619 const result = try WValue.toLocal(.stack, func, ty);
7620 return func.finishAir(inst, result, &.{atomic_load.ptr});
7514 return func.finishAir(inst, .stack, &.{atomic_load.ptr});
76217515}
76227516
76237517fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -7734,8 +7628,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
77347628 .offset = ptr.offset(),
77357629 .alignment = @intCast(ty.abiAlignment(pt).toByteUnits().?),
77367630 });
7737 const result = try WValue.toLocal(.stack, func, ty);
7738 return func.finishAir(inst, result, &.{ pl_op.operand, extra.operand });
7631 return func.finishAir(inst, .stack, &.{ pl_op.operand, extra.operand });
77397632 },
77407633 }
77417634 } else {
......@@ -7847,8 +7740,7 @@ fn airFrameAddress(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
78477740 try func.initializeStack();
78487741 }
78497742 try func.emitWValue(func.bottom_stack_value);
7850 const result = try WValue.toLocal(.stack, func, Type.usize);
7851 return func.finishAir(inst, result, &.{});
7743 return func.finishAir(inst, .stack, &.{});
78527744}
78537745
78547746fn typeOf(func: *CodeGen, inst: Air.Inst.Ref) Type {