copy arguments that are not size multiple of 8

This commit is contained in:
Folkert 2023-04-26 23:58:01 +02:00
parent 64130dbbbc
commit f95c79bb53
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
3 changed files with 105 additions and 24 deletions

View file

@ -980,14 +980,26 @@ impl Assembler<AArch64GeneralReg, AArch64FloatReg> for AArch64Assembler {
todo!("saving floating point reg to stack for AArch64");
}
#[inline(always)]
fn mov_stack32_reg64(buf: &mut Vec<'_, u8>, offset: i32, src: AArch64GeneralReg) {
if offset < 0 {
todo!("negative stack offsets for AArch64");
} else if offset < (0xFFF << 8) {
debug_assert!(offset % 8 == 0);
str_reg64_reg64_imm12(buf, src, AArch64GeneralReg::ZRSP, (offset as u16) >> 3);
} else {
todo!("stack offsets over 32k for AArch64");
fn mov_stack32_reg(
buf: &mut Vec<'_, u8>,
register_width: RegisterWidth,
offset: i32,
src: AArch64GeneralReg,
) {
match register_width {
RegisterWidth::W8 => todo!(),
RegisterWidth::W16 => todo!(),
RegisterWidth::W32 => todo!(),
RegisterWidth::W64 => {
if offset < 0 {
todo!("negative stack offsets for AArch64");
} else if offset < (0xFFF << 8) {
debug_assert!(offset % 8 == 0);
str_reg64_reg64_imm12(buf, src, AArch64GeneralReg::ZRSP, (offset as u16) >> 3);
} else {
todo!("stack offsets over 32k for AArch64");
}
}
}
}
#[inline(always)]

View file

@ -362,7 +362,26 @@ pub trait Assembler<GeneralReg: RegTrait, FloatReg: RegTrait>: Sized + Copy {
fn mov_freg64_stack32(buf: &mut Vec<'_, u8>, dst: FloatReg, offset: i32);
fn mov_reg64_stack32(buf: &mut Vec<'_, u8>, dst: GeneralReg, offset: i32);
fn mov_stack32_freg64(buf: &mut Vec<'_, u8>, offset: i32, src: FloatReg);
fn mov_stack32_reg64(buf: &mut Vec<'_, u8>, offset: i32, src: GeneralReg);
fn mov_stack32_reg(
buf: &mut Vec<'_, u8>,
register_width: RegisterWidth,
offset: i32,
src: GeneralReg,
);
fn mov_stack32_reg64(buf: &mut Vec<'_, u8>, offset: i32, src: GeneralReg) {
Self::mov_stack32_reg(buf, RegisterWidth::W64, offset, src)
}
fn mov_stack32_reg32(buf: &mut Vec<'_, u8>, offset: i32, src: GeneralReg) {
Self::mov_stack32_reg(buf, RegisterWidth::W32, offset, src)
}
fn mov_stack32_reg16(buf: &mut Vec<'_, u8>, offset: i32, src: GeneralReg) {
Self::mov_stack32_reg(buf, RegisterWidth::W16, offset, src)
}
fn mov_stack32_reg8(buf: &mut Vec<'_, u8>, offset: i32, src: GeneralReg) {
Self::mov_stack32_reg(buf, RegisterWidth::W8, offset, src)
}
fn sqrt_freg64_freg64(buf: &mut Vec<'_, u8>, dst: FloatReg, src: FloatReg);
fn sqrt_freg32_freg32(buf: &mut Vec<'_, u8>, dst: FloatReg, src: FloatReg);

View file

@ -536,21 +536,50 @@ impl X64_64SystemVStoreArgs {
self.tmp_stack_offset += size as i32;
}
Layout::Union(UnionLayout::NonRecursive(_)) => {
// for now, just also store this on the stack
type ASM = X86_64Assembler;
let tmp_reg = Self::GENERAL_RETURN_REGS[0];
let stack_offset = self.tmp_stack_offset as i32;
let mut copied = 0;
let (base_offset, size) = storage_manager.stack_offset_and_size(&sym);
debug_assert_eq!(base_offset % 8, 0);
for i in (0..size as i32).step_by(8) {
X86_64Assembler::mov_reg64_base32(
buf,
Self::GENERAL_RETURN_REGS[0],
base_offset + i,
);
X86_64Assembler::mov_stack32_reg64(
buf,
self.tmp_stack_offset + i,
Self::GENERAL_RETURN_REGS[0],
);
if size - copied >= 8 {
for _ in (0..(size - copied)).step_by(8) {
ASM::mov_reg64_base32(buf, tmp_reg, base_offset + copied as i32);
ASM::mov_stack32_reg64(buf, stack_offset + copied as i32, tmp_reg);
copied += 8;
}
}
if size - copied >= 4 {
for _ in (0..(size - copied)).step_by(4) {
ASM::mov_reg32_base32(buf, tmp_reg, base_offset + copied as i32);
ASM::mov_stack32_reg32(buf, stack_offset + copied as i32, tmp_reg);
copied += 4;
}
}
if size - copied >= 2 {
for _ in (0..(size - copied)).step_by(2) {
ASM::mov_reg16_base32(buf, tmp_reg, base_offset + copied as i32);
ASM::mov_stack32_reg16(buf, stack_offset + copied as i32, tmp_reg);
copied += 2;
}
}
if size - copied >= 1 {
for _ in (0..(size - copied)).step_by(1) {
ASM::mov_reg8_base32(buf, tmp_reg, base_offset + copied as i32);
ASM::mov_stack32_reg8(buf, stack_offset + copied as i32, tmp_reg);
copied += 1;
}
}
self.tmp_stack_offset += size as i32;
}
_ => {
@ -1631,8 +1660,13 @@ impl Assembler<X86_64GeneralReg, X86_64FloatReg> for X86_64Assembler {
movsd_base64_offset32_freg64(buf, X86_64GeneralReg::RSP, offset, src)
}
#[inline(always)]
fn mov_stack32_reg64(buf: &mut Vec<'_, u8>, offset: i32, src: X86_64GeneralReg) {
mov_base64_offset32_reg64(buf, X86_64GeneralReg::RSP, offset, src)
fn mov_stack32_reg(
buf: &mut Vec<'_, u8>,
register_width: RegisterWidth,
offset: i32,
src: X86_64GeneralReg,
) {
mov_base_offset32_reg(buf, register_width, X86_64GeneralReg::RSP, offset, src)
}
#[inline(always)]
@ -2583,6 +2617,22 @@ fn mov_reg_reg(
// The following base and stack based operations could be optimized based on how many bytes the offset actually is.
#[inline(always)]
fn mov_base_offset32_reg(
buf: &mut Vec<'_, u8>,
register_width: RegisterWidth,
base: X86_64GeneralReg,
offset: i32,
src: X86_64GeneralReg,
) {
match register_width {
RegisterWidth::W8 => mov_base16_offset32_reg16(buf, base, offset, src),
RegisterWidth::W16 => mov_base16_offset32_reg16(buf, base, offset, src),
RegisterWidth::W32 => mov_base32_offset32_reg32(buf, base, offset, src),
RegisterWidth::W64 => mov_base64_offset32_reg64(buf, base, offset, src),
}
}
/// `MOV r/m64,r64` -> Move r64 to r/m64, where m64 references a base + offset.
#[inline(always)]
fn mov_base64_offset32_reg64(