authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-03-22 13:24:42+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-22 20:16:05-07:00
loga4e8294c91d21e6c574bbae94e064935d90e8e95
tree2070feeb07e23e754a3b35b18b611767e12326a4
parent6ac04d8fd7d63dfd4aa611e1564f1d4768baf408

stage2 ARM: change semantics of MCValue.stack_argument_offset

MCValue.stack_argument_offset now has the same semantics as MCValue.stack_offset

1 files changed, 21 insertions(+), 32 deletions(-)

src/arch/arm/CodeGen.zig+21-32
...@@ -1348,7 +1348,7 @@ fn slicePtr(self: *Self, mcv: MCValue) !MCValue {...@@ -1348,7 +1348,7 @@ fn slicePtr(self: *Self, mcv: MCValue) !MCValue {
1348 .dead, .unreach => unreachable,1348 .dead, .unreach => unreachable,
1349 .register => unreachable, // a slice doesn't fit in one register1349 .register => unreachable, // a slice doesn't fit in one register
1350 .stack_argument_offset => |off| {1350 .stack_argument_offset => |off| {
1351 return MCValue{ .stack_argument_offset = off + 4 };1351 return MCValue{ .stack_argument_offset = off };
1352 },1352 },
1353 .stack_offset => |off| {1353 .stack_offset => |off| {
1354 return MCValue{ .stack_offset = off };1354 return MCValue{ .stack_offset = off };
...@@ -1377,7 +1377,7 @@ fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void {...@@ -1377,7 +1377,7 @@ fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void {
1377 .dead, .unreach => unreachable,1377 .dead, .unreach => unreachable,
1378 .register => unreachable, // a slice doesn't fit in one register1378 .register => unreachable, // a slice doesn't fit in one register
1379 .stack_argument_offset => |off| {1379 .stack_argument_offset => |off| {
1380 break :result MCValue{ .stack_argument_offset = off };1380 break :result MCValue{ .stack_argument_offset = off - 4 };
1381 },1381 },
1382 .stack_offset => |off| {1382 .stack_offset => |off| {
1383 break :result MCValue{ .stack_offset = off - 4 };1383 break :result MCValue{ .stack_offset = off - 4 };
...@@ -1782,14 +1782,12 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type...@@ -1782,14 +1782,12 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
1782 try self.genSetReg(ptr_ty, src_reg, .{ .ptr_stack_offset = off });1782 try self.genSetReg(ptr_ty, src_reg, .{ .ptr_stack_offset = off });
1783 },1783 },
1784 .memory => |addr| try self.genSetReg(Type.usize, src_reg, .{ .immediate = @intCast(u32, addr) }),1784 .memory => |addr| try self.genSetReg(Type.usize, src_reg, .{ .immediate = @intCast(u32, addr) }),
1785 .stack_argument_offset => |unadjusted_off| {1785 .stack_argument_offset => |off| {
1786 const adj_off = unadjusted_off + elem_size;
1787
1788 _ = try self.addInst(.{1786 _ = try self.addInst(.{
1789 .tag = .ldr_ptr_stack_argument,1787 .tag = .ldr_ptr_stack_argument,
1790 .data = .{ .r_stack_offset = .{1788 .data = .{ .r_stack_offset = .{
1791 .rt = src_reg,1789 .rt = src_reg,
1792 .stack_offset = adj_off,1790 .stack_offset = off,
1793 } },1791 } },
1794 });1792 });
1795 },1793 },
...@@ -1884,22 +1882,18 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -1884,22 +1882,18 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
1884 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {1882 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
1885 const mcv = try self.resolveInst(operand);1883 const mcv = try self.resolveInst(operand);
1886 const struct_ty = self.air.typeOf(operand);1884 const struct_ty = self.air.typeOf(operand);
1887 const struct_size = @intCast(u32, struct_ty.abiSize(self.target.*));
1888 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, self.target.*));1885 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, self.target.*));
1889 const struct_field_ty = struct_ty.structFieldType(index);
1890 const struct_field_size = @intCast(u32, struct_field_ty.abiSize(self.target.*));
1891 const adjusted_field_offset = struct_size - struct_field_offset - struct_field_size;
18921886
1893 switch (mcv) {1887 switch (mcv) {
1894 .dead, .unreach => unreachable,1888 .dead, .unreach => unreachable,
1895 .stack_argument_offset => |off| {1889 .stack_argument_offset => |off| {
1896 break :result MCValue{ .stack_argument_offset = off + adjusted_field_offset };1890 break :result MCValue{ .stack_argument_offset = off - struct_field_offset };
1897 },1891 },
1898 .stack_offset => |off| {1892 .stack_offset => |off| {
1899 break :result MCValue{ .stack_offset = off - struct_field_offset };1893 break :result MCValue{ .stack_offset = off - struct_field_offset };
1900 },1894 },
1901 .memory => |addr| {1895 .memory => |addr| {
1902 break :result MCValue{ .memory = addr + adjusted_field_offset };1896 break :result MCValue{ .memory = addr + struct_field_offset };
1903 },1897 },
1904 else => return self.fail("TODO implement codegen struct_field_val for {}", .{mcv}),1898 else => return self.fail("TODO implement codegen struct_field_val for {}", .{mcv}),
1905 }1899 }
...@@ -3683,14 +3677,12 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro...@@ -3683,14 +3677,12 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
3683 try self.genSetReg(ptr_ty, src_reg, .{ .ptr_stack_offset = off });3677 try self.genSetReg(ptr_ty, src_reg, .{ .ptr_stack_offset = off });
3684 },3678 },
3685 .memory => |addr| try self.genSetReg(ptr_ty, src_reg, .{ .immediate = @intCast(u32, addr) }),3679 .memory => |addr| try self.genSetReg(ptr_ty, src_reg, .{ .immediate = @intCast(u32, addr) }),
3686 .stack_argument_offset => |unadjusted_off| {3680 .stack_argument_offset => |off| {
3687 const adj_off = unadjusted_off + abi_size;
3688
3689 _ = try self.addInst(.{3681 _ = try self.addInst(.{
3690 .tag = .ldr_ptr_stack_argument,3682 .tag = .ldr_ptr_stack_argument,
3691 .data = .{ .r_stack_offset = .{3683 .data = .{ .r_stack_offset = .{
3692 .rt = src_reg,3684 .rt = src_reg,
3693 .stack_offset = adj_off,3685 .stack_offset = off,
3694 } },3686 } },
3695 });3687 });
3696 },3688 },
...@@ -3948,9 +3940,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -3948,9 +3940,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
3948 });3940 });
3949 }3941 }
3950 },3942 },
3951 .stack_argument_offset => |unadjusted_off| {3943 .stack_argument_offset => |off| {
3952 const abi_size = ty.abiSize(self.target.*);3944 const abi_size = ty.abiSize(self.target.*);
3953 const adj_off = unadjusted_off + abi_size;
39543945
3955 const tag: Mir.Inst.Tag = switch (abi_size) {3946 const tag: Mir.Inst.Tag = switch (abi_size) {
3956 1 => if (ty.isSignedInt()) Mir.Inst.Tag.ldrsb_stack_argument else .ldrb_stack_argument,3947 1 => if (ty.isSignedInt()) Mir.Inst.Tag.ldrsb_stack_argument else .ldrb_stack_argument,
...@@ -3963,7 +3954,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -3963,7 +3954,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
3963 .tag = tag,3954 .tag = tag,
3964 .data = .{ .r_stack_offset = .{3955 .data = .{ .r_stack_offset = .{
3965 .rt = reg,3956 .rt = reg,
3966 .stack_offset = @intCast(u32, adj_off),3957 .stack_offset = off,
3967 } },3958 } },
3968 });3959 });
3969 },3960 },
...@@ -3979,7 +3970,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I...@@ -3979,7 +3970,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I
3979 if (!self.wantSafety())3970 if (!self.wantSafety())
3980 return; // The already existing value will do just fine.3971 return; // The already existing value will do just fine.
3981 // TODO Upgrade this to a memset call when we have that available.3972 // TODO Upgrade this to a memset call when we have that available.
3982 switch (ty.abiSize(self.target.*)) {3973 switch (abi_size) {
3983 1 => return self.genSetStackArgument(ty, stack_offset, .{ .immediate = 0xaa }),3974 1 => return self.genSetStackArgument(ty, stack_offset, .{ .immediate = 0xaa }),
3984 2 => return self.genSetStackArgument(ty, stack_offset, .{ .immediate = 0xaaaa }),3975 2 => return self.genSetStackArgument(ty, stack_offset, .{ .immediate = 0xaaaa }),
3985 4 => return self.genSetStackArgument(ty, stack_offset, .{ .immediate = 0xaaaaaaaa }),3976 4 => return self.genSetStackArgument(ty, stack_offset, .{ .immediate = 0xaaaaaaaa }),
...@@ -3987,13 +3978,11 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I...@@ -3987,13 +3978,11 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I
3987 }3978 }
3988 },3979 },
3989 .register => |reg| {3980 .register => |reg| {
3990 const adj_off = stack_offset - abi_size;
3991
3992 switch (abi_size) {3981 switch (abi_size) {
3993 1, 4 => {3982 1, 4 => {
3994 const offset = if (math.cast(u12, adj_off)) |imm| blk: {3983 const offset = if (math.cast(u12, stack_offset)) |imm| blk: {
3995 break :blk Instruction.Offset.imm(imm);3984 break :blk Instruction.Offset.imm(imm);
3996 } else |_| Instruction.Offset.reg(try self.copyToTmpRegister(Type.initTag(.u32), MCValue{ .immediate = adj_off }), .none);3985 } else |_| Instruction.Offset.reg(try self.copyToTmpRegister(Type.initTag(.u32), MCValue{ .immediate = stack_offset }), .none);
39973986
3998 const tag: Mir.Inst.Tag = switch (abi_size) {3987 const tag: Mir.Inst.Tag = switch (abi_size) {
3999 1 => .strb,3988 1 => .strb,
...@@ -4011,9 +4000,9 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I...@@ -4011,9 +4000,9 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I
4011 });4000 });
4012 },4001 },
4013 2 => {4002 2 => {
4014 const offset = if (adj_off <= math.maxInt(u8)) blk: {4003 const offset = if (stack_offset <= math.maxInt(u8)) blk: {
4015 break :blk Instruction.ExtraLoadStoreOffset.imm(@intCast(u8, adj_off));4004 break :blk Instruction.ExtraLoadStoreOffset.imm(@intCast(u8, stack_offset));
4016 } else Instruction.ExtraLoadStoreOffset.reg(try self.copyToTmpRegister(Type.initTag(.u32), MCValue{ .immediate = adj_off }));4005 } else Instruction.ExtraLoadStoreOffset.reg(try self.copyToTmpRegister(Type.initTag(.u32), MCValue{ .immediate = stack_offset }));
40174006
4018 _ = try self.addInst(.{4007 _ = try self.addInst(.{
4019 .tag = .strh,4008 .tag = .strh,
...@@ -4060,8 +4049,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I...@@ -4060,8 +4049,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I
4060 }4049 }
40614050
4062 // add dst_reg, sp, #stack_offset4051 // add dst_reg, sp, #stack_offset
4063 const adj_dst_offset = stack_offset - abi_size;4052 const dst_offset_op: Instruction.Operand = if (Instruction.Operand.fromU32(stack_offset)) |x| x else {
4064 const dst_offset_op: Instruction.Operand = if (Instruction.Operand.fromU32(adj_dst_offset)) |x| x else {
4065 return self.fail("TODO load: set reg to stack offset with all possible offsets", .{});4053 return self.fail("TODO load: set reg to stack offset with all possible offsets", .{});
4066 };4054 };
4067 _ = try self.addInst(.{4055 _ = try self.addInst(.{
...@@ -4553,8 +4541,8 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {...@@ -4553,8 +4541,8 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
4553 if (ty.abiAlignment(self.target.*) == 8)4541 if (ty.abiAlignment(self.target.*) == 8)
4554 nsaa = std.mem.alignForwardGeneric(u32, nsaa, 8);4542 nsaa = std.mem.alignForwardGeneric(u32, nsaa, 8);
45554543
4556 result.args[i] = .{ .stack_argument_offset = nsaa };
4557 nsaa += param_size;4544 nsaa += param_size;
4545 result.args[i] = .{ .stack_argument_offset = nsaa };
4558 }4546 }
4559 }4547 }
45604548
...@@ -4583,9 +4571,10 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {...@@ -4583,9 +4571,10 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
45834571
4584 for (param_types) |ty, i| {4572 for (param_types) |ty, i| {
4585 if (ty.abiSize(self.target.*) > 0) {4573 if (ty.abiSize(self.target.*) > 0) {
4586 stack_offset = std.mem.alignForwardGeneric(u32, stack_offset, ty.abiAlignment(self.target.*));4574 const param_size = @intCast(u32, ty.abiSize(self.target.*));
4575
4576 stack_offset = std.mem.alignForwardGeneric(u32, stack_offset, ty.abiAlignment(self.target.*)) + param_size;
4587 result.args[i] = .{ .stack_argument_offset = stack_offset };4577 result.args[i] = .{ .stack_argument_offset = stack_offset };
4588 stack_offset += @intCast(u32, ty.abiSize(self.target.*));
4589 } else {4578 } else {
4590 result.args[i] = .{ .none = {} };4579 result.args[i] = .{ .none = {} };
4591 }4580 }