authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-07 16:02:43+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-07 20:13:29+01:00
logbbd7969c87e03c9312eeafd9940ef8287a3ad689
tree293c89a8c76f0df820dc86a79102bc8ebbb58d7a
parent0a7801236cf3601ff20b3c1c16cd27c1d089157e

stage2,x64: implement genSetStack for memory operand


1 files changed, 38 insertions(+), 5 deletions(-)

src/arch/x86_64/CodeGen.zig+38-5
...@@ -3487,6 +3487,7 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE...@@ -3487,6 +3487,7 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE
3487}3487}
34883488
3489fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerError!void {3489fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerError!void {
3490 const abi_size = ty.abiSize(self.target.*);
3490 switch (mcv) {3491 switch (mcv) {
3491 .dead => unreachable,3492 .dead => unreachable,
3492 .ptr_embedded_in_code => unreachable,3493 .ptr_embedded_in_code => unreachable,
...@@ -3510,7 +3511,6 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerErro...@@ -3510,7 +3511,6 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerErro
3510 return self.genSetStack(ty, stack_offset, .{ .register = reg });3511 return self.genSetStack(ty, stack_offset, .{ .register = reg });
3511 },3512 },
3512 .immediate => |x_big| {3513 .immediate => |x_big| {
3513 const abi_size = ty.abiSize(self.target.*);
3514 const adj_off = stack_offset + @intCast(i32, abi_size);3514 const adj_off = stack_offset + @intCast(i32, abi_size);
3515 if (adj_off > 128) {3515 if (adj_off > 128) {
3516 return self.fail("TODO implement set stack variable with large stack offset", .{});3516 return self.fail("TODO implement set stack variable with large stack offset", .{});
...@@ -3583,7 +3583,6 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerErro...@@ -3583,7 +3583,6 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerErro
3583 if (stack_offset > math.maxInt(i32)) {3583 if (stack_offset > math.maxInt(i32)) {
3584 return self.fail("stack offset too large", .{});3584 return self.fail("stack offset too large", .{});
3585 }3585 }
3586 const abi_size = ty.abiSize(self.target.*);
3587 const adj_off = stack_offset + @intCast(i32, abi_size);3586 const adj_off = stack_offset + @intCast(i32, abi_size);
3588 _ = try self.addInst(.{3587 _ = try self.addInst(.{
3589 .tag = .mov,3588 .tag = .mov,
...@@ -3600,11 +3599,46 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerErro...@@ -3600,11 +3599,46 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerErro
3600 .got_load,3599 .got_load,
3601 .direct_load,3600 .direct_load,
3602 => {3601 => {
3603 if (ty.abiSize(self.target.*) <= 8) {3602 if (abi_size <= 8) {
3604 const reg = try self.copyToTmpRegister(ty, mcv);3603 const reg = try self.copyToTmpRegister(ty, mcv);
3605 return self.genSetStack(ty, stack_offset, MCValue{ .register = reg });3604 return self.genSetStack(ty, stack_offset, MCValue{ .register = reg });
3606 }3605 }
3607 return self.fail("TODO implement memcpy for setting stack from {}", .{mcv});3606
3607 try self.register_manager.getReg(.rax, null);
3608 try self.register_manager.getReg(.rcx, null);
3609
3610 self.register_manager.freezeRegs(&.{ .rax, .rcx, .rbp });
3611 defer self.register_manager.unfreezeRegs(&.{ .rax, .rcx, .rbp });
3612
3613 const addr_reg: Register = blk: {
3614 switch (mcv) {
3615 .memory => |addr| {
3616 const reg = try self.copyToTmpRegister(Type.usize, .{ .immediate = addr });
3617 break :blk reg;
3618 },
3619 else => {
3620 return self.fail("TODO implement memcpy for setting stack from {}", .{mcv});
3621 },
3622 }
3623 };
3624
3625 self.register_manager.freezeRegs(&.{addr_reg});
3626 defer self.register_manager.unfreezeRegs(&.{addr_reg});
3627
3628 const regs = try self.register_manager.allocRegs(2, .{ null, null });
3629 const count_reg = regs[0];
3630 const tmp_reg = regs[1];
3631
3632 // TODO allow for abi_size to be u64
3633 try self.genSetReg(Type.u32, count_reg, .{ .immediate = @intCast(u32, abi_size) });
3634
3635 return self.genInlineMemcpy(
3636 -(stack_offset + @intCast(i32, abi_size)),
3637 .rbp,
3638 addr_reg.to64(),
3639 count_reg.to64(),
3640 tmp_reg.to8(),
3641 );
3608 },3642 },
3609 .ptr_stack_offset => {3643 .ptr_stack_offset => {
3610 const reg = try self.copyToTmpRegister(ty, mcv);3644 const reg = try self.copyToTmpRegister(ty, mcv);
...@@ -3616,7 +3650,6 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerErro...@@ -3616,7 +3650,6 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerErro
3616 return;3650 return;
3617 }3651 }
36183652
3619 const abi_size = ty.abiSize(self.target.*);
3620 if (abi_size <= 8) {3653 if (abi_size <= 8) {
3621 const reg = try self.copyToTmpRegister(ty, mcv);3654 const reg = try self.copyToTmpRegister(ty, mcv);
3622 return self.genSetStack(ty, stack_offset, MCValue{ .register = reg });3655 return self.genSetStack(ty, stack_offset, MCValue{ .register = reg });