mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-28 08:01:33 +00:00
Cleanup calling & implement I64ExtendSI32.
This commit is contained in:
@ -467,6 +467,43 @@ impl X64FunctionCode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn emit_relaxed_zx_sx(
|
||||||
|
a: &mut Assembler,
|
||||||
|
m: &mut Machine,
|
||||||
|
op: fn(&mut Assembler, Size, Location, Size, Location),
|
||||||
|
sz_src: Size,
|
||||||
|
mut src: Location,
|
||||||
|
sz_dst: Size,
|
||||||
|
dst: Location,
|
||||||
|
) {
|
||||||
|
let tmp_src = m.acquire_temp_gpr().unwrap();
|
||||||
|
let tmp_dst = m.acquire_temp_gpr().unwrap();
|
||||||
|
|
||||||
|
match src {
|
||||||
|
Location::Imm32(_) | Location::Imm64(_) => {
|
||||||
|
a.emit_mov(Size::S64, src, Location::GPR(tmp_src));
|
||||||
|
src = Location::GPR(tmp_src);
|
||||||
|
}
|
||||||
|
Location::Memory(_, _) | Location::GPR(_) => {}
|
||||||
|
_ => unreachable!()
|
||||||
|
}
|
||||||
|
|
||||||
|
match dst {
|
||||||
|
Location::Imm32(_) | Location::Imm64(_) => unreachable!(),
|
||||||
|
Location::Memory(_, _) => {
|
||||||
|
op(a, sz_src, src, sz_dst, Location::GPR(tmp_dst));
|
||||||
|
a.emit_mov(Size::S64, Location::GPR(tmp_dst), dst);
|
||||||
|
}
|
||||||
|
Location::GPR(_) => {
|
||||||
|
op(a, sz_src, src, sz_dst, dst);
|
||||||
|
}
|
||||||
|
_ => unreachable!()
|
||||||
|
}
|
||||||
|
|
||||||
|
m.release_temp_gpr(tmp_dst);
|
||||||
|
m.release_temp_gpr(tmp_src);
|
||||||
|
}
|
||||||
|
|
||||||
fn emit_relaxed_binop(
|
fn emit_relaxed_binop(
|
||||||
a: &mut Assembler,
|
a: &mut Assembler,
|
||||||
m: &mut Machine,
|
m: &mut Machine,
|
||||||
@ -803,6 +840,49 @@ impl X64FunctionCode {
|
|||||||
f(a, Size::S64, Location::GPR(GPR::RCX), ret);
|
f(a, Size::S64, Location::GPR(GPR::RCX), ret);
|
||||||
value_stack.push((ret, LocalOrTemp::Temp));
|
value_stack.push((ret, LocalOrTemp::Temp));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn emit_call_sysv<I: Iterator<Item = Location>>(a: &mut Assembler, m: &mut Machine, label: DynamicLabel, params: I) {
|
||||||
|
let used_gprs = m.get_used_gprs();
|
||||||
|
for r in used_gprs.iter() {
|
||||||
|
a.emit_push(Size::S64, Location::GPR(*r));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut stack_offset: usize = 0;
|
||||||
|
|
||||||
|
let mut call_movs: Vec<(Location, GPR)> = vec![];
|
||||||
|
|
||||||
|
for (i, param) in params.enumerate() {
|
||||||
|
let loc = Machine::get_param_location(1 + i);
|
||||||
|
match loc {
|
||||||
|
Location::GPR(x) => {
|
||||||
|
call_movs.push((param, x));
|
||||||
|
}
|
||||||
|
Location::Memory(_, _) => {
|
||||||
|
a.emit_push(Size::S64, param);
|
||||||
|
stack_offset += 8;
|
||||||
|
}
|
||||||
|
_ => unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sort_call_movs(&mut call_movs);
|
||||||
|
for (loc, gpr) in call_movs {
|
||||||
|
if loc != Location::GPR(gpr) {
|
||||||
|
a.emit_mov(Size::S64, loc, Location::GPR(gpr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a.emit_mov(Size::S64, Location::GPR(Machine::get_vmctx_reg()), Machine::get_param_location(0)); // vmctx
|
||||||
|
a.emit_call_label(label);
|
||||||
|
|
||||||
|
if stack_offset > 0 {
|
||||||
|
a.emit_add(Size::S64, Location::Imm32(stack_offset as u32), Location::GPR(GPR::RSP));
|
||||||
|
}
|
||||||
|
|
||||||
|
for r in used_gprs.iter().rev() {
|
||||||
|
a.emit_pop(Size::S64, Location::GPR(*r));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FunctionCodeGenerator for X64FunctionCode {
|
impl FunctionCodeGenerator for X64FunctionCode {
|
||||||
@ -1109,6 +1189,15 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
|||||||
Size::S32, loc, ret,
|
Size::S32, loc, ret,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Operator::I64ExtendSI32 => {
|
||||||
|
let loc = get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||||
|
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0];
|
||||||
|
self.value_stack.push((ret, LocalOrTemp::Temp));
|
||||||
|
Self::emit_relaxed_zx_sx(
|
||||||
|
a, &mut self.machine, Assembler::emit_movsx,
|
||||||
|
Size::S32, loc, Size::S64, ret,
|
||||||
|
);
|
||||||
|
}
|
||||||
Operator::I32WrapI64 => {
|
Operator::I32WrapI64 => {
|
||||||
let loc = get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
let loc = get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||||
let ret = self.machine.acquire_locations(a, &[WpType::I32], false)[0];
|
let ret = self.machine.acquire_locations(a, &[WpType::I32], false)[0];
|
||||||
@ -1141,46 +1230,7 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
|||||||
.collect();
|
.collect();
|
||||||
self.machine.release_locations_only_regs(&released);
|
self.machine.release_locations_only_regs(&released);
|
||||||
|
|
||||||
let used_gprs = self.machine.get_used_gprs();
|
Self::emit_call_sysv(a, &mut self.machine, label, params.iter().map(|&(x, _)| x));
|
||||||
for r in used_gprs.iter() {
|
|
||||||
a.emit_push(Size::S64, Location::GPR(*r));
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut stack_offset: usize = 0;
|
|
||||||
|
|
||||||
let mut call_movs: Vec<(Location, GPR)> = vec![];
|
|
||||||
|
|
||||||
for i in (0..param_types.len()).rev() {
|
|
||||||
let loc = Machine::get_param_location(1 + i);
|
|
||||||
match loc {
|
|
||||||
Location::GPR(x) => {
|
|
||||||
call_movs.push((params[i].0, x));
|
|
||||||
}
|
|
||||||
Location::Memory(_, _) => {
|
|
||||||
a.emit_push(Size::S64, params[i].0);
|
|
||||||
stack_offset += 8;
|
|
||||||
}
|
|
||||||
_ => unreachable!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sort_call_movs(&mut call_movs);
|
|
||||||
for (loc, gpr) in call_movs {
|
|
||||||
if loc != Location::GPR(gpr) {
|
|
||||||
a.emit_mov(Size::S64, loc, Location::GPR(gpr));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
a.emit_mov(Size::S64, Location::GPR(Machine::get_vmctx_reg()), Machine::get_param_location(0)); // vmctx
|
|
||||||
a.emit_call_label(label);
|
|
||||||
|
|
||||||
if stack_offset > 0 {
|
|
||||||
a.emit_add(Size::S64, Location::Imm32(stack_offset as u32), Location::GPR(GPR::RSP));
|
|
||||||
}
|
|
||||||
|
|
||||||
for r in used_gprs.iter().rev() {
|
|
||||||
a.emit_pop(Size::S64, Location::GPR(*r));
|
|
||||||
}
|
|
||||||
|
|
||||||
self.machine.release_locations_only_stack(a, &released);
|
self.machine.release_locations_only_stack(a, &released);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user