authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-01-04 18:57:25+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-01-06 09:54:33+01:00
logf4aa276a0c665633980ea49bccb29da9d02d2ae1
tree6a04dd73df6fb3e24fa37e88bd1a929c40919506
parentf01e6eec562e31445e940c5664c793ff443c35aa

stage2: fix inline memcpy


1 files changed, 63 insertions(+), 19 deletions(-)

src/arch/x86_64/CodeGen.zig+63-19
......@@ -1260,7 +1260,7 @@ fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void {
12601260 const dst_mcv: MCValue = blk: {
12611261 switch (operand) {
12621262 .stack_offset => |off| {
1263 break :blk MCValue{ .stack_offset = off };
1263 break :blk MCValue{ .stack_offset = off + 8 };
12641264 },
12651265 else => return self.fail("TODO implement slice_ptr for {}", .{operand}),
12661266 }
......@@ -1277,7 +1277,7 @@ fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void {
12771277 const dst_mcv: MCValue = blk: {
12781278 switch (operand) {
12791279 .stack_offset => |off| {
1280 break :blk MCValue{ .stack_offset = off + 8 };
1280 break :blk MCValue{ .stack_offset = off };
12811281 },
12821282 else => return self.fail("TODO implement slice_len for {}", .{operand}),
12831283 }
......@@ -1515,18 +1515,22 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo
15151515 .data = .{ .imm = 0 },
15161516 });
15171517 },
1518 .stack_offset => |unadjusted_off| {
1518 .stack_offset => |off| {
15191519 if (abi_size <= 8) {
15201520 const tmp_reg = try self.register_manager.allocReg(null, &.{reg});
15211521 try self.load(.{ .register = tmp_reg }, ptr, ptr_ty);
1522 return self.genSetStack(elem_ty, unadjusted_off, MCValue{ .register = tmp_reg });
1522 return self.genSetStack(elem_ty, off, MCValue{ .register = tmp_reg });
15231523 }
15241524
1525 const regs = try self.register_manager.allocRegs(2, .{ null, null }, &.{ reg, .rax, .rcx });
1525 const regs = try self.register_manager.allocRegs(
1526 3,
1527 .{ null, null, null },
1528 &.{ reg, .rax, .rcx },
1529 );
15261530 const addr_reg = regs[0];
15271531 const len_reg = regs[1];
1532 const tmp_reg = regs[2];
15281533
1529 const off = unadjusted_off + abi_size;
15301534 _ = try self.addInst(.{
15311535 .tag = .mov,
15321536 .ops = (Mir.Ops{
......@@ -1536,13 +1540,17 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo
15361540 .data = undefined,
15371541 });
15381542
1543 try self.register_manager.getReg(.rax, null);
1544 try self.register_manager.getReg(.rcx, null);
1545
15391546 // TODO allow for abi size to be u64
15401547 try self.genSetReg(Type.initTag(.u32), len_reg, .{ .immediate = @intCast(u32, abi_size) });
15411548
15421549 return self.genInlineMemcpy(
1543 -@intCast(i32, off),
1550 -@intCast(i32, off + abi_size),
15441551 registerAlias(addr_reg, @divExact(reg.size(), 8)),
15451552 len_reg.to64(),
1553 tmp_reg.to8(),
15461554 );
15471555 },
15481556 else => return self.fail("TODO implement loading from register into {}", .{dst_mcv}),
......@@ -2148,6 +2156,14 @@ fn airCall(self: *Self, inst: Air.Inst.Index) !void {
21482156 assert(ty.zigTypeTag() == .Pointer);
21492157 const mcv = try self.resolveInst(callee);
21502158 try self.genSetReg(Type.initTag(.usize), .rax, mcv);
2159 _ = try self.addInst(.{
2160 .tag = .call,
2161 .ops = (Mir.Ops{
2162 .reg1 = .rax,
2163 .flags = 0b01,
2164 }).encode(),
2165 .data = undefined,
2166 });
21512167 }
21522168 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
21532169 for (info.args) |mc_arg, arg_i| {
......@@ -2217,6 +2233,14 @@ fn airCall(self: *Self, inst: Air.Inst.Index) !void {
22172233 assert(ty.zigTypeTag() == .Pointer);
22182234 const mcv = try self.resolveInst(callee);
22192235 try self.genSetReg(Type.initTag(.usize), .rax, mcv);
2236 _ = try self.addInst(.{
2237 .tag = .call,
2238 .ops = (Mir.Ops{
2239 .reg1 = .rax,
2240 .flags = 0b01,
2241 }).encode(),
2242 .data = undefined,
2243 });
22202244 }
22212245 } else if (self.bin_file.cast(link.File.Plan9)) |p9| {
22222246 for (info.args) |mc_arg, arg_i| {
......@@ -2269,7 +2293,17 @@ fn airCall(self: *Self, inst: Air.Inst.Index) !void {
22692293 });
22702294 } else return self.fail("TODO implement calling extern fn on plan9", .{});
22712295 } else {
2272 return self.fail("TODO implement calling runtime known function pointer", .{});
2296 assert(ty.zigTypeTag() == .Pointer);
2297 const mcv = try self.resolveInst(callee);
2298 try self.genSetReg(Type.initTag(.usize), .rax, mcv);
2299 _ = try self.addInst(.{
2300 .tag = .call,
2301 .ops = (Mir.Ops{
2302 .reg1 = .rax,
2303 .flags = 0b01,
2304 }).encode(),
2305 .data = undefined,
2306 });
22732307 }
22742308 } else unreachable;
22752309
......@@ -3118,8 +3152,8 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
31183152 }
31193153 return self.fail("TODO implement memcpy for setting stack from {}", .{mcv});
31203154 },
3121 .stack_offset => |unadjusted_off| {
3122 if (stack_offset == unadjusted_off) {
3155 .stack_offset => |off| {
3156 if (stack_offset == off) {
31233157 // Copy stack variable to itself; nothing to do.
31243158 return;
31253159 }
......@@ -3130,33 +3164,43 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
31303164 return self.genSetStack(ty, stack_offset, MCValue{ .register = reg });
31313165 }
31323166
3133 const regs = try self.register_manager.allocRegs(2, .{ null, null }, &.{ .rax, .rcx });
3167 const regs = try self.register_manager.allocRegs(3, .{ null, null, null }, &.{ .rax, .rcx });
31343168 const addr_reg = regs[0];
31353169 const len_reg = regs[1];
3170 const tmp_reg = regs[2];
3171
3172 try self.register_manager.getReg(.rax, null);
3173 try self.register_manager.getReg(.rcx, null);
31363174
3137 const off = unadjusted_off + abi_size;
31383175 _ = try self.addInst(.{
31393176 .tag = .lea,
31403177 .ops = (Mir.Ops{
31413178 .reg1 = addr_reg.to64(),
31423179 .reg2 = .rbp,
31433180 }).encode(),
3144 .data = .{ .imm = -@intCast(i32, off) },
3181 .data = .{ .imm = -@intCast(i32, off + abi_size) },
31453182 });
31463183
31473184 // TODO allow for abi_size to be u64
31483185 try self.genSetReg(Type.initTag(.u32), len_reg, .{ .immediate = @intCast(u32, abi_size) });
31493186
3150 return self.genInlineMemcpy(-@intCast(i32, off), addr_reg.to64(), len_reg.to64());
3187 return self.genInlineMemcpy(
3188 -@intCast(i32, stack_offset + abi_size),
3189 addr_reg.to64(),
3190 len_reg.to64(),
3191 tmp_reg.to8(),
3192 );
31513193 },
31523194 }
31533195}
31543196
3155fn genInlineMemcpy(self: *Self, stack_offset: i32, addr_reg: Register, len_reg: Register) InnerError!void {
3156 try self.register_manager.getReg(.rax, null);
3157 try self.register_manager.getReg(.rcx, null);
3158 const tmp_reg = try self.register_manager.allocReg(null, &.{ addr_reg, len_reg, .rax, .rcx });
3159
3197fn genInlineMemcpy(
3198 self: *Self,
3199 stack_offset: i32,
3200 addr_reg: Register,
3201 len_reg: Register,
3202 tmp_reg: Register,
3203) InnerError!void {
31603204 // mov rcx, 0
31613205 _ = try self.addInst(.{
31623206 .tag = .mov,