diff --git a/src/backend.rs b/src/backend.rs index e9c767fe45..e7a7be5445 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -689,6 +689,8 @@ struct Labels { neg_const_f64: Option>, abs_const_f32: Option>, abs_const_f64: Option>, + truncate_f32_const_u32: Option>, + truncate_f64_const_u32: Option>, truncate_f32_const_u64: Option>, truncate_f64_const_u64: Option>, copysign_consts_f32: Option>, @@ -2399,24 +2401,50 @@ impl<'module, M: ModuleContext> Context<'module, M> { ; mov Rq(out.rq().unwrap()), [Rq(reg.unwrap_or(vmctx).rq().unwrap()) + offset as i32] ); + if let Some(reg) = reg { + self.block_state.regs.release(reg); + } + self.push(ValueLocation::Reg(out)); } pub fn set_global(&mut self, global_idx: u32) { let val = self.pop(); - let offset = self.module_context.vmctx_vmglobal_definition( + let (reg, offset) = self.module_context .defined_global_index(global_idx) - .expect("TODO: Support imported globals"), - ); + .map(|defined_global_index| { + (None, self.module_context + .vmctx_vmglobal_definition(defined_global_index)) + }) + .unwrap_or_else(|| { + let reg = self.block_state.regs.take(I64); + + dynasm!(self.asm + ; mov Rq(reg.rq().unwrap()), [ + Rq(VMCTX) + + self.module_context.vmctx_vmglobal_import_from(global_idx) as i32 + ] + ); + + (Some(reg), 0) + }); + let val = self.into_reg(GPRType::Rq, val); + let vmctx = GPR::Rq(VMCTX); // We always use `Rq` (even for floats) since the globals are not necessarily aligned to 128 bits dynasm!(self.asm - ; mov [Rq(VMCTX) + offset as i32], Rq(val.rq().unwrap()) + ; mov [ + Rq(reg.unwrap_or(vmctx).rq().unwrap()) + offset as i32 + ], Rq(val.rq().unwrap()) ); + if let Some(reg) = reg { + self.block_state.regs.release(reg); + } + self.block_state.regs.release(val); } @@ -4560,8 +4588,7 @@ impl<'module, M: ModuleContext> Context<'module, M> { self.align(16); self.define_label(l); dynasm!(self.asm - ; .dword 0 - ; .dword 0x43E00000 + ; .qword 0x43E0000000000000 ); self.labels.truncate_f64_const_u64 = Some(Pending::defined(l)); } @@ -4619,8 +4646,8 @@ impl<'module, M: ModuleContext> Context<'module, M> { self.align(16); self.define_label(conv_const_1); dynasm!(self.asm - ; .qword 4841369599423283200 - ; .qword 4985484787499139072 + ; .qword 0x4330000000000000 + ; .qword 0x4530000000000000 ); self.labels.from_u64_consts_f64 = Some(Pending::defined((conv_const_0, conv_const_1))); } diff --git a/src/function_body.rs b/src/function_body.rs index a357c3400f..21c50ab2e5 100644 --- a/src/function_body.rs +++ b/src/function_body.rs @@ -320,8 +320,6 @@ where ) { (Some(Left(ref cc)), ref mut other @ None) | (ref mut other @ None, Some(Left(ref cc))) => { - // TODO: This doesn't handle the difference in parameters - we need a unified - // CC type where each element can be either a `CCLoc` or a `ValueLocation` assert_eq!(then.to_drop, else_.to_drop); **other = Some(Left(cc.clone()));