sse: Implement 0F2C/0F2D/CVTT[PS][SD]2[SP]I (#57)
This commit is contained in:
parent
9665dbf994
commit
3ea0089878
|
@ -548,14 +548,14 @@ const encodings = [
|
|||
{ sse: 1, opcode: 0x0F2B, reg_ud: 1, e: 1 },
|
||||
{ sse: 1, opcode: 0x660F2B, reg_ud: 1, e: 1 },
|
||||
|
||||
{ sse: 1, opcode: 0x0F2C, e: 1, skip: 1, },
|
||||
{ sse: 1, opcode: 0x660F2C, e: 1, skip: 1, },
|
||||
{ sse: 1, opcode: 0x0F2C, e: 1, },
|
||||
{ sse: 1, opcode: 0x660F2C, e: 1, },
|
||||
{ sse: 1, opcode: 0xF20F2C, e: 1, },
|
||||
{ sse: 1, opcode: 0xF30F2C, e: 1, skip: 1, },
|
||||
{ sse: 1, opcode: 0x0F2D, e: 1, skip: 1, },
|
||||
{ sse: 1, opcode: 0x660F2D, e: 1, skip: 1, },
|
||||
{ sse: 1, opcode: 0xF30F2C, e: 1, },
|
||||
{ sse: 1, opcode: 0x0F2D, e: 1, },
|
||||
{ sse: 1, opcode: 0x660F2D, e: 1, },
|
||||
{ sse: 1, opcode: 0xF20F2D, e: 1, },
|
||||
{ sse: 1, opcode: 0xF30F2D, e: 1, skip: 1, },
|
||||
{ sse: 1, opcode: 0xF30F2D, e: 1, },
|
||||
|
||||
{ sse: 1, opcode: 0x0F2E, e: 1 },
|
||||
{ sse: 1, opcode: 0x660F2E, e: 1 },
|
||||
|
|
|
@ -984,24 +984,46 @@ pub unsafe fn instr_660F2B_mem(mut addr: i32, mut r: i32) -> () {
|
|||
c_comment!(("XXX: Aligned write or #gp"));
|
||||
mov_r_m128(addr, r);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_0F2C(mut source: reg64, mut r: i32) -> () {
|
||||
// cvttps2pi mm, xmm/m64
|
||||
let result = reg64 {
|
||||
i32_0: [
|
||||
sse_convert_f32_to_i32(source.f32_0[0].trunc()),
|
||||
sse_convert_f32_to_i32(source.f32_0[1].trunc()),
|
||||
],
|
||||
};
|
||||
write_mmx_reg64(r, result);
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_0F2C_mem(mut addr: i32, mut r: i32) -> () {
|
||||
instr_0F2C(return_on_pagefault!(safe_read64s(addr)), r);
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_0F2C(mut source: reg64, mut r: i32) -> () { unimplemented_sse(); }
|
||||
pub unsafe fn instr_0F2C_reg(mut r1: i32, mut r2: i32) -> () { instr_0F2C(read_xmm64s(r1), r2); }
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_0F2C_reg(mut r1: i32, mut r2: i32) -> () { instr_0F2C(read_mmx64s(r1), r2); }
|
||||
pub unsafe fn instr_660F2C(mut source: reg128, mut r: i32) -> () {
|
||||
// cvttpd2pi mm, xmm/m128
|
||||
let result = reg64 {
|
||||
// XXX: Check conversion
|
||||
i32_0: [
|
||||
sse_convert_f64_to_i32(source.f64_0[0]),
|
||||
sse_convert_f64_to_i32(source.f64_0[1]),
|
||||
],
|
||||
};
|
||||
write_mmx_reg64(r, result);
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_660F2C_mem(mut addr: i32, mut r: i32) -> () {
|
||||
instr_660F2C(return_on_pagefault!(safe_read128s(addr)), r);
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_660F2C(mut source: reg128, mut r: i32) -> () { unimplemented_sse(); }
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_660F2C_reg(mut r1: i32, mut r2: i32) -> () {
|
||||
instr_660F2C(read_xmm128s(r1), r2);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_F20F2C(mut source: reg64, mut r: i32) -> () {
|
||||
let mut si: i32 = 0;
|
||||
|
@ -1032,13 +1054,17 @@ pub unsafe fn instr_F20F2C_reg(mut r1: i32, mut r2: i32) -> () {
|
|||
pub unsafe fn instr_F20F2C_mem(mut addr: i32, mut r: i32) -> () {
|
||||
instr_F20F2C(return_on_pagefault!(safe_read64s(addr)), r);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_F30F2C(source: f32, mut r: i32) -> () {
|
||||
let result = source.trunc();
|
||||
write_reg32(r, sse_convert_f32_to_i32(source));
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_F30F2C_mem(mut addr: i32, mut r: i32) -> () {
|
||||
instr_F30F2C(return_on_pagefault!(fpu_load_m32(addr)) as f32, r);
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_F30F2C(mut source: f32, mut r: i32) -> () { unimplemented_sse(); }
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_F30F2C_reg(mut r1: i32, mut r2: i32) -> () {
|
||||
instr_F30F2C(read_xmm_f32(r1), r2);
|
||||
}
|
||||
|
@ -5874,16 +5900,36 @@ pub unsafe fn instr_F30F2A_reg(mut r1: i32, mut r2: i32) -> () { instr_F30F2A(re
|
|||
pub unsafe fn instr_F30F2A_mem(mut addr: i32, mut r: i32) -> () {
|
||||
instr_F30F2A(return_on_pagefault!(safe_read32s(addr)), r);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_0F2D(mut source: reg64, mut r: i32) -> () { unimplemented_sse(); }
|
||||
pub unsafe fn instr_0F2D(mut source: reg64, mut r: i32) -> () {
|
||||
// cvtps2pi mm, xmm/m64
|
||||
let result = reg64 {
|
||||
i32_0: [
|
||||
sse_convert_f32_to_i32(source.f32_0[0].round()),
|
||||
sse_convert_f32_to_i32(source.f32_0[1].round()),
|
||||
],
|
||||
};
|
||||
write_mmx_reg64(r, result);
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_0F2D_reg(mut r1: i32, mut r2: i32) -> () { instr_0F2D(read_mmx64s(r1), r2); }
|
||||
pub unsafe fn instr_0F2D_reg(mut r1: i32, mut r2: i32) -> () { instr_0F2D(read_xmm64s(r1), r2); }
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_0F2D_mem(mut addr: i32, mut r: i32) -> () {
|
||||
instr_0F2D(return_on_pagefault!(safe_read64s(addr)), r);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_660F2D(mut source: reg128, mut r: i32) -> () { unimplemented_sse(); }
|
||||
pub unsafe fn instr_660F2D(mut source: reg128, mut r: i32) -> () {
|
||||
// cvtpd2pi mm, xmm/m128
|
||||
let result = reg64 {
|
||||
i32_0: [
|
||||
sse_convert_f64_to_i32(source.f64_0[0].round()),
|
||||
sse_convert_f64_to_i32(source.f64_0[1].round()),
|
||||
],
|
||||
};
|
||||
write_mmx_reg64(r, result);
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_660F2D_reg(mut r1: i32, mut r2: i32) -> () {
|
||||
instr_660F2D(read_xmm128s(r1), r2);
|
||||
|
@ -5906,7 +5952,10 @@ pub unsafe fn instr_F20F2D_mem(mut addr: i32, mut r: i32) -> () {
|
|||
instr_F20F2D(return_on_pagefault!(safe_read64s(addr)), r);
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_F30F2D(mut source: f32, mut r: i32) -> () { unimplemented_sse(); }
|
||||
pub unsafe fn instr_F30F2D(mut source: f32, mut r: i32) -> () {
|
||||
// cvtss2si r32, xmm1/m32
|
||||
write_reg32(r, sse_convert_f32_to_i32(source.round()));
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_F30F2D_reg(mut r1: i32, mut r2: i32) -> () {
|
||||
instr_F30F2D(read_xmm_f32(r1), r2);
|
||||
|
@ -5915,6 +5964,7 @@ pub unsafe fn instr_F30F2D_reg(mut r1: i32, mut r2: i32) -> () {
|
|||
pub unsafe fn instr_F30F2D_mem(mut addr: i32, mut r: i32) -> () {
|
||||
instr_F30F2D(return_on_pagefault!(fpu_load_m32(addr)) as f32, r);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_0F51(mut source: reg128, mut r: i32) -> () {
|
||||
c_comment!(("sqrtps xmm, xmm/mem128"));
|
||||
|
|
|
@ -397,10 +397,23 @@ pub unsafe fn sse_max(mut x: f64, mut y: f64) -> f64 {
|
|||
c_comment!(("if both x and y are 0 or x is nan, y is returned"));
|
||||
return if x > y { x } else { y };
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn sse_convert_f64_to_i32(mut x: f64) -> i32 {
|
||||
pub unsafe fn sse_convert_f32_to_i32(mut x: f32) -> i32 {
|
||||
c_comment!(("TODO: Rounding modes"));
|
||||
if x >= 2147483648u32.wrapping_neg() as f64 && x < 2147483648u32 as f64 {
|
||||
if x >= -2147483648.0 && x < 2147483648.0 {
|
||||
return x as i64 as i32;
|
||||
}
|
||||
else {
|
||||
c_comment!(("TODO: Signal"));
|
||||
return 2147483648u32.wrapping_neg() as i32;
|
||||
};
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn sse_convert_f64_to_i32(mut x: f64) -> i32 {
|
||||
c_comment!(("TODO: Rounding modes"));
|
||||
if x >= -2147483648.0 as f64 && x < 2147483648.0 as f64 {
|
||||
return x as i64 as i32;
|
||||
}
|
||||
else {
|
||||
|
|
Loading…
Reference in a new issue