mirror of
https://github.com/fluencelabs/wasmer
synced 2025-03-16 16:20:49 +00:00
F32ConvertUI64, F64ConvertUI64
This commit is contained in:
parent
69d6093955
commit
e78a5ba602
@ -1172,7 +1172,7 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
||||
}
|
||||
|
||||
fn feed_opcode(&mut self, op: Operator, module_info: &ModuleInfo) -> Result<(), CodegenError> {
|
||||
println!("{:?} {}", op, self.value_stack.len());
|
||||
//println!("{:?} {}", op, self.value_stack.len());
|
||||
let was_unreachable;
|
||||
|
||||
if self.unreachable_depth > 0 {
|
||||
@ -1363,11 +1363,7 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
||||
Operator::I32GeS => Self::emit_cmpop_i32(a, &mut self.machine, &mut self.value_stack, Condition::GreaterEqual),
|
||||
Operator::I64Const { value } => {
|
||||
let value = value as u64;
|
||||
if value <= ::std::u32::MAX as u64 {
|
||||
self.value_stack.push((Location::Imm32(value as u32), LocalOrTemp::Temp))
|
||||
} else {
|
||||
self.value_stack.push((Location::Imm64(value), LocalOrTemp::Temp))
|
||||
}
|
||||
self.value_stack.push((Location::Imm64(value), LocalOrTemp::Temp));
|
||||
},
|
||||
Operator::I64Add => Self::emit_binop_i64(a, &mut self.machine, &mut self.value_stack, Assembler::emit_add),
|
||||
Operator::I64Sub => Self::emit_binop_i64(a, &mut self.machine, &mut self.value_stack, Assembler::emit_sub),
|
||||
@ -1770,7 +1766,7 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
||||
self.machine.release_temp_gpr(tmp_in);
|
||||
self.machine.release_temp_xmm(tmp_out);
|
||||
}
|
||||
Operator::F32ConvertSI64 | Operator::F32ConvertUI64 /* FIXME: INCORRECT */ => {
|
||||
Operator::F32ConvertSI64 => {
|
||||
let loc = get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||
let ret = self.machine.acquire_locations(a, &[WpType::F32], false)[0];
|
||||
self.value_stack.push((ret, LocalOrTemp::Temp));
|
||||
@ -1784,6 +1780,36 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
||||
self.machine.release_temp_gpr(tmp_in);
|
||||
self.machine.release_temp_xmm(tmp_out);
|
||||
}
|
||||
Operator::F32ConvertUI64 => {
|
||||
let loc = get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||
let ret = self.machine.acquire_locations(a, &[WpType::F32], false)[0];
|
||||
self.value_stack.push((ret, LocalOrTemp::Temp));
|
||||
let tmp_out = self.machine.acquire_temp_xmm().unwrap();
|
||||
let tmp_in = self.machine.acquire_temp_gpr().unwrap();
|
||||
let tmp = self.machine.acquire_temp_gpr().unwrap();
|
||||
|
||||
let do_convert = a.get_label();
|
||||
let end_convert = a.get_label();
|
||||
|
||||
a.emit_mov(Size::S64, loc, Location::GPR(tmp_in));
|
||||
a.emit_test_gpr_64(tmp_in);
|
||||
a.emit_jmp(Condition::Signed, do_convert);
|
||||
a.emit_vcvtsi2ss_64(tmp_out, GPROrMemory::GPR(tmp_in), tmp_out);
|
||||
a.emit_jmp(Condition::None, end_convert);
|
||||
a.emit_label(do_convert);
|
||||
a.emit_mov(Size::S64, Location::GPR(tmp_in), Location::GPR(tmp));
|
||||
a.emit_and(Size::S64, Location::Imm32(1), Location::GPR(tmp));
|
||||
a.emit_shr(Size::S64, Location::Imm8(1), Location::GPR(tmp_in));
|
||||
a.emit_or(Size::S64, Location::GPR(tmp), Location::GPR(tmp_in));
|
||||
a.emit_vcvtsi2ss_64(tmp_out, GPROrMemory::GPR(tmp_in), tmp_out);
|
||||
a.emit_vaddss(tmp_out, XMMOrMemory::XMM(tmp_out), tmp_out);
|
||||
a.emit_label(end_convert);
|
||||
a.emit_mov(Size::S32, Location::XMM(tmp_out), ret);
|
||||
|
||||
self.machine.release_temp_gpr(tmp);
|
||||
self.machine.release_temp_gpr(tmp_in);
|
||||
self.machine.release_temp_xmm(tmp_out);
|
||||
}
|
||||
|
||||
Operator::F64ConvertSI32 => {
|
||||
let loc = get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||
@ -1813,7 +1839,7 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
||||
self.machine.release_temp_gpr(tmp_in);
|
||||
self.machine.release_temp_xmm(tmp_out);
|
||||
}
|
||||
Operator::F64ConvertSI64 | Operator::F64ConvertUI64 /* FIXME: INCORRECT */ => {
|
||||
Operator::F64ConvertSI64 => {
|
||||
let loc = get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||
let ret = self.machine.acquire_locations(a, &[WpType::F64], false)[0];
|
||||
self.value_stack.push((ret, LocalOrTemp::Temp));
|
||||
@ -1827,6 +1853,36 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
||||
self.machine.release_temp_gpr(tmp_in);
|
||||
self.machine.release_temp_xmm(tmp_out);
|
||||
}
|
||||
Operator::F64ConvertUI64 => {
|
||||
let loc = get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||
let ret = self.machine.acquire_locations(a, &[WpType::F64], false)[0];
|
||||
self.value_stack.push((ret, LocalOrTemp::Temp));
|
||||
let tmp_out = self.machine.acquire_temp_xmm().unwrap();
|
||||
let tmp_in = self.machine.acquire_temp_gpr().unwrap();
|
||||
let tmp = self.machine.acquire_temp_gpr().unwrap();
|
||||
|
||||
let do_convert = a.get_label();
|
||||
let end_convert = a.get_label();
|
||||
|
||||
a.emit_mov(Size::S64, loc, Location::GPR(tmp_in));
|
||||
a.emit_test_gpr_64(tmp_in);
|
||||
a.emit_jmp(Condition::Signed, do_convert);
|
||||
a.emit_vcvtsi2sd_64(tmp_out, GPROrMemory::GPR(tmp_in), tmp_out);
|
||||
a.emit_jmp(Condition::None, end_convert);
|
||||
a.emit_label(do_convert);
|
||||
a.emit_mov(Size::S64, Location::GPR(tmp_in), Location::GPR(tmp));
|
||||
a.emit_and(Size::S64, Location::Imm32(1), Location::GPR(tmp));
|
||||
a.emit_shr(Size::S64, Location::Imm8(1), Location::GPR(tmp_in));
|
||||
a.emit_or(Size::S64, Location::GPR(tmp), Location::GPR(tmp_in));
|
||||
a.emit_vcvtsi2sd_64(tmp_out, GPROrMemory::GPR(tmp_in), tmp_out);
|
||||
a.emit_vaddsd(tmp_out, XMMOrMemory::XMM(tmp_out), tmp_out);
|
||||
a.emit_label(end_convert);
|
||||
a.emit_mov(Size::S64, Location::XMM(tmp_out), ret);
|
||||
|
||||
self.machine.release_temp_gpr(tmp);
|
||||
self.machine.release_temp_gpr(tmp_in);
|
||||
self.machine.release_temp_xmm(tmp_out);
|
||||
}
|
||||
|
||||
Operator::Call { function_index } => {
|
||||
let function_index = function_index as usize;
|
||||
|
@ -59,6 +59,7 @@ pub enum Condition {
|
||||
LessEqual,
|
||||
Equal,
|
||||
NotEqual,
|
||||
Signed,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
@ -181,6 +182,8 @@ pub trait Emitter {
|
||||
fn emit_vcvtsi2sd_32(&mut self, src1: XMM, src2: GPROrMemory, dst: XMM);
|
||||
fn emit_vcvtsi2sd_64(&mut self, src1: XMM, src2: GPROrMemory, dst: XMM);
|
||||
|
||||
fn emit_test_gpr_64(&mut self, reg: GPR);
|
||||
|
||||
fn emit_ud2(&mut self);
|
||||
fn emit_ret(&mut self);
|
||||
fn emit_call_label(&mut self, label: Self::Label);
|
||||
@ -449,12 +452,18 @@ impl Emitter for Assembler {
|
||||
(Size::S8, Location::GPR(src), Location::Memory(dst, disp)) => {
|
||||
dynasm!(self ; mov [Rq(dst as u8) + disp], Rb(src as u8));
|
||||
}
|
||||
(Size::S8, Location::Memory(src, disp), Location::GPR(dst)) => {
|
||||
dynasm!(self ; mov Rb(dst as u8), [Rq(src as u8) + disp]);
|
||||
}
|
||||
(Size::S8, Location::Imm32(src), Location::Memory(dst, disp)) => {
|
||||
dynasm!(self ; mov BYTE [Rq(dst as u8) + disp], src as i8);
|
||||
}
|
||||
(Size::S16, Location::GPR(src), Location::Memory(dst, disp)) => {
|
||||
dynasm!(self ; mov [Rq(dst as u8) + disp], Rw(src as u8));
|
||||
}
|
||||
(Size::S16, Location::Memory(src, disp), Location::GPR(dst)) => {
|
||||
dynasm!(self ; mov Rw(dst as u8), [Rq(src as u8) + disp]);
|
||||
}
|
||||
(Size::S16, Location::Imm32(src), Location::Memory(dst, disp)) => {
|
||||
dynasm!(self ; mov WORD [Rq(dst as u8) + disp], src as i16);
|
||||
}
|
||||
@ -534,6 +543,7 @@ impl Emitter for Assembler {
|
||||
Condition::LessEqual => jmp_op!(jle, self, label),
|
||||
Condition::Equal => jmp_op!(je, self, label),
|
||||
Condition::NotEqual => jmp_op!(jne, self, label),
|
||||
Condition::Signed => jmp_op!(js, self, label),
|
||||
}
|
||||
}
|
||||
fn emit_jmp_location(&mut self, loc: Location) {
|
||||
@ -556,6 +566,7 @@ impl Emitter for Assembler {
|
||||
Condition::LessEqual => trap_op!(jle, self),
|
||||
Condition::Equal => trap_op!(je, self),
|
||||
Condition::NotEqual => trap_op!(jne, self),
|
||||
Condition::Signed => trap_op!(js, self),
|
||||
}
|
||||
}
|
||||
fn emit_set(&mut self, condition: Condition, dst: GPR) {
|
||||
@ -570,6 +581,7 @@ impl Emitter for Assembler {
|
||||
Condition::LessEqual => dynasm!(self ; setle Rb(dst as u8)),
|
||||
Condition::Equal => dynasm!(self ; sete Rb(dst as u8)),
|
||||
Condition::NotEqual => dynasm!(self ; setne Rb(dst as u8)),
|
||||
Condition::Signed => dynasm!(self ; sets Rb(dst as u8)),
|
||||
_ => unreachable!()
|
||||
}
|
||||
}
|
||||
@ -806,6 +818,10 @@ impl Emitter for Assembler {
|
||||
}
|
||||
}
|
||||
|
||||
fn emit_test_gpr_64(&mut self, reg: GPR) {
|
||||
dynasm!(self ; test Rq(reg as u8), Rq(reg as u8));
|
||||
}
|
||||
|
||||
fn emit_ud2(&mut self) {
|
||||
dynasm!(self ; ud2);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user