32-bit float mov instruction

This commit is contained in:
Folkert 2023-07-09 15:41:41 +02:00
parent bb97c384bb
commit 6a19009acf
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
4 changed files with 51 additions and 1 deletions

View file

@ -832,6 +832,10 @@ impl Assembler<AArch64GeneralReg, AArch64FloatReg> for AArch64Assembler {
todo!("saving floating point reg to base offset for AArch64");
}
#[inline(always)]
fn mov_base32_freg32(_buf: &mut Vec<'_, u8>, _offset: i32, _src: AArch64FloatReg) {
todo!("saving floating point reg to base offset for AArch64");
}
#[inline(always)]
fn movesd_mem64_offset32_freg64(
_buf: &mut Vec<'_, u8>,
_ptr: AArch64GeneralReg,

View file

@ -321,6 +321,7 @@ pub trait Assembler<GeneralReg: RegTrait, FloatReg: RegTrait>: Sized + Copy {
fn mov_reg8_base32(buf: &mut Vec<'_, u8>, dst: GeneralReg, offset: i32);
fn mov_base32_freg64(buf: &mut Vec<'_, u8>, offset: i32, src: FloatReg);
fn mov_base32_freg32(buf: &mut Vec<'_, u8>, offset: i32, src: FloatReg);
fn mov_base32_reg64(buf: &mut Vec<'_, u8>, offset: i32, src: GeneralReg);
fn mov_base32_reg32(buf: &mut Vec<'_, u8>, offset: i32, src: GeneralReg);

View file

@ -783,7 +783,11 @@ impl<
let reg = self.load_to_float_reg(buf, sym);
ASM::mov_base32_freg64(buf, to_offset, reg);
}
FloatWidth::F32 => todo!(),
FloatWidth::F32 => {
debug_assert_eq!(to_offset % 4, 0);
let reg = self.load_to_float_reg(buf, sym);
ASM::mov_base32_freg64(buf, to_offset, reg);
}
},
Builtin::Bool => {
// same as 8-bit integer, but we special-case true/false because these symbols

View file

@ -1584,6 +1584,11 @@ impl Assembler<X86_64GeneralReg, X86_64FloatReg> for X86_64Assembler {
movsd_base64_offset32_freg64(buf, X86_64GeneralReg::RBP, offset, src)
}
#[inline(always)]
fn mov_base32_freg32(buf: &mut Vec<'_, u8>, offset: i32, src: X86_64FloatReg) {
movss_base32_offset32_freg32(buf, X86_64GeneralReg::RBP, offset, src)
}
#[inline(always)]
fn movesd_mem64_offset32_freg64(
buf: &mut Vec<'_, u8>,
@ -3180,6 +3185,31 @@ fn movsd_base64_offset32_freg64(
buf.extend(offset.to_le_bytes());
}
// `MOVSS r/m64,xmm1` -> Move xmm1 to r/m64. where m64 references the base pointer.
#[inline(always)]
fn movss_base32_offset32_freg32(
buf: &mut Vec<'_, u8>,
base: X86_64GeneralReg,
offset: i32,
src: X86_64FloatReg,
) {
let rex = add_rm_extension(base, REX_W);
let rex = add_reg_extension(src, rex);
let src_mod = (src as u8 % 8) << 3;
let base_mod = base as u8 % 8;
buf.reserve(10);
buf.push(0xF3);
if src as u8 > 7 || base as u8 > 7 {
buf.push(rex);
}
buf.extend([0x0F, 0x11, 0x80 | src_mod | base_mod]);
// Using RSP or R12 requires a secondary index byte.
if base == X86_64GeneralReg::RSP || base == X86_64GeneralReg::R12 {
buf.push(0x24);
}
buf.extend(offset.to_le_bytes());
}
/// `MOVSD xmm1,r/m64` -> Move r/m64 to xmm1. where m64 references the base pointer.
#[inline(always)]
fn movsd_freg64_base64_offset32(
@ -3966,6 +3996,17 @@ mod tests {
);
}
#[test]
fn test_movss_base64_offset32_freg64() {
disassembler_test!(
movss_base32_offset32_freg32,
|reg1, imm, reg2| format!("movss dword ptr [{} + 0x{:x}], {}", reg1, imm, reg2),
ALL_GENERAL_REGS,
[TEST_I32],
ALL_FLOAT_REGS
);
}
#[test]
fn test_mov_reg64_base64_offset32() {
disassembler_test!(