authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-03-20 13:48:14+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-22 20:16:05-07:00
log6ac04d8fd7d63dfd4aa611e1564f1d4768baf408
treec4d866f3f6539da2f7b2ae6f6d7fd15fadcee0ed
parente8813b296bc55a13b534bd9b2a03e1f6af366915

stage2 ARM: change semantics of MCValue.stack_offset

A stack_offset will now denote the exact offset applied to the start of the stack frame (=fp when frame pointer is emitted)

1 files changed, 44 insertions(+), 68 deletions(-)

src/arch/arm/CodeGen.zig+44-68
...@@ -396,8 +396,8 @@ fn gen(self: *Self) !void {...@@ -396,8 +396,8 @@ fn gen(self: *Self) !void {
396 // The address of where to store the return value is in396 // The address of where to store the return value is in
397 // r0. As this register might get overwritten along the397 // r0. As this register might get overwritten along the
398 // way, save the address to the stack.398 // way, save the address to the stack.
399 const stack_offset = mem.alignForwardGeneric(u32, self.next_stack_offset, 4);399 const stack_offset = mem.alignForwardGeneric(u32, self.next_stack_offset, 4) + 4;
400 self.next_stack_offset = stack_offset + 4;400 self.next_stack_offset = stack_offset;
401 self.max_end_stack = @maximum(self.max_end_stack, self.next_stack_offset);401 self.max_end_stack = @maximum(self.max_end_stack, self.next_stack_offset);
402402
403 try self.genSetStack(Type.usize, stack_offset, MCValue{ .register = .r0 });403 try self.genSetStack(Type.usize, stack_offset, MCValue{ .register = .r0 });
...@@ -780,10 +780,9 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: u32) !u...@@ -780,10 +780,9 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: u32) !u
780 if (abi_align > self.stack_align)780 if (abi_align > self.stack_align)
781 self.stack_align = abi_align;781 self.stack_align = abi_align;
782 // TODO find a free slot instead of always appending782 // TODO find a free slot instead of always appending
783 const offset = mem.alignForwardGeneric(u32, self.next_stack_offset, abi_align);783 const offset = mem.alignForwardGeneric(u32, self.next_stack_offset, abi_align) + abi_size;
784 self.next_stack_offset = offset + abi_size;784 self.next_stack_offset = offset;
785 if (self.next_stack_offset > self.max_end_stack)785 self.max_end_stack = @maximum(self.max_end_stack, self.next_stack_offset);
786 self.max_end_stack = self.next_stack_offset;
787 try self.stack.putNoClobber(self.gpa, offset, .{786 try self.stack.putNoClobber(self.gpa, offset, .{
788 .inst = inst,787 .inst = inst,
789 .size = abi_size,788 .size = abi_size,
...@@ -797,8 +796,10 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -797,8 +796,10 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
797796
798 if (!elem_ty.hasRuntimeBits()) {797 if (!elem_ty.hasRuntimeBits()) {
799 // As this stack item will never be dereferenced at runtime,798 // As this stack item will never be dereferenced at runtime,
800 // return the current stack offset799 // return the stack offset 0. Stack offset 0 will be where all
801 return self.next_stack_offset;800 // zero-sized stack allocations live as non-zero-sized
801 // allocations will always have an offset > 0.
802 return @as(u32, 0);
802 }803 }
803804
804 const target = self.target.*;805 const target = self.target.*;
...@@ -1161,8 +1162,8 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void {...@@ -1161,8 +1162,8 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void {
1161 const len_ty = self.air.typeOf(bin_op.rhs);1162 const len_ty = self.air.typeOf(bin_op.rhs);
11621163
1163 const stack_offset = try self.allocMem(inst, 8, 8);1164 const stack_offset = try self.allocMem(inst, 8, 8);
1164 try self.genSetStack(ptr_ty, stack_offset + 4, ptr);1165 try self.genSetStack(ptr_ty, stack_offset, ptr);
1165 try self.genSetStack(len_ty, stack_offset, len);1166 try self.genSetStack(len_ty, stack_offset - 4, len);
1166 break :result MCValue{ .stack_offset = stack_offset };1167 break :result MCValue{ .stack_offset = stack_offset };
1167 };1168 };
1168 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });1169 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
...@@ -1180,36 +1181,18 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index) !void {...@@ -1180,36 +1181,18 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index) !void {
1180 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });1181 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
1181}1182}
11821183
1183fn airAddWrap(self: *Self, inst: Air.Inst.Index) !void {
1184 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1185 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement addwrap for {}", .{self.target.cpu.arch});
1186 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
1187}
1188
1189fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {1184fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {
1190 const bin_op = self.air.instructions.items(.data)[inst].bin_op;1185 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1191 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement add_sat for {}", .{self.target.cpu.arch});1186 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement add_sat for {}", .{self.target.cpu.arch});
1192 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });1187 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
1193}1188}
11941189
1195fn airSubWrap(self: *Self, inst: Air.Inst.Index) !void {
1196 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1197 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement subwrap for {}", .{self.target.cpu.arch});
1198 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
1199}
1200
1201fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {1190fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {
1202 const bin_op = self.air.instructions.items(.data)[inst].bin_op;1191 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1203 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement sub_sat for {}", .{self.target.cpu.arch});1192 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement sub_sat for {}", .{self.target.cpu.arch});
1204 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });1193 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
1205}1194}
12061195
1207fn airMulWrap(self: *Self, inst: Air.Inst.Index) !void {
1208 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1209 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement mulwrap for {}", .{self.target.cpu.arch});
1210 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
1211}
1212
1213fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {1196fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {
1214 const bin_op = self.air.instructions.items(.data)[inst].bin_op;1197 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1215 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement mul_sat for {}", .{self.target.cpu.arch});1198 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement mul_sat for {}", .{self.target.cpu.arch});
...@@ -1327,12 +1310,14 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {...@@ -1327,12 +1310,14 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
1327 const ty_op = self.air.instructions.items(.data)[inst].ty_op;1310 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1328 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {1311 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
1329 const optional_ty = self.air.typeOfIndex(inst);1312 const optional_ty = self.air.typeOfIndex(inst);
1313 const abi_size = @intCast(u32, optional_ty.abiSize(self.target.*));
13301314
1331 // Optional with a zero-bit payload type is just a boolean true1315 // Optional with a zero-bit payload type is just a boolean true
1332 if (optional_ty.abiSize(self.target.*) == 1)1316 if (abi_size == 1) {
1333 break :result MCValue{ .immediate = 1 };1317 break :result MCValue{ .immediate = 1 };
13341318 } else {
1335 return self.fail("TODO implement wrap optional for {}", .{self.target.cpu.arch});1319 return self.fail("TODO implement wrap optional for {}", .{self.target.cpu.arch});
1320 }
1336 };1321 };
1337 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });1322 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
1338}1323}
...@@ -1366,7 +1351,7 @@ fn slicePtr(self: *Self, mcv: MCValue) !MCValue {...@@ -1366,7 +1351,7 @@ fn slicePtr(self: *Self, mcv: MCValue) !MCValue {
1366 return MCValue{ .stack_argument_offset = off + 4 };1351 return MCValue{ .stack_argument_offset = off + 4 };
1367 },1352 },
1368 .stack_offset => |off| {1353 .stack_offset => |off| {
1369 return MCValue{ .stack_offset = off + 4 };1354 return MCValue{ .stack_offset = off };
1370 },1355 },
1371 .memory => |addr| {1356 .memory => |addr| {
1372 return MCValue{ .memory = addr };1357 return MCValue{ .memory = addr };
...@@ -1395,7 +1380,7 @@ fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void {...@@ -1395,7 +1380,7 @@ fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void {
1395 break :result MCValue{ .stack_argument_offset = off };1380 break :result MCValue{ .stack_argument_offset = off };
1396 },1381 },
1397 .stack_offset => |off| {1382 .stack_offset => |off| {
1398 break :result MCValue{ .stack_offset = off };1383 break :result MCValue{ .stack_offset = off - 4 };
1399 },1384 },
1400 .memory => |addr| {1385 .memory => |addr| {
1401 break :result MCValue{ .memory = addr + 4 };1386 break :result MCValue{ .memory = addr + 4 };
...@@ -1413,7 +1398,7 @@ fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -1413,7 +1398,7 @@ fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {
1413 switch (mcv) {1398 switch (mcv) {
1414 .dead, .unreach => unreachable,1399 .dead, .unreach => unreachable,
1415 .ptr_stack_offset => |off| {1400 .ptr_stack_offset => |off| {
1416 break :result MCValue{ .ptr_stack_offset = off };1401 break :result MCValue{ .ptr_stack_offset = off - 4 };
1417 },1402 },
1418 else => return self.fail("TODO implement ptr_slice_len_ptr for {}", .{mcv}),1403 else => return self.fail("TODO implement ptr_slice_len_ptr for {}", .{mcv}),
1419 }1404 }
...@@ -1428,7 +1413,7 @@ fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -1428,7 +1413,7 @@ fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void {
1428 switch (mcv) {1413 switch (mcv) {
1429 .dead, .unreach => unreachable,1414 .dead, .unreach => unreachable,
1430 .ptr_stack_offset => |off| {1415 .ptr_stack_offset => |off| {
1431 break :result MCValue{ .ptr_stack_offset = off + 4 };1416 break :result MCValue{ .ptr_stack_offset = off };
1432 },1417 },
1433 else => return self.fail("TODO implement ptr_slice_ptr_ptr for {}", .{mcv}),1418 else => return self.fail("TODO implement ptr_slice_ptr_ptr for {}", .{mcv}),
1434 }1419 }
...@@ -1860,13 +1845,10 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde...@@ -1860,13 +1845,10 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde
1860 const mcv = try self.resolveInst(operand);1845 const mcv = try self.resolveInst(operand);
1861 const ptr_ty = self.air.typeOf(operand);1846 const ptr_ty = self.air.typeOf(operand);
1862 const struct_ty = ptr_ty.childType();1847 const struct_ty = ptr_ty.childType();
1863 const struct_size = @intCast(u32, struct_ty.abiSize(self.target.*));
1864 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, self.target.*));1848 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, self.target.*));
1865 const struct_field_ty = struct_ty.structFieldType(index);
1866 const struct_field_size = @intCast(u32, struct_field_ty.abiSize(self.target.*));
1867 switch (mcv) {1849 switch (mcv) {
1868 .ptr_stack_offset => |off| {1850 .ptr_stack_offset => |off| {
1869 break :result MCValue{ .ptr_stack_offset = off + struct_size - struct_field_offset - struct_field_size };1851 break :result MCValue{ .ptr_stack_offset = off - struct_field_offset };
1870 },1852 },
1871 else => {1853 else => {
1872 const offset_reg = try self.copyToTmpRegister(ptr_ty, .{1854 const offset_reg = try self.copyToTmpRegister(ptr_ty, .{
...@@ -1914,7 +1896,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -1914,7 +1896,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
1914 break :result MCValue{ .stack_argument_offset = off + adjusted_field_offset };1896 break :result MCValue{ .stack_argument_offset = off + adjusted_field_offset };
1915 },1897 },
1916 .stack_offset => |off| {1898 .stack_offset => |off| {
1917 break :result MCValue{ .stack_offset = off + adjusted_field_offset };1899 break :result MCValue{ .stack_offset = off - struct_field_offset };
1918 },1900 },
1919 .memory => |addr| {1901 .memory => |addr| {
1920 break :result MCValue{ .memory = addr + adjusted_field_offset };1902 break :result MCValue{ .memory = addr + adjusted_field_offset };
...@@ -2871,10 +2853,9 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {...@@ -2871,10 +2853,9 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
2871 if (abi_align > self.stack_align)2853 if (abi_align > self.stack_align)
2872 self.stack_align = abi_align;2854 self.stack_align = abi_align;
2873 // TODO find a free slot instead of always appending2855 // TODO find a free slot instead of always appending
2874 const offset = mem.alignForwardGeneric(u32, self.next_stack_offset, abi_align);2856 const offset = mem.alignForwardGeneric(u32, self.next_stack_offset, abi_align) + abi_size;
2875 self.next_stack_offset = offset + abi_size;2857 self.next_stack_offset = offset;
2876 if (self.next_stack_offset > self.max_end_stack)2858 self.max_end_stack = @maximum(self.max_end_stack, self.next_stack_offset);
2877 self.max_end_stack = self.next_stack_offset;
28782859
2879 const tmp_mcv = MCValue{ .stack_offset = offset };2860 const tmp_mcv = MCValue{ .stack_offset = offset };
2880 try self.load(tmp_mcv, ptr, ptr_ty);2861 try self.load(tmp_mcv, ptr, ptr_ty);
...@@ -3192,7 +3173,9 @@ fn isErr(self: *Self, ty: Type, operand: MCValue) !MCValue {...@@ -3192,7 +3173,9 @@ fn isErr(self: *Self, ty: Type, operand: MCValue) !MCValue {
31923173
3193 if (!error_type.hasRuntimeBits()) {3174 if (!error_type.hasRuntimeBits()) {
3194 return MCValue{ .immediate = 0 }; // always false3175 return MCValue{ .immediate = 0 }; // always false
3195 } else if (!payload_type.hasRuntimeBits()) {3176 }
3177
3178 if (!payload_type.hasRuntimeBits()) {
3196 if (error_type.abiSize(self.target.*) <= 4) {3179 if (error_type.abiSize(self.target.*) <= 4) {
3197 const reg_mcv: MCValue = switch (operand) {3180 const reg_mcv: MCValue = switch (operand) {
3198 .register => operand,3181 .register => operand,
...@@ -3620,13 +3603,11 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro...@@ -3620,13 +3603,11 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
3620 return self.genSetStack(ty, stack_offset, MCValue{ .register = reg });3603 return self.genSetStack(ty, stack_offset, MCValue{ .register = reg });
3621 },3604 },
3622 .register => |reg| {3605 .register => |reg| {
3623 const adj_off = stack_offset + abi_size;
3624
3625 switch (abi_size) {3606 switch (abi_size) {
3626 1, 4 => {3607 1, 4 => {
3627 const offset = if (math.cast(u12, adj_off)) |imm| blk: {3608 const offset = if (math.cast(u12, stack_offset)) |imm| blk: {
3628 break :blk Instruction.Offset.imm(imm);3609 break :blk Instruction.Offset.imm(imm);
3629 } else |_| Instruction.Offset.reg(try self.copyToTmpRegister(Type.initTag(.u32), MCValue{ .immediate = adj_off }), .none);3610 } else |_| Instruction.Offset.reg(try self.copyToTmpRegister(Type.initTag(.u32), MCValue{ .immediate = stack_offset }), .none);
36303611
3631 const tag: Mir.Inst.Tag = switch (abi_size) {3612 const tag: Mir.Inst.Tag = switch (abi_size) {
3632 1 => .strb,3613 1 => .strb,
...@@ -3647,9 +3628,9 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro...@@ -3647,9 +3628,9 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
3647 });3628 });
3648 },3629 },
3649 2 => {3630 2 => {
3650 const offset = if (adj_off <= math.maxInt(u8)) blk: {3631 const offset = if (stack_offset <= math.maxInt(u8)) blk: {
3651 break :blk Instruction.ExtraLoadStoreOffset.imm(@intCast(u8, adj_off));3632 break :blk Instruction.ExtraLoadStoreOffset.imm(@intCast(u8, stack_offset));
3652 } else Instruction.ExtraLoadStoreOffset.reg(try self.copyToTmpRegister(Type.initTag(.u32), MCValue{ .immediate = adj_off }));3633 } else Instruction.ExtraLoadStoreOffset.reg(try self.copyToTmpRegister(Type.initTag(.u32), MCValue{ .immediate = stack_offset }));
36533634
3654 _ = try self.addInst(.{3635 _ = try self.addInst(.{
3655 .tag = .strh,3636 .tag = .strh,
...@@ -3739,13 +3720,9 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -3739,13 +3720,9 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
3739 // Write the debug undefined value.3720 // Write the debug undefined value.
3740 return self.genSetReg(ty, reg, .{ .immediate = 0xaaaaaaaa });3721 return self.genSetReg(ty, reg, .{ .immediate = 0xaaaaaaaa });
3741 },3722 },
3742 .ptr_stack_offset => |unadjusted_off| {3723 .ptr_stack_offset => |off| {
3743 // TODO: maybe addressing from sp instead of fp3724 // TODO: maybe addressing from sp instead of fp
3744 const elem_ty = ty.childType();3725 const op = Instruction.Operand.fromU32(off) orelse
3745 const abi_size = @intCast(u32, elem_ty.abiSize(self.target.*));
3746 const adj_off = unadjusted_off + abi_size;
3747
3748 const op = Instruction.Operand.fromU32(adj_off) orelse
3749 return self.fail("TODO larger stack offsets", .{});3726 return self.fail("TODO larger stack offsets", .{});
37503727
3751 _ = try self.addInst(.{3728 _ = try self.addInst(.{
...@@ -3919,10 +3896,9 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -3919,10 +3896,9 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
3919 try self.genSetReg(ty, reg, .{ .immediate = @intCast(u32, addr) });3896 try self.genSetReg(ty, reg, .{ .immediate = @intCast(u32, addr) });
3920 try self.genLdrRegister(reg, reg, ty);3897 try self.genLdrRegister(reg, reg, ty);
3921 },3898 },
3922 .stack_offset => |unadjusted_off| {3899 .stack_offset => |off| {
3923 // TODO: maybe addressing from sp instead of fp3900 // TODO: maybe addressing from sp instead of fp
3924 const abi_size = @intCast(u32, ty.abiSize(self.target.*));3901 const abi_size = @intCast(u32, ty.abiSize(self.target.*));
3925 const adj_off = unadjusted_off + abi_size;
39263902
3927 const tag: Mir.Inst.Tag = switch (abi_size) {3903 const tag: Mir.Inst.Tag = switch (abi_size) {
3928 1 => if (ty.isSignedInt()) Mir.Inst.Tag.ldrsb else .ldrb,3904 1 => if (ty.isSignedInt()) Mir.Inst.Tag.ldrsb else .ldrb,
...@@ -3939,9 +3915,9 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -3939,9 +3915,9 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
3939 };3915 };
39403916
3941 if (extra_offset) {3917 if (extra_offset) {
3942 const offset = if (adj_off <= math.maxInt(u8)) blk: {3918 const offset = if (off <= math.maxInt(u8)) blk: {
3943 break :blk Instruction.ExtraLoadStoreOffset.imm(@intCast(u8, adj_off));3919 break :blk Instruction.ExtraLoadStoreOffset.imm(@intCast(u8, off));
3944 } else Instruction.ExtraLoadStoreOffset.reg(try self.copyToTmpRegister(Type.initTag(.u32), MCValue{ .immediate = adj_off }));3920 } else Instruction.ExtraLoadStoreOffset.reg(try self.copyToTmpRegister(Type.initTag(.usize), MCValue{ .immediate = off }));
39453921
3946 _ = try self.addInst(.{3922 _ = try self.addInst(.{
3947 .tag = tag,3923 .tag = tag,
...@@ -3955,9 +3931,9 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -3955,9 +3931,9 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
3955 } },3931 } },
3956 });3932 });
3957 } else {3933 } else {
3958 const offset = if (adj_off <= math.maxInt(u12)) blk: {3934 const offset = if (off <= math.maxInt(u12)) blk: {
3959 break :blk Instruction.Offset.imm(@intCast(u12, adj_off));3935 break :blk Instruction.Offset.imm(@intCast(u12, off));
3960 } else Instruction.Offset.reg(try self.copyToTmpRegister(Type.initTag(.u32), MCValue{ .immediate = adj_off }), .none);3936 } else Instruction.Offset.reg(try self.copyToTmpRegister(Type.initTag(.usize), MCValue{ .immediate = off }), .none);
39613937
3962 _ = try self.addInst(.{3938 _ = try self.addInst(.{
3963 .tag = tag,3939 .tag = tag,
...@@ -4136,8 +4112,8 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {...@@ -4136,8 +4112,8 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
4136 const array_len = @intCast(u32, array_ty.arrayLen());4112 const array_len = @intCast(u32, array_ty.arrayLen());
41374113
4138 const stack_offset = try self.allocMem(inst, 8, 8);4114 const stack_offset = try self.allocMem(inst, 8, 8);
4139 try self.genSetStack(ptr_ty, stack_offset + 4, ptr);4115 try self.genSetStack(ptr_ty, stack_offset, ptr);
4140 try self.genSetStack(Type.initTag(.usize), stack_offset, .{ .immediate = array_len });4116 try self.genSetStack(Type.initTag(.usize), stack_offset - 4, .{ .immediate = array_len });
4141 break :result MCValue{ .stack_offset = stack_offset };4117 break :result MCValue{ .stack_offset = stack_offset };
4142 };4118 };
4143 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });4119 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });