authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-07-29 02:28:35-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-07-29 02:29:37-07:00
log8899e6e334758f2e101399075d0456195035c372
tree5ae6f6dd8afba7cacd3d5b1532d4c25b3661189d
parent606f157a6b6001b2623d28275a892c1a8ee3a646

stage2: codegen: fix off-by-one stack variable offsets


1 files changed, 14 insertions(+), 8 deletions(-)

src-self-hosted/codegen.zig+14-8
......@@ -1346,11 +1346,13 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
13461346 return self.fail(src, "TODO implement set stack variable with compare flags value (signed)", .{});
13471347 },
13481348 .immediate => |x_big| {
1349 if (stack_offset > 128) {
1349 const abi_size = ty.abiSize(self.target.*);
1350 const adj_off = stack_offset + abi_size;
1351 if (adj_off > 128) {
13501352 return self.fail(src, "TODO implement set stack variable with large stack offset", .{});
13511353 }
13521354 try self.code.ensureCapacity(self.code.items.len + 8);
1353 switch (ty.abiSize(self.target.*)) {
1355 switch (abi_size) {
13541356 1 => {
13551357 return self.fail(src, "TODO implement set abi_size=1 stack variable with immediate", .{});
13561358 },
......@@ -1361,7 +1363,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
13611363 const x = @intCast(u32, x_big);
13621364 // We have a positive stack offset value but we want a twos complement negative
13631365 // offset from rbp, which is at the top of the stack frame.
1364 const negative_offset = @intCast(i8, -@intCast(i32, stack_offset));
1366 const negative_offset = @intCast(i8, -@intCast(i32, adj_off));
13651367 const twos_comp = @bitCast(u8, negative_offset);
13661368 // mov DWORD PTR [rbp+offset], immediate
13671369 self.code.appendSliceAssumeCapacity(&[_]u8{ 0xc7, 0x45, twos_comp });
......@@ -1382,19 +1384,21 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
13821384 return self.fail(src, "TODO implement set stack variable from embedded_in_code", .{});
13831385 },
13841386 .register => |reg| {
1387 const abi_size = ty.abiSize(self.target.*);
1388 const adj_off = stack_offset + abi_size;
13851389 try self.code.ensureCapacity(self.code.items.len + 7);
13861390 self.rex(.{ .w = reg.size() == 64, .b = reg.isExtended() });
13871391 const reg_id: u8 = @truncate(u3, reg.id());
1388 if (stack_offset <= 128) {
1392 if (adj_off <= 128) {
13891393 // example: 48 89 55 7f mov QWORD PTR [rbp+0x7f],rdx
13901394 const RM = @as(u8, 0b01_000_101) | (reg_id << 3);
1391 const negative_offset = @intCast(i8, -@intCast(i32, stack_offset));
1395 const negative_offset = @intCast(i8, -@intCast(i32, adj_off));
13921396 const twos_comp = @bitCast(u8, negative_offset);
13931397 self.code.appendSliceAssumeCapacity(&[_]u8{ 0x89, RM, twos_comp });
1394 } else if (stack_offset <= 2147483648) {
1398 } else if (adj_off <= 2147483648) {
13951399 // example: 48 89 95 80 00 00 00 mov QWORD PTR [rbp+0x80],rdx
13961400 const RM = @as(u8, 0b10_000_101) | (reg_id << 3);
1397 const negative_offset = @intCast(i32, -@intCast(i33, stack_offset));
1401 const negative_offset = @intCast(i32, -@intCast(i33, adj_off));
13981402 const twos_comp = @bitCast(u32, negative_offset);
13991403 self.code.appendSliceAssumeCapacity(&[_]u8{ 0x89, RM });
14001404 mem.writeIntLittle(u32, self.code.addManyAsArrayAssumeCapacity(4), twos_comp);
......@@ -1605,8 +1609,10 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
16051609 }
16061610 }
16071611 },
1608 .stack_offset => |off| {
1612 .stack_offset => |unadjusted_off| {
16091613 try self.code.ensureCapacity(self.code.items.len + 7);
1614 const size_bytes = @divExact(reg.size(), 8);
1615 const off = unadjusted_off + size_bytes;
16101616 self.rex(.{ .w = reg.size() == 64, .r = reg.isExtended() });
16111617 const reg_id: u8 = @truncate(u3, reg.id());
16121618 if (off <= 128) {