authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-03-25 19:16:58+01:00
committergravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-03-25 19:21:34+01:00
logf7da4b9bc802b66d409413596204df355604fc67
tree5a5c88e0d6abf5f2303ca5d7b407d79a8cd996ca
parent16e49663329007c7f9c33086f4938c1450b1ebbd
signaturelock-open Commit is signed but in an unrecognized format.

stage2 AArch64: change semantics of MCValue.stack_offset

Mirrors the changes performed to stack_offset in the ARM backend

1 files changed, 35 insertions(+), 37 deletions(-)

src/arch/aarch64/CodeGen.zig+35-37
...@@ -809,10 +809,9 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: u32) !u...@@ -809,10 +809,9 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: u32) !u
809 if (abi_align > self.stack_align)809 if (abi_align > self.stack_align)
810 self.stack_align = abi_align;810 self.stack_align = abi_align;
811 // TODO find a free slot instead of always appending811 // TODO find a free slot instead of always appending
812 const offset = mem.alignForwardGeneric(u32, self.next_stack_offset, abi_align);812 const offset = mem.alignForwardGeneric(u32, self.next_stack_offset, abi_align) + abi_size;
813 self.next_stack_offset = offset + abi_size;813 self.next_stack_offset = offset;
814 if (self.next_stack_offset > self.max_end_stack)814 self.max_end_stack = @maximum(self.max_end_stack, self.next_stack_offset);
815 self.max_end_stack = self.next_stack_offset;
816 try self.stack.putNoClobber(self.gpa, offset, .{815 try self.stack.putNoClobber(self.gpa, offset, .{
817 .inst = inst,816 .inst = inst,
818 .size = abi_size,817 .size = abi_size,
...@@ -825,9 +824,10 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -825,9 +824,10 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
825 const elem_ty = self.air.typeOfIndex(inst).elemType();824 const elem_ty = self.air.typeOfIndex(inst).elemType();
826825
827 if (!elem_ty.hasRuntimeBits()) {826 if (!elem_ty.hasRuntimeBits()) {
828 // As this stack item will never be dereferenced at runtime,827 // return the stack offset 0. Stack offset 0 will be where all
829 // return the current stack offset828 // zero-sized stack allocations live as non-zero-sized
830 return self.next_stack_offset;829 // allocations will always have an offset > 0.
830 return @as(u32, 0);
831 }831 }
832832
833 const target = self.target.*;833 const target = self.target.*;
...@@ -1097,8 +1097,8 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void {...@@ -1097,8 +1097,8 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void {
1097 const ptr_bytes = @divExact(ptr_bits, 8);1097 const ptr_bytes = @divExact(ptr_bits, 8);
10981098
1099 const stack_offset = try self.allocMem(inst, ptr_bytes * 2, ptr_bytes * 2);1099 const stack_offset = try self.allocMem(inst, ptr_bytes * 2, ptr_bytes * 2);
1100 try self.genSetStack(ptr_ty, stack_offset + ptr_bytes, ptr);1100 try self.genSetStack(ptr_ty, stack_offset, ptr);
1101 try self.genSetStack(len_ty, stack_offset, len);1101 try self.genSetStack(len_ty, stack_offset - ptr_bytes, len);
1102 break :result MCValue{ .stack_offset = stack_offset };1102 break :result MCValue{ .stack_offset = stack_offset };
1103 };1103 };
1104 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });1104 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
...@@ -1515,7 +1515,13 @@ fn binOp(...@@ -1515,7 +1515,13 @@ fn binOp(
1515 const elem_size = elem_ty.abiSize(self.target.*);1515 const elem_size = elem_ty.abiSize(self.target.*);
15161516
1517 if (elem_size == 1) {1517 if (elem_size == 1) {
1518 return try self.binOpRegister(tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty);1518 const base_tag: Air.Inst.Tag = switch (tag) {
1519 .ptr_add => .add,
1520 .ptr_sub => .sub,
1521 else => unreachable,
1522 };
1523
1524 return try self.binOpRegister(base_tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty);
1519 } else {1525 } else {
1520 // convert the offset into a byte offset by1526 // convert the offset into a byte offset by
1521 // multiplying it with elem_size1527 // multiplying it with elem_size
...@@ -1724,14 +1730,12 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {...@@ -1724,14 +1730,12 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
1724fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void {1730fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void {
1725 const ty_op = self.air.instructions.items(.data)[inst].ty_op;1731 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1726 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {1732 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
1727 const ptr_bits = self.target.cpu.arch.ptrBitWidth();
1728 const ptr_bytes = @divExact(ptr_bits, 8);
1729 const mcv = try self.resolveInst(ty_op.operand);1733 const mcv = try self.resolveInst(ty_op.operand);
1730 switch (mcv) {1734 switch (mcv) {
1731 .dead, .unreach, .none => unreachable,1735 .dead, .unreach, .none => unreachable,
1732 .register => unreachable, // a slice doesn't fit in one register1736 .register => unreachable, // a slice doesn't fit in one register
1733 .stack_offset => |off| {1737 .stack_offset => |off| {
1734 break :result MCValue{ .stack_offset = off + ptr_bytes };1738 break :result MCValue{ .stack_offset = off };
1735 },1739 },
1736 .memory => |addr| {1740 .memory => |addr| {
1737 break :result MCValue{ .memory = addr };1741 break :result MCValue{ .memory = addr };
...@@ -1752,7 +1756,7 @@ fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void {...@@ -1752,7 +1756,7 @@ fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void {
1752 .dead, .unreach, .none => unreachable,1756 .dead, .unreach, .none => unreachable,
1753 .register => unreachable, // a slice doesn't fit in one register1757 .register => unreachable, // a slice doesn't fit in one register
1754 .stack_offset => |off| {1758 .stack_offset => |off| {
1755 break :result MCValue{ .stack_offset = off };1759 break :result MCValue{ .stack_offset = off - ptr_bytes };
1756 },1760 },
1757 .memory => |addr| {1761 .memory => |addr| {
1758 break :result MCValue{ .memory = addr + ptr_bytes };1762 break :result MCValue{ .memory = addr + ptr_bytes };
...@@ -1772,7 +1776,7 @@ fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -1772,7 +1776,7 @@ fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {
1772 switch (mcv) {1776 switch (mcv) {
1773 .dead, .unreach, .none => unreachable,1777 .dead, .unreach, .none => unreachable,
1774 .ptr_stack_offset => |off| {1778 .ptr_stack_offset => |off| {
1775 break :result MCValue{ .ptr_stack_offset = off + ptr_bytes };1779 break :result MCValue{ .ptr_stack_offset = off - ptr_bytes };
1776 },1780 },
1777 else => return self.fail("TODO implement ptr_slice_len_ptr for {}", .{mcv}),1781 else => return self.fail("TODO implement ptr_slice_len_ptr for {}", .{mcv}),
1778 }1782 }
...@@ -1819,7 +1823,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -1819,7 +1823,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
1819 defer if (index_is_register) self.register_manager.unfreezeRegs(&.{index_mcv.register});1823 defer if (index_is_register) self.register_manager.unfreezeRegs(&.{index_mcv.register});
18201824
1821 const base_mcv: MCValue = switch (slice_mcv) {1825 const base_mcv: MCValue = switch (slice_mcv) {
1822 .stack_offset => |off| .{ .register = try self.copyToTmpRegister(slice_ptr_field_type, .{ .stack_offset = off + 8 }) },1826 .stack_offset => |off| .{ .register = try self.copyToTmpRegister(slice_ptr_field_type, .{ .stack_offset = off }) },
1823 else => return self.fail("TODO slice_elem_val when slice is {}", .{slice_mcv}),1827 else => return self.fail("TODO slice_elem_val when slice is {}", .{slice_mcv}),
1824 };1828 };
1825 self.register_manager.freezeRegs(&.{base_mcv.register});1829 self.register_manager.freezeRegs(&.{base_mcv.register});
...@@ -2293,13 +2297,10 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde...@@ -2293,13 +2297,10 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde
2293 const mcv = try self.resolveInst(operand);2297 const mcv = try self.resolveInst(operand);
2294 const ptr_ty = self.air.typeOf(operand);2298 const ptr_ty = self.air.typeOf(operand);
2295 const struct_ty = ptr_ty.childType();2299 const struct_ty = ptr_ty.childType();
2296 const struct_size = @intCast(u32, struct_ty.abiSize(self.target.*));
2297 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, self.target.*));2300 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, self.target.*));
2298 const struct_field_ty = struct_ty.structFieldType(index);
2299 const struct_field_size = @intCast(u32, struct_field_ty.abiSize(self.target.*));
2300 switch (mcv) {2301 switch (mcv) {
2301 .ptr_stack_offset => |off| {2302 .ptr_stack_offset => |off| {
2302 break :result MCValue{ .ptr_stack_offset = off + struct_size - struct_field_offset - struct_field_size };2303 break :result MCValue{ .ptr_stack_offset = off - struct_field_offset };
2303 },2304 },
2304 else => {2305 else => {
2305 const offset_reg = try self.copyToTmpRegister(ptr_ty, .{2306 const offset_reg = try self.copyToTmpRegister(ptr_ty, .{
...@@ -2621,11 +2622,15 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {...@@ -2621,11 +2622,15 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
2621 .Pointer => Type.usize,2622 .Pointer => Type.usize,
2622 .ErrorSet => Type.initTag(.u16),2623 .ErrorSet => Type.initTag(.u16),
2623 .Optional => blk: {2624 .Optional => blk: {
2624 if (lhs_ty.isPtrLikeOptional()) {2625 var opt_buffer: Type.Payload.ElemType = undefined;
2626 const payload_ty = lhs_ty.optionalChild(&opt_buffer);
2627 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
2628 break :blk Type.initTag(.u1);
2629 } else if (lhs_ty.isPtrLikeOptional()) {
2625 break :blk Type.usize;2630 break :blk Type.usize;
2631 } else {
2632 return self.fail("TODO AArch64 cmp non-pointer optionals", .{});
2626 }2633 }
2627
2628 return self.fail("TODO AArch64 cmp optionals", .{});
2629 },2634 },
2630 .Float => return self.fail("TODO AArch64 cmp floats", .{}),2635 .Float => return self.fail("TODO AArch64 cmp floats", .{}),
2631 else => unreachable,2636 else => unreachable,
...@@ -3318,8 +3323,6 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro...@@ -3318,8 +3323,6 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
3318 return self.genSetStack(ty, stack_offset, MCValue{ .register = reg });3323 return self.genSetStack(ty, stack_offset, MCValue{ .register = reg });
3319 },3324 },
3320 .register => |reg| {3325 .register => |reg| {
3321 const adj_off = stack_offset + abi_size;
3322
3323 switch (abi_size) {3326 switch (abi_size) {
3324 1, 2, 4, 8 => {3327 1, 2, 4, 8 => {
3325 const tag: Mir.Inst.Tag = switch (abi_size) {3328 const tag: Mir.Inst.Tag = switch (abi_size) {
...@@ -3334,7 +3337,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro...@@ -3334,7 +3337,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
3334 .tag = tag,3337 .tag = tag,
3335 .data = .{ .load_store_stack = .{3338 .data = .{ .load_store_stack = .{
3336 .rt = rt,3339 .rt = rt,
3337 .offset = @intCast(u32, adj_off),3340 .offset = @intCast(u32, stack_offset),
3338 } },3341 } },
3339 });3342 });
3340 },3343 },
...@@ -3430,13 +3433,9 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -3430,13 +3433,9 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
3430 else => unreachable, // unexpected register size3433 else => unreachable, // unexpected register size
3431 }3434 }
3432 },3435 },
3433 .ptr_stack_offset => |unadjusted_off| {3436 .ptr_stack_offset => |off| {
3434 // TODO: maybe addressing from sp instead of fp3437 // TODO: maybe addressing from sp instead of fp
3435 const elem_ty = ty.childType();3438 const imm12 = math.cast(u12, off) catch
3436 const abi_size = elem_ty.abiSize(self.target.*);
3437 const adj_off = unadjusted_off + abi_size;
3438
3439 const imm12 = math.cast(u12, adj_off) catch
3440 return self.fail("TODO larger stack offsets", .{});3439 return self.fail("TODO larger stack offsets", .{});
34413440
3442 _ = try self.addInst(.{3441 _ = try self.addInst(.{
...@@ -3526,9 +3525,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -3526,9 +3525,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
3526 try self.genSetReg(ty, reg, .{ .immediate = addr });3525 try self.genSetReg(ty, reg, .{ .immediate = addr });
3527 try self.genLdrRegister(reg, reg, ty.abiSize(self.target.*));3526 try self.genLdrRegister(reg, reg, ty.abiSize(self.target.*));
3528 },3527 },
3529 .stack_offset => |unadjusted_off| {3528 .stack_offset => |off| {
3530 const abi_size = ty.abiSize(self.target.*);3529 const abi_size = ty.abiSize(self.target.*);
3531 const adj_off = unadjusted_off + abi_size;
35323530
3533 switch (abi_size) {3531 switch (abi_size) {
3534 1, 2, 4, 8 => {3532 1, 2, 4, 8 => {
...@@ -3548,7 +3546,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -3548,7 +3546,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
3548 .tag = tag,3546 .tag = tag,
3549 .data = .{ .load_store_stack = .{3547 .data = .{ .load_store_stack = .{
3550 .rt = rt,3548 .rt = rt,
3551 .offset = @intCast(u32, adj_off),3549 .offset = @intCast(u32, off),
3552 } },3550 } },
3553 });3551 });
3554 },3552 },
...@@ -3583,8 +3581,8 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {...@@ -3583,8 +3581,8 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
3583 const ptr_bytes = @divExact(ptr_bits, 8);3581 const ptr_bytes = @divExact(ptr_bits, 8);
35843582
3585 const stack_offset = try self.allocMem(inst, ptr_bytes * 2, ptr_bytes * 2);3583 const stack_offset = try self.allocMem(inst, ptr_bytes * 2, ptr_bytes * 2);
3586 try self.genSetStack(ptr_ty, stack_offset + ptr_bytes, ptr);3584 try self.genSetStack(ptr_ty, stack_offset, ptr);
3587 try self.genSetStack(Type.initTag(.usize), stack_offset, .{ .immediate = array_len });3585 try self.genSetStack(Type.initTag(.usize), stack_offset - ptr_bytes, .{ .immediate = array_len });
3588 break :result MCValue{ .stack_offset = stack_offset };3586 break :result MCValue{ .stack_offset = stack_offset };
3589 };3587 };
3590 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });3588 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });