mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 21:39:07 +00:00
Add immediate operation for setting floats to 0.0
This commit is contained in:
parent
616b45f366
commit
ec14c9a9f1
1 changed files with 75 additions and 0 deletions
|
@ -659,6 +659,10 @@ impl Assembler<AArch64GeneralReg, AArch64FloatReg> for AArch64Assembler {
|
|||
imm: f32,
|
||||
) {
|
||||
// See https://stackoverflow.com/a/64608524
|
||||
if imm == 0.0 && !imm.is_sign_negative() {
|
||||
movi_freg_zero(buf, dst);
|
||||
return;
|
||||
}
|
||||
match encode_f32_to_imm8(imm) {
|
||||
Some(imm8) => {
|
||||
fmov_freg_imm8(buf, FloatType::Single, dst, imm8);
|
||||
|
@ -676,6 +680,10 @@ impl Assembler<AArch64GeneralReg, AArch64FloatReg> for AArch64Assembler {
|
|||
imm: f64,
|
||||
) {
|
||||
// See https://stackoverflow.com/a/64608524
|
||||
if imm == 0.0 && !imm.is_sign_negative() {
|
||||
movi_freg_zero(buf, dst);
|
||||
return;
|
||||
}
|
||||
match encode_f64_to_imm8(imm) {
|
||||
Some(imm8) => {
|
||||
fmov_freg_imm8(buf, FloatType::Double, dst, imm8);
|
||||
|
@ -1876,6 +1884,53 @@ impl LoadStoreRegisterImmediate {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(PackedStruct)]
|
||||
#[packed_struct(endian = "msb")]
|
||||
pub struct AdvancedSimdModifiedImmediate {
|
||||
fixed: bool,
|
||||
q: bool,
|
||||
op: bool,
|
||||
fixed2: Integer<u16, packed_bits::Bits<10>>,
|
||||
a: bool,
|
||||
b: bool,
|
||||
c: bool,
|
||||
cmode: Integer<u8, packed_bits::Bits<4>>,
|
||||
o2: bool,
|
||||
fixed3: bool,
|
||||
d: bool,
|
||||
e: bool,
|
||||
f: bool,
|
||||
g: bool,
|
||||
h: bool,
|
||||
rd: Integer<u8, packed_bits::Bits<5>>,
|
||||
}
|
||||
|
||||
impl Aarch64Bytes for AdvancedSimdModifiedImmediate {}
|
||||
|
||||
impl AdvancedSimdModifiedImmediate {
|
||||
#[inline(always)]
|
||||
fn new(rd: AArch64FloatReg) -> Self {
|
||||
Self {
|
||||
fixed: false,
|
||||
q: false,
|
||||
op: true,
|
||||
fixed2: 0b0111100000.into(),
|
||||
a: false,
|
||||
b: false,
|
||||
c: false,
|
||||
cmode: 0b1110.into(),
|
||||
o2: false,
|
||||
fixed3: true,
|
||||
d: false,
|
||||
e: false,
|
||||
f: false,
|
||||
g: false,
|
||||
h: false,
|
||||
rd: rd.id().into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
pub enum FloatType {
|
||||
/// 32 bit
|
||||
|
@ -2865,6 +2920,14 @@ fn fsqrt_freg_freg(
|
|||
buf.extend(inst.bytes());
|
||||
}
|
||||
|
||||
/// Currently, we're only using MOVI to set a float register to 0.0.
|
||||
#[inline(always)]
|
||||
fn movi_freg_zero(buf: &mut Vec<'_, u8>, dst: AArch64FloatReg) {
|
||||
let inst = AdvancedSimdModifiedImmediate::new(dst);
|
||||
|
||||
buf.extend(inst.bytes());
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@ -3883,4 +3946,16 @@ mod tests {
|
|||
ALL_FLOAT_REGS
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_movi_freg_zero() {
|
||||
disassembler_test!(
|
||||
movi_freg_zero,
|
||||
|reg: AArch64FloatReg| format!(
|
||||
"movi {}, #0000000000000000",
|
||||
reg.capstone_string(FloatType::Double)
|
||||
),
|
||||
ALL_FLOAT_REGS
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue