create cvtsx2_help

This commit is contained in:
satotake 2021-12-05 15:40:00 +00:00 committed by GitHub
parent f7f36fb3c3
commit 5003223465
2 changed files with 68 additions and 9 deletions

View file

@ -1530,7 +1530,7 @@ fn set_reg64_help(op_code: u8, buf: &mut Vec<'_, u8>, reg: X86_64GeneralReg) {
} }
#[inline(always)] #[inline(always)]
fn cvt_help(buf: &mut Vec<'_, u8>, op_code1: u8, op_code2: u8, reg1: u8, reg2: u8) { fn cvtsi2_help(buf: &mut Vec<'_, u8>, op_code1: u8, op_code2: u8, reg1: u8, reg2: u8) {
let rex = add_rm_extension_u8(reg2, REX_W); let rex = add_rm_extension_u8(reg2, REX_W);
let rex = add_reg_extension_u8(reg1, rex); let rex = add_reg_extension_u8(reg1, rex);
let mod1 = (reg1 % 8) << 3; let mod1 = (reg1 % 8) << 3;
@ -1539,6 +1539,14 @@ fn cvt_help(buf: &mut Vec<'_, u8>, op_code1: u8, op_code2: u8, reg1: u8, reg2: u
buf.extend(&[op_code1, rex, 0x0F, op_code2, 0xC0 + mod1 + mod2]) buf.extend(&[op_code1, rex, 0x0F, op_code2, 0xC0 + mod1 + mod2])
} }
#[inline(always)]
fn cvtsx2_help(buf: &mut Vec<'_, u8>, op_code1: u8, op_code2: u8, reg1: u8, reg2: u8) {
let mod1 = (reg1 % 8) << 3;
let mod2 = reg2 % 8;
buf.extend(&[op_code1, 0x0F, op_code2, 0xC0 + mod1 + mod2])
}
/// `SETE r/m64` -> Set Byte on Condition - zero/equal (ZF=1) /// `SETE r/m64` -> Set Byte on Condition - zero/equal (ZF=1)
#[inline(always)] #[inline(always)]
fn sete_reg64(buf: &mut Vec<'_, u8>, reg: X86_64GeneralReg) { fn sete_reg64(buf: &mut Vec<'_, u8>, reg: X86_64GeneralReg) {
@ -1548,33 +1556,33 @@ fn sete_reg64(buf: &mut Vec<'_, u8>, reg: X86_64GeneralReg) {
/// `CVTSS2SD xmm` -> Convert one single-precision floating-point value in xmm/m32 to one double-precision floating-point value in xmm. /// `CVTSS2SD xmm` -> Convert one single-precision floating-point value in xmm/m32 to one double-precision floating-point value in xmm.
#[inline(always)] #[inline(always)]
fn cvtss2sd_freg64_freg32(buf: &mut Vec<'_, u8>, dst: X86_64FloatReg, src: X86_64FloatReg) { fn cvtss2sd_freg64_freg32(buf: &mut Vec<'_, u8>, dst: X86_64FloatReg, src: X86_64FloatReg) {
cvt_help(buf, 0xF3, 0x5A, dst as u8, src as u8) cvtsx2_help(buf, 0xF3, 0x5A, src as u8, dst as u8)
} }
/// `CVTSD2SS xmm` -> Convert one double-precision floating-point value in xmm to one single-precision floating-point value and merge with high bits. /// `CVTSD2SS xmm` -> Convert one double-precision floating-point value in xmm to one single-precision floating-point value and merge with high bits.
#[inline(always)] #[inline(always)]
fn cvtsd2ss_freg32_freg64(buf: &mut Vec<'_, u8>, dst: X86_64FloatReg, src: X86_64FloatReg) { fn cvtsd2ss_freg32_freg64(buf: &mut Vec<'_, u8>, dst: X86_64FloatReg, src: X86_64FloatReg) {
cvt_help(buf, 0xF2, 0x5A, dst as u8, src as u8) cvtsx2_help(buf, 0xF2, 0x5A, dst as u8, src as u8)
} }
/// `CVTSI2SD r/m64` -> Convert one signed quadword integer from r/m64 to one double-precision floating-point value in xmm. /// `CVTSI2SD r/m64` -> Convert one signed quadword integer from r/m64 to one double-precision floating-point value in xmm.
#[inline(always)] #[inline(always)]
fn cvtsi2sd_freg64_reg64(buf: &mut Vec<'_, u8>, dst: X86_64FloatReg, src: X86_64GeneralReg) { fn cvtsi2sd_freg64_reg64(buf: &mut Vec<'_, u8>, dst: X86_64FloatReg, src: X86_64GeneralReg) {
cvt_help(buf, 0xF2, 0x2A, dst as u8, src as u8) cvtsi2_help(buf, 0xF2, 0x2A, dst as u8, src as u8)
} }
/// `CVTSI2SS r/m64` -> Convert one signed quadword integer from r/m64 to one single-precision floating-point value in xmm. /// `CVTSI2SS r/m64` -> Convert one signed quadword integer from r/m64 to one single-precision floating-point value in xmm.
#[allow(dead_code)] #[allow(dead_code)]
#[inline(always)] #[inline(always)]
fn cvtsi2ss_freg64_reg64(buf: &mut Vec<'_, u8>, dst: X86_64FloatReg, src: X86_64GeneralReg) { fn cvtsi2ss_freg64_reg64(buf: &mut Vec<'_, u8>, dst: X86_64FloatReg, src: X86_64GeneralReg) {
cvt_help(buf, 0xF3, 0x2A, dst as u8, src as u8) cvtsi2_help(buf, 0xF3, 0x2A, dst as u8, src as u8)
} }
/// `CVTTSS2SI xmm/m32` -> Convert one single-precision floating-point value from xmm/m32 to one signed quadword integer in r64 using truncation. /// `CVTTSS2SI xmm/m32` -> Convert one single-precision floating-point value from xmm/m32 to one signed quadword integer in r64 using truncation.
#[allow(dead_code)] #[allow(dead_code)]
#[inline(always)] #[inline(always)]
fn cvttss2si_reg64_freg64(buf: &mut Vec<'_, u8>, dst: X86_64GeneralReg, src: X86_64FloatReg) { fn cvttss2si_reg64_freg64(buf: &mut Vec<'_, u8>, dst: X86_64GeneralReg, src: X86_64FloatReg) {
cvt_help(buf, 0xF3, 0x2C, dst as u8, src as u8) cvtsi2_help(buf, 0xF3, 0x2C, dst as u8, src as u8)
} }
/// `SETNE r/m64` -> Set byte if not equal (ZF=0). /// `SETNE r/m64` -> Set byte if not equal (ZF=0).
@ -2173,11 +2181,12 @@ mod tests {
} }
#[test] #[test]
fn test_cvt_help() { fn test_cvtsi2_help() {
let arena = bumpalo::Bump::new(); let arena = bumpalo::Bump::new();
let mut buf = bumpalo::vec![in &arena]; let mut buf = bumpalo::vec![in &arena];
let cvtsi2ss_code: u8 = 0x2A; let cvtsi2ss_code: u8 = 0x2A;
let cvttss2si_code: u8 = 0x2C; let cvttss2si_code: u8 = 0x2C;
let cvtss2sd_code: u8 = 0x5A;
for (op_code, reg1, reg2, expected) in &[ for (op_code, reg1, reg2, expected) in &[
( (
@ -2206,7 +2215,7 @@ mod tests {
), ),
] { ] {
buf.clear(); buf.clear();
cvt_help(&mut buf, 0xF3, *op_code, *reg1 as u8, *reg2 as u8); cvtsi2_help(&mut buf, 0xF3, *op_code, *reg1 as u8, *reg2 as u8);
assert_eq!(expected, &buf[..]); assert_eq!(expected, &buf[..]);
} }
@ -2237,7 +2246,18 @@ mod tests {
), ),
] { ] {
buf.clear(); buf.clear();
cvt_help(&mut buf, 0xF3, *op_code, *reg1 as u8, *reg2 as u8); cvtsi2_help(&mut buf, 0xF3, *op_code, *reg1 as u8, *reg2 as u8);
assert_eq!(expected, &buf[..]);
}
for (op_code, reg1, reg2, expected) in &[(
cvtss2sd_code,
X86_64FloatReg::XMM1,
X86_64FloatReg::XMM0,
[0xF3, 0x0F, 0x5A, 0xC8],
)] {
buf.clear();
cvtsx2_help(&mut buf, 0xF3, *op_code, *reg1 as u8, *reg2 as u8);
assert_eq!(expected, &buf[..]); assert_eq!(expected, &buf[..]);
} }
} }

View file

@ -1308,6 +1308,45 @@ fn num_to_float() {
assert_evals_to!("Num.toFloat 9", 9.0, f64); assert_evals_to!("Num.toFloat 9", 9.0, f64);
} }
#[test]
#[cfg(any(feature = "gen-dev"))]
fn num_to_float_f64_to_f32() {
assert_evals_to!(
indoc!(
r#"
f64 : F64
f64 = 9.0
f32 : F32
f32 = Num.toFloat f64
f32
"#
),
9.0,
f32
);
}
// #[test]
// #[cfg(any(feature = "gen-dev"))]
// fn num_to_float_f32_to_f64() {
// assert_evals_to!(
// indoc!(
// r#"
// f32 : F32
// f32 = 9.0
// f64 : F64
// f64 = Num.toFloat f32
// f64
// "#
// ),
// 9.0,
// f64
// );
// }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))] #[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
fn float_to_float() { fn float_to_float() {