mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 11:52:19 +00:00
simplify moving with the scratch register we now have
This commit is contained in:
parent
dd12069013
commit
dc179a1aa6
3 changed files with 17 additions and 42 deletions
|
@ -1262,21 +1262,21 @@ impl Assembler<AArch64GeneralReg, AArch64FloatReg> for AArch64Assembler {
|
|||
_relocs: &mut Vec<'_, Relocation>,
|
||||
dst: AArch64FloatReg,
|
||||
imm: f32,
|
||||
) -> Result<(), ()> {
|
||||
) {
|
||||
// See https://stackoverflow.com/a/64608524
|
||||
if imm == 0.0 && !imm.is_sign_negative() {
|
||||
movi_freg_zero(buf, dst);
|
||||
return Ok(());
|
||||
return;
|
||||
}
|
||||
|
||||
match encode_f32_to_imm8(imm) {
|
||||
Some(imm8) => {
|
||||
fmov_freg_imm8(buf, FloatWidth::F32, dst, imm8);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
None => {
|
||||
// there is no way to load a bigger float without a general register
|
||||
Err(())
|
||||
let tmp = AArch64GeneralReg::X15;
|
||||
Self::mov_reg64_imm64(buf, tmp, i32::from_ne_bytes(imm.to_ne_bytes()) as i64);
|
||||
Self::mov_freg32_reg32(buf, dst, tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1286,22 +1286,21 @@ impl Assembler<AArch64GeneralReg, AArch64FloatReg> for AArch64Assembler {
|
|||
_relocs: &mut Vec<'_, Relocation>,
|
||||
dst: AArch64FloatReg,
|
||||
imm: f64,
|
||||
) -> Result<(), ()> {
|
||||
) {
|
||||
// See https://stackoverflow.com/a/64608524
|
||||
if imm == 0.0 && !imm.is_sign_negative() {
|
||||
movi_freg_zero(buf, dst);
|
||||
return Ok(());
|
||||
return;
|
||||
}
|
||||
|
||||
match encode_f64_to_imm8(imm) {
|
||||
Some(imm8) => {
|
||||
fmov_freg_imm8(buf, FloatWidth::F64, dst, imm8);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
None => {
|
||||
// there is no way to load a bigger float without a general register
|
||||
Err(())
|
||||
let tmp = AArch64GeneralReg::X15;
|
||||
Self::mov_reg64_imm64(buf, tmp, i64::from_ne_bytes(imm.to_ne_bytes()));
|
||||
Self::mov_freg64_reg64(buf, dst, tmp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -298,13 +298,13 @@ pub trait Assembler<GeneralReg: RegTrait, FloatReg: RegTrait>: Sized + Copy {
|
|||
relocs: &mut Vec<'_, Relocation>,
|
||||
dst: FloatReg,
|
||||
imm: f32,
|
||||
) -> Result<(), ()>;
|
||||
);
|
||||
fn mov_freg64_imm64(
|
||||
buf: &mut Vec<'_, u8>,
|
||||
relocs: &mut Vec<'_, Relocation>,
|
||||
dst: FloatReg,
|
||||
imm: f64,
|
||||
) -> Result<(), ()>;
|
||||
);
|
||||
fn mov_reg64_imm64(buf: &mut Vec<'_, u8>, dst: GeneralReg, imm: i64);
|
||||
fn mov_freg64_freg64(buf: &mut Vec<'_, u8>, dst: FloatReg, src: FloatReg);
|
||||
|
||||
|
@ -4257,32 +4257,12 @@ impl<
|
|||
(Literal::Float(x), LayoutRepr::Builtin(Builtin::Float(FloatWidth::F64))) => {
|
||||
let freg = self.storage_manager.claim_float_reg(&mut self.buf, sym);
|
||||
let val = *x;
|
||||
if ASM::mov_freg64_imm64(&mut self.buf, &mut self.relocs, freg, val).is_err() {
|
||||
// do the naive thing
|
||||
let tmp = Symbol::DEV_TMP;
|
||||
let reg = self.storage_manager.claim_general_reg(&mut self.buf, &tmp);
|
||||
let val = i64::from_ne_bytes(val.to_ne_bytes());
|
||||
ASM::mov_reg64_imm64(&mut self.buf, reg, val);
|
||||
|
||||
ASM::mov_freg64_reg64(&mut self.buf, freg, reg);
|
||||
|
||||
self.storage_manager.free_symbol(&tmp);
|
||||
}
|
||||
ASM::mov_freg64_imm64(&mut self.buf, &mut self.relocs, freg, val);
|
||||
}
|
||||
(Literal::Float(x), LayoutRepr::Builtin(Builtin::Float(FloatWidth::F32))) => {
|
||||
let freg = self.storage_manager.claim_float_reg(&mut self.buf, sym);
|
||||
let val = *x as f32;
|
||||
if ASM::mov_freg32_imm32(&mut self.buf, &mut self.relocs, freg, val).is_err() {
|
||||
// do the naive thing
|
||||
let tmp = Symbol::DEV_TMP;
|
||||
let reg = self.storage_manager.claim_general_reg(&mut self.buf, &tmp);
|
||||
let val = i32::from_ne_bytes(val.to_ne_bytes());
|
||||
ASM::mov_reg64_imm64(&mut self.buf, reg, val as i64);
|
||||
|
||||
ASM::mov_freg32_reg32(&mut self.buf, freg, reg);
|
||||
|
||||
self.storage_manager.free_symbol(&tmp);
|
||||
}
|
||||
ASM::mov_freg32_imm32(&mut self.buf, &mut self.relocs, freg, val);
|
||||
}
|
||||
(Literal::Decimal(bytes), LayoutRepr::Builtin(Builtin::Decimal)) => {
|
||||
self.storage_manager.with_tmp_general_reg(
|
||||
|
|
|
@ -2156,14 +2156,12 @@ impl Assembler<X86_64GeneralReg, X86_64FloatReg> for X86_64Assembler {
|
|||
relocs: &mut Vec<'_, Relocation>,
|
||||
dst: X86_64FloatReg,
|
||||
imm: f32,
|
||||
) -> Result<(), ()> {
|
||||
) {
|
||||
movss_freg32_rip_offset32(buf, dst, 0);
|
||||
relocs.push(Relocation::LocalData {
|
||||
offset: buf.len() as u64 - 4,
|
||||
data: imm.to_le_bytes().to_vec(),
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
#[inline(always)]
|
||||
fn mov_freg64_imm64(
|
||||
|
@ -2171,14 +2169,12 @@ impl Assembler<X86_64GeneralReg, X86_64FloatReg> for X86_64Assembler {
|
|||
relocs: &mut Vec<'_, Relocation>,
|
||||
dst: X86_64FloatReg,
|
||||
imm: f64,
|
||||
) -> Result<(), ()> {
|
||||
) {
|
||||
movsd_freg64_rip_offset32(buf, dst, 0);
|
||||
relocs.push(Relocation::LocalData {
|
||||
offset: buf.len() as u64 - 4,
|
||||
data: imm.to_le_bytes().to_vec(),
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
#[inline(always)]
|
||||
fn mov_reg64_imm64(buf: &mut Vec<'_, u8>, dst: X86_64GeneralReg, imm: i64) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue