gen_dev: Add MOVQ/MOVD to x86 backend

This commit is contained in:
Basile Henry 2023-05-02 22:55:25 +01:00
parent b8aaaaabda
commit 1391920d0e
3 changed files with 70 additions and 0 deletions

View file

@ -750,6 +750,16 @@ impl Assembler<AArch64GeneralReg, AArch64FloatReg> for AArch64Assembler {
fn mov_freg64_freg64(buf: &mut Vec<'_, u8>, dst: AArch64FloatReg, src: AArch64FloatReg) {
fmov_freg_freg(buf, FloatWidth::F64, dst, src);
}
#[inline(always)]
fn mov_reg32_freg32(_buf: &mut Vec<'_, u8>, _dst: AArch64GeneralReg, _src: AArch64FloatReg) {
unimplemented!();
}
#[inline(always)]
fn mov_reg64_freg64(_buf: &mut Vec<'_, u8>, _dst: AArch64GeneralReg, _src: AArch64FloatReg) {
unimplemented!();
}
#[inline(always)]
fn mov_reg_reg(
buf: &mut Vec<'_, u8>,

View file

@ -269,6 +269,9 @@ pub trait Assembler<GeneralReg: RegTrait, FloatReg: RegTrait>: Sized + Copy {
fn mov_reg64_imm64(buf: &mut Vec<'_, u8>, dst: GeneralReg, imm: i64);
fn mov_freg64_freg64(buf: &mut Vec<'_, u8>, dst: FloatReg, src: FloatReg);
fn mov_reg32_freg32(buf: &mut Vec<'_, u8>, dst: GeneralReg, src: FloatReg);
fn mov_reg64_freg64(buf: &mut Vec<'_, u8>, dst: GeneralReg, src: FloatReg);
fn mov_reg_reg(
buf: &mut Vec<'_, u8>,
register_width: RegisterWidth,

View file

@ -1483,6 +1483,16 @@ impl Assembler<X86_64GeneralReg, X86_64FloatReg> for X86_64Assembler {
fn mov_freg64_freg64(buf: &mut Vec<'_, u8>, dst: X86_64FloatReg, src: X86_64FloatReg) {
movsd_freg64_freg64(buf, dst, src);
}
#[inline(always)]
fn mov_reg32_freg32(buf: &mut Vec<'_, u8>, dst: X86_64GeneralReg, src: X86_64FloatReg) {
movd_reg32_freg32(buf, dst, src);
}
#[inline(always)]
fn mov_reg64_freg64(buf: &mut Vec<'_, u8>, dst: X86_64GeneralReg, src: X86_64FloatReg) {
movq_reg64_freg64(buf, dst, src);
}
#[inline(always)]
fn mov_reg_reg(
buf: &mut Vec<'_, u8>,
@ -2901,6 +2911,33 @@ fn movzx_reg64_base16_offset32(
movzx_reg64_base_offset32(buf, dst, base, offset, 0xB7)
}
#[inline(always)]
fn movd_reg32_freg32(buf: &mut Vec<'_, u8>, dst: X86_64GeneralReg, 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 {
let rex = add_rm_extension(dst, REX);
let rex = add_reg_extension(src, rex);
buf.extend([0x66, rex, 0x0F, 0x7E, 0xC0 | (src_mod << 3) | (dst_mod)])
} else {
buf.extend([0x66, 0x0F, 0x7E, 0xC0 | (src_mod << 3) | (dst_mod)])
}
}
#[inline(always)]
fn movq_reg64_freg64(buf: &mut Vec<'_, u8>, dst: X86_64GeneralReg, src: X86_64FloatReg) {
let dst_mod = dst as u8 % 8;
let src_mod = src as u8 % 8;
let rex = add_rm_extension(dst, REX_W);
let rex = add_reg_extension(src, rex);
buf.extend([0x66, rex, 0x0F, 0x7E, 0xC0 | (src_mod << 3) | (dst_mod)]);
}
/// `MOVSD xmm1,xmm2` -> Move scalar double-precision floating-point value from xmm2 to xmm1 register.
/// This will not generate anything if dst and src are the same.
#[inline(always)]
@ -3905,6 +3942,26 @@ mod tests {
);
}
#[test]
fn test_movd_reg32_freg32() {
disassembler_test!(
movd_reg32_freg32,
|dst: X86_64GeneralReg, src| format!("movd {}, {}", dst.low_32bits_string(), src),
ALL_GENERAL_REGS,
ALL_FLOAT_REGS
);
}
#[test]
fn test_movq_reg64_freg64() {
disassembler_test!(
movq_reg64_freg64,
|dst, src| format!("movq {}, {}", dst, src),
ALL_GENERAL_REGS,
ALL_FLOAT_REGS
);
}
#[test]
fn test_movsd_freg64_freg64() {
disassembler_test!(