mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 15:21:12 +00:00
fix reading float from a pointer
This commit is contained in:
parent
e4b0d77f2e
commit
9e8854614a
3 changed files with 94 additions and 3 deletions
|
@ -1224,6 +1224,24 @@ impl Assembler<AArch64GeneralReg, AArch64FloatReg> for AArch64Assembler {
|
|||
};
|
||||
cset_reg64_cond(buf, dst, cond);
|
||||
}
|
||||
|
||||
fn mov_freg64_mem64_offset32(
|
||||
_buf: &mut Vec<'_, u8>,
|
||||
_dst: AArch64FloatReg,
|
||||
_src: AArch64GeneralReg,
|
||||
_offset: i32,
|
||||
) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn mov_freg32_mem32_offset32(
|
||||
_buf: &mut Vec<'_, u8>,
|
||||
_dst: AArch64FloatReg,
|
||||
_src: AArch64GeneralReg,
|
||||
_offset: i32,
|
||||
) {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl AArch64Assembler {}
|
||||
|
|
|
@ -332,6 +332,19 @@ pub trait Assembler<GeneralReg: RegTrait, FloatReg: RegTrait>: Sized + Copy {
|
|||
);
|
||||
fn mov_reg8_mem8_offset32(buf: &mut Vec<'_, u8>, dst: GeneralReg, src: GeneralReg, offset: i32);
|
||||
|
||||
fn mov_freg64_mem64_offset32(
|
||||
buf: &mut Vec<'_, u8>,
|
||||
dst: FloatReg,
|
||||
src: GeneralReg,
|
||||
offset: i32,
|
||||
);
|
||||
fn mov_freg32_mem32_offset32(
|
||||
buf: &mut Vec<'_, u8>,
|
||||
dst: FloatReg,
|
||||
src: GeneralReg,
|
||||
offset: i32,
|
||||
);
|
||||
|
||||
// move from register to memory
|
||||
fn mov_mem64_offset32_reg64(
|
||||
buf: &mut Vec<'_, u8>,
|
||||
|
@ -3204,9 +3217,13 @@ impl<
|
|||
ASM::mov_reg8_mem8_offset32(buf, dst_reg, ptr_reg, 0);
|
||||
}
|
||||
},
|
||||
Builtin::Float(_) => {
|
||||
Builtin::Float(FloatWidth::F64) => {
|
||||
let dst_reg = storage_manager.claim_float_reg(buf, &dst);
|
||||
ASM::mov_freg64_freg64(buf, dst_reg, CC::FLOAT_RETURN_REGS[0]);
|
||||
ASM::mov_freg64_mem64_offset32(buf, dst_reg, ptr_reg, 0);
|
||||
}
|
||||
Builtin::Float(FloatWidth::F32) => {
|
||||
let dst_reg = storage_manager.claim_float_reg(buf, &dst);
|
||||
ASM::mov_freg32_mem32_offset32(buf, dst_reg, ptr_reg, 0);
|
||||
}
|
||||
Builtin::Bool => {
|
||||
// the same as an 8-bit integer
|
||||
|
|
|
@ -1510,6 +1510,26 @@ impl Assembler<X86_64GeneralReg, X86_64FloatReg> for X86_64Assembler {
|
|||
raw_movsx_reg_reg(buf, input_width, dst, src);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn mov_freg64_mem64_offset32(
|
||||
buf: &mut Vec<'_, u8>,
|
||||
dst: X86_64FloatReg,
|
||||
src: X86_64GeneralReg,
|
||||
offset: i32,
|
||||
) {
|
||||
movsd_freg64_base64_offset32(buf, dst, src, offset)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn mov_freg32_mem32_offset32(
|
||||
buf: &mut Vec<'_, u8>,
|
||||
dst: X86_64FloatReg,
|
||||
src: X86_64GeneralReg,
|
||||
offset: i32,
|
||||
) {
|
||||
movss_freg32_base32_offset32(buf, dst, src, offset)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn mov_freg64_base32(buf: &mut Vec<'_, u8>, dst: X86_64FloatReg, offset: i32) {
|
||||
movsd_freg64_base64_offset32(buf, dst, X86_64GeneralReg::RBP, offset)
|
||||
|
@ -2997,7 +3017,7 @@ fn movsd_freg64_rip_offset32(buf: &mut Vec<'_, u8>, dst: X86_64FloatReg, offset:
|
|||
buf.extend(offset.to_le_bytes());
|
||||
}
|
||||
|
||||
/// `MOVSD r/m64,xmm1` -> Move xmm1 to r/m64. where m64 references the base pointer.
|
||||
// `MOVSD r/m64,xmm1` -> Move xmm1 to r/m64. where m64 references the base pointer.
|
||||
#[inline(always)]
|
||||
fn movsd_base64_offset32_freg64(
|
||||
buf: &mut Vec<'_, u8>,
|
||||
|
@ -3047,6 +3067,31 @@ fn movsd_freg64_base64_offset32(
|
|||
buf.extend(offset.to_le_bytes());
|
||||
}
|
||||
|
||||
/// `MOVSS xmm1,r/m32` -> Move r/m32 to xmm1. where m64 references the base pointer.
|
||||
#[inline(always)]
|
||||
fn movss_freg32_base32_offset32(
|
||||
buf: &mut Vec<'_, u8>,
|
||||
dst: X86_64FloatReg,
|
||||
base: X86_64GeneralReg,
|
||||
offset: i32,
|
||||
) {
|
||||
let rex = add_rm_extension(base, REX_W);
|
||||
let rex = add_reg_extension(dst, rex);
|
||||
let dst_mod = (dst as u8 % 8) << 3;
|
||||
let base_mod = base as u8 % 8;
|
||||
buf.reserve(10);
|
||||
buf.push(0xF3);
|
||||
if dst as u8 > 7 || base as u8 > 7 {
|
||||
buf.push(rex);
|
||||
}
|
||||
buf.extend([0x0F, 0x10, 0x80 | dst_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());
|
||||
}
|
||||
|
||||
/// `NEG r/m64` -> Two's complement negate r/m64.
|
||||
#[inline(always)]
|
||||
fn neg_reg64(buf: &mut Vec<'_, u8>, reg: X86_64GeneralReg) {
|
||||
|
@ -3729,6 +3774,17 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_movss_freg32_base32_offset32() {
|
||||
disassembler_test!(
|
||||
movss_freg32_base32_offset32,
|
||||
|reg1, reg2, imm| format!("movss {}, dword ptr [{} + 0x{:x}]", reg1, reg2, imm),
|
||||
ALL_FLOAT_REGS,
|
||||
ALL_GENERAL_REGS,
|
||||
[TEST_I32]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_movsd_base64_offset32_freg64() {
|
||||
disassembler_test!(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue