mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 11:52:19 +00:00
dev backend: f32 abs
This commit is contained in:
parent
1da3a335df
commit
351c9215fe
4 changed files with 80 additions and 5 deletions
|
@ -1242,6 +1242,16 @@ impl Assembler<AArch64GeneralReg, AArch64FloatReg> for AArch64Assembler {
|
|||
fabs_freg_freg(buf, FloatWidth::F64, dst, src);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn abs_freg32_freg32(
|
||||
buf: &mut Vec<'_, u8>,
|
||||
_relocs: &mut Vec<'_, Relocation>,
|
||||
dst: AArch64FloatReg,
|
||||
src: AArch64FloatReg,
|
||||
) {
|
||||
fabs_freg_freg(buf, FloatWidth::F32, dst, src);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn add_reg64_reg64_imm32(
|
||||
buf: &mut Vec<'_, u8>,
|
||||
|
|
|
@ -164,6 +164,12 @@ pub trait Assembler<GeneralReg: RegTrait, FloatReg: RegTrait>: Sized + Copy {
|
|||
dst: FloatReg,
|
||||
src: FloatReg,
|
||||
);
|
||||
fn abs_freg32_freg32(
|
||||
buf: &mut Vec<'_, u8>,
|
||||
relocs: &mut Vec<'_, Relocation>,
|
||||
dst: FloatReg,
|
||||
src: FloatReg,
|
||||
);
|
||||
|
||||
fn add_reg64_reg64_imm32(buf: &mut Vec<'_, u8>, dst: GeneralReg, src1: GeneralReg, imm32: i32);
|
||||
fn add_reg64_reg64_reg64(
|
||||
|
@ -1316,6 +1322,11 @@ impl<
|
|||
let src_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src);
|
||||
ASM::abs_freg64_freg64(&mut self.buf, &mut self.relocs, dst_reg, src_reg);
|
||||
}
|
||||
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F32)) => {
|
||||
let dst_reg = self.storage_manager.claim_float_reg(&mut self.buf, dst);
|
||||
let src_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src);
|
||||
ASM::abs_freg32_freg32(&mut self.buf, &mut self.relocs, dst_reg, src_reg);
|
||||
}
|
||||
x => todo!("NumAbs: layout, {:?}", x),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1955,6 +1955,24 @@ impl Assembler<X86_64GeneralReg, X86_64FloatReg> for X86_64Assembler {
|
|||
andpd_freg64_freg64(buf, dst, src);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn abs_freg32_freg32(
|
||||
buf: &mut Vec<'_, u8>,
|
||||
relocs: &mut Vec<'_, Relocation>,
|
||||
dst: X86_64FloatReg,
|
||||
src: X86_64FloatReg,
|
||||
) {
|
||||
movss_freg32_rip_offset32(buf, dst, 0);
|
||||
|
||||
// TODO: make sure this constant only loads once instead of every call to abs
|
||||
relocs.push(Relocation::LocalData {
|
||||
offset: buf.len() as u64 - 4,
|
||||
data: 0x7fffffffu64.to_le_bytes().to_vec(),
|
||||
});
|
||||
|
||||
andps_freg32_freg32(buf, dst, src);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn add_reg64_reg64_imm32(
|
||||
buf: &mut Vec<'_, u8>,
|
||||
|
@ -3179,6 +3197,25 @@ fn andpd_freg64_freg64(buf: &mut Vec<'_, u8>, dst: X86_64FloatReg, src: X86_64Fl
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn andps_freg32_freg32(buf: &mut Vec<'_, u8>, dst: X86_64FloatReg, src: X86_64FloatReg) {
|
||||
let dst_high = dst as u8 > 7;
|
||||
let dst_mod = dst as u8 % 8;
|
||||
let src_high = src as u8 > 7;
|
||||
let src_mod = src as u8 % 8;
|
||||
|
||||
if dst_high || src_high {
|
||||
buf.extend([
|
||||
0x40 | ((dst_high as u8) << 2) | (src_high as u8),
|
||||
0x0F,
|
||||
0x54,
|
||||
0xC0 | (dst_mod << 3) | (src_mod),
|
||||
])
|
||||
} else {
|
||||
buf.extend([0x0F, 0x54, 0xC0 | (dst_mod << 3) | (src_mod)])
|
||||
}
|
||||
}
|
||||
|
||||
/// r/m64 AND imm8 (sign-extended).
|
||||
#[inline(always)]
|
||||
fn and_reg64_imm8(buf: &mut Vec<'_, u8>, dst: X86_64GeneralReg, imm: i8) {
|
||||
|
@ -4483,6 +4520,16 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_andps_freg32_freg32() {
|
||||
disassembler_test!(
|
||||
andps_freg32_freg32,
|
||||
|reg1, reg2| format!("andps {reg1}, {reg2}"),
|
||||
ALL_FLOAT_REGS,
|
||||
ALL_FLOAT_REGS
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_and_reg64_reg64() {
|
||||
disassembler_test!(
|
||||
|
|
|
@ -531,11 +531,18 @@ fn f64_abs() {
|
|||
assert_evals_to!("Num.abs -4.7f64", 4.7, f64);
|
||||
assert_evals_to!("Num.abs 5.8f64", 5.8, f64);
|
||||
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
{
|
||||
assert_evals_to!("Num.abs Num.maxF64", f64::MAX, f64);
|
||||
assert_evals_to!("Num.abs Num.minF64", f64::MAX, f64);
|
||||
}
|
||||
assert_evals_to!("Num.abs Num.maxF64", f64::MAX, f64);
|
||||
assert_evals_to!("Num.abs Num.minF64", f64::MAX, f64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
|
||||
fn f32_abs() {
|
||||
assert_evals_to!("Num.abs -4.7f32", 4.7, f32);
|
||||
assert_evals_to!("Num.abs 5.8f32", 5.8, f32);
|
||||
|
||||
assert_evals_to!("Num.abs Num.maxF32", f32::MAX, f32);
|
||||
assert_evals_to!("Num.abs Num.minF32", f32::MAX, f32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue