mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 23:31:12 +00:00
Add small string support to the dev backend
This commit is contained in:
parent
1fba3702a8
commit
2f24067267
3 changed files with 1017 additions and 7 deletions
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue