| ... | @@ -32,8 +32,13 @@ const WValue = union(enum) { | ... | @@ -32,8 +32,13 @@ const WValue = union(enum) { |
| 32 | none: void, | 32 | none: void, |
| 33 | /// The value lives on top of the stack | 33 | /// The value lives on top of the stack |
| 34 | stack: void, | 34 | stack: void, |
| 35 | /// Index of the local variable | 35 | /// Index of the local |
| 36 | local: u32, | 36 | local: struct { |
| | 37 | /// Contains the index to the local |
| | 38 | value: u32, |
| | 39 | /// The amount of instructions referencing this `WValue` |
| | 40 | references: u32, |
| | 41 | }, |
| 37 | /// An immediate 32bit value | 42 | /// An immediate 32bit value |
| 38 | imm32: u32, | 43 | imm32: u32, |
| 39 | /// An immediate 64bit value | 44 | /// An immediate 64bit value |
| ... | @@ -60,7 +65,12 @@ const WValue = union(enum) { | ... | @@ -60,7 +65,12 @@ const WValue = union(enum) { |
| 60 | function_index: u32, | 65 | function_index: u32, |
| 61 | /// Offset from the bottom of the virtual stack, with the offset | 66 | /// Offset from the bottom of the virtual stack, with the offset |
| 62 | /// pointing to where the value lives. | 67 | /// pointing to where the value lives. |
| 63 | stack_offset: u32, | 68 | stack_offset: struct { |
| | 69 | /// Contains the actual value of the offset |
| | 70 | value: u32, |
| | 71 | /// The amount of instructions referencing this `WValue` |
| | 72 | references: u32, |
| | 73 | }, |
| 64 | | 74 | |
| 65 | /// Returns the offset from the bottom of the stack. This is useful when | 75 | /// Returns the offset from the bottom of the stack. This is useful when |
| 66 | /// we use the load or store instruction to ensure we retrieve the value | 76 | /// we use the load or store instruction to ensure we retrieve the value |
| ... | @@ -70,7 +80,7 @@ const WValue = union(enum) { | ... | @@ -70,7 +80,7 @@ const WValue = union(enum) { |
| 70 | /// loads and stores without requiring checks everywhere. | 80 | /// loads and stores without requiring checks everywhere. |
| 71 | fn offset(self: WValue) u32 { | 81 | fn offset(self: WValue) u32 { |
| 72 | switch (self) { | 82 | switch (self) { |
| 73 | .stack_offset => |stack_offset| return stack_offset, | 83 | .stack_offset => |stack_offset| return stack_offset.value, |
| 74 | else => return 0, | 84 | else => return 0, |
| 75 | } | 85 | } |
| 76 | } | 86 | } |
| ... | @@ -81,9 +91,9 @@ const WValue = union(enum) { | ... | @@ -81,9 +91,9 @@ const WValue = union(enum) { |
| 81 | fn toLocal(value: WValue, gen: *Self, ty: Type) InnerError!WValue { | 91 | fn toLocal(value: WValue, gen: *Self, ty: Type) InnerError!WValue { |
| 82 | switch (value) { | 92 | switch (value) { |
| 83 | .stack => { | 93 | .stack => { |
| 84 | const local = try gen.allocLocal(ty); | 94 | const new_local = try gen.allocLocal(ty); |
| 85 | try gen.addLabel(.local_set, local.local); | 95 | try gen.addLabel(.local_set, new_local.local.value); |
| 86 | return local; | 96 | return new_local; |
| 87 | }, | 97 | }, |
| 88 | .local, .stack_offset => return value, | 98 | .local, .stack_offset => return value, |
| 89 | else => unreachable, | 99 | else => unreachable, |
| ... | @@ -95,7 +105,7 @@ const WValue = union(enum) { | ... | @@ -95,7 +105,7 @@ const WValue = union(enum) { |
| 95 | /// The valtype of the local is deducted by using the index of the given `WValue`. | 105 | /// The valtype of the local is deducted by using the index of the given `WValue`. |
| 96 | fn free(value: *WValue, gen: *Self) void { | 106 | fn free(value: *WValue, gen: *Self) void { |
| 97 | if (value.* != .local) return; | 107 | if (value.* != .local) return; |
| 98 | const local_value = value.local; | 108 | const local_value = value.local.value; |
| 99 | const reserved = gen.args.len + @boolToInt(gen.return_value != .none) + 2; // 2 for stack locals | 109 | const reserved = gen.args.len + @boolToInt(gen.return_value != .none) + 2; // 2 for stack locals |
| 100 | if (local_value < reserved) return; // reserved locals may never be re-used. | 110 | if (local_value < reserved) return; // reserved locals may never be re-used. |
| 101 | | 111 | |
| ... | @@ -107,7 +117,7 @@ const WValue = union(enum) { | ... | @@ -107,7 +117,7 @@ const WValue = union(enum) { |
| 107 | .f32 => gen.free_locals_f32.append(gen.gpa, local_value) catch return, | 117 | .f32 => gen.free_locals_f32.append(gen.gpa, local_value) catch return, |
| 108 | .f64 => gen.free_locals_f64.append(gen.gpa, local_value) catch return, | 118 | .f64 => gen.free_locals_f64.append(gen.gpa, local_value) catch return, |
| 109 | } | 119 | } |
| 110 | value.* = WValue{ .none = {} }; | 120 | value.* = undefined; |
| 111 | } | 121 | } |
| 112 | }; | 122 | }; |
| 113 | | 123 | |
| ... | @@ -761,7 +771,9 @@ const BigTomb = struct { | ... | @@ -761,7 +771,9 @@ const BigTomb = struct { |
| 761 | bt.gen.values.putAssumeCapacityNoClobber(Air.indexToRef(bt.inst), result); | 771 | bt.gen.values.putAssumeCapacityNoClobber(Air.indexToRef(bt.inst), result); |
| 762 | } | 772 | } |
| 763 | | 773 | |
| 764 | bt.gen.air_bookkeeping += 1; | 774 | if (builtin.mode == .Debug) { |
| | 775 | bt.gen.air_bookkeeping += 1; |
| | 776 | } |
| 765 | } | 777 | } |
| 766 | }; | 778 | }; |
| 767 | | 779 | |
| ... | @@ -883,7 +895,7 @@ fn genBlockType(ty: Type, target: std.Target) u8 { | ... | @@ -883,7 +895,7 @@ fn genBlockType(ty: Type, target: std.Target) u8 { |
| 883 | fn emitWValue(self: *Self, value: WValue) InnerError!void { | 895 | fn emitWValue(self: *Self, value: WValue) InnerError!void { |
| 884 | switch (value) { | 896 | switch (value) { |
| 885 | .none, .stack => {}, // no-op | 897 | .none, .stack => {}, // no-op |
| 886 | .local => |idx| try self.addLabel(.local_get, idx), | 898 | .local => |idx| try self.addLabel(.local_get, idx.value), |
| 887 | .imm32 => |val| try self.addImm32(@bitCast(i32, val)), | 899 | .imm32 => |val| try self.addImm32(@bitCast(i32, val)), |
| 888 | .imm64 => |val| try self.addImm64(val), | 900 | .imm64 => |val| try self.addImm64(val), |
| 889 | .float32 => |val| try self.addInst(.{ .tag = .f32_const, .data = .{ .float32 = val } }), | 901 | .float32 => |val| try self.addInst(.{ .tag = .f32_const, .data = .{ .float32 = val } }), |
| ... | @@ -907,16 +919,16 @@ fn allocLocal(self: *Self, ty: Type) InnerError!WValue { | ... | @@ -907,16 +919,16 @@ fn allocLocal(self: *Self, ty: Type) InnerError!WValue { |
| 907 | const valtype = typeToValtype(ty, self.target); | 919 | const valtype = typeToValtype(ty, self.target); |
| 908 | switch (valtype) { | 920 | switch (valtype) { |
| 909 | .i32 => if (self.free_locals_i32.popOrNull()) |index| { | 921 | .i32 => if (self.free_locals_i32.popOrNull()) |index| { |
| 910 | return WValue{ .local = index }; | 922 | return WValue{ .local = .{ .value = index, .references = 1 } }; |
| 911 | }, | 923 | }, |
| 912 | .i64 => if (self.free_locals_i64.popOrNull()) |index| { | 924 | .i64 => if (self.free_locals_i64.popOrNull()) |index| { |
| 913 | return WValue{ .local = index }; | 925 | return WValue{ .local = .{ .value = index, .references = 1 } }; |
| 914 | }, | 926 | }, |
| 915 | .f32 => if (self.free_locals_f32.popOrNull()) |index| { | 927 | .f32 => if (self.free_locals_f32.popOrNull()) |index| { |
| 916 | return WValue{ .local = index }; | 928 | return WValue{ .local = .{ .value = index, .references = 1 } }; |
| 917 | }, | 929 | }, |
| 918 | .f64 => if (self.free_locals_f64.popOrNull()) |index| { | 930 | .f64 => if (self.free_locals_f64.popOrNull()) |index| { |
| 919 | return WValue{ .local = index }; | 931 | return WValue{ .local = .{ .value = index, .references = 1 } }; |
| 920 | }, | 932 | }, |
| 921 | } | 933 | } |
| 922 | // no local was free to be re-used, so allocate a new local instead | 934 | // no local was free to be re-used, so allocate a new local instead |
| ... | @@ -929,7 +941,7 @@ fn ensureAllocLocal(self: *Self, ty: Type) InnerError!WValue { | ... | @@ -929,7 +941,7 @@ fn ensureAllocLocal(self: *Self, ty: Type) InnerError!WValue { |
| 929 | try self.locals.append(self.gpa, genValtype(ty, self.target)); | 941 | try self.locals.append(self.gpa, genValtype(ty, self.target)); |
| 930 | const initial_index = self.local_index; | 942 | const initial_index = self.local_index; |
| 931 | self.local_index += 1; | 943 | self.local_index += 1; |
| 932 | return WValue{ .local = initial_index }; | 944 | return WValue{ .local = .{ .value = initial_index, .references = 1 } }; |
| 933 | } | 945 | } |
| 934 | | 946 | |
| 935 | /// Generates a `wasm.Type` from a given function type. | 947 | /// Generates a `wasm.Type` from a given function type. |
| ... | @@ -1059,7 +1071,7 @@ fn genFunc(self: *Self) InnerError!void { | ... | @@ -1059,7 +1071,7 @@ fn genFunc(self: *Self) InnerError!void { |
| 1059 | // load stack pointer | 1071 | // load stack pointer |
| 1060 | try prologue.append(.{ .tag = .global_get, .data = .{ .label = 0 } }); | 1072 | try prologue.append(.{ .tag = .global_get, .data = .{ .label = 0 } }); |
| 1061 | // store stack pointer so we can restore it when we return from the function | 1073 | // store stack pointer so we can restore it when we return from the function |
| 1062 | try prologue.append(.{ .tag = .local_tee, .data = .{ .label = self.initial_stack_value.local } }); | 1074 | try prologue.append(.{ .tag = .local_tee, .data = .{ .label = self.initial_stack_value.local.value } }); |
| 1063 | // get the total stack size | 1075 | // get the total stack size |
| 1064 | const aligned_stack = std.mem.alignForwardGeneric(u32, self.stack_size, self.stack_alignment); | 1076 | const aligned_stack = std.mem.alignForwardGeneric(u32, self.stack_size, self.stack_alignment); |
| 1065 | try prologue.append(.{ .tag = .i32_const, .data = .{ .imm32 = @intCast(i32, aligned_stack) } }); | 1077 | try prologue.append(.{ .tag = .i32_const, .data = .{ .imm32 = @intCast(i32, aligned_stack) } }); |
| ... | @@ -1070,7 +1082,7 @@ fn genFunc(self: *Self) InnerError!void { | ... | @@ -1070,7 +1082,7 @@ fn genFunc(self: *Self) InnerError!void { |
| 1070 | // Bitwise-and the value to get the new stack pointer to ensure the pointers are aligned with the abi alignment | 1082 | // Bitwise-and the value to get the new stack pointer to ensure the pointers are aligned with the abi alignment |
| 1071 | try prologue.append(.{ .tag = .i32_and, .data = .{ .tag = {} } }); | 1083 | try prologue.append(.{ .tag = .i32_and, .data = .{ .tag = {} } }); |
| 1072 | // store the current stack pointer as the bottom, which will be used to calculate all stack pointer offsets | 1084 | // store the current stack pointer as the bottom, which will be used to calculate all stack pointer offsets |
| 1073 | try prologue.append(.{ .tag = .local_tee, .data = .{ .label = self.bottom_stack_value.local } }); | 1085 | try prologue.append(.{ .tag = .local_tee, .data = .{ .label = self.bottom_stack_value.local.value } }); |
| 1074 | // Store the current stack pointer value into the global stack pointer so other function calls will | 1086 | // Store the current stack pointer value into the global stack pointer so other function calls will |
| 1075 | // start from this value instead and not overwrite the current stack. | 1087 | // start from this value instead and not overwrite the current stack. |
| 1076 | try prologue.append(.{ .tag = .global_set, .data = .{ .label = 0 } }); | 1088 | try prologue.append(.{ .tag = .global_set, .data = .{ .label = 0 } }); |
| ... | @@ -1141,7 +1153,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) InnerError!CallWValu | ... | @@ -1141,7 +1153,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) InnerError!CallWValu |
| 1141 | if (firstParamSRet(fn_info.cc, fn_info.return_type, self.target)) { | 1153 | if (firstParamSRet(fn_info.cc, fn_info.return_type, self.target)) { |
| 1142 | // the sret arg will be passed as first argument, therefore we | 1154 | // the sret arg will be passed as first argument, therefore we |
| 1143 | // set the `return_value` before allocating locals for regular args. | 1155 | // set the `return_value` before allocating locals for regular args. |
| 1144 | result.return_value = .{ .local = self.local_index }; | 1156 | result.return_value = .{ .local = .{ .value = self.local_index, .references = 1 } }; |
| 1145 | self.local_index += 1; | 1157 | self.local_index += 1; |
| 1146 | } | 1158 | } |
| 1147 | | 1159 | |
| ... | @@ -1152,7 +1164,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) InnerError!CallWValu | ... | @@ -1152,7 +1164,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) InnerError!CallWValu |
| 1152 | continue; | 1164 | continue; |
| 1153 | } | 1165 | } |
| 1154 | | 1166 | |
| 1155 | try args.append(.{ .local = self.local_index }); | 1167 | try args.append(.{ .local = .{ .value = self.local_index, .references = 1 } }); |
| 1156 | self.local_index += 1; | 1168 | self.local_index += 1; |
| 1157 | } | 1169 | } |
| 1158 | }, | 1170 | }, |
| ... | @@ -1161,7 +1173,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) InnerError!CallWValu | ... | @@ -1161,7 +1173,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) InnerError!CallWValu |
| 1161 | const ty_classes = abi.classifyType(ty, self.target); | 1173 | const ty_classes = abi.classifyType(ty, self.target); |
| 1162 | for (ty_classes) |class| { | 1174 | for (ty_classes) |class| { |
| 1163 | if (class == .none) continue; | 1175 | if (class == .none) continue; |
| 1164 | try args.append(.{ .local = self.local_index }); | 1176 | try args.append(.{ .local = .{ .value = self.local_index, .references = 1 } }); |
| 1165 | self.local_index += 1; | 1177 | self.local_index += 1; |
| 1166 | } | 1178 | } |
| 1167 | } | 1179 | } |
| ... | @@ -1254,14 +1266,14 @@ fn lowerToStack(self: *Self, value: WValue) !void { | ... | @@ -1254,14 +1266,14 @@ fn lowerToStack(self: *Self, value: WValue) !void { |
| 1254 | switch (value) { | 1266 | switch (value) { |
| 1255 | .stack_offset => |offset| { | 1267 | .stack_offset => |offset| { |
| 1256 | try self.emitWValue(value); | 1268 | try self.emitWValue(value); |
| 1257 | if (offset > 0) { | 1269 | if (offset.value > 0) { |
| 1258 | switch (self.arch()) { | 1270 | switch (self.arch()) { |
| 1259 | .wasm32 => { | 1271 | .wasm32 => { |
| 1260 | try self.addImm32(@bitCast(i32, offset)); | 1272 | try self.addImm32(@bitCast(i32, offset.value)); |
| 1261 | try self.addTag(.i32_add); | 1273 | try self.addTag(.i32_add); |
| 1262 | }, | 1274 | }, |
| 1263 | .wasm64 => { | 1275 | .wasm64 => { |
| 1264 | try self.addImm64(offset); | 1276 | try self.addImm64(offset.value); |
| 1265 | try self.addTag(.i64_add); | 1277 | try self.addTag(.i64_add); |
| 1266 | }, | 1278 | }, |
| 1267 | else => unreachable, | 1279 | else => unreachable, |
| ... | @@ -1323,7 +1335,7 @@ fn allocStack(self: *Self, ty: Type) !WValue { | ... | @@ -1323,7 +1335,7 @@ fn allocStack(self: *Self, ty: Type) !WValue { |
| 1323 | const offset = std.mem.alignForwardGeneric(u32, self.stack_size, abi_align); | 1335 | const offset = std.mem.alignForwardGeneric(u32, self.stack_size, abi_align); |
| 1324 | defer self.stack_size = offset + abi_size; | 1336 | defer self.stack_size = offset + abi_size; |
| 1325 | | 1337 | |
| 1326 | return WValue{ .stack_offset = offset }; | 1338 | return WValue{ .stack_offset = .{ .value = offset, .references = 1 } }; |
| 1327 | } | 1339 | } |
| 1328 | | 1340 | |
| 1329 | /// From a given AIR instruction generates a pointer to the stack where | 1341 | /// From a given AIR instruction generates a pointer to the stack where |
| ... | @@ -1356,7 +1368,7 @@ fn allocStackPtr(self: *Self, inst: Air.Inst.Index) !WValue { | ... | @@ -1356,7 +1368,7 @@ fn allocStackPtr(self: *Self, inst: Air.Inst.Index) !WValue { |
| 1356 | const offset = std.mem.alignForwardGeneric(u32, self.stack_size, abi_alignment); | 1368 | const offset = std.mem.alignForwardGeneric(u32, self.stack_size, abi_alignment); |
| 1357 | defer self.stack_size = offset + abi_size; | 1369 | defer self.stack_size = offset + abi_size; |
| 1358 | | 1370 | |
| 1359 | return WValue{ .stack_offset = offset }; | 1371 | return WValue{ .stack_offset = .{ .value = offset, .references = 1 } }; |
| 1360 | } | 1372 | } |
| 1361 | | 1373 | |
| 1362 | /// From given zig bitsize, returns the wasm bitsize | 1374 | /// From given zig bitsize, returns the wasm bitsize |
| ... | @@ -1475,7 +1487,7 @@ fn memcpy(self: *Self, dst: WValue, src: WValue, len: WValue) !void { | ... | @@ -1475,7 +1487,7 @@ fn memcpy(self: *Self, dst: WValue, src: WValue, len: WValue) !void { |
| 1475 | }, | 1487 | }, |
| 1476 | else => unreachable, | 1488 | else => unreachable, |
| 1477 | } | 1489 | } |
| 1478 | try self.addLabel(.local_set, offset.local); | 1490 | try self.addLabel(.local_set, offset.local.value); |
| 1479 | try self.addLabel(.br, 0); // jump to start of loop | 1491 | try self.addLabel(.br, 0); // jump to start of loop |
| 1480 | } | 1492 | } |
| 1481 | try self.endBlock(); // close off loop block | 1493 | try self.endBlock(); // close off loop block |
| ... | @@ -1568,7 +1580,7 @@ fn buildPointerOffset(self: *Self, ptr_value: WValue, offset: u64, action: enum | ... | @@ -1568,7 +1580,7 @@ fn buildPointerOffset(self: *Self, ptr_value: WValue, offset: u64, action: enum |
| 1568 | else => unreachable, | 1580 | else => unreachable, |
| 1569 | } | 1581 | } |
| 1570 | } | 1582 | } |
| 1571 | try self.addLabel(.local_set, result_ptr.local); | 1583 | try self.addLabel(.local_set, result_ptr.local.value); |
| 1572 | return result_ptr; | 1584 | return result_ptr; |
| 1573 | } | 1585 | } |
| 1574 | | 1586 | |
| ... | @@ -1984,14 +1996,14 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. | ... | @@ -1984,14 +1996,14 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. |
| 1984 | // TODO: Make this less fragile and optimize | 1996 | // TODO: Make this less fragile and optimize |
| 1985 | } else if (fn_ty.fnInfo().cc == .C and ret_ty.zigTypeTag() == .Struct or ret_ty.zigTypeTag() == .Union) { | 1997 | } else if (fn_ty.fnInfo().cc == .C and ret_ty.zigTypeTag() == .Struct or ret_ty.zigTypeTag() == .Union) { |
| 1986 | const result_local = try self.allocLocal(ret_ty); | 1998 | const result_local = try self.allocLocal(ret_ty); |
| 1987 | try self.addLabel(.local_set, result_local.local); | 1999 | try self.addLabel(.local_set, result_local.local.value); |
| 1988 | const scalar_type = abi.scalarType(ret_ty, self.target); | 2000 | const scalar_type = abi.scalarType(ret_ty, self.target); |
| 1989 | const result = try self.allocStack(scalar_type); | 2001 | const result = try self.allocStack(scalar_type); |
| 1990 | try self.store(result, result_local, scalar_type, 0); | 2002 | try self.store(result, result_local, scalar_type, 0); |
| 1991 | break :result_value result; | 2003 | break :result_value result; |
| 1992 | } else { | 2004 | } else { |
| 1993 | const result_local = try self.allocLocal(ret_ty); | 2005 | const result_local = try self.allocLocal(ret_ty); |
| 1994 | try self.addLabel(.local_set, result_local.local); | 2006 | try self.addLabel(.local_set, result_local.local.value); |
| 1995 | break :result_value result_local; | 2007 | break :result_value result_local; |
| 1996 | } | 2008 | } |
| 1997 | }; | 2009 | }; |
| ... | @@ -2175,7 +2187,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) InnerError!void { | ... | @@ -2175,7 +2187,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) InnerError!void { |
| 2175 | .dwarf => |dwarf| { | 2187 | .dwarf => |dwarf| { |
| 2176 | // TODO: Get the original arg index rather than wasm arg index | 2188 | // TODO: Get the original arg index rather than wasm arg index |
| 2177 | const name = self.mod_fn.getParamName(self.bin_file.base.options.module.?, arg_index); | 2189 | const name = self.mod_fn.getParamName(self.bin_file.base.options.module.?, arg_index); |
| 2178 | const leb_size = link.File.Wasm.getULEB128Size(arg.local); | 2190 | const leb_size = link.File.Wasm.getULEB128Size(arg.local.value); |
| 2179 | const dbg_info = &dwarf.dbg_info; | 2191 | const dbg_info = &dwarf.dbg_info; |
| 2180 | try dbg_info.ensureUnusedCapacity(3 + leb_size + 5 + name.len + 1); | 2192 | try dbg_info.ensureUnusedCapacity(3 + leb_size + 5 + name.len + 1); |
| 2181 | // wasm locations are encoded as follow: | 2193 | // wasm locations are encoded as follow: |
| ... | @@ -2189,7 +2201,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) InnerError!void { | ... | @@ -2189,7 +2201,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) InnerError!void { |
| 2189 | std.dwarf.OP.WASM_location, | 2201 | std.dwarf.OP.WASM_location, |
| 2190 | std.dwarf.OP.WASM_local, | 2202 | std.dwarf.OP.WASM_local, |
| 2191 | }); | 2203 | }); |
| 2192 | leb.writeULEB128(dbg_info.writer(), arg.local) catch unreachable; | 2204 | leb.writeULEB128(dbg_info.writer(), arg.local.value) catch unreachable; |
| 2193 | try self.addDbgInfoTypeReloc(arg_ty); | 2205 | try self.addDbgInfoTypeReloc(arg_ty); |
| 2194 | dbg_info.appendSliceAssumeCapacity(name); | 2206 | dbg_info.appendSliceAssumeCapacity(name); |
| 2195 | dbg_info.appendAssumeCapacity(0); | 2207 | dbg_info.appendAssumeCapacity(0); |
| ... | @@ -2869,7 +2881,7 @@ fn airBr(self: *Self, inst: Air.Inst.Index) InnerError!void { | ... | @@ -2869,7 +2881,7 @@ fn airBr(self: *Self, inst: Air.Inst.Index) InnerError!void { |
| 2869 | try self.lowerToStack(operand); | 2881 | try self.lowerToStack(operand); |
| 2870 | | 2882 | |
| 2871 | if (block.value != .none) { | 2883 | if (block.value != .none) { |
| 2872 | try self.addLabel(.local_set, block.value.local); | 2884 | try self.addLabel(.local_set, block.value.local.value); |
| 2873 | } | 2885 | } |
| 2874 | } | 2886 | } |
| 2875 | | 2887 | |
| ... | @@ -2893,7 +2905,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) InnerError!void { | ... | @@ -2893,7 +2905,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) InnerError!void { |
| 2893 | try self.emitWValue(operand); | 2905 | try self.emitWValue(operand); |
| 2894 | try self.addTag(.i32_eqz); | 2906 | try self.addTag(.i32_eqz); |
| 2895 | const not_tmp = try self.allocLocal(operand_ty); | 2907 | const not_tmp = try self.allocLocal(operand_ty); |
| 2896 | try self.addLabel(.local_set, not_tmp.local); | 2908 | try self.addLabel(.local_set, not_tmp.local.value); |
| 2897 | break :result not_tmp; | 2909 | break :result not_tmp; |
| 2898 | } else { | 2910 | } else { |
| 2899 | const operand_bits = operand_ty.intInfo(self.target).bits; | 2911 | const operand_bits = operand_ty.intInfo(self.target).bits; |
| ... | @@ -2985,7 +2997,7 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u32) InnerEr | ... | @@ -2985,7 +2997,7 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u32) InnerEr |
| 2985 | fn structFieldPtr(self: *Self, struct_ptr: WValue, offset: u32) InnerError!WValue { | 2997 | fn structFieldPtr(self: *Self, struct_ptr: WValue, offset: u32) InnerError!WValue { |
| 2986 | switch (struct_ptr) { | 2998 | switch (struct_ptr) { |
| 2987 | .stack_offset => |stack_offset| { | 2999 | .stack_offset => |stack_offset| { |
| 2988 | return WValue{ .stack_offset = stack_offset + offset }; | 3000 | return WValue{ .stack_offset = .{ .value = stack_offset.value + offset, .references = 1 } }; |
| 2989 | }, | 3001 | }, |
| 2990 | else => return self.buildPointerOffset(struct_ptr, offset, .new), | 3002 | else => return self.buildPointerOffset(struct_ptr, offset, .new), |
| 2991 | } | 3003 | } |
| ... | @@ -3011,7 +3023,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) InnerError!void { | ... | @@ -3011,7 +3023,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) InnerError!void { |
| 3011 | if (isByRef(field_ty, self.target)) { | 3023 | if (isByRef(field_ty, self.target)) { |
| 3012 | switch (operand) { | 3024 | switch (operand) { |
| 3013 | .stack_offset => |stack_offset| { | 3025 | .stack_offset => |stack_offset| { |
| 3014 | break :result WValue{ .stack_offset = stack_offset + offset }; | 3026 | break :result WValue{ .stack_offset = .{ .value = stack_offset.value + offset, .references = 1 } }; |
| 3015 | }, | 3027 | }, |
| 3016 | else => break :result try self.buildPointerOffset(operand, offset, .new), | 3028 | else => break :result try self.buildPointerOffset(operand, offset, .new), |
| 3017 | } | 3029 | } |
| ... | @@ -3214,7 +3226,7 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerError!v | ... | @@ -3214,7 +3226,7 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerError!v |
| 3214 | try self.addTag(Mir.Inst.Tag.fromOpcode(opcode)); | 3226 | try self.addTag(Mir.Inst.Tag.fromOpcode(opcode)); |
| 3215 | | 3227 | |
| 3216 | const is_err_tmp = try self.allocLocal(Type.i32); | 3228 | const is_err_tmp = try self.allocLocal(Type.i32); |
| 3217 | try self.addLabel(.local_set, is_err_tmp.local); | 3229 | try self.addLabel(.local_set, is_err_tmp.local.value); |
| 3218 | break :result is_err_tmp; | 3230 | break :result is_err_tmp; |
| 3219 | }; | 3231 | }; |
| 3220 | self.finishAir(inst, result, &.{un_op}); | 3232 | self.finishAir(inst, result, &.{un_op}); |
| ... | @@ -3578,7 +3590,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) InnerError!void { | ... | @@ -3578,7 +3590,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) InnerError!void { |
| 3578 | try self.addTag(.i32_add); | 3590 | try self.addTag(.i32_add); |
| 3579 | | 3591 | |
| 3580 | const result_ptr = try self.allocLocal(elem_ty); | 3592 | const result_ptr = try self.allocLocal(elem_ty); |
| 3581 | try self.addLabel(.local_set, result_ptr.local); | 3593 | try self.addLabel(.local_set, result_ptr.local.value); |
| 3582 | | 3594 | |
| 3583 | const result = if (!isByRef(elem_ty, self.target)) result: { | 3595 | const result = if (!isByRef(elem_ty, self.target)) result: { |
| 3584 | const elem_val = try self.load(result_ptr, elem_ty, 0); | 3596 | const elem_val = try self.load(result_ptr, elem_ty, 0); |
| ... | @@ -3608,7 +3620,7 @@ fn airSliceElemPtr(self: *Self, inst: Air.Inst.Index) InnerError!void { | ... | @@ -3608,7 +3620,7 @@ fn airSliceElemPtr(self: *Self, inst: Air.Inst.Index) InnerError!void { |
| 3608 | try self.addTag(.i32_add); | 3620 | try self.addTag(.i32_add); |
| 3609 | | 3621 | |
| 3610 | const result = try self.allocLocal(Type.i32); | 3622 | const result = try self.allocLocal(Type.i32); |
| 3611 | try self.addLabel(.local_set, result.local); | 3623 | try self.addLabel(.local_set, result.local.value); |
| 3612 | self.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs }); | 3624 | self.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs }); |
| 3613 | } | 3625 | } |
| 3614 | | 3626 | |
| ... | @@ -3715,7 +3727,7 @@ fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) InnerError!void { | ... | @@ -3715,7 +3727,7 @@ fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) InnerError!void { |
| 3715 | | 3727 | |
| 3716 | const elem_result = val: { | 3728 | const elem_result = val: { |
| 3717 | var result = try self.allocLocal(elem_ty); | 3729 | var result = try self.allocLocal(elem_ty); |
| 3718 | try self.addLabel(.local_set, result.local); | 3730 | try self.addLabel(.local_set, result.local.value); |
| 3719 | if (isByRef(elem_ty, self.target)) { | 3731 | if (isByRef(elem_ty, self.target)) { |
| 3720 | break :val result; | 3732 | break :val result; |
| 3721 | } | 3733 | } |
| ... | @@ -3753,7 +3765,7 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) InnerError!void { | ... | @@ -3753,7 +3765,7 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) InnerError!void { |
| 3753 | try self.addTag(.i32_add); | 3765 | try self.addTag(.i32_add); |
| 3754 | | 3766 | |
| 3755 | const result = try self.allocLocal(Type.i32); | 3767 | const result = try self.allocLocal(Type.i32); |
| 3756 | try self.addLabel(.local_set, result.local); | 3768 | try self.addLabel(.local_set, result.local.value); |
| 3757 | self.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs }); | 3769 | self.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs }); |
| 3758 | } | 3770 | } |
| 3759 | | 3771 | |
| ... | @@ -3781,7 +3793,7 @@ fn airPtrBinOp(self: *Self, inst: Air.Inst.Index, op: Op) InnerError!void { | ... | @@ -3781,7 +3793,7 @@ fn airPtrBinOp(self: *Self, inst: Air.Inst.Index, op: Op) InnerError!void { |
| 3781 | try self.addTag(Mir.Inst.Tag.fromOpcode(bin_opcode)); | 3793 | try self.addTag(Mir.Inst.Tag.fromOpcode(bin_opcode)); |
| 3782 | | 3794 | |
| 3783 | const result = try self.allocLocal(Type.usize); | 3795 | const result = try self.allocLocal(Type.usize); |
| 3784 | try self.addLabel(.local_set, result.local); | 3796 | try self.addLabel(.local_set, result.local.value); |
| 3785 | self.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs }); | 3797 | self.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs }); |
| 3786 | } | 3798 | } |
| 3787 | | 3799 | |
| ... | @@ -3874,7 +3886,7 @@ fn memset(self: *Self, ptr: WValue, len: WValue, value: WValue) InnerError!void | ... | @@ -3874,7 +3886,7 @@ fn memset(self: *Self, ptr: WValue, len: WValue, value: WValue) InnerError!void |
| 3874 | .wasm64 => try self.addTag(.i64_add), | 3886 | .wasm64 => try self.addTag(.i64_add), |
| 3875 | else => unreachable, | 3887 | else => unreachable, |
| 3876 | } | 3888 | } |
| 3877 | try self.addLabel(.local_set, offset.local); | 3889 | try self.addLabel(.local_set, offset.local.value); |
| 3878 | try self.addLabel(.br, 0); // jump to start of loop | 3890 | try self.addLabel(.br, 0); // jump to start of loop |
| 3879 | try self.endBlock(); | 3891 | try self.endBlock(); |
| 3880 | try self.endBlock(); | 3892 | try self.endBlock(); |
| ... | @@ -3900,7 +3912,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) InnerError!void { | ... | @@ -3900,7 +3912,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) InnerError!void { |
| 3900 | | 3912 | |
| 3901 | const elem_result = val: { | 3913 | const elem_result = val: { |
| 3902 | var result = try self.allocLocal(Type.usize); | 3914 | var result = try self.allocLocal(Type.usize); |
| 3903 | try self.addLabel(.local_set, result.local); | 3915 | try self.addLabel(.local_set, result.local.value); |
| 3904 | | 3916 | |
| 3905 | if (isByRef(elem_ty, self.target)) { | 3917 | if (isByRef(elem_ty, self.target)) { |
| 3906 | break :val result; | 3918 | break :val result; |
| ... | @@ -3961,7 +3973,7 @@ fn airIntToFloat(self: *Self, inst: Air.Inst.Index) InnerError!void { | ... | @@ -3961,7 +3973,7 @@ fn airIntToFloat(self: *Self, inst: Air.Inst.Index) InnerError!void { |
| 3961 | try self.addTag(Mir.Inst.Tag.fromOpcode(op)); | 3973 | try self.addTag(Mir.Inst.Tag.fromOpcode(op)); |
| 3962 | | 3974 | |
| 3963 | const result = try self.allocLocal(dest_ty); | 3975 | const result = try self.allocLocal(dest_ty); |
| 3964 | try self.addLabel(.local_set, result.local); | 3976 | try self.addLabel(.local_set, result.local.value); |
| 3965 | self.finishAir(inst, result, &.{ty_op.operand}); | 3977 | self.finishAir(inst, result, &.{ty_op.operand}); |
| 3966 | } | 3978 | } |
| 3967 | | 3979 | |
| ... | @@ -4107,7 +4119,7 @@ fn airWasmMemorySize(self: *Self, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4107,7 +4119,7 @@ fn airWasmMemorySize(self: *Self, inst: Air.Inst.Index) InnerError!void { |
| 4107 | | 4119 | |
| 4108 | const result = try self.allocLocal(self.air.typeOfIndex(inst)); | 4120 | const result = try self.allocLocal(self.air.typeOfIndex(inst)); |
| 4109 | try self.addLabel(.memory_size, pl_op.payload); | 4121 | try self.addLabel(.memory_size, pl_op.payload); |
| 4110 | try self.addLabel(.local_set, result.local); | 4122 | try self.addLabel(.local_set, result.local.value); |
| 4111 | self.finishAir(inst, result, &.{pl_op.operand}); | 4123 | self.finishAir(inst, result, &.{pl_op.operand}); |
| 4112 | } | 4124 | } |
| 4113 | | 4125 | |
| ... | @@ -4119,7 +4131,7 @@ fn airWasmMemoryGrow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4119,7 +4131,7 @@ fn airWasmMemoryGrow(self: *Self, inst: Air.Inst.Index) !void { |
| 4119 | const result = try self.allocLocal(self.air.typeOfIndex(inst)); | 4131 | const result = try self.allocLocal(self.air.typeOfIndex(inst)); |
| 4120 | try self.emitWValue(operand); | 4132 | try self.emitWValue(operand); |
| 4121 | try self.addLabel(.memory_grow, pl_op.payload); | 4133 | try self.addLabel(.memory_grow, pl_op.payload); |
| 4122 | try self.addLabel(.local_set, result.local); | 4134 | try self.addLabel(.local_set, result.local.value); |
| 4123 | self.finishAir(inst, result, &.{pl_op.operand}); | 4135 | self.finishAir(inst, result, &.{pl_op.operand}); |
| 4124 | } | 4136 | } |
| 4125 | | 4137 | |
| ... | @@ -4148,7 +4160,7 @@ fn cmpOptionals(self: *Self, lhs: WValue, rhs: WValue, operand_ty: Type, op: std | ... | @@ -4148,7 +4160,7 @@ fn cmpOptionals(self: *Self, lhs: WValue, rhs: WValue, operand_ty: Type, op: std |
| 4148 | try self.addLabel(.br_if, 0); | 4160 | try self.addLabel(.br_if, 0); |
| 4149 | | 4161 | |
| 4150 | try self.addImm32(1); | 4162 | try self.addImm32(1); |
| 4151 | try self.addLabel(.local_set, result.local); | 4163 | try self.addLabel(.local_set, result.local.value); |
| 4152 | try self.endBlock(); | 4164 | try self.endBlock(); |
| 4153 | | 4165 | |
| 4154 | try self.emitWValue(result); | 4166 | try self.emitWValue(result); |
| ... | @@ -4363,10 +4375,10 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4363,10 +4375,10 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) InnerError!void { |
| 4363 | | 4375 | |
| 4364 | const result = if (field_offset != 0) result: { | 4376 | const result = if (field_offset != 0) result: { |
| 4365 | const base = try self.buildPointerOffset(field_ptr, 0, .new); | 4377 | const base = try self.buildPointerOffset(field_ptr, 0, .new); |
| 4366 | try self.addLabel(.local_get, base.local); | 4378 | try self.addLabel(.local_get, base.local.value); |
| 4367 | try self.addImm32(@bitCast(i32, @intCast(u32, field_offset))); | 4379 | try self.addImm32(@bitCast(i32, @intCast(u32, field_offset))); |
| 4368 | try self.addTag(.i32_sub); | 4380 | try self.addTag(.i32_sub); |
| 4369 | try self.addLabel(.local_set, base.local); | 4381 | try self.addLabel(.local_set, base.local.value); |
| 4370 | break :result base; | 4382 | break :result base; |
| 4371 | } else field_ptr; | 4383 | } else field_ptr; |
| 4372 | | 4384 | |
| ... | @@ -4425,7 +4437,7 @@ fn airPopcount(self: *Self, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4425,7 +4437,7 @@ fn airPopcount(self: *Self, inst: Air.Inst.Index) InnerError!void { |
| 4425 | } | 4437 | } |
| 4426 | | 4438 | |
| 4427 | const result = try self.allocLocal(result_ty); | 4439 | const result = try self.allocLocal(result_ty); |
| 4428 | try self.addLabel(.local_set, result.local); | 4440 | try self.addLabel(.local_set, result.local.value); |
| 4429 | self.finishAir(inst, result, &.{ty_op.operand}); | 4441 | self.finishAir(inst, result, &.{ty_op.operand}); |
| 4430 | } | 4442 | } |
| 4431 | | 4443 | |
| ... | @@ -4467,7 +4479,7 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4467,7 +4479,7 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) InnerError!void { |
| 4467 | } | 4479 | } |
| 4468 | | 4480 | |
| 4469 | const result_ptr = try self.allocLocal(Type.usize); | 4481 | const result_ptr = try self.allocLocal(Type.usize); |
| 4470 | try self.addLabel(.local_set, result_ptr.local); | 4482 | try self.addLabel(.local_set, result_ptr.local.value); |
| 4471 | self.finishAir(inst, result_ptr, &.{un_op}); | 4483 | self.finishAir(inst, result_ptr, &.{un_op}); |
| 4472 | } | 4484 | } |
| 4473 | | 4485 | |
| ... | @@ -4714,7 +4726,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4714,7 +4726,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) InnerError!void { |
| 4714 | const shr = try self.binOp(bin_op, .{ .imm64 = int_info.bits }, new_ty, .shr); | 4726 | const shr = try self.binOp(bin_op, .{ .imm64 = int_info.bits }, new_ty, .shr); |
| 4715 | const wrap = try self.intcast(shr, new_ty, lhs_ty); | 4727 | const wrap = try self.intcast(shr, new_ty, lhs_ty); |
| 4716 | _ = try self.cmp(wrap, zero, lhs_ty, .neq); | 4728 | _ = try self.cmp(wrap, zero, lhs_ty, .neq); |
| 4717 | try self.addLabel(.local_set, overflow_bit.local); | 4729 | try self.addLabel(.local_set, overflow_bit.local.value); |
| 4718 | break :blk try self.intcast(bin_op, new_ty, lhs_ty); | 4730 | break :blk try self.intcast(bin_op, new_ty, lhs_ty); |
| 4719 | } else { | 4731 | } else { |
| 4720 | const down_cast = try (try self.intcast(bin_op, new_ty, lhs_ty)).toLocal(self, lhs_ty); | 4732 | const down_cast = try (try self.intcast(bin_op, new_ty, lhs_ty)).toLocal(self, lhs_ty); |
| ... | @@ -4724,7 +4736,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4724,7 +4736,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) InnerError!void { |
| 4724 | const shr_res = try self.binOp(bin_op, .{ .imm64 = int_info.bits }, new_ty, .shr); | 4736 | const shr_res = try self.binOp(bin_op, .{ .imm64 = int_info.bits }, new_ty, .shr); |
| 4725 | const down_shr_res = try self.intcast(shr_res, new_ty, lhs_ty); | 4737 | const down_shr_res = try self.intcast(shr_res, new_ty, lhs_ty); |
| 4726 | _ = try self.cmp(down_shr_res, shr, lhs_ty, .neq); | 4738 | _ = try self.cmp(down_shr_res, shr, lhs_ty, .neq); |
| 4727 | try self.addLabel(.local_set, overflow_bit.local); | 4739 | try self.addLabel(.local_set, overflow_bit.local.value); |
| 4728 | break :blk down_cast; | 4740 | break :blk down_cast; |
| 4729 | } | 4741 | } |
| 4730 | } else if (int_info.signedness == .signed) blk: { | 4742 | } else if (int_info.signedness == .signed) blk: { |
| ... | @@ -4733,7 +4745,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4733,7 +4745,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) InnerError!void { |
| 4733 | const bin_op = try (try self.binOp(lhs_abs, rhs_abs, lhs_ty, .mul)).toLocal(self, lhs_ty); | 4745 | const bin_op = try (try self.binOp(lhs_abs, rhs_abs, lhs_ty, .mul)).toLocal(self, lhs_ty); |
| 4734 | const mul_abs = try self.signAbsValue(bin_op, lhs_ty); | 4746 | const mul_abs = try self.signAbsValue(bin_op, lhs_ty); |
| 4735 | _ = try self.cmp(mul_abs, bin_op, lhs_ty, .neq); | 4747 | _ = try self.cmp(mul_abs, bin_op, lhs_ty, .neq); |
| 4736 | try self.addLabel(.local_set, overflow_bit.local); | 4748 | try self.addLabel(.local_set, overflow_bit.local.value); |
| 4737 | break :blk try self.wrapOperand(bin_op, lhs_ty); | 4749 | break :blk try self.wrapOperand(bin_op, lhs_ty); |
| 4738 | } else blk: { | 4750 | } else blk: { |
| 4739 | var bin_op = try (try self.binOp(lhs, rhs, lhs_ty, .mul)).toLocal(self, lhs_ty); | 4751 | var bin_op = try (try self.binOp(lhs, rhs, lhs_ty, .mul)).toLocal(self, lhs_ty); |
| ... | @@ -4744,7 +4756,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4744,7 +4756,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) InnerError!void { |
| 4744 | WValue{ .imm64 = int_info.bits }; | 4756 | WValue{ .imm64 = int_info.bits }; |
| 4745 | const shr = try self.binOp(bin_op, shift_imm, lhs_ty, .shr); | 4757 | const shr = try self.binOp(bin_op, shift_imm, lhs_ty, .shr); |
| 4746 | _ = try self.cmp(shr, zero, lhs_ty, .neq); | 4758 | _ = try self.cmp(shr, zero, lhs_ty, .neq); |
| 4747 | try self.addLabel(.local_set, overflow_bit.local); | 4759 | try self.addLabel(.local_set, overflow_bit.local.value); |
| 4748 | break :blk try self.wrapOperand(bin_op, lhs_ty); | 4760 | break :blk try self.wrapOperand(bin_op, lhs_ty); |
| 4749 | }; | 4761 | }; |
| 4750 | var bin_op_local = try bin_op.toLocal(self, lhs_ty); | 4762 | var bin_op_local = try bin_op.toLocal(self, lhs_ty); |
| ... | @@ -4785,7 +4797,7 @@ fn airMaxMin(self: *Self, inst: Air.Inst.Index, op: enum { max, min }) InnerErro | ... | @@ -4785,7 +4797,7 @@ fn airMaxMin(self: *Self, inst: Air.Inst.Index, op: enum { max, min }) InnerErro |
| 4785 | // store result in local | 4797 | // store result in local |
| 4786 | const result_ty = if (isByRef(ty, self.target)) Type.u32 else ty; | 4798 | const result_ty = if (isByRef(ty, self.target)) Type.u32 else ty; |
| 4787 | const result = try self.allocLocal(result_ty); | 4799 | const result = try self.allocLocal(result_ty); |
| 4788 | try self.addLabel(.local_set, result.local); | 4800 | try self.addLabel(.local_set, result.local.value); |
| 4789 | self.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs }); | 4801 | self.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs }); |
| 4790 | } | 4802 | } |
| 4791 | | 4803 | |
| ... | @@ -4872,7 +4884,7 @@ fn airClz(self: *Self, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4872,7 +4884,7 @@ fn airClz(self: *Self, inst: Air.Inst.Index) InnerError!void { |
| 4872 | } | 4884 | } |
| 4873 | | 4885 | |
| 4874 | const result = try self.allocLocal(result_ty); | 4886 | const result = try self.allocLocal(result_ty); |
| 4875 | try self.addLabel(.local_set, result.local); | 4887 | try self.addLabel(.local_set, result.local.value); |
| 4876 | self.finishAir(inst, result, &.{ty_op.operand}); | 4888 | self.finishAir(inst, result, &.{ty_op.operand}); |
| 4877 | } | 4889 | } |
| 4878 | | 4890 | |
| ... | @@ -4937,7 +4949,7 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4937,7 +4949,7 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) InnerError!void { |
| 4937 | } | 4949 | } |
| 4938 | | 4950 | |
| 4939 | const result = try self.allocLocal(result_ty); | 4951 | const result = try self.allocLocal(result_ty); |
| 4940 | try self.addLabel(.local_set, result.local); | 4952 | try self.addLabel(.local_set, result.local.value); |
| 4941 | self.finishAir(inst, result, &.{ty_op.operand}); | 4953 | self.finishAir(inst, result, &.{ty_op.operand}); |
| 4942 | } | 4954 | } |
| 4943 | | 4955 | |
| ... | @@ -4958,7 +4970,7 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index, is_ptr: bool) !void { | ... | @@ -4958,7 +4970,7 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index, is_ptr: bool) !void { |
| 4958 | try dbg_info.append(@enumToInt(link.File.Dwarf.AbbrevKind.variable)); | 4970 | try dbg_info.append(@enumToInt(link.File.Dwarf.AbbrevKind.variable)); |
| 4959 | switch (operand) { | 4971 | switch (operand) { |
| 4960 | .local => |local| { | 4972 | .local => |local| { |
| 4961 | const leb_size = link.File.Wasm.getULEB128Size(local); | 4973 | const leb_size = link.File.Wasm.getULEB128Size(local.value); |
| 4962 | try dbg_info.ensureUnusedCapacity(2 + leb_size); | 4974 | try dbg_info.ensureUnusedCapacity(2 + leb_size); |
| 4963 | // wasm locals are encoded as follow: | 4975 | // wasm locals are encoded as follow: |
| 4964 | // DW_OP_WASM_location wasm-op | 4976 | // DW_OP_WASM_location wasm-op |
| ... | @@ -4970,7 +4982,7 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index, is_ptr: bool) !void { | ... | @@ -4970,7 +4982,7 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index, is_ptr: bool) !void { |
| 4970 | std.dwarf.OP.WASM_location, | 4982 | std.dwarf.OP.WASM_location, |
| 4971 | std.dwarf.OP.WASM_local, | 4983 | std.dwarf.OP.WASM_local, |
| 4972 | }); | 4984 | }); |
| 4973 | leb.writeULEB128(dbg_info.writer(), local) catch unreachable; | 4985 | leb.writeULEB128(dbg_info.writer(), local.value) catch unreachable; |
| 4974 | }, | 4986 | }, |
| 4975 | else => {}, // TODO | 4987 | else => {}, // TODO |
| 4976 | } | 4988 | } |
| ... | @@ -5179,7 +5191,7 @@ fn airDivFloor(self: *Self, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5179,7 +5191,7 @@ fn airDivFloor(self: *Self, inst: Air.Inst.Index) InnerError!void { |
| 5179 | const div_result = try self.allocLocal(ty); | 5191 | const div_result = try self.allocLocal(ty); |
| 5180 | // leave on stack | 5192 | // leave on stack |
| 5181 | _ = try self.binOp(lhs_res, rhs_res, ty, .div); | 5193 | _ = try self.binOp(lhs_res, rhs_res, ty, .div); |
| 5182 | try self.addLabel(.local_tee, div_result.local); | 5194 | try self.addLabel(.local_tee, div_result.local.value); |
| 5183 | _ = try self.cmp(lhs_res, zero, ty, .lt); | 5195 | _ = try self.cmp(lhs_res, zero, ty, .lt); |
| 5184 | _ = try self.cmp(rhs_res, zero, ty, .lt); | 5196 | _ = try self.cmp(rhs_res, zero, ty, .lt); |
| 5185 | switch (wasm_bits) { | 5197 | switch (wasm_bits) { |
| ... | @@ -5232,7 +5244,7 @@ fn airDivFloor(self: *Self, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5232,7 +5244,7 @@ fn airDivFloor(self: *Self, inst: Air.Inst.Index) InnerError!void { |
| 5232 | } | 5244 | } |
| 5233 | | 5245 | |
| 5234 | const result = try self.allocLocal(ty); | 5246 | const result = try self.allocLocal(ty); |
| 5235 | try self.addLabel(.local_set, result.local); | 5247 | try self.addLabel(.local_set, result.local.value); |
| 5236 | self.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs }); | 5248 | self.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs }); |
| 5237 | } | 5249 | } |
| 5238 | | 5250 | |
| ... | @@ -5257,7 +5269,7 @@ fn divSigned(self: *Self, lhs: WValue, rhs: WValue, ty: Type) InnerError!WValue | ... | @@ -5257,7 +5269,7 @@ fn divSigned(self: *Self, lhs: WValue, rhs: WValue, ty: Type) InnerError!WValue |
| 5257 | try self.addTag(.i32_div_s); | 5269 | try self.addTag(.i32_div_s); |
| 5258 | | 5270 | |
| 5259 | const result = try self.allocLocal(ty); | 5271 | const result = try self.allocLocal(ty); |
| 5260 | try self.addLabel(.local_set, result.local); | 5272 | try self.addLabel(.local_set, result.local.value); |
| 5261 | return result; | 5273 | return result; |
| 5262 | } | 5274 | } |
| 5263 | | 5275 | |
| ... | @@ -5323,7 +5335,7 @@ fn airCeilFloorTrunc(self: *Self, inst: Air.Inst.Index, op: Op) InnerError!void | ... | @@ -5323,7 +5335,7 @@ fn airCeilFloorTrunc(self: *Self, inst: Air.Inst.Index, op: Op) InnerError!void |
| 5323 | } | 5335 | } |
| 5324 | | 5336 | |
| 5325 | const result = try self.allocLocal(ty); | 5337 | const result = try self.allocLocal(ty); |
| 5326 | try self.addLabel(.local_set, result.local); | 5338 | try self.addLabel(.local_set, result.local.value); |
| 5327 | self.finishAir(inst, result, &.{un_op}); | 5339 | self.finishAir(inst, result, &.{un_op}); |
| 5328 | } | 5340 | } |
| 5329 | | 5341 | |
| ... | @@ -5374,7 +5386,7 @@ fn airSatBinOp(self: *Self, inst: Air.Inst.Index, op: Op) InnerError!void { | ... | @@ -5374,7 +5386,7 @@ fn airSatBinOp(self: *Self, inst: Air.Inst.Index, op: Op) InnerError!void { |
| 5374 | | 5386 | |
| 5375 | try self.addTag(.select); | 5387 | try self.addTag(.select); |
| 5376 | const result = try self.allocLocal(ty); | 5388 | const result = try self.allocLocal(ty); |
| 5377 | try self.addLabel(.local_set, result.local); | 5389 | try self.addLabel(.local_set, result.local.value); |
| 5378 | return self.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs }); | 5390 | return self.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs }); |
| 5379 | } | 5391 | } |
| 5380 | | 5392 | |
| ... | @@ -5412,13 +5424,13 @@ fn signedSat(self: *Self, lhs_operand: WValue, rhs_operand: WValue, ty: Type, op | ... | @@ -5412,13 +5424,13 @@ fn signedSat(self: *Self, lhs_operand: WValue, rhs_operand: WValue, ty: Type, op |
| 5412 | try self.emitWValue(max_wvalue); | 5424 | try self.emitWValue(max_wvalue); |
| 5413 | _ = try self.cmp(bin_result, max_wvalue, ty, .lt); | 5425 | _ = try self.cmp(bin_result, max_wvalue, ty, .lt); |
| 5414 | try self.addTag(.select); | 5426 | try self.addTag(.select); |
| 5415 | try self.addLabel(.local_set, bin_result.local); // re-use local | 5427 | try self.addLabel(.local_set, bin_result.local.value); // re-use local |
| 5416 | | 5428 | |
| 5417 | try self.emitWValue(bin_result); | 5429 | try self.emitWValue(bin_result); |
| 5418 | try self.emitWValue(min_wvalue); | 5430 | try self.emitWValue(min_wvalue); |
| 5419 | _ = try self.cmp(bin_result, min_wvalue, ty, .gt); | 5431 | _ = try self.cmp(bin_result, min_wvalue, ty, .gt); |
| 5420 | try self.addTag(.select); | 5432 | try self.addTag(.select); |
| 5421 | try self.addLabel(.local_set, bin_result.local); // re-use local | 5433 | try self.addLabel(.local_set, bin_result.local.value); // re-use local |
| 5422 | return (try self.wrapOperand(bin_result, ty)).toLocal(self, ty); | 5434 | return (try self.wrapOperand(bin_result, ty)).toLocal(self, ty); |
| 5423 | } else { | 5435 | } else { |
| 5424 | const zero = switch (wasm_bits) { | 5436 | const zero = switch (wasm_bits) { |
| ... | @@ -5436,7 +5448,7 @@ fn signedSat(self: *Self, lhs_operand: WValue, rhs_operand: WValue, ty: Type, op | ... | @@ -5436,7 +5448,7 @@ fn signedSat(self: *Self, lhs_operand: WValue, rhs_operand: WValue, ty: Type, op |
| 5436 | const cmp_bin_result = try self.cmp(bin_result, lhs, ty, .lt); | 5448 | const cmp_bin_result = try self.cmp(bin_result, lhs, ty, .lt); |
| 5437 | _ = try self.binOp(cmp_zero_result, cmp_bin_result, Type.u32, .xor); // comparisons always return i32, so provide u32 as type to xor. | 5449 | _ = try self.binOp(cmp_zero_result, cmp_bin_result, Type.u32, .xor); // comparisons always return i32, so provide u32 as type to xor. |
| 5438 | try self.addTag(.select); | 5450 | try self.addTag(.select); |
| 5439 | try self.addLabel(.local_set, bin_result.local); // re-use local | 5451 | try self.addLabel(.local_set, bin_result.local.value); // re-use local |
| 5440 | return bin_result; | 5452 | return bin_result; |
| 5441 | } | 5453 | } |
| 5442 | } | 5454 | } |
| ... | @@ -5489,7 +5501,7 @@ fn airShlSat(self: *Self, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5489,7 +5501,7 @@ fn airShlSat(self: *Self, inst: Air.Inst.Index) InnerError!void { |
| 5489 | try self.emitWValue(shl); | 5501 | try self.emitWValue(shl); |
| 5490 | _ = try self.cmp(lhs, shr, ty, .neq); | 5502 | _ = try self.cmp(lhs, shr, ty, .neq); |
| 5491 | try self.addTag(.select); | 5503 | try self.addTag(.select); |
| 5492 | try self.addLabel(.local_set, result.local); | 5504 | try self.addLabel(.local_set, result.local.value); |
| 5493 | break :outer_blk; | 5505 | break :outer_blk; |
| 5494 | } else { | 5506 | } else { |
| 5495 | const shift_size = wasm_bits - int_info.bits; | 5507 | const shift_size = wasm_bits - int_info.bits; |
| ... | @@ -5534,12 +5546,12 @@ fn airShlSat(self: *Self, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5534,12 +5546,12 @@ fn airShlSat(self: *Self, inst: Air.Inst.Index) InnerError!void { |
| 5534 | try self.emitWValue(shl); | 5546 | try self.emitWValue(shl); |
| 5535 | _ = try self.cmp(shl_res, shr, ty, .neq); | 5547 | _ = try self.cmp(shl_res, shr, ty, .neq); |
| 5536 | try self.addTag(.select); | 5548 | try self.addTag(.select); |
| 5537 | try self.addLabel(.local_set, result.local); | 5549 | try self.addLabel(.local_set, result.local.value); |
| 5538 | var shift_result = try self.binOp(result, shift_value, ty, .shr); | 5550 | var shift_result = try self.binOp(result, shift_value, ty, .shr); |
| 5539 | if (is_signed) { | 5551 | if (is_signed) { |
| 5540 | shift_result = try self.wrapOperand(shift_result, ty); | 5552 | shift_result = try self.wrapOperand(shift_result, ty); |
| 5541 | } | 5553 | } |
| 5542 | try self.addLabel(.local_set, result.local); | 5554 | try self.addLabel(.local_set, result.local.value); |
| 5543 | } | 5555 | } |
| 5544 | | 5556 | |
| 5545 | return self.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs }); | 5557 | return self.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs }); |