mirror of
https://github.com/fluencelabs/wasmer
synced 2025-03-16 16:20:49 +00:00
Align stack to 16 bytes and implement i32 stores.
This commit is contained in:
parent
a43f8ea0b1
commit
07eac13ee3
@ -843,6 +843,9 @@ impl X64FunctionCode {
|
||||
}
|
||||
|
||||
fn emit_call_sysv<I: Iterator<Item = Location>, F: FnOnce(&mut Assembler)>(a: &mut Assembler, m: &mut Machine, cb: F, params: I) {
|
||||
let params: Vec<_> = params.collect();
|
||||
|
||||
// Save used GPRs.
|
||||
let used_gprs = m.get_used_gprs();
|
||||
for r in used_gprs.iter() {
|
||||
a.emit_push(Size::S64, Location::GPR(*r));
|
||||
@ -850,36 +853,60 @@ impl X64FunctionCode {
|
||||
|
||||
let mut stack_offset: usize = 0;
|
||||
|
||||
// Calculate stack offset.
|
||||
for (i, param) in params.iter().enumerate() {
|
||||
let loc = Machine::get_param_location(1 + i);
|
||||
match loc {
|
||||
Location::Memory(_, _) => {
|
||||
stack_offset += 8;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
// Align stack to 16 bytes.
|
||||
if (m.get_stack_offset() + used_gprs.len() * 8 + stack_offset) % 16 != 0 {
|
||||
a.emit_sub(Size::S64, Location::Imm32(8), Location::GPR(GPR::RSP));
|
||||
stack_offset += 8;
|
||||
}
|
||||
|
||||
let mut call_movs: Vec<(Location, GPR)> = vec![];
|
||||
|
||||
for (i, param) in params.enumerate() {
|
||||
// Prepare register & stack parameters.
|
||||
for (i, param) in params.iter().enumerate() {
|
||||
let loc = Machine::get_param_location(1 + i);
|
||||
match loc {
|
||||
Location::GPR(x) => {
|
||||
call_movs.push((param, x));
|
||||
call_movs.push((*param, x));
|
||||
}
|
||||
Location::Memory(_, _) => {
|
||||
a.emit_push(Size::S64, param);
|
||||
stack_offset += 8;
|
||||
a.emit_push(Size::S64, *param);
|
||||
}
|
||||
_ => unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
// Sort register moves so that register are not overwritten before read.
|
||||
sort_call_movs(&mut call_movs);
|
||||
|
||||
// Emit register moves.
|
||||
for (loc, gpr) in call_movs {
|
||||
if loc != Location::GPR(gpr) {
|
||||
a.emit_mov(Size::S64, loc, Location::GPR(gpr));
|
||||
}
|
||||
}
|
||||
|
||||
// Put vmctx as the first parameter.
|
||||
a.emit_mov(Size::S64, Location::GPR(Machine::get_vmctx_reg()), Machine::get_param_location(0)); // vmctx
|
||||
|
||||
cb(a);
|
||||
|
||||
// Restore stack.
|
||||
if stack_offset > 0 {
|
||||
a.emit_add(Size::S64, Location::Imm32(stack_offset as u32), Location::GPR(GPR::RSP));
|
||||
}
|
||||
|
||||
// Restore GPRs.
|
||||
for r in used_gprs.iter().rev() {
|
||||
a.emit_pop(Size::S64, Location::GPR(*r));
|
||||
}
|
||||
@ -1551,6 +1578,28 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
||||
);
|
||||
});
|
||||
}
|
||||
Operator::I32Store8 { memarg } => {
|
||||
let target_value = get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||
let target_addr = get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||
|
||||
Self::emit_memory_op(module_info, a, &mut self.machine, target_addr, memarg.offset as usize, 1, |a, m, addr| {
|
||||
Self::emit_relaxed_binop(
|
||||
a, m, Assembler::emit_mov,
|
||||
Size::S8, target_value, Location::Memory(addr, 0),
|
||||
);
|
||||
});
|
||||
}
|
||||
Operator::I32Store16 { memarg } => {
|
||||
let target_value = get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||
let target_addr = get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||
|
||||
Self::emit_memory_op(module_info, a, &mut self.machine, target_addr, memarg.offset as usize, 2, |a, m, addr| {
|
||||
Self::emit_relaxed_binop(
|
||||
a, m, Assembler::emit_mov,
|
||||
Size::S16, target_value, Location::Memory(addr, 0),
|
||||
);
|
||||
});
|
||||
}
|
||||
Operator::Unreachable => {
|
||||
a.emit_ud2();
|
||||
self.unreachable_depth = 1;
|
||||
|
@ -326,6 +326,12 @@ impl Emitter for Assembler {
|
||||
mov, self, sz, src, dst,
|
||||
{
|
||||
match (sz, src, dst) {
|
||||
(Size::S8, Location::GPR(src), Location::Memory(dst, disp)) => {
|
||||
dynasm!(self ; mov [Rq(dst as u8) + disp], Rb(src as u8));
|
||||
}
|
||||
(Size::S16, Location::GPR(src), Location::Memory(dst, disp)) => {
|
||||
dynasm!(self ; mov [Rq(dst as u8) + disp], Rw(src as u8));
|
||||
}
|
||||
(Size::S32, Location::GPR(src), Location::XMM(dst)) => {
|
||||
dynasm!(self ; movd Rx(dst as u8), Rd(src as u8));
|
||||
},
|
||||
|
@ -21,6 +21,10 @@ impl Machine {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_stack_offset(&self) -> usize {
|
||||
self.stack_offset.0
|
||||
}
|
||||
|
||||
pub fn get_used_gprs(&self) -> Vec<GPR> {
|
||||
self.used_gprs.iter().cloned().collect()
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user