authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-10 13:01:23+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-11 10:52:13+01:00
log08e2f5d08390d41b58c92707693385e5e2968fc8
tree54547ecfb53ce4817174e6db467cc17ce4d10efe
parentf0400ad93eac984332c938b39e9c1627062d6b6a

codegen: handle lowering of const slice pointers


2 files changed, 71 insertions(+), 17 deletions(-)

src/arch/x86_64/CodeGen.zig+71-16
......@@ -3514,8 +3514,14 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE
35143514 else => return self.fail("TODO implement args on stack for {} with abi size > 8", .{mcv}),
35153515 }
35163516 },
3517 .embedded_in_code => {
3518 if (abi_size <= 8) {
3519 const reg = try self.copyToTmpRegister(ty, mcv);
3520 return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg });
3521 }
3522 return self.fail("TODO implement args on stack for {} with abi size > 8", .{mcv});
3523 },
35173524 .memory,
3518 .embedded_in_code,
35193525 .direct_load,
35203526 .got_load,
35213527 => {
......@@ -3523,7 +3529,58 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE
35233529 const reg = try self.copyToTmpRegister(ty, mcv);
35243530 return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg });
35253531 }
3526 return self.fail("TODO implement memcpy for setting args on stack from {}", .{mcv});
3532
3533 self.register_manager.freezeRegs(&.{ .rax, .rcx });
3534 defer self.register_manager.unfreezeRegs(&.{ .rax, .rcx });
3535
3536 const addr_reg: Register = blk: {
3537 switch (mcv) {
3538 .got_load,
3539 .direct_load,
3540 => |sym_index| {
3541 const flags: u2 = switch (mcv) {
3542 .got_load => 0b00,
3543 .direct_load => 0b01,
3544 else => unreachable,
3545 };
3546 const addr_reg = try self.register_manager.allocReg(null);
3547 _ = try self.addInst(.{
3548 .tag = .lea_pie,
3549 .ops = (Mir.Ops{
3550 .reg1 = addr_reg.to64(),
3551 .flags = flags,
3552 }).encode(),
3553 .data = .{ .linker_sym_index = sym_index },
3554 });
3555 break :blk addr_reg;
3556 },
3557 .memory => |addr| {
3558 const addr_reg = try self.copyToTmpRegister(Type.usize, .{ .immediate = addr });
3559 break :blk addr_reg;
3560 },
3561 else => unreachable,
3562 }
3563 };
3564
3565 self.register_manager.freezeRegs(&.{addr_reg});
3566 defer self.register_manager.unfreezeRegs(&.{addr_reg});
3567
3568 const regs = try self.register_manager.allocRegs(2, .{ null, null });
3569 const count_reg = regs[0];
3570 const tmp_reg = regs[1];
3571
3572 try self.register_manager.getReg(.rax, null);
3573 try self.register_manager.getReg(.rcx, null);
3574
3575 // TODO allow for abi_size to be u64
3576 try self.genSetReg(Type.u32, count_reg, .{ .immediate = @intCast(u32, abi_size) });
3577 try self.genInlineMemcpy(
3578 -(stack_offset + @intCast(i32, abi_size)),
3579 .rsp,
3580 addr_reg.to64(),
3581 count_reg.to64(),
3582 tmp_reg.to8(),
3583 );
35273584 },
35283585 .register => |reg| {
35293586 _ = try self.addInst(.{
......@@ -4488,6 +4545,7 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCVa
44884545}
44894546
44904547fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue {
4548 log.debug("lowerUnnamedConst: ty = {}, val = {}", .{ tv.ty, tv.val });
44914549 const local_sym_index = self.bin_file.lowerUnnamedConst(tv, self.mod_fn.owner_decl) catch |err| {
44924550 return self.fail("lowering unnamed constant failed: {s}", .{@errorName(err)});
44934551 };
......@@ -4520,23 +4578,20 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
45204578 switch (typed_value.ty.zigTypeTag()) {
45214579 .Pointer => switch (typed_value.ty.ptrSize()) {
45224580 .Slice => {
4523 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
4524 const ptr_type = typed_value.ty.slicePtrFieldType(&buf);
4525 const ptr_mcv = try self.genTypedValue(.{ .ty = ptr_type, .val = typed_value.val });
4526 const slice_len = typed_value.val.sliceLen();
4527 // Codegen can't handle some kinds of indirection. If the wrong union field is accessed here it may mean
4528 // the Sema code needs to use anonymous Decls or alloca instructions to store data.
4529 const ptr_imm = ptr_mcv.memory;
4530 _ = slice_len;
4531 _ = ptr_imm;
4532 // We need more general support for const data being stored in memory to make this work.
4533 return self.fail("TODO codegen for const slices", .{});
4581 return self.lowerUnnamedConst(typed_value);
45344582 },
45354583 else => {
4536 if (typed_value.val.tag() == .int_u64) {
4537 return MCValue{ .immediate = typed_value.val.toUnsignedInt() };
4584 switch (typed_value.val.tag()) {
4585 .int_u64 => {
4586 return MCValue{ .immediate = typed_value.val.toUnsignedInt() };
4587 },
4588 .slice => {
4589 return self.lowerUnnamedConst(typed_value);
4590 },
4591 else => {
4592 return self.fail("TODO codegen more kinds of const pointers: {}", .{typed_value.val.tag()});
4593 },
45384594 }
4539 return self.fail("TODO codegen more kinds of const pointers: {}", .{typed_value.val.tag()});
45404595 },
45414596 },
45424597 .Int => {
src/codegen.zig-1
......@@ -230,7 +230,6 @@ pub fn generateSymbol(
230230 return lowerDeclRef(bin_file, src_loc, typed_value, decl, code, debug_output);
231231 },
232232 .slice => {
233 // TODO populate .debug_info for the slice
234233 const slice = typed_value.val.castTag(.slice).?.data;
235234
236235 // generate ptr