authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-07-28 19:11:23-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-07-29 02:29:37-07:00
logcb3e8e323dc6846e16e868fcfb4d4bf135f56f48
tree82dcb617c21d5b84b21c146331f5ace397f41d0f
parent5ccee4c986aa9ed73d3deab3145f43689aa58ee4

stage2: x86_64 codegen for movs to/from stack variables


1 files changed, 41 insertions(+), 2 deletions(-)

src-self-hosted/codegen.zig+41-2
...@@ -1271,7 +1271,25 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -1271,7 +1271,25 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
1271 return self.fail(src, "TODO implement set stack variable from embedded_in_code", .{});1271 return self.fail(src, "TODO implement set stack variable from embedded_in_code", .{});
1272 },1272 },
1273 .register => |reg| {1273 .register => |reg| {
1274 return self.fail(src, "TODO implement set stack variable from register", .{});1274 try self.code.ensureCapacity(self.code.items.len + 7);
1275 self.rex(.{ .w = reg.size() == 64, .b = reg.isExtended() });
1276 const reg_id: u8 = @truncate(u3, reg.id());
1277 if (stack_offset <= 128) {
1278 // example: 48 89 55 7f mov QWORD PTR [rbp+0x7f],rdx
1279 const RM = @as(u8, 0b01_101_000) | reg_id;
1280 const negative_offset = @intCast(i8, -@intCast(i32, stack_offset));
1281 const twos_comp = @bitCast(u8, negative_offset);
1282 self.code.appendSliceAssumeCapacity(&[_]u8{ 0x89, RM, twos_comp });
1283 } else if (stack_offset <= 2147483648) {
1284 // example: 48 89 95 80 00 00 00 mov QWORD PTR [rbp+0x80],rdx
1285 const RM = @as(u8, 0b10_101_000) | reg_id;
1286 const negative_offset = @intCast(i32, -@intCast(i33, stack_offset));
1287 const twos_comp = @bitCast(u32, negative_offset);
1288 self.code.appendSliceAssumeCapacity(&[_]u8{ 0x89, RM });
1289 mem.writeIntLittle(u32, self.code.addManyAsArrayAssumeCapacity(4), twos_comp);
1290 } else {
1291 return self.fail(src, "stack offset too large", .{});
1292 }
1275 },1293 },
1276 .memory => |vaddr| {1294 .memory => |vaddr| {
1277 return self.fail(src, "TODO implement set stack variable from memory vaddr", .{});1295 return self.fail(src, "TODO implement set stack variable from memory vaddr", .{});
...@@ -1475,7 +1493,28 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -1475,7 +1493,28 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
1475 }1493 }
1476 },1494 },
1477 .stack_offset => |off| {1495 .stack_offset => |off| {
1478 return self.fail(src, "TODO implement genSetReg for stack variables", .{});1496 if (reg.size() != 64) {
1497 return self.fail(src, "TODO decide whether to implement non-64-bit loads", .{});
1498 }
1499 try self.code.ensureCapacity(self.code.items.len + 7);
1500 self.rex(.{ .w = true, .r = reg.isExtended() });
1501 const reg_id: u8 = @truncate(u3, reg.id());
1502 if (off <= 128) {
1503 // Example: 48 8b 4d 7f mov rcx,QWORD PTR [rbp+0x7f]
1504 const RM = @as(u8, 0b01_000_101) | (reg_id << 3);
1505 const negative_offset = @intCast(i8, -@intCast(i32, off));
1506 const twos_comp = @bitCast(u8, negative_offset);
1507 self.code.appendSliceAssumeCapacity(&[_]u8{ 0x8b, RM, twos_comp });
1508 } else if (off <= 2147483648) {
1509 // Example: 48 8b 8d 80 00 00 00 mov rcx,QWORD PTR [rbp+0x80]
1510 const RM = @as(u8, 0b10_000_101) | (reg_id << 3);
1511 const negative_offset = @intCast(i32, -@intCast(i33, off));
1512 const twos_comp = @bitCast(u32, negative_offset);
1513 self.code.appendSliceAssumeCapacity(&[_]u8{ 0x8b, RM });
1514 mem.writeIntLittle(u32, self.code.addManyAsArrayAssumeCapacity(4), twos_comp);
1515 } else {
1516 return self.fail(src, "stack offset too large", .{});
1517 }
1479 },1518 },
1480 },1519 },
1481 else => return self.fail(src, "TODO implement getSetReg for {}", .{self.target.cpu.arch}),1520 else => return self.fail(src, "TODO implement getSetReg for {}", .{self.target.cpu.arch}),