| ... | ... | @@ -3487,6 +3487,7 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE |
| 3487 | 3487 | } |
| 3488 | 3488 | |
| 3489 | 3489 | fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerError!void { |
| 3490 | const abi_size = ty.abiSize(self.target.*); |
| 3490 | 3491 | switch (mcv) { |
| 3491 | 3492 | .dead => unreachable, |
| 3492 | 3493 | .ptr_embedded_in_code => unreachable, |
| ... | ... | @@ -3510,7 +3511,6 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerErro |
| 3510 | 3511 | return self.genSetStack(ty, stack_offset, .{ .register = reg }); |
| 3511 | 3512 | }, |
| 3512 | 3513 | .immediate => |x_big| { |
| 3513 | | const abi_size = ty.abiSize(self.target.*); |
| 3514 | 3514 | const adj_off = stack_offset + @intCast(i32, abi_size); |
| 3515 | 3515 | if (adj_off > 128) { |
| 3516 | 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 | 3583 | if (stack_offset > math.maxInt(i32)) { |
| 3584 | 3584 | return self.fail("stack offset too large", .{}); |
| 3585 | 3585 | } |
| 3586 | | const abi_size = ty.abiSize(self.target.*); |
| 3587 | 3586 | const adj_off = stack_offset + @intCast(i32, abi_size); |
| 3588 | 3587 | _ = try self.addInst(.{ |
| 3589 | 3588 | .tag = .mov, |
| ... | ... | @@ -3600,11 +3599,46 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerErro |
| 3600 | 3599 | .got_load, |
| 3601 | 3600 | .direct_load, |
| 3602 | 3601 | => { |
| 3603 | | if (ty.abiSize(self.target.*) <= 8) { |
| 3602 | if (abi_size <= 8) { |
| 3604 | 3603 | const reg = try self.copyToTmpRegister(ty, mcv); |
| 3605 | 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 | 3643 | .ptr_stack_offset => { |
| 3610 | 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 | 3650 | return; |
| 3617 | 3651 | } |
| 3618 | 3652 | |
| 3619 | | const abi_size = ty.abiSize(self.target.*); |
| 3620 | 3653 | if (abi_size <= 8) { |
| 3621 | 3654 | const reg = try self.copyToTmpRegister(ty, mcv); |
| 3622 | 3655 | return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }); |