Implement imported mutable globals
This commit is contained in:
@@ -689,6 +689,8 @@ struct Labels {
|
|||||||
neg_const_f64: Option<Pending<Label>>,
|
neg_const_f64: Option<Pending<Label>>,
|
||||||
abs_const_f32: Option<Pending<Label>>,
|
abs_const_f32: Option<Pending<Label>>,
|
||||||
abs_const_f64: Option<Pending<Label>>,
|
abs_const_f64: Option<Pending<Label>>,
|
||||||
|
truncate_f32_const_u32: Option<Pending<Label>>,
|
||||||
|
truncate_f64_const_u32: Option<Pending<Label>>,
|
||||||
truncate_f32_const_u64: Option<Pending<Label>>,
|
truncate_f32_const_u64: Option<Pending<Label>>,
|
||||||
truncate_f64_const_u64: Option<Pending<Label>>,
|
truncate_f64_const_u64: Option<Pending<Label>>,
|
||||||
copysign_consts_f32: Option<Pending<(Label, Label)>>,
|
copysign_consts_f32: Option<Pending<(Label, Label)>>,
|
||||||
@@ -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]
|
; 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));
|
self.push(ValueLocation::Reg(out));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_global(&mut self, global_idx: u32) {
|
pub fn set_global(&mut self, global_idx: u32) {
|
||||||
let val = self.pop();
|
let val = self.pop();
|
||||||
let offset = self.module_context.vmctx_vmglobal_definition(
|
let (reg, offset) =
|
||||||
self.module_context
|
self.module_context
|
||||||
.defined_global_index(global_idx)
|
.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 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
|
// We always use `Rq` (even for floats) since the globals are not necessarily aligned to 128 bits
|
||||||
dynasm!(self.asm
|
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);
|
self.block_state.regs.release(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4560,8 +4588,7 @@ impl<'module, M: ModuleContext> Context<'module, M> {
|
|||||||
self.align(16);
|
self.align(16);
|
||||||
self.define_label(l);
|
self.define_label(l);
|
||||||
dynasm!(self.asm
|
dynasm!(self.asm
|
||||||
; .dword 0
|
; .qword 0x43E0000000000000
|
||||||
; .dword 0x43E00000
|
|
||||||
);
|
);
|
||||||
self.labels.truncate_f64_const_u64 = Some(Pending::defined(l));
|
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.align(16);
|
||||||
self.define_label(conv_const_1);
|
self.define_label(conv_const_1);
|
||||||
dynasm!(self.asm
|
dynasm!(self.asm
|
||||||
; .qword 4841369599423283200
|
; .qword 0x4330000000000000
|
||||||
; .qword 4985484787499139072
|
; .qword 0x4530000000000000
|
||||||
);
|
);
|
||||||
self.labels.from_u64_consts_f64 = Some(Pending::defined((conv_const_0, conv_const_1)));
|
self.labels.from_u64_consts_f64 = Some(Pending::defined((conv_const_0, conv_const_1)));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -320,8 +320,6 @@ where
|
|||||||
) {
|
) {
|
||||||
(Some(Left(ref cc)), ref mut other @ None)
|
(Some(Left(ref cc)), ref mut other @ None)
|
||||||
| (ref mut other @ None, Some(Left(ref cc))) => {
|
| (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);
|
assert_eq!(then.to_drop, else_.to_drop);
|
||||||
**other = Some(Left(cc.clone()));
|
**other = Some(Left(cc.clone()));
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user