Add small string support to the dev backend

This commit is contained in:
Brendan Hansknecht 2021-09-18 14:41:44 -07:00
parent 1fba3702a8
commit 2f24067267
3 changed files with 1017 additions and 7 deletions

View file

@ -9,7 +9,7 @@ use std::marker::PhantomData;
pub mod aarch64;
pub mod x86_64;
const PTR_SIZE: u32 = 64;
const PTR_SIZE: u32 = 8;
pub trait CallConv<GeneralReg: RegTrait, FloatReg: RegTrait> {
const GENERAL_PARAM_REGS: &'static [GeneralReg];
@ -489,6 +489,25 @@ impl<
ASM::mov_freg64_freg64(&mut self.buf, dst_reg, CC::FLOAT_RETURN_REGS[0]);
Ok(())
}
Layout::Builtin(Builtin::Str) => {
if CC::returns_via_arg_pointer(ret_layout)? {
// This will happen on windows, return via pointer here.
Err("FnCall: Returning strings via pointer not yet implemented".to_string())
} else {
let offset = self.claim_stack_size(16)?;
self.symbol_storage_map.insert(
*dst,
SymbolStorage::Base {
offset,
size: 16,
owned: true,
},
);
ASM::mov_base32_reg64(&mut self.buf, offset, CC::GENERAL_RETURN_REGS[0]);
ASM::mov_base32_reg64(&mut self.buf, offset + 8, CC::GENERAL_RETURN_REGS[1]);
Ok(())
}
}
x => Err(format!(
"FnCall: receiving return type, {:?}, is not yet implemented",
x
@ -893,6 +912,35 @@ impl<
ASM::mov_freg64_imm64(&mut self.buf, &mut self.relocs, reg, val);
Ok(())
}
Literal::Str(x) if x.len() < 16 => {
// Load small string.
let reg = self.get_tmp_general_reg()?;
let offset = self.claim_stack_size(16)?;
self.symbol_storage_map.insert(
*sym,
SymbolStorage::Base {
offset,
size: 16,
owned: true,
},
);
let mut bytes = [0; 16];
bytes[..x.len()].copy_from_slice(x.as_bytes());
bytes[15] = (x.len() as u8) | 0b1000_0000;
let mut num_bytes = [0; 8];
num_bytes.copy_from_slice(&bytes[..8]);
let num = i64::from_ne_bytes(num_bytes);
ASM::mov_reg64_imm64(&mut self.buf, reg, num);
ASM::mov_base32_reg64(&mut self.buf, offset, reg);
num_bytes.copy_from_slice(&bytes[8..]);
let num = i64::from_ne_bytes(num_bytes);
ASM::mov_reg64_imm64(&mut self.buf, reg, num);
ASM::mov_base32_reg64(&mut self.buf, offset + 8, reg);
Ok(())
}
x => Err(format!("loading literal, {:?}, is not yet implemented", x)),
}
}
@ -1012,6 +1060,20 @@ impl<
Layout::Builtin(Builtin::Float64) => {
ASM::mov_freg64_base32(&mut self.buf, CC::FLOAT_RETURN_REGS[0], *offset);
}
Layout::Builtin(Builtin::Str) => {
if self.symbol_storage_map.contains_key(&Symbol::RET_POINTER) {
// This will happen on windows, return via pointer here.
Err("Returning strings via pointer not yet implemented".to_string())
} else {
ASM::mov_reg64_base32(&mut self.buf, CC::GENERAL_RETURN_REGS[0], *offset);
ASM::mov_reg64_base32(
&mut self.buf,
CC::GENERAL_RETURN_REGS[1],
*offset + 8,
);
Ok(())
}
}
Layout::Struct(field_layouts) => {
let (offset, size) = (*offset, *size);
// Nothing to do for empty struct