Make singlepass backend emit state mapping information.

This commit is contained in:
losfair 2019-06-12 00:21:43 +08:00
parent da9bf05218
commit ddd0653a25
3 changed files with 155 additions and 80 deletions

View File

@ -19,6 +19,8 @@ pub struct MachineStateDiff {
pub enum MachineValue { pub enum MachineValue {
Undefined, Undefined,
PreserveRegister(RegisterIndex), PreserveRegister(RegisterIndex),
CopyStackBPRelative(i32), // relative to Base Pointer, in byte offset
ExplicitShadow, // indicates that all values above this are above the shadow region
WasmStack(usize), WasmStack(usize),
WasmLocal(usize), WasmLocal(usize),
} }
@ -26,13 +28,15 @@ pub enum MachineValue {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct FunctionStateMap { pub struct FunctionStateMap {
pub initial: MachineState, pub initial: MachineState,
pub shadow_size: usize, // for single-pass backend, 32 bytes on x86-64
pub diffs: Vec<MachineStateDiff>, pub diffs: Vec<MachineStateDiff>,
} }
impl FunctionStateMap { impl FunctionStateMap {
pub fn new(initial: MachineState) -> FunctionStateMap { pub fn new(initial: MachineState, shadow_size: usize) -> FunctionStateMap {
FunctionStateMap { FunctionStateMap {
initial, initial,
shadow_size,
diffs: vec![], diffs: vec![],
} }
} }

View File

@ -141,6 +141,7 @@ enum LocalOrTemp {
pub struct X64FunctionCode { pub struct X64FunctionCode {
signatures: Arc<Map<SigIndex, FuncSig>>, signatures: Arc<Map<SigIndex, FuncSig>>,
function_signatures: Arc<Map<FuncIndex, SigIndex>>, function_signatures: Arc<Map<FuncIndex, SigIndex>>,
last_state: MachineState,
assembler: Option<Assembler>, assembler: Option<Assembler>,
function_labels: Option<HashMap<usize, (DynamicLabel, Option<AssemblyOffset>)>>, function_labels: Option<HashMap<usize, (DynamicLabel, Option<AssemblyOffset>)>>,
@ -349,6 +350,7 @@ impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext, CodegenError>
begin_label_info.1 = Some(begin_offset); begin_label_info.1 = Some(begin_offset);
let begin_label = begin_label_info.0; let begin_label = begin_label_info.0;
let machine = Machine::new();
dynasm!( dynasm!(
assembler assembler
@ -358,7 +360,7 @@ impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext, CodegenError>
let code = X64FunctionCode { let code = X64FunctionCode {
signatures: self.signatures.as_ref().unwrap().clone(), signatures: self.signatures.as_ref().unwrap().clone(),
function_signatures: self.function_signatures.as_ref().unwrap().clone(), function_signatures: self.function_signatures.as_ref().unwrap().clone(),
state_map: FunctionStateMap::default(), last_state: machine.state.clone(),
assembler: Some(assembler), assembler: Some(assembler),
function_labels: Some(function_labels), function_labels: Some(function_labels),
@ -369,7 +371,7 @@ impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext, CodegenError>
num_locals: 0, num_locals: 0,
value_stack: vec![], value_stack: vec![],
control_stack: vec![], control_stack: vec![],
machine: Machine::new(), machine,
unreachable_depth: 0, unreachable_depth: 0,
config: self.config.as_ref().unwrap().clone(), config: self.config.as_ref().unwrap().clone(),
}; };
@ -733,7 +735,7 @@ impl X64FunctionCode {
// Using Red Zone here. // Using Red Zone here.
let loc_b = get_location_released(a, m, value_stack.pop().unwrap()); let loc_b = get_location_released(a, m, value_stack.pop().unwrap());
let loc_a = get_location_released(a, m, value_stack.pop().unwrap()); let loc_a = get_location_released(a, m, value_stack.pop().unwrap());
let ret = m.acquire_locations(a, &[WpType::I32], false)[0]; let ret = m.acquire_locations(a, &[(WpType::I32, MachineValue::WasmStack(value_stack.len()))], false)[0];
if loc_a != ret { if loc_a != ret {
let tmp = m.acquire_temp_gpr().unwrap(); let tmp = m.acquire_temp_gpr().unwrap();
@ -772,7 +774,7 @@ impl X64FunctionCode {
// Using Red Zone here. // Using Red Zone here.
let loc_b = get_location_released(a, m, value_stack.pop().unwrap()); let loc_b = get_location_released(a, m, value_stack.pop().unwrap());
let loc_a = get_location_released(a, m, value_stack.pop().unwrap()); let loc_a = get_location_released(a, m, value_stack.pop().unwrap());
let ret = m.acquire_locations(a, &[WpType::I64], false)[0]; let ret = m.acquire_locations(a, &[(WpType::I64, MachineValue::WasmStack(value_stack.len()))], false)[0];
if loc_a != ret { if loc_a != ret {
let tmp = m.acquire_temp_gpr().unwrap(); let tmp = m.acquire_temp_gpr().unwrap();
@ -812,7 +814,7 @@ impl X64FunctionCode {
// Using Red Zone here. // Using Red Zone here.
let loc_a = get_location_released(a, m, value_stack.pop().unwrap()); let loc_a = get_location_released(a, m, value_stack.pop().unwrap());
let ret = m.acquire_locations(a, &[WpType::I32], false)[0]; let ret = m.acquire_locations(a, &[(WpType::I32, MachineValue::WasmStack(value_stack.len()))], false)[0];
match ret { match ret {
Location::GPR(x) => { Location::GPR(x) => {
Self::emit_relaxed_binop(a, m, Assembler::emit_cmp, Size::S32, loc_b, loc_a); Self::emit_relaxed_binop(a, m, Assembler::emit_cmp, Size::S32, loc_b, loc_a);
@ -854,7 +856,7 @@ impl X64FunctionCode {
// Using Red Zone here. // Using Red Zone here.
let loc_a = get_location_released(a, m, value_stack.pop().unwrap()); let loc_a = get_location_released(a, m, value_stack.pop().unwrap());
let ret = m.acquire_locations(a, &[WpType::I32], false)[0]; let ret = m.acquire_locations(a, &[(WpType::I32, MachineValue::WasmStack(value_stack.len()))], false)[0];
match ret { match ret {
Location::GPR(x) => { Location::GPR(x) => {
Self::emit_relaxed_binop(a, m, Assembler::emit_cmp, Size::S64, loc_b, loc_a); Self::emit_relaxed_binop(a, m, Assembler::emit_cmp, Size::S64, loc_b, loc_a);
@ -893,7 +895,7 @@ impl X64FunctionCode {
f: fn(&mut Assembler, Size, Location, Location), f: fn(&mut Assembler, Size, Location, Location),
) { ) {
let loc = get_location_released(a, m, value_stack.pop().unwrap()); let loc = get_location_released(a, m, value_stack.pop().unwrap());
let ret = m.acquire_locations(a, &[WpType::I32], false)[0]; let ret = m.acquire_locations(a, &[(WpType::I32, MachineValue::WasmStack(value_stack.len()))], false)[0];
match loc { match loc {
Location::Imm32(_) => { Location::Imm32(_) => {
@ -932,7 +934,7 @@ impl X64FunctionCode {
f: fn(&mut Assembler, Size, Location, Location), f: fn(&mut Assembler, Size, Location, Location),
) { ) {
let loc = get_location_released(a, m, value_stack.pop().unwrap()); let loc = get_location_released(a, m, value_stack.pop().unwrap());
let ret = m.acquire_locations(a, &[WpType::I64], false)[0]; let ret = m.acquire_locations(a, &[(WpType::I64, MachineValue::WasmStack(value_stack.len()))], false)[0];
match loc { match loc {
Location::Imm64(_) | Location::Imm32(_) => { Location::Imm64(_) | Location::Imm32(_) => {
@ -972,7 +974,7 @@ impl X64FunctionCode {
) { ) {
let loc_b = get_location_released(a, m, value_stack.pop().unwrap()); let loc_b = get_location_released(a, m, value_stack.pop().unwrap());
let loc_a = get_location_released(a, m, value_stack.pop().unwrap()); let loc_a = get_location_released(a, m, value_stack.pop().unwrap());
let ret = m.acquire_locations(a, &[WpType::I32], false)[0]; let ret = m.acquire_locations(a, &[(WpType::I32, MachineValue::WasmStack(value_stack.len()))], false)[0];
a.emit_mov(Size::S32, loc_b, Location::GPR(GPR::RCX)); a.emit_mov(Size::S32, loc_b, Location::GPR(GPR::RCX));
@ -993,7 +995,7 @@ impl X64FunctionCode {
) { ) {
let loc_b = get_location_released(a, m, value_stack.pop().unwrap()); let loc_b = get_location_released(a, m, value_stack.pop().unwrap());
let loc_a = get_location_released(a, m, value_stack.pop().unwrap()); let loc_a = get_location_released(a, m, value_stack.pop().unwrap());
let ret = m.acquire_locations(a, &[WpType::I64], false)[0]; let ret = m.acquire_locations(a, &[(WpType::I64, MachineValue::WasmStack(value_stack.len()))], false)[0];
a.emit_mov(Size::S64, loc_b, Location::GPR(GPR::RCX)); a.emit_mov(Size::S64, loc_b, Location::GPR(GPR::RCX));
@ -1014,7 +1016,7 @@ impl X64FunctionCode {
) { ) {
let loc_b = get_location_released(a, m, value_stack.pop().unwrap()); let loc_b = get_location_released(a, m, value_stack.pop().unwrap());
let loc_a = get_location_released(a, m, value_stack.pop().unwrap()); let loc_a = get_location_released(a, m, value_stack.pop().unwrap());
let ret = m.acquire_locations(a, &[WpType::F64], false)[0]; let ret = m.acquire_locations(a, &[(WpType::F64, MachineValue::WasmStack(value_stack.len()))], false)[0];
value_stack.push((ret, LocalOrTemp::Temp)); value_stack.push((ret, LocalOrTemp::Temp));
Self::emit_relaxed_avx(a, m, f, loc_a, loc_b, ret); Self::emit_relaxed_avx(a, m, f, loc_a, loc_b, ret);
@ -1029,7 +1031,7 @@ impl X64FunctionCode {
) { ) {
let loc_b = get_location_released(a, m, value_stack.pop().unwrap()); let loc_b = get_location_released(a, m, value_stack.pop().unwrap());
let loc_a = get_location_released(a, m, value_stack.pop().unwrap()); let loc_a = get_location_released(a, m, value_stack.pop().unwrap());
let ret = m.acquire_locations(a, &[WpType::I32], false)[0]; let ret = m.acquire_locations(a, &[(WpType::I32, MachineValue::WasmStack(value_stack.len()))], false)[0];
value_stack.push((ret, LocalOrTemp::Temp)); value_stack.push((ret, LocalOrTemp::Temp));
Self::emit_relaxed_avx(a, m, f, loc_a, loc_b, ret); Self::emit_relaxed_avx(a, m, f, loc_a, loc_b, ret);
@ -1044,7 +1046,7 @@ impl X64FunctionCode {
f: fn(&mut Assembler, XMM, XMMOrMemory, XMM), f: fn(&mut Assembler, XMM, XMMOrMemory, XMM),
) { ) {
let loc = get_location_released(a, m, value_stack.pop().unwrap()); let loc = get_location_released(a, m, value_stack.pop().unwrap());
let ret = m.acquire_locations(a, &[WpType::F64], false)[0]; let ret = m.acquire_locations(a, &[(WpType::F64, MachineValue::WasmStack(value_stack.len()))], false)[0];
value_stack.push((ret, LocalOrTemp::Temp)); value_stack.push((ret, LocalOrTemp::Temp));
Self::emit_relaxed_avx(a, m, f, loc, loc, ret); Self::emit_relaxed_avx(a, m, f, loc, loc, ret);
@ -1059,12 +1061,16 @@ impl X64FunctionCode {
cb: F, cb: F,
params: I, params: I,
) { ) {
// Values pushed in this function are above the shadow region.
m.state.stack_values.push(MachineValue::ExplicitShadow);
let params: Vec<_> = params.collect(); let params: Vec<_> = params.collect();
// Save used GPRs. // Save used GPRs.
let used_gprs = m.get_used_gprs(); let used_gprs = m.get_used_gprs();
for r in used_gprs.iter() { for r in used_gprs.iter() {
a.emit_push(Size::S64, Location::GPR(*r)); a.emit_push(Size::S64, Location::GPR(*r));
m.state.stack_values.push(MachineValue::PreserveRegister(X64Register::GPR(*r).to_index()));
} }
// Save used XMM registers. // Save used XMM registers.
@ -1086,6 +1092,9 @@ impl X64FunctionCode {
Location::Memory(GPR::RCX, (i * 8) as i32), Location::Memory(GPR::RCX, (i * 8) as i32),
); );
} }
for r in used_xmms.iter().rev() {
m.state.stack_values.push(MachineValue::PreserveRegister(X64Register::XMM(*r).to_index()));
}
} }
let mut stack_offset: usize = 0; let mut stack_offset: usize = 0;
@ -1105,6 +1114,7 @@ impl X64FunctionCode {
if (m.get_stack_offset() + used_gprs.len() * 8 + stack_offset) % 16 != 0 { 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)); a.emit_sub(Size::S64, Location::Imm32(8), Location::GPR(GPR::RSP));
stack_offset += 8; stack_offset += 8;
m.state.stack_values.push(MachineValue::Undefined);
} }
let mut call_movs: Vec<(Location, GPR)> = vec![]; let mut call_movs: Vec<(Location, GPR)> = vec![];
@ -1117,6 +1127,23 @@ impl X64FunctionCode {
call_movs.push((*param, x)); call_movs.push((*param, x));
} }
Location::Memory(_, _) => { Location::Memory(_, _) => {
match *param {
Location::GPR(x) => {
m.state.stack_values.push(MachineValue::PreserveRegister(X64Register::GPR(x).to_index()));
}
Location::XMM(x) => {
m.state.stack_values.push(MachineValue::PreserveRegister(X64Register::XMM(x).to_index()));
}
Location::Memory(reg, offset) => {
if reg != GPR::RBP {
unreachable!();
}
m.state.stack_values.push(MachineValue::CopyStackBPRelative(offset));
}
_ => {
m.state.stack_values.push(MachineValue::Undefined);
}
}
match *param { match *param {
// Dynasm bug: RSP in memory operand does not work // Dynasm bug: RSP in memory operand does not work
Location::Imm64(_) | Location::XMM(_) => { Location::Imm64(_) | Location::XMM(_) => {
@ -1182,6 +1209,10 @@ impl X64FunctionCode {
Location::Imm32(stack_offset as u32), Location::Imm32(stack_offset as u32),
Location::GPR(GPR::RSP), Location::GPR(GPR::RSP),
); );
assert!(stack_offset % 8 == 0);
for _ in 0..stack_offset / 8 {
m.state.stack_values.pop().unwrap();
}
} }
// Restore XMMs. // Restore XMMs.
@ -1200,12 +1231,18 @@ impl X64FunctionCode {
Location::Imm32((used_xmms.len() * 8) as u32), Location::Imm32((used_xmms.len() * 8) as u32),
Location::GPR(GPR::RSP), Location::GPR(GPR::RSP),
); );
for _ in 0..used_xmms.len() {
m.state.stack_values.pop().unwrap();
}
} }
// Restore GPRs. // Restore GPRs.
for r in used_gprs.iter().rev() { for r in used_gprs.iter().rev() {
a.emit_pop(Size::S64, Location::GPR(*r)); a.emit_pop(Size::S64, Location::GPR(*r));
m.state.stack_values.pop().unwrap();
} }
assert_eq!(m.state.stack_values.pop().unwrap(), MachineValue::ExplicitShadow);
} }
/// Emits a System V call sequence, specialized for labels as the call target. /// Emits a System V call sequence, specialized for labels as the call target.
@ -1450,6 +1487,8 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
.machine .machine
.init_locals(a, self.num_locals, self.num_params); .init_locals(a, self.num_locals, self.num_params);
println!("initial state = {:?}", self.machine.state);
a.emit_sub(Size::S64, Location::Imm32(32), Location::GPR(GPR::RSP)); // simulate "red zone" if not supported by the platform a.emit_sub(Size::S64, Location::Imm32(32), Location::GPR(GPR::RSP)); // simulate "red zone" if not supported by the platform
self.control_stack.push(ControlFrame { self.control_stack.push(ControlFrame {
@ -1536,7 +1575,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
let loc = self.machine.acquire_locations( let loc = self.machine.acquire_locations(
a, a,
&[WpType::I64], &[(WpType::I64, MachineValue::WasmStack(self.value_stack.len()))],
false, false,
)[0]; )[0];
self.value_stack.push((loc, LocalOrTemp::Temp)); self.value_stack.push((loc, LocalOrTemp::Temp));
@ -1609,7 +1648,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
); );
self.machine.acquire_locations( self.machine.acquire_locations(
a, a,
&[type_to_wp_type(module_info.globals[local_index].desc.ty)], &[(type_to_wp_type(module_info.globals[local_index].desc.ty), MachineValue::WasmStack(self.value_stack.len()))],
false, false,
)[0] )[0]
} }
@ -1629,9 +1668,9 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
); );
self.machine.acquire_locations( self.machine.acquire_locations(
a, a,
&[type_to_wp_type( &[(type_to_wp_type(
module_info.imported_globals[import_index].1.ty, module_info.imported_globals[import_index].1.ty,
)], ), MachineValue::WasmStack(self.value_stack.len()))],
false, false,
)[0] )[0]
} }
@ -1752,7 +1791,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let loc_a = let loc_a =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); 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, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
a.emit_mov(Size::S32, loc_a, Location::GPR(GPR::RAX)); a.emit_mov(Size::S32, loc_a, Location::GPR(GPR::RAX));
a.emit_xor(Size::S32, Location::GPR(GPR::RDX), Location::GPR(GPR::RDX)); a.emit_xor(Size::S32, Location::GPR(GPR::RDX), Location::GPR(GPR::RDX));
Self::emit_relaxed_xdiv( Self::emit_relaxed_xdiv(
@ -1771,7 +1810,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let loc_a = let loc_a =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); 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, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
a.emit_mov(Size::S32, loc_a, Location::GPR(GPR::RAX)); a.emit_mov(Size::S32, loc_a, Location::GPR(GPR::RAX));
a.emit_cdq(); a.emit_cdq();
Self::emit_relaxed_xdiv( Self::emit_relaxed_xdiv(
@ -1790,7 +1829,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let loc_a = let loc_a =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); 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, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
a.emit_mov(Size::S32, loc_a, Location::GPR(GPR::RAX)); a.emit_mov(Size::S32, loc_a, Location::GPR(GPR::RAX));
a.emit_xor(Size::S32, Location::GPR(GPR::RDX), Location::GPR(GPR::RDX)); a.emit_xor(Size::S32, Location::GPR(GPR::RDX), Location::GPR(GPR::RDX));
Self::emit_relaxed_xdiv( Self::emit_relaxed_xdiv(
@ -1809,7 +1848,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let loc_a = let loc_a =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); 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, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
let normal_path = a.get_label(); let normal_path = a.get_label();
let end = a.get_label(); let end = a.get_label();
@ -2009,7 +2048,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let loc_a = let loc_a =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::I64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
a.emit_mov(Size::S64, loc_a, Location::GPR(GPR::RAX)); a.emit_mov(Size::S64, loc_a, Location::GPR(GPR::RAX));
a.emit_xor(Size::S64, Location::GPR(GPR::RDX), Location::GPR(GPR::RDX)); a.emit_xor(Size::S64, Location::GPR(GPR::RDX), Location::GPR(GPR::RDX));
Self::emit_relaxed_xdiv( Self::emit_relaxed_xdiv(
@ -2028,7 +2067,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let loc_a = let loc_a =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::I64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
a.emit_mov(Size::S64, loc_a, Location::GPR(GPR::RAX)); a.emit_mov(Size::S64, loc_a, Location::GPR(GPR::RAX));
a.emit_cqo(); a.emit_cqo();
Self::emit_relaxed_xdiv( Self::emit_relaxed_xdiv(
@ -2047,7 +2086,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let loc_a = let loc_a =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::I64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
a.emit_mov(Size::S64, loc_a, Location::GPR(GPR::RAX)); a.emit_mov(Size::S64, loc_a, Location::GPR(GPR::RAX));
a.emit_xor(Size::S64, Location::GPR(GPR::RDX), Location::GPR(GPR::RDX)); a.emit_xor(Size::S64, Location::GPR(GPR::RDX), Location::GPR(GPR::RDX));
Self::emit_relaxed_xdiv( Self::emit_relaxed_xdiv(
@ -2066,7 +2105,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let loc_a = let loc_a =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::I64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
let normal_path = a.get_label(); let normal_path = a.get_label();
let end = a.get_label(); let end = a.get_label();
@ -2240,7 +2279,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I64ExtendUI32 => { Operator::I64ExtendUI32 => {
let loc = let loc =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::I64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
Self::emit_relaxed_binop( Self::emit_relaxed_binop(
a, a,
@ -2254,7 +2293,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I64ExtendSI32 => { Operator::I64ExtendSI32 => {
let loc = let loc =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::I64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
Self::emit_relaxed_zx_sx( Self::emit_relaxed_zx_sx(
a, a,
@ -2269,7 +2308,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I32WrapI64 => { Operator::I32WrapI64 => {
let loc = let loc =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); 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, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
Self::emit_relaxed_binop( Self::emit_relaxed_binop(
a, a,
@ -2392,7 +2431,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let loc_a = let loc_a =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(a, &[WpType::F32], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::F32, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
let tmp1 = self.machine.acquire_temp_gpr().unwrap(); let tmp1 = self.machine.acquire_temp_gpr().unwrap();
@ -2418,7 +2457,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::F32Abs => { Operator::F32Abs => {
let loc = let loc =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(a, &[WpType::F32], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::F32, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
let tmp = self.machine.acquire_temp_gpr().unwrap(); let tmp = self.machine.acquire_temp_gpr().unwrap();
a.emit_mov(Size::S32, loc, Location::GPR(tmp)); a.emit_mov(Size::S32, loc, Location::GPR(tmp));
@ -2434,7 +2473,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::F32Neg => { Operator::F32Neg => {
let loc = let loc =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(a, &[WpType::F32], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::F32, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
let tmp = self.machine.acquire_temp_gpr().unwrap(); let tmp = self.machine.acquire_temp_gpr().unwrap();
a.emit_mov(Size::S32, loc, Location::GPR(tmp)); a.emit_mov(Size::S32, loc, Location::GPR(tmp));
@ -2554,7 +2593,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let loc_a = let loc_a =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(a, &[WpType::F64], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::F64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
let tmp1 = self.machine.acquire_temp_gpr().unwrap(); let tmp1 = self.machine.acquire_temp_gpr().unwrap();
@ -2589,7 +2628,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::F64Abs => { Operator::F64Abs => {
let loc = let loc =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(a, &[WpType::F64], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::F64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
let tmp = self.machine.acquire_temp_gpr().unwrap(); let tmp = self.machine.acquire_temp_gpr().unwrap();
@ -2611,7 +2650,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::F64Neg => { Operator::F64Neg => {
let loc = let loc =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(a, &[WpType::F64], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::F64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
let tmp = self.machine.acquire_temp_gpr().unwrap(); let tmp = self.machine.acquire_temp_gpr().unwrap();
a.emit_mov(Size::S64, loc, Location::GPR(tmp)); a.emit_mov(Size::S64, loc, Location::GPR(tmp));
@ -2636,7 +2675,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I32ReinterpretF32 => { Operator::I32ReinterpretF32 => {
let loc = let loc =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); 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, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
if loc != ret { if loc != ret {
@ -2653,7 +2692,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::F32ReinterpretI32 => { Operator::F32ReinterpretI32 => {
let loc = let loc =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(a, &[WpType::F32], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::F32, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
if loc != ret { if loc != ret {
@ -2671,7 +2710,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I64ReinterpretF64 => { Operator::I64ReinterpretF64 => {
let loc = let loc =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::I64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
if loc != ret { if loc != ret {
@ -2688,7 +2727,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::F64ReinterpretI64 => { Operator::F64ReinterpretI64 => {
let loc = let loc =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(a, &[WpType::F64], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::F64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
if loc != ret { if loc != ret {
@ -2706,7 +2745,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I32TruncUF32 => { Operator::I32TruncUF32 => {
let loc = let loc =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); 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, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
let tmp_out = self.machine.acquire_temp_gpr().unwrap(); let tmp_out = self.machine.acquire_temp_gpr().unwrap();
let tmp_in = self.machine.acquire_temp_xmm().unwrap(); let tmp_in = self.machine.acquire_temp_xmm().unwrap();
@ -2731,7 +2770,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I32TruncSF32 => { Operator::I32TruncSF32 => {
let loc = let loc =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); 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, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
let tmp_out = self.machine.acquire_temp_gpr().unwrap(); let tmp_out = self.machine.acquire_temp_gpr().unwrap();
let tmp_in = self.machine.acquire_temp_xmm().unwrap(); let tmp_in = self.machine.acquire_temp_xmm().unwrap();
@ -2762,7 +2801,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I64TruncSF32 => { Operator::I64TruncSF32 => {
let loc = let loc =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::I64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
let tmp_out = self.machine.acquire_temp_gpr().unwrap(); let tmp_out = self.machine.acquire_temp_gpr().unwrap();
let tmp_in = self.machine.acquire_temp_xmm().unwrap(); let tmp_in = self.machine.acquire_temp_xmm().unwrap();
@ -2807,7 +2846,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
*/ */
let loc = let loc =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::I64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
let tmp_out = self.machine.acquire_temp_gpr().unwrap(); let tmp_out = self.machine.acquire_temp_gpr().unwrap();
let tmp_in = self.machine.acquire_temp_xmm().unwrap(); // xmm2 let tmp_in = self.machine.acquire_temp_xmm().unwrap(); // xmm2
@ -2862,7 +2901,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I32TruncUF64 => { Operator::I32TruncUF64 => {
let loc = let loc =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); 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, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
let tmp_out = self.machine.acquire_temp_gpr().unwrap(); let tmp_out = self.machine.acquire_temp_gpr().unwrap();
let tmp_in = self.machine.acquire_temp_xmm().unwrap(); let tmp_in = self.machine.acquire_temp_xmm().unwrap();
@ -2887,7 +2926,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I32TruncSF64 => { Operator::I32TruncSF64 => {
let loc = let loc =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); 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, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
let tmp_out = self.machine.acquire_temp_gpr().unwrap(); let tmp_out = self.machine.acquire_temp_gpr().unwrap();
let tmp_in = self.machine.acquire_temp_xmm().unwrap(); let tmp_in = self.machine.acquire_temp_xmm().unwrap();
@ -2923,7 +2962,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I64TruncSF64 => { Operator::I64TruncSF64 => {
let loc = let loc =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::I64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
let tmp_out = self.machine.acquire_temp_gpr().unwrap(); let tmp_out = self.machine.acquire_temp_gpr().unwrap();
let tmp_in = self.machine.acquire_temp_xmm().unwrap(); let tmp_in = self.machine.acquire_temp_xmm().unwrap();
@ -2954,7 +2993,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I64TruncUF64 => { Operator::I64TruncUF64 => {
let loc = let loc =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::I64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
let tmp_out = self.machine.acquire_temp_gpr().unwrap(); let tmp_out = self.machine.acquire_temp_gpr().unwrap();
let tmp_in = self.machine.acquire_temp_xmm().unwrap(); // xmm2 let tmp_in = self.machine.acquire_temp_xmm().unwrap(); // xmm2
@ -3009,7 +3048,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::F32ConvertSI32 => { Operator::F32ConvertSI32 => {
let loc = let loc =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(a, &[WpType::F32], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::F32, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
let tmp_out = self.machine.acquire_temp_xmm().unwrap(); let tmp_out = self.machine.acquire_temp_xmm().unwrap();
let tmp_in = self.machine.acquire_temp_gpr().unwrap(); let tmp_in = self.machine.acquire_temp_gpr().unwrap();
@ -3024,7 +3063,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::F32ConvertUI32 => { Operator::F32ConvertUI32 => {
let loc = let loc =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(a, &[WpType::F32], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::F32, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
let tmp_out = self.machine.acquire_temp_xmm().unwrap(); let tmp_out = self.machine.acquire_temp_xmm().unwrap();
let tmp_in = self.machine.acquire_temp_gpr().unwrap(); let tmp_in = self.machine.acquire_temp_gpr().unwrap();
@ -3039,7 +3078,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::F32ConvertSI64 => { Operator::F32ConvertSI64 => {
let loc = let loc =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(a, &[WpType::F32], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::F32, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
let tmp_out = self.machine.acquire_temp_xmm().unwrap(); let tmp_out = self.machine.acquire_temp_xmm().unwrap();
let tmp_in = self.machine.acquire_temp_gpr().unwrap(); let tmp_in = self.machine.acquire_temp_gpr().unwrap();
@ -3054,7 +3093,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::F32ConvertUI64 => { Operator::F32ConvertUI64 => {
let loc = let loc =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(a, &[WpType::F32], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::F32, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
let tmp_out = self.machine.acquire_temp_xmm().unwrap(); let tmp_out = self.machine.acquire_temp_xmm().unwrap();
let tmp_in = self.machine.acquire_temp_gpr().unwrap(); let tmp_in = self.machine.acquire_temp_gpr().unwrap();
@ -3086,7 +3125,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::F64ConvertSI32 => { Operator::F64ConvertSI32 => {
let loc = let loc =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(a, &[WpType::F64], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::F64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
let tmp_out = self.machine.acquire_temp_xmm().unwrap(); let tmp_out = self.machine.acquire_temp_xmm().unwrap();
let tmp_in = self.machine.acquire_temp_gpr().unwrap(); let tmp_in = self.machine.acquire_temp_gpr().unwrap();
@ -3101,7 +3140,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::F64ConvertUI32 => { Operator::F64ConvertUI32 => {
let loc = let loc =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(a, &[WpType::F64], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::F64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
let tmp_out = self.machine.acquire_temp_xmm().unwrap(); let tmp_out = self.machine.acquire_temp_xmm().unwrap();
let tmp_in = self.machine.acquire_temp_gpr().unwrap(); let tmp_in = self.machine.acquire_temp_gpr().unwrap();
@ -3116,7 +3155,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::F64ConvertSI64 => { Operator::F64ConvertSI64 => {
let loc = let loc =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(a, &[WpType::F64], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::F64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
let tmp_out = self.machine.acquire_temp_xmm().unwrap(); let tmp_out = self.machine.acquire_temp_xmm().unwrap();
let tmp_in = self.machine.acquire_temp_gpr().unwrap(); let tmp_in = self.machine.acquire_temp_gpr().unwrap();
@ -3131,7 +3170,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::F64ConvertUI64 => { Operator::F64ConvertUI64 => {
let loc = let loc =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(a, &[WpType::F64], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::F64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
let tmp_out = self.machine.acquire_temp_xmm().unwrap(); let tmp_out = self.machine.acquire_temp_xmm().unwrap();
let tmp_in = self.machine.acquire_temp_gpr().unwrap(); let tmp_in = self.machine.acquire_temp_gpr().unwrap();
@ -3200,7 +3239,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
self.machine.release_locations_only_stack(a, &released); self.machine.release_locations_only_stack(a, &released);
if return_types.len() > 0 { if return_types.len() > 0 {
let ret = self.machine.acquire_locations(a, &[return_types[0]], false)[0]; let ret = self.machine.acquire_locations(a, &[(return_types[0], MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
a.emit_mov(Size::S64, Location::GPR(GPR::RAX), ret); a.emit_mov(Size::S64, Location::GPR(GPR::RAX), ret);
} }
@ -3313,7 +3352,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
self.machine.release_locations_only_stack(a, &released); self.machine.release_locations_only_stack(a, &released);
if return_types.len() > 0 { if return_types.len() > 0 {
let ret = self.machine.acquire_locations(a, &[return_types[0]], false)[0]; let ret = self.machine.acquire_locations(a, &[(return_types[0], MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
a.emit_mov(Size::S64, Location::GPR(GPR::RAX), ret); a.emit_mov(Size::S64, Location::GPR(GPR::RAX), ret);
} }
@ -3384,7 +3423,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let v_a = let v_a =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::I64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
let end_label = a.get_label(); let end_label = a.get_label();
@ -3473,7 +3512,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
}, },
::std::iter::once(Location::Imm32(memory_index.index() as u32)), ::std::iter::once(Location::Imm32(memory_index.index() as u32)),
); );
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::I64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
a.emit_mov(Size::S64, Location::GPR(GPR::RAX), ret); a.emit_mov(Size::S64, Location::GPR(GPR::RAX), ret);
} }
@ -3513,14 +3552,14 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
self.machine.release_locations_only_stack(a, &[param_pages]); self.machine.release_locations_only_stack(a, &[param_pages]);
} }
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::I64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
a.emit_mov(Size::S64, Location::GPR(GPR::RAX), ret); a.emit_mov(Size::S64, Location::GPR(GPR::RAX), ret);
} }
Operator::I32Load { ref memarg } => { Operator::I32Load { ref memarg } => {
let target = let target =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); 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, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
Self::emit_memory_op( Self::emit_memory_op(
@ -3546,7 +3585,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::F32Load { ref memarg } => { Operator::F32Load { ref memarg } => {
let target = let target =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(a, &[WpType::F32], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::F32, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
Self::emit_memory_op( Self::emit_memory_op(
@ -3572,7 +3611,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I32Load8U { ref memarg } => { Operator::I32Load8U { ref memarg } => {
let target = let target =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); 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, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
Self::emit_memory_op( Self::emit_memory_op(
@ -3599,7 +3638,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I32Load8S { ref memarg } => { Operator::I32Load8S { ref memarg } => {
let target = let target =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); 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, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
Self::emit_memory_op( Self::emit_memory_op(
@ -3626,7 +3665,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I32Load16U { ref memarg } => { Operator::I32Load16U { ref memarg } => {
let target = let target =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); 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, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
Self::emit_memory_op( Self::emit_memory_op(
@ -3653,7 +3692,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I32Load16S { ref memarg } => { Operator::I32Load16S { ref memarg } => {
let target = let target =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); 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, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
Self::emit_memory_op( Self::emit_memory_op(
@ -3784,7 +3823,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I64Load { ref memarg } => { Operator::I64Load { ref memarg } => {
let target = let target =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::I64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
Self::emit_memory_op( Self::emit_memory_op(
@ -3810,7 +3849,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::F64Load { ref memarg } => { Operator::F64Load { ref memarg } => {
let target = let target =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(a, &[WpType::F64], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::F64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
Self::emit_memory_op( Self::emit_memory_op(
@ -3836,7 +3875,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I64Load8U { ref memarg } => { Operator::I64Load8U { ref memarg } => {
let target = let target =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::I64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
Self::emit_memory_op( Self::emit_memory_op(
@ -3863,7 +3902,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I64Load8S { ref memarg } => { Operator::I64Load8S { ref memarg } => {
let target = let target =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::I64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
Self::emit_memory_op( Self::emit_memory_op(
@ -3890,7 +3929,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I64Load16U { ref memarg } => { Operator::I64Load16U { ref memarg } => {
let target = let target =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::I64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
Self::emit_memory_op( Self::emit_memory_op(
@ -3917,7 +3956,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I64Load16S { ref memarg } => { Operator::I64Load16S { ref memarg } => {
let target = let target =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::I64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
Self::emit_memory_op( Self::emit_memory_op(
@ -3944,7 +3983,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I64Load32U { ref memarg } => { Operator::I64Load32U { ref memarg } => {
let target = let target =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::I64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
Self::emit_memory_op( Self::emit_memory_op(
@ -3976,7 +4015,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I64Load32S { ref memarg } => { Operator::I64Load32S { ref memarg } => {
let target = let target =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap()); get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0]; let ret = self.machine.acquire_locations(a, &[(WpType::I64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp)); self.value_stack.push((ret, LocalOrTemp::Temp));
Self::emit_memory_op( Self::emit_memory_op(
@ -4315,7 +4354,9 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
if frame.returns.len() > 0 { if frame.returns.len() > 0 {
assert_eq!(frame.returns.len(), 1); assert_eq!(frame.returns.len(), 1);
let loc = self.machine.acquire_locations(a, &frame.returns, false)[0]; let loc = self.machine.acquire_locations(a, &[
(frame.returns[0], MachineValue::WasmStack(self.value_stack.len()))
], false)[0];
a.emit_mov(Size::S64, Location::GPR(GPR::RAX), loc); a.emit_mov(Size::S64, Location::GPR(GPR::RAX), loc);
self.value_stack.push((loc, LocalOrTemp::Temp)); self.value_stack.push((loc, LocalOrTemp::Temp));
} }
@ -4326,6 +4367,10 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
} }
} }
let diff = self.machine.state.diff(&self.last_state);
println!("Event {:?} caused state difference {:?}", ev, diff);
self.last_state = self.machine.state.clone();
Ok(()) Ok(())
} }
} }

View File

@ -3,6 +3,7 @@ use smallvec::SmallVec;
use std::collections::HashSet; use std::collections::HashSet;
use wasmparser::Type as WpType; use wasmparser::Type as WpType;
use wasmer_runtime_core::state::*; use wasmer_runtime_core::state::*;
use wasmer_runtime_core::state::x64::X64Register;
struct MachineStackOffset(usize); struct MachineStackOffset(usize);
@ -11,7 +12,7 @@ pub struct Machine {
used_xmms: HashSet<XMM>, used_xmms: HashSet<XMM>,
stack_offset: MachineStackOffset, stack_offset: MachineStackOffset,
save_area_offset: Option<MachineStackOffset>, save_area_offset: Option<MachineStackOffset>,
state: MachineState, pub state: MachineState,
} }
impl Machine { impl Machine {
@ -21,6 +22,7 @@ impl Machine {
used_xmms: HashSet::new(), used_xmms: HashSet::new(),
stack_offset: MachineStackOffset(0), stack_offset: MachineStackOffset(0),
save_area_offset: None, save_area_offset: None,
state: x64::new_machine_state(),
} }
} }
@ -131,13 +133,13 @@ impl Machine {
pub fn acquire_locations<E: Emitter>( pub fn acquire_locations<E: Emitter>(
&mut self, &mut self,
assembler: &mut E, assembler: &mut E,
tys: &[WpType], tys: &[(WpType, MachineValue)],
zeroed: bool, zeroed: bool,
) -> SmallVec<[Location; 1]> { ) -> SmallVec<[Location; 1]> {
let mut ret = smallvec![]; let mut ret = smallvec![];
let mut delta_stack_offset: usize = 0; let mut delta_stack_offset: usize = 0;
for ty in tys { for (ty, mv) in tys {
let loc = match *ty { let loc = match *ty {
WpType::F32 | WpType::F64 => self.pick_xmm().map(Location::XMM), WpType::F32 | WpType::F64 => self.pick_xmm().map(Location::XMM),
WpType::I32 | WpType::I64 => self.pick_gpr().map(Location::GPR), WpType::I32 | WpType::I64 => self.pick_gpr().map(Location::GPR),
@ -153,8 +155,12 @@ impl Machine {
}; };
if let Location::GPR(x) = loc { if let Location::GPR(x) = loc {
self.used_gprs.insert(x); self.used_gprs.insert(x);
self.state.register_values[X64Register::GPR(x).to_index().0] = *mv;
} else if let Location::XMM(x) = loc { } else if let Location::XMM(x) = loc {
self.used_xmms.insert(x); self.used_xmms.insert(x);
self.state.register_values[X64Register::XMM(x).to_index().0] = *mv;
} else {
self.state.stack_values.push(*mv);
} }
ret.push(loc); ret.push(loc);
} }
@ -182,9 +188,11 @@ impl Machine {
match *loc { match *loc {
Location::GPR(ref x) => { Location::GPR(ref x) => {
assert_eq!(self.used_gprs.remove(x), true); assert_eq!(self.used_gprs.remove(x), true);
self.state.register_values[X64Register::GPR(*x).to_index().0] = MachineValue::Undefined;
} }
Location::XMM(ref x) => { Location::XMM(ref x) => {
assert_eq!(self.used_xmms.remove(x), true); assert_eq!(self.used_xmms.remove(x), true);
self.state.register_values[X64Register::XMM(*x).to_index().0] = MachineValue::Undefined;
} }
Location::Memory(GPR::RBP, x) => { Location::Memory(GPR::RBP, x) => {
if x >= 0 { if x >= 0 {
@ -196,6 +204,7 @@ impl Machine {
} }
self.stack_offset.0 -= 8; self.stack_offset.0 -= 8;
delta_stack_offset += 8; delta_stack_offset += 8;
self.state.stack_values.pop().unwrap();
} }
_ => {} _ => {}
} }
@ -215,9 +224,11 @@ impl Machine {
match *loc { match *loc {
Location::GPR(ref x) => { Location::GPR(ref x) => {
assert_eq!(self.used_gprs.remove(x), true); assert_eq!(self.used_gprs.remove(x), true);
self.state.register_values[X64Register::GPR(*x).to_index().0] = MachineValue::Undefined;
} }
Location::XMM(ref x) => { Location::XMM(ref x) => {
assert_eq!(self.used_xmms.remove(x), true); assert_eq!(self.used_xmms.remove(x), true);
self.state.register_values[X64Register::XMM(*x).to_index().0] = MachineValue::Undefined;
} }
_ => {} _ => {}
} }
@ -243,6 +254,7 @@ impl Machine {
} }
self.stack_offset.0 -= 8; self.stack_offset.0 -= 8;
delta_stack_offset += 8; delta_stack_offset += 8;
self.state.stack_values.pop().unwrap();
} }
_ => {} _ => {}
} }
@ -327,6 +339,18 @@ impl Machine {
allocated += 1; allocated += 1;
} }
for (i, loc) in locations.iter().enumerate() {
match *loc {
Location::GPR(x) => {
self.state.register_values[X64Register::GPR(x).to_index().0] = MachineValue::WasmLocal(i);
}
Location::Memory(_, _) => {
self.state.stack_values.push(MachineValue::WasmLocal(i));
}
_ => unreachable!(),
}
}
// How many machine stack slots did all the locals use? // How many machine stack slots did all the locals use?
let num_mem_slots = locations let num_mem_slots = locations
.iter() .iter()
@ -348,15 +372,17 @@ impl Machine {
// Save callee-saved registers. // Save callee-saved registers.
for loc in locations.iter() { for loc in locations.iter() {
if let Location::GPR(_) = *loc { if let Location::GPR(x) = *loc {
a.emit_push(Size::S64, *loc); a.emit_push(Size::S64, *loc);
self.stack_offset.0 += 8; self.stack_offset.0 += 8;
self.state.stack_values.push(MachineValue::PreserveRegister(X64Register::GPR(x).to_index()));
} }
} }
// Save R15 for vmctx use. // Save R15 for vmctx use.
a.emit_push(Size::S64, Location::GPR(GPR::R15)); a.emit_push(Size::S64, Location::GPR(GPR::R15));
self.stack_offset.0 += 8; self.stack_offset.0 += 8;
self.state.stack_values.push(MachineValue::PreserveRegister(X64Register::GPR(GPR::R15).to_index()));
// Save the offset of static area. // Save the offset of static area.
self.save_area_offset = Some(MachineStackOffset(self.stack_offset.0)); self.save_area_offset = Some(MachineStackOffset(self.stack_offset.0));
@ -431,7 +457,7 @@ mod test {
fn test_release_locations_keep_state_nopanic() { fn test_release_locations_keep_state_nopanic() {
let mut machine = Machine::new(); let mut machine = Machine::new();
let mut assembler = Assembler::new().unwrap(); let mut assembler = Assembler::new().unwrap();
let locs = machine.acquire_locations(&mut assembler, &[WpType::I32; 10], false); let locs = machine.acquire_locations(&mut assembler, &[(WpType::I32, MachineValue::Undefined); 10], false);
machine.release_locations_keep_state(&mut assembler, &locs); machine.release_locations_keep_state(&mut assembler, &locs);
} }