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 {
Undefined,
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),
WasmLocal(usize),
}
@ -26,13 +28,15 @@ pub enum MachineValue {
#[derive(Clone, Debug)]
pub struct FunctionStateMap {
pub initial: MachineState,
pub shadow_size: usize, // for single-pass backend, 32 bytes on x86-64
pub diffs: Vec<MachineStateDiff>,
}
impl FunctionStateMap {
pub fn new(initial: MachineState) -> FunctionStateMap {
pub fn new(initial: MachineState, shadow_size: usize) -> FunctionStateMap {
FunctionStateMap {
initial,
shadow_size,
diffs: vec![],
}
}

View File

@ -141,6 +141,7 @@ enum LocalOrTemp {
pub struct X64FunctionCode {
signatures: Arc<Map<SigIndex, FuncSig>>,
function_signatures: Arc<Map<FuncIndex, SigIndex>>,
last_state: MachineState,
assembler: Option<Assembler>,
function_labels: Option<HashMap<usize, (DynamicLabel, Option<AssemblyOffset>)>>,
@ -349,6 +350,7 @@ impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext, CodegenError>
begin_label_info.1 = Some(begin_offset);
let begin_label = begin_label_info.0;
let machine = Machine::new();
dynasm!(
assembler
@ -358,7 +360,7 @@ impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext, CodegenError>
let code = X64FunctionCode {
signatures: self.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),
function_labels: Some(function_labels),
@ -369,7 +371,7 @@ impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext, CodegenError>
num_locals: 0,
value_stack: vec![],
control_stack: vec![],
machine: Machine::new(),
machine,
unreachable_depth: 0,
config: self.config.as_ref().unwrap().clone(),
};
@ -733,7 +735,7 @@ impl X64FunctionCode {
// Using Red Zone here.
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 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 {
let tmp = m.acquire_temp_gpr().unwrap();
@ -772,7 +774,7 @@ impl X64FunctionCode {
// Using Red Zone here.
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 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 {
let tmp = m.acquire_temp_gpr().unwrap();
@ -812,7 +814,7 @@ impl X64FunctionCode {
// Using Red Zone here.
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 {
Location::GPR(x) => {
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.
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 {
Location::GPR(x) => {
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),
) {
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 {
Location::Imm32(_) => {
@ -932,7 +934,7 @@ impl X64FunctionCode {
f: fn(&mut Assembler, Size, Location, Location),
) {
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 {
Location::Imm64(_) | Location::Imm32(_) => {
@ -972,7 +974,7 @@ impl X64FunctionCode {
) {
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 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));
@ -993,7 +995,7 @@ impl X64FunctionCode {
) {
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 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));
@ -1014,7 +1016,7 @@ impl X64FunctionCode {
) {
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 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));
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_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));
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),
) {
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));
Self::emit_relaxed_avx(a, m, f, loc, loc, ret);
@ -1059,12 +1061,16 @@ impl X64FunctionCode {
cb: F,
params: I,
) {
// Values pushed in this function are above the shadow region.
m.state.stack_values.push(MachineValue::ExplicitShadow);
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));
m.state.stack_values.push(MachineValue::PreserveRegister(X64Register::GPR(*r).to_index()));
}
// Save used XMM registers.
@ -1086,6 +1092,9 @@ impl X64FunctionCode {
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;
@ -1105,6 +1114,7 @@ impl X64FunctionCode {
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;
m.state.stack_values.push(MachineValue::Undefined);
}
let mut call_movs: Vec<(Location, GPR)> = vec![];
@ -1117,6 +1127,23 @@ impl X64FunctionCode {
call_movs.push((*param, x));
}
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 {
// Dynasm bug: RSP in memory operand does not work
Location::Imm64(_) | Location::XMM(_) => {
@ -1182,6 +1209,10 @@ impl X64FunctionCode {
Location::Imm32(stack_offset as u32),
Location::GPR(GPR::RSP),
);
assert!(stack_offset % 8 == 0);
for _ in 0..stack_offset / 8 {
m.state.stack_values.pop().unwrap();
}
}
// Restore XMMs.
@ -1200,12 +1231,18 @@ impl X64FunctionCode {
Location::Imm32((used_xmms.len() * 8) as u32),
Location::GPR(GPR::RSP),
);
for _ in 0..used_xmms.len() {
m.state.stack_values.pop().unwrap();
}
}
// Restore GPRs.
for r in used_gprs.iter().rev() {
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.
@ -1450,6 +1487,8 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
.machine
.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
self.control_stack.push(ControlFrame {
@ -1536,7 +1575,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
let loc = self.machine.acquire_locations(
a,
&[WpType::I64],
&[(WpType::I64, MachineValue::WasmStack(self.value_stack.len()))],
false,
)[0];
self.value_stack.push((loc, LocalOrTemp::Temp));
@ -1609,7 +1648,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
);
self.machine.acquire_locations(
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,
)[0]
}
@ -1629,9 +1668,9 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
);
self.machine.acquire_locations(
a,
&[type_to_wp_type(
&[(type_to_wp_type(
module_info.imported_globals[import_index].1.ty,
)],
), MachineValue::WasmStack(self.value_stack.len()))],
false,
)[0]
}
@ -1752,7 +1791,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let loc_a =
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_xor(Size::S32, Location::GPR(GPR::RDX), Location::GPR(GPR::RDX));
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());
let loc_a =
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_cdq();
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());
let loc_a =
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_xor(Size::S32, Location::GPR(GPR::RDX), Location::GPR(GPR::RDX));
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());
let loc_a =
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 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());
let loc_a =
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_xor(Size::S64, Location::GPR(GPR::RDX), Location::GPR(GPR::RDX));
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());
let loc_a =
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_cqo();
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());
let loc_a =
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_xor(Size::S64, Location::GPR(GPR::RDX), Location::GPR(GPR::RDX));
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());
let loc_a =
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 end = a.get_label();
@ -2240,7 +2279,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I64ExtendUI32 => {
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];
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::emit_relaxed_binop(
a,
@ -2254,7 +2293,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
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];
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::emit_relaxed_zx_sx(
a,
@ -2269,7 +2308,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I32WrapI64 => {
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, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp));
Self::emit_relaxed_binop(
a,
@ -2392,7 +2431,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let loc_a =
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));
let tmp1 = self.machine.acquire_temp_gpr().unwrap();
@ -2418,7 +2457,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::F32Abs => {
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];
let ret = self.machine.acquire_locations(a, &[(WpType::F32, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp));
let tmp = self.machine.acquire_temp_gpr().unwrap();
a.emit_mov(Size::S32, loc, Location::GPR(tmp));
@ -2434,7 +2473,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::F32Neg => {
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];
let ret = self.machine.acquire_locations(a, &[(WpType::F32, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp));
let tmp = self.machine.acquire_temp_gpr().unwrap();
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());
let loc_a =
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));
let tmp1 = self.machine.acquire_temp_gpr().unwrap();
@ -2589,7 +2628,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::F64Abs => {
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];
let ret = self.machine.acquire_locations(a, &[(WpType::F64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp));
let tmp = self.machine.acquire_temp_gpr().unwrap();
@ -2611,7 +2650,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::F64Neg => {
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];
let ret = self.machine.acquire_locations(a, &[(WpType::F64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp));
let tmp = self.machine.acquire_temp_gpr().unwrap();
a.emit_mov(Size::S64, loc, Location::GPR(tmp));
@ -2636,7 +2675,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I32ReinterpretF32 => {
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, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp));
if loc != ret {
@ -2653,7 +2692,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::F32ReinterpretI32 => {
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];
let ret = self.machine.acquire_locations(a, &[(WpType::F32, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp));
if loc != ret {
@ -2671,7 +2710,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I64ReinterpretF64 => {
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];
let ret = self.machine.acquire_locations(a, &[(WpType::I64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp));
if loc != ret {
@ -2688,7 +2727,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::F64ReinterpretI64 => {
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];
let ret = self.machine.acquire_locations(a, &[(WpType::F64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp));
if loc != ret {
@ -2706,7 +2745,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I32TruncUF32 => {
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, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp));
let tmp_out = self.machine.acquire_temp_gpr().unwrap();
let tmp_in = self.machine.acquire_temp_xmm().unwrap();
@ -2731,7 +2770,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I32TruncSF32 => {
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, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp));
let tmp_out = self.machine.acquire_temp_gpr().unwrap();
let tmp_in = self.machine.acquire_temp_xmm().unwrap();
@ -2762,7 +2801,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I64TruncSF32 => {
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];
let ret = self.machine.acquire_locations(a, &[(WpType::I64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp));
let tmp_out = self.machine.acquire_temp_gpr().unwrap();
let tmp_in = self.machine.acquire_temp_xmm().unwrap();
@ -2807,7 +2846,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
*/
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];
let ret = self.machine.acquire_locations(a, &[(WpType::I64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp));
let tmp_out = self.machine.acquire_temp_gpr().unwrap();
let tmp_in = self.machine.acquire_temp_xmm().unwrap(); // xmm2
@ -2862,7 +2901,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I32TruncUF64 => {
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, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp));
let tmp_out = self.machine.acquire_temp_gpr().unwrap();
let tmp_in = self.machine.acquire_temp_xmm().unwrap();
@ -2887,7 +2926,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I32TruncSF64 => {
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, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp));
let tmp_out = self.machine.acquire_temp_gpr().unwrap();
let tmp_in = self.machine.acquire_temp_xmm().unwrap();
@ -2923,7 +2962,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I64TruncSF64 => {
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];
let ret = self.machine.acquire_locations(a, &[(WpType::I64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp));
let tmp_out = self.machine.acquire_temp_gpr().unwrap();
let tmp_in = self.machine.acquire_temp_xmm().unwrap();
@ -2954,7 +2993,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I64TruncUF64 => {
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];
let ret = self.machine.acquire_locations(a, &[(WpType::I64, MachineValue::WasmStack(self.value_stack.len()))], false)[0];
self.value_stack.push((ret, LocalOrTemp::Temp));
let tmp_out = self.machine.acquire_temp_gpr().unwrap();
let tmp_in = self.machine.acquire_temp_xmm().unwrap(); // xmm2
@ -3009,7 +3048,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::F32ConvertSI32 => {
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];
let ret = self.machine.acquire_locations(a, &[(WpType::F32, MachineValue::WasmStack(self.value_stack.len()))], 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();
@ -3024,7 +3063,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::F32ConvertUI32 => {
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];
let ret = self.machine.acquire_locations(a, &[(WpType::F32, MachineValue::WasmStack(self.value_stack.len()))], 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();
@ -3039,7 +3078,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
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];
let ret = self.machine.acquire_locations(a, &[(WpType::F32, MachineValue::WasmStack(self.value_stack.len()))], 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();
@ -3054,7 +3093,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
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];
let ret = self.machine.acquire_locations(a, &[(WpType::F32, MachineValue::WasmStack(self.value_stack.len()))], 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();
@ -3086,7 +3125,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::F64ConvertSI32 => {
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];
let ret = self.machine.acquire_locations(a, &[(WpType::F64, MachineValue::WasmStack(self.value_stack.len()))], 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();
@ -3101,7 +3140,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::F64ConvertUI32 => {
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];
let ret = self.machine.acquire_locations(a, &[(WpType::F64, MachineValue::WasmStack(self.value_stack.len()))], 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();
@ -3116,7 +3155,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
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];
let ret = self.machine.acquire_locations(a, &[(WpType::F64, MachineValue::WasmStack(self.value_stack.len()))], 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();
@ -3131,7 +3170,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
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];
let ret = self.machine.acquire_locations(a, &[(WpType::F64, MachineValue::WasmStack(self.value_stack.len()))], 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();
@ -3200,7 +3239,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
self.machine.release_locations_only_stack(a, &released);
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));
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);
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));
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());
let v_a =
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));
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)),
);
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));
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]);
}
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));
a.emit_mov(Size::S64, Location::GPR(GPR::RAX), ret);
}
Operator::I32Load { ref memarg } => {
let target =
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::emit_memory_op(
@ -3546,7 +3585,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::F32Load { ref memarg } => {
let target =
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::emit_memory_op(
@ -3572,7 +3611,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I32Load8U { ref memarg } => {
let target =
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::emit_memory_op(
@ -3599,7 +3638,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I32Load8S { ref memarg } => {
let target =
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::emit_memory_op(
@ -3626,7 +3665,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I32Load16U { ref memarg } => {
let target =
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::emit_memory_op(
@ -3653,7 +3692,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I32Load16S { ref memarg } => {
let target =
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::emit_memory_op(
@ -3784,7 +3823,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I64Load { ref memarg } => {
let target =
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::emit_memory_op(
@ -3810,7 +3849,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::F64Load { ref memarg } => {
let target =
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::emit_memory_op(
@ -3836,7 +3875,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I64Load8U { ref memarg } => {
let target =
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::emit_memory_op(
@ -3863,7 +3902,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I64Load8S { ref memarg } => {
let target =
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::emit_memory_op(
@ -3890,7 +3929,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I64Load16U { ref memarg } => {
let target =
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::emit_memory_op(
@ -3917,7 +3956,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I64Load16S { ref memarg } => {
let target =
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::emit_memory_op(
@ -3944,7 +3983,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I64Load32U { ref memarg } => {
let target =
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::emit_memory_op(
@ -3976,7 +4015,7 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
Operator::I64Load32S { ref memarg } => {
let target =
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::emit_memory_op(
@ -4315,7 +4354,9 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
if frame.returns.len() > 0 {
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);
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(())
}
}

View File

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