partially jit some sse conversion instructions

This commit is contained in:
Fabian 2020-12-31 19:14:33 -06:00
parent 30e444460b
commit 0c4e8a7e09
4 changed files with 103 additions and 14 deletions

View file

@ -647,12 +647,12 @@ const encodings = [
{ sse: 1, opcode: 0x0F2C, e: 1, },
{ sse: 1, opcode: 0x660F2C, e: 1, },
{ sse: 1, opcode: 0xF20F2C, e: 1, },
{ sse: 1, opcode: 0xF30F2C, e: 1, },
{ sse: 1, opcode: 0xF20F2C, e: 1, custom: 1 },
{ sse: 1, opcode: 0xF30F2C, e: 1, custom: 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, },
{ sse: 1, opcode: 0xF20F2D, e: 1, custom: 1 },
{ sse: 1, opcode: 0xF30F2D, e: 1, custom: 1 },
{ sse: 1, opcode: 0x0F2E, e: 1 },
{ sse: 1, opcode: 0x660F2E, e: 1 },

View file

@ -4463,9 +4463,7 @@ pub unsafe fn instr_F20F2D(source: u64, r: i32) {
// cvtsd2si r32, xmm/m64
write_reg32(r, sse_convert_f64_to_i32(f64::from_bits(source)));
}
#[no_mangle]
pub unsafe fn instr_F20F2D_reg(r1: i32, r2: i32) { instr_F20F2D(read_xmm64s(r1), r2); }
#[no_mangle]
pub unsafe fn instr_F20F2D_mem(addr: i32, r: i32) {
instr_F20F2D(return_on_pagefault!(safe_read64s(addr)), r);
}
@ -4473,9 +4471,7 @@ pub unsafe fn instr_F30F2D(source: f32, r: i32) {
// cvtss2si r32, xmm1/m32
write_reg32(r, sse_convert_f32_to_i32(source));
}
#[no_mangle]
pub unsafe fn instr_F30F2D_reg(r1: i32, r2: i32) { instr_F30F2D(read_xmm_f32(r1), r2); }
#[no_mangle]
pub unsafe fn instr_F30F2D_mem(addr: i32, r: i32) {
instr_F30F2D(return_on_pagefault!(safe_read_f32(addr)), r);
}

View file

@ -4854,6 +4854,64 @@ pub fn instr_660F2B_reg_jit(ctx: &mut JitContext, _r1: u32, _r2: u32) {
codegen::gen_trigger_ud(ctx);
}
pub fn instr_F20F2C_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
codegen::gen_modrm_resolve_safe_read64(ctx, modrm_byte);
ctx.builder.reinterpret_i64_as_f64();
ctx.builder
.call_fn1_f64_ret("sse_convert_with_truncation_f64_to_i32");
codegen::gen_set_reg32(ctx, r);
}
pub fn instr_F20F2C_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
ctx.builder
.const_i32(global_pointers::get_reg_xmm_offset(r1) as i32);
ctx.builder.load_aligned_f64(0);
ctx.builder
.call_fn1_f64_ret("sse_convert_with_truncation_f64_to_i32");
codegen::gen_set_reg32(ctx, r2);
}
pub fn instr_F30F2C_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
ctx.builder.reinterpret_i32_as_f32();
ctx.builder
.call_fn1_f32_ret("sse_convert_with_truncation_f32_to_i32");
codegen::gen_set_reg32(ctx, r);
}
pub fn instr_F30F2C_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
ctx.builder
.const_i32(global_pointers::get_reg_xmm_offset(r1) as i32);
ctx.builder.load_aligned_f32(0);
ctx.builder
.call_fn1_f32_ret("sse_convert_with_truncation_f32_to_i32");
codegen::gen_set_reg32(ctx, r2);
}
pub fn instr_F20F2D_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
codegen::gen_modrm_resolve_safe_read64(ctx, modrm_byte);
ctx.builder.reinterpret_i64_as_f64();
ctx.builder.call_fn1_f64_ret("sse_convert_f64_to_i32");
codegen::gen_set_reg32(ctx, r);
}
pub fn instr_F20F2D_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
ctx.builder
.const_i32(global_pointers::get_reg_xmm_offset(r1) as i32);
ctx.builder.load_aligned_f64(0);
ctx.builder.call_fn1_f64_ret("sse_convert_f64_to_i32");
codegen::gen_set_reg32(ctx, r2);
}
pub fn instr_F30F2D_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
ctx.builder.reinterpret_i32_as_f32();
ctx.builder.call_fn1_f32_ret("sse_convert_f32_to_i32");
codegen::gen_set_reg32(ctx, r);
}
pub fn instr_F30F2D_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
ctx.builder
.const_i32(global_pointers::get_reg_xmm_offset(r1) as i32);
ctx.builder.load_aligned_f32(0);
ctx.builder.call_fn1_f32_ret("sse_convert_f32_to_i32");
codegen::gen_set_reg32(ctx, r2);
}
pub fn instr_0F60_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
mmx_read64_mm_mem32(ctx, "instr_0F60", modrm_byte, r);
}

View file

@ -21,6 +21,9 @@ enum FunctionType {
FN2_RET_TYPE_INDEX,
FN1_RET_I64_TYPE_INDEX,
FN1_F32_RET_TYPE_INDEX,
FN1_F64_RET_TYPE_INDEX,
FN2_I32_I64_TYPE_INDEX,
FN2_I64_I32_TYPE_INDEX,
FN2_I64_I32_RET_TYPE_INDEX,
@ -299,6 +302,20 @@ impl WasmBuilder {
self.output.push(1);
self.output.push(op::TYPE_I64);
},
FunctionType::FN1_F32_RET_TYPE_INDEX => {
self.output.push(op::TYPE_FUNC);
self.output.push(1);
self.output.push(op::TYPE_F32);
self.output.push(1);
self.output.push(op::TYPE_I32);
},
FunctionType::FN1_F64_RET_TYPE_INDEX => {
self.output.push(op::TYPE_FUNC);
self.output.push(1);
self.output.push(op::TYPE_F64);
self.output.push(1);
self.output.push(op::TYPE_I32);
},
FunctionType::FN2_I32_I64_TYPE_INDEX => {
self.output.push(op::TYPE_FUNC);
self.output.push(2);
@ -663,12 +680,24 @@ impl WasmBuilder {
write_leb_u32(&mut self.instruction_body, byte_offset);
}
pub fn load_aligned_f64(&mut self, byte_offset: u32) {
self.instruction_body.push(op::OP_F64LOAD);
self.instruction_body.push(op::MEM_ALIGN64);
write_leb_u32(&mut self.instruction_body, byte_offset);
}
pub fn load_aligned_i64(&mut self, byte_offset: u32) {
self.instruction_body.push(op::OP_I64LOAD);
self.instruction_body.push(op::MEM_ALIGN64);
write_leb_u32(&mut self.instruction_body, byte_offset);
}
pub fn load_aligned_f32(&mut self, byte_offset: u32) {
self.instruction_body.push(op::OP_F32LOAD);
self.instruction_body.push(op::MEM_ALIGN32);
write_leb_u32(&mut self.instruction_body, byte_offset);
}
pub fn load_aligned_i32(&mut self, byte_offset: u32) {
self.instruction_body.push(op::OP_I32LOAD);
self.instruction_body.push(op::MEM_ALIGN32);
@ -765,15 +794,15 @@ impl WasmBuilder {
pub fn ltu_i32(&mut self) { self.instruction_body.push(op::OP_I32LTU); }
//pub fn reinterpret_i32_as_f32(&mut self) {
// self.instruction_body.push(op::OP_F32REINTERPRETI32);
//}
pub fn reinterpret_i32_as_f32(&mut self) {
self.instruction_body.push(op::OP_F32REINTERPRETI32);
}
//pub fn reinterpret_f32_as_i32(&mut self) {
// self.instruction_body.push(op::OP_I32REINTERPRETF32);
//}
//pub fn reinterpret_i64_as_f64(&mut self) {
// self.instruction_body.push(op::OP_F64REINTERPRETI64);
//}
pub fn reinterpret_i64_as_f64(&mut self) {
self.instruction_body.push(op::OP_F64REINTERPRETI64);
}
//pub fn reinterpret_f64_as_i64(&mut self) {
// self.instruction_body.push(op::OP_I64REINTERPRETF64);
//}
@ -890,6 +919,12 @@ impl WasmBuilder {
pub fn call_fn1_ret_i64(&mut self, name: &str) {
self.call_fn(name, FunctionType::FN1_RET_I64_TYPE_INDEX)
}
pub fn call_fn1_f32_ret(&mut self, name: &str) {
self.call_fn(name, FunctionType::FN1_F32_RET_TYPE_INDEX)
}
pub fn call_fn1_f64_ret(&mut self, name: &str) {
self.call_fn(name, FunctionType::FN1_F64_RET_TYPE_INDEX)
}
pub fn call_fn2(&mut self, name: &str) { self.call_fn(name, FunctionType::FN2_TYPE_INDEX) }
pub fn call_fn2_i32_i64(&mut self, name: &str) {
self.call_fn(name, FunctionType::FN2_I32_I64_TYPE_INDEX)