Refactor and optimize memory access
This commit is contained in:
parent
f759443802
commit
610b66e4cb
@ -1,3 +1,4 @@
|
|||||||
pub mod edition;
|
pub mod edition;
|
||||||
pub mod helper;
|
pub mod helper;
|
||||||
pub mod translator;
|
pub mod translator;
|
||||||
|
pub mod visitor;
|
||||||
|
@ -47,24 +47,24 @@ pub struct Body<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Body<'a> {
|
impl<'a> Body<'a> {
|
||||||
pub fn new(spec: &'a dyn Edition) -> Self {
|
pub fn new(spec: &'a dyn Edition, base: u32) -> Self {
|
||||||
|
let mut reg = Register::new();
|
||||||
|
|
||||||
|
reg.push(base);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
spec,
|
spec,
|
||||||
|
reg,
|
||||||
label_list: vec![],
|
label_list: vec![],
|
||||||
table_list: Vec::new(),
|
table_list: Vec::new(),
|
||||||
reg: Register::new(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gen(&mut self, index: usize, module: &Module) -> Result<Vec<u8>> {
|
pub fn generate(&mut self, index: usize, m: &Module, w: Writer) -> Result<()> {
|
||||||
let mut w = Vec::new();
|
m.code[index]
|
||||||
|
|
||||||
module.code[index]
|
|
||||||
.inst_list
|
.inst_list
|
||||||
.iter()
|
.iter()
|
||||||
.try_for_each(|v| self.gen_inst(index, v, module, &mut w))?;
|
.try_for_each(|v| self.gen_inst(index, v, m, w))
|
||||||
|
|
||||||
Ok(w)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gen_jump(&mut self, up: u32, w: Writer) -> Result<()> {
|
fn gen_jump(&mut self, up: u32, w: Writer) -> Result<()> {
|
||||||
@ -107,14 +107,14 @@ impl<'a> Body<'a> {
|
|||||||
|
|
||||||
self.reg.push(1);
|
self.reg.push(1);
|
||||||
|
|
||||||
write!(w, "{0} = load.{1}(MEMORY_LIST[0], {0} + {2}) ", reg, t, o)
|
write!(w, "{0} = load.{1}(memory_at_0, {0} + {2}) ", reg, t, o)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gen_store(&mut self, t: &str, o: u32, f: &Code, w: Writer) -> Result<()> {
|
fn gen_store(&mut self, t: &str, o: u32, f: &Code, w: Writer) -> Result<()> {
|
||||||
let val = f.var_name_of(self.reg.pop(1));
|
let val = f.var_name_of(self.reg.pop(1));
|
||||||
let reg = f.var_name_of(self.reg.pop(1));
|
let reg = f.var_name_of(self.reg.pop(1));
|
||||||
|
|
||||||
write!(w, "store.{}(MEMORY_LIST[0], {} + {}, {}) ", t, reg, o, val)
|
write!(w, "store.{}(memory_at_0, {} + {}, {}) ", t, reg, o, val)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gen_const<T: Display>(&mut self, val: T, f: &Code, w: Writer) -> Result<()> {
|
fn gen_const<T: Display>(&mut self, val: T, f: &Code, w: Writer) -> Result<()> {
|
||||||
@ -342,14 +342,14 @@ impl<'a> Body<'a> {
|
|||||||
Instruction::CurrentMemory(index) => {
|
Instruction::CurrentMemory(index) => {
|
||||||
let reg = func.var_name_of(self.reg.push(1));
|
let reg = func.var_name_of(self.reg.push(1));
|
||||||
|
|
||||||
write!(w, "{} = rt.memory.size(MEMORY_LIST[{}])", reg, index)
|
write!(w, "{} = rt.memory.size(memory_at_{})", reg, index)
|
||||||
}
|
}
|
||||||
Instruction::GrowMemory(index) => {
|
Instruction::GrowMemory(index) => {
|
||||||
let reg = func.var_name_of(self.reg.pop(1));
|
let reg = func.var_name_of(self.reg.pop(1));
|
||||||
|
|
||||||
self.reg.push(1);
|
self.reg.push(1);
|
||||||
|
|
||||||
write!(w, "{0} = rt.memory.grow(MEMORY_LIST[{1}], {0})", reg, index)
|
write!(w, "{0} = rt.memory.grow(memory_at_{1}, {0})", reg, index)
|
||||||
}
|
}
|
||||||
Instruction::I32Const(v) => self.gen_const(v, func, w),
|
Instruction::I32Const(v) => self.gen_const(v, func, w),
|
||||||
Instruction::I64Const(v) => self.gen_const(self.spec.i64(*v), func, w),
|
Instruction::I64Const(v) => self.gen_const(self.spec.i64(*v), func, w),
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::io::{Result, Write};
|
use std::{collections::BTreeSet, io::Result};
|
||||||
|
|
||||||
use parity_wasm::elements::Instruction;
|
use parity_wasm::elements::Instruction;
|
||||||
|
|
||||||
@ -6,6 +6,7 @@ use crate::{
|
|||||||
backend::{
|
backend::{
|
||||||
edition::data::Edition,
|
edition::data::Edition,
|
||||||
helper::writer::{write_ordered, Writer},
|
helper::writer::{write_ordered, Writer},
|
||||||
|
visitor::{memory::visit_for_memory, register::visit_for_register},
|
||||||
},
|
},
|
||||||
data::Module,
|
data::Module,
|
||||||
};
|
};
|
||||||
@ -27,49 +28,52 @@ pub fn gen_init_expression(code: &[Instruction], w: Writer) -> Result<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gen_prelude(num_param: u32, num_local: u32) -> Result<Vec<u8>> {
|
fn gen_prelude(num_stack: u32, num_param: u32, num_local: u32, w: Writer) -> Result<()> {
|
||||||
let mut w = Vec::new();
|
let num_reg = num_stack - num_param - num_local;
|
||||||
|
|
||||||
write!(w, "function(")?;
|
write!(w, "function(")?;
|
||||||
write_ordered("param", num_param, &mut w)?;
|
write_ordered("param", num_param, w)?;
|
||||||
write!(w, ")")?;
|
write!(w, ")")?;
|
||||||
|
|
||||||
if num_local != 0 {
|
if num_local != 0 {
|
||||||
let zero = vec!["0"; num_local as usize].join(", ");
|
let zero = vec!["0"; num_local as usize].join(", ");
|
||||||
|
|
||||||
write!(w, "local ")?;
|
write!(w, "local ")?;
|
||||||
write_ordered("var", num_local, &mut w)?;
|
write_ordered("var", num_local, w)?;
|
||||||
write!(w, "= {} ", zero)?;
|
write!(w, "= {} ", zero)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(w)
|
if num_reg != 0 {
|
||||||
}
|
|
||||||
|
|
||||||
fn gen_reg_list(last: u32, num_param: u32, num_local: u32) -> Result<Vec<u8>> {
|
|
||||||
let mut w = Vec::new();
|
|
||||||
let num = last - num_local - num_param;
|
|
||||||
|
|
||||||
if num != 0 {
|
|
||||||
write!(w, "local ")?;
|
write!(w, "local ")?;
|
||||||
write_ordered("reg", num, &mut w)?;
|
write_ordered("reg", num_reg, w)?;
|
||||||
write!(w, " ")?;
|
write!(w, " ")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(w)
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gen_memory(set: BTreeSet<u8>, w: Writer) -> Result<()> {
|
||||||
|
set.into_iter()
|
||||||
|
.try_for_each(|i| write!(w, "local memory_at_{0} = MEMORY_LIST[{0}]", i))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gen_function(spec: &dyn Edition, index: usize, m: &Module, w: Writer) -> Result<()> {
|
pub fn gen_function(spec: &dyn Edition, index: usize, m: &Module, w: Writer) -> Result<()> {
|
||||||
let mut inner = Body::new(spec);
|
let mem_set = visit_for_memory(m, index);
|
||||||
|
let num_stack = visit_for_register(m, index);
|
||||||
|
|
||||||
let num_param = m.in_arity[index].num_param;
|
let num_param = m.in_arity[index].num_param;
|
||||||
let num_local = m.code[index].num_local;
|
let num_local = m.code[index].num_local;
|
||||||
|
|
||||||
inner.reg.push(num_param + num_local);
|
let mut inner = Body::new(spec, num_param + num_local);
|
||||||
|
|
||||||
let prelude = gen_prelude(num_param, num_local)?;
|
gen_prelude(num_stack, num_param, num_local, w)?;
|
||||||
let body = inner.gen(index, m)?;
|
gen_memory(mem_set, w)?;
|
||||||
let reg = gen_reg_list(inner.reg.last, num_param, num_local)?;
|
inner.generate(index, m, w)?;
|
||||||
|
|
||||||
w.write_all(&prelude)?;
|
assert!(
|
||||||
w.write_all(®)?;
|
inner.reg.last == num_stack,
|
||||||
w.write_all(&body)
|
"Mismatched register allocation"
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
45
src/backend/visitor/memory.rs
Normal file
45
src/backend/visitor/memory.rs
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
use std::collections::BTreeSet;
|
||||||
|
|
||||||
|
use parity_wasm::elements::Instruction;
|
||||||
|
|
||||||
|
use crate::data::Module;
|
||||||
|
|
||||||
|
pub fn visit_for_memory(m: &Module, index: usize) -> BTreeSet<u8> {
|
||||||
|
let mut result = BTreeSet::new();
|
||||||
|
|
||||||
|
for i in m.code[index].inst_list {
|
||||||
|
match i {
|
||||||
|
Instruction::I32Store(_, _)
|
||||||
|
| Instruction::I64Store(_, _)
|
||||||
|
| Instruction::F32Store(_, _)
|
||||||
|
| Instruction::F64Store(_, _)
|
||||||
|
| Instruction::I32Store8(_, _)
|
||||||
|
| Instruction::I32Store16(_, _)
|
||||||
|
| Instruction::I64Store8(_, _)
|
||||||
|
| Instruction::I64Store16(_, _)
|
||||||
|
| Instruction::I64Store32(_, _)
|
||||||
|
| Instruction::I32Load(_, _)
|
||||||
|
| Instruction::I64Load(_, _)
|
||||||
|
| Instruction::F32Load(_, _)
|
||||||
|
| Instruction::F64Load(_, _)
|
||||||
|
| Instruction::I32Load8S(_, _)
|
||||||
|
| Instruction::I32Load8U(_, _)
|
||||||
|
| Instruction::I32Load16S(_, _)
|
||||||
|
| Instruction::I32Load16U(_, _)
|
||||||
|
| Instruction::I64Load8S(_, _)
|
||||||
|
| Instruction::I64Load8U(_, _)
|
||||||
|
| Instruction::I64Load16S(_, _)
|
||||||
|
| Instruction::I64Load16U(_, _)
|
||||||
|
| Instruction::I64Load32S(_, _)
|
||||||
|
| Instruction::I64Load32U(_, _) => {
|
||||||
|
result.insert(0);
|
||||||
|
}
|
||||||
|
Instruction::CurrentMemory(index) | Instruction::GrowMemory(index) => {
|
||||||
|
result.insert(*index);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
2
src/backend/visitor/mod.rs
Normal file
2
src/backend/visitor/mod.rs
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
pub mod memory;
|
||||||
|
pub mod register;
|
280
src/backend/visitor/register.rs
Normal file
280
src/backend/visitor/register.rs
Normal file
@ -0,0 +1,280 @@
|
|||||||
|
use parity_wasm::elements::Instruction;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
backend::helper::register::Register,
|
||||||
|
data::{Arity, Module},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn visit_for_register(m: &Module, index: usize) -> u32 {
|
||||||
|
let mut reg = Register::new();
|
||||||
|
let num_param = m.in_arity[index].num_param;
|
||||||
|
let num_local = m.code[index].num_local;
|
||||||
|
|
||||||
|
reg.push(num_param + num_local);
|
||||||
|
|
||||||
|
for i in m.code[index].inst_list {
|
||||||
|
match i {
|
||||||
|
Instruction::Block(_) | Instruction::Loop(_) => {
|
||||||
|
reg.save();
|
||||||
|
}
|
||||||
|
Instruction::If(_) => {
|
||||||
|
reg.pop(1);
|
||||||
|
reg.save();
|
||||||
|
}
|
||||||
|
Instruction::Else => {
|
||||||
|
reg.load();
|
||||||
|
reg.save();
|
||||||
|
}
|
||||||
|
Instruction::End => {
|
||||||
|
reg.load();
|
||||||
|
}
|
||||||
|
Instruction::BrIf(_) | Instruction::BrTable(_) => {
|
||||||
|
reg.pop(1);
|
||||||
|
}
|
||||||
|
Instruction::Call(i) => {
|
||||||
|
let arity = m.arity_of(*i as usize);
|
||||||
|
|
||||||
|
reg.pop(arity.num_param);
|
||||||
|
reg.push(arity.num_result);
|
||||||
|
}
|
||||||
|
Instruction::CallIndirect(i, _) => {
|
||||||
|
let types = m.parent.type_section().unwrap().types();
|
||||||
|
let arity = Arity::from_index(types, *i);
|
||||||
|
|
||||||
|
reg.pop(arity.num_param + 1);
|
||||||
|
reg.push(arity.num_result);
|
||||||
|
}
|
||||||
|
Instruction::Drop => {
|
||||||
|
reg.pop(1);
|
||||||
|
}
|
||||||
|
Instruction::Select => {
|
||||||
|
reg.pop(3);
|
||||||
|
reg.push(1);
|
||||||
|
}
|
||||||
|
Instruction::GetLocal(_) => {
|
||||||
|
reg.push(1);
|
||||||
|
}
|
||||||
|
Instruction::SetLocal(_) => {
|
||||||
|
reg.pop(1);
|
||||||
|
}
|
||||||
|
Instruction::TeeLocal(_) => {
|
||||||
|
reg.pop(1);
|
||||||
|
reg.push(1);
|
||||||
|
}
|
||||||
|
Instruction::GetGlobal(_) => {
|
||||||
|
reg.push(1);
|
||||||
|
}
|
||||||
|
Instruction::SetGlobal(_) => {
|
||||||
|
reg.pop(1);
|
||||||
|
}
|
||||||
|
Instruction::I32Load(_, _)
|
||||||
|
| Instruction::I64Load(_, _)
|
||||||
|
| Instruction::F32Load(_, _)
|
||||||
|
| Instruction::F64Load(_, _)
|
||||||
|
| Instruction::I32Load8S(_, _)
|
||||||
|
| Instruction::I32Load8U(_, _)
|
||||||
|
| Instruction::I32Load16S(_, _)
|
||||||
|
| Instruction::I32Load16U(_, _)
|
||||||
|
| Instruction::I64Load8S(_, _)
|
||||||
|
| Instruction::I64Load8U(_, _)
|
||||||
|
| Instruction::I64Load16S(_, _)
|
||||||
|
| Instruction::I64Load16U(_, _)
|
||||||
|
| Instruction::I64Load32S(_, _)
|
||||||
|
| Instruction::I64Load32U(_, _) => {
|
||||||
|
reg.pop(1);
|
||||||
|
reg.push(1);
|
||||||
|
}
|
||||||
|
Instruction::I32Store(_, _)
|
||||||
|
| Instruction::I64Store(_, _)
|
||||||
|
| Instruction::F32Store(_, _)
|
||||||
|
| Instruction::F64Store(_, _)
|
||||||
|
| Instruction::I32Store8(_, _)
|
||||||
|
| Instruction::I32Store16(_, _)
|
||||||
|
| Instruction::I64Store8(_, _)
|
||||||
|
| Instruction::I64Store16(_, _)
|
||||||
|
| Instruction::I64Store32(_, _) => {
|
||||||
|
reg.pop(2);
|
||||||
|
}
|
||||||
|
Instruction::CurrentMemory(_) => {
|
||||||
|
reg.push(1);
|
||||||
|
}
|
||||||
|
Instruction::GrowMemory(_) => {
|
||||||
|
reg.pop(1);
|
||||||
|
reg.push(1);
|
||||||
|
}
|
||||||
|
Instruction::I32Const(_)
|
||||||
|
| Instruction::I64Const(_)
|
||||||
|
| Instruction::F32Const(_)
|
||||||
|
| Instruction::F64Const(_) => {
|
||||||
|
reg.push(1);
|
||||||
|
}
|
||||||
|
Instruction::I32Eqz => {
|
||||||
|
reg.pop(1);
|
||||||
|
reg.push(1);
|
||||||
|
}
|
||||||
|
Instruction::I32Eq
|
||||||
|
| Instruction::I32Ne
|
||||||
|
| Instruction::I32LtS
|
||||||
|
| Instruction::I32LtU
|
||||||
|
| Instruction::I32GtS
|
||||||
|
| Instruction::I32GtU
|
||||||
|
| Instruction::I32LeS
|
||||||
|
| Instruction::I32LeU
|
||||||
|
| Instruction::I32GeS
|
||||||
|
| Instruction::I32GeU => {
|
||||||
|
reg.pop(2);
|
||||||
|
reg.push(1);
|
||||||
|
}
|
||||||
|
Instruction::I64Eqz => {
|
||||||
|
reg.pop(1);
|
||||||
|
reg.push(1);
|
||||||
|
}
|
||||||
|
Instruction::I64Eq
|
||||||
|
| Instruction::I64Ne
|
||||||
|
| Instruction::I64LtS
|
||||||
|
| Instruction::I64LtU
|
||||||
|
| Instruction::I64GtS
|
||||||
|
| Instruction::I64GtU
|
||||||
|
| Instruction::I64LeS
|
||||||
|
| Instruction::I64LeU
|
||||||
|
| Instruction::I64GeS
|
||||||
|
| Instruction::I64GeU
|
||||||
|
| Instruction::F32Eq
|
||||||
|
| Instruction::F32Ne
|
||||||
|
| Instruction::F32Lt
|
||||||
|
| Instruction::F32Gt
|
||||||
|
| Instruction::F32Le
|
||||||
|
| Instruction::F32Ge
|
||||||
|
| Instruction::F64Eq
|
||||||
|
| Instruction::F64Ne
|
||||||
|
| Instruction::F64Lt
|
||||||
|
| Instruction::F64Gt
|
||||||
|
| Instruction::F64Le
|
||||||
|
| Instruction::F64Ge => {
|
||||||
|
reg.pop(2);
|
||||||
|
reg.push(1);
|
||||||
|
}
|
||||||
|
Instruction::I32Clz | Instruction::I32Ctz | Instruction::I32Popcnt => {
|
||||||
|
reg.pop(1);
|
||||||
|
reg.push(1);
|
||||||
|
}
|
||||||
|
Instruction::I32Add
|
||||||
|
| Instruction::I32Sub
|
||||||
|
| Instruction::I32Mul
|
||||||
|
| Instruction::I32DivS
|
||||||
|
| Instruction::I32DivU
|
||||||
|
| Instruction::I32RemS
|
||||||
|
| Instruction::I32RemU
|
||||||
|
| Instruction::I32And
|
||||||
|
| Instruction::I32Or
|
||||||
|
| Instruction::I32Xor
|
||||||
|
| Instruction::I32Shl
|
||||||
|
| Instruction::I32ShrS
|
||||||
|
| Instruction::I32ShrU
|
||||||
|
| Instruction::I32Rotl
|
||||||
|
| Instruction::I32Rotr => {
|
||||||
|
reg.pop(2);
|
||||||
|
reg.push(1);
|
||||||
|
}
|
||||||
|
Instruction::I64Clz | Instruction::I64Ctz | Instruction::I64Popcnt => {
|
||||||
|
reg.pop(1);
|
||||||
|
reg.push(1);
|
||||||
|
}
|
||||||
|
Instruction::I64Add
|
||||||
|
| Instruction::I64Sub
|
||||||
|
| Instruction::I64Mul
|
||||||
|
| Instruction::I64DivS
|
||||||
|
| Instruction::I64DivU
|
||||||
|
| Instruction::I64RemS
|
||||||
|
| Instruction::I64RemU
|
||||||
|
| Instruction::I64And
|
||||||
|
| Instruction::I64Or
|
||||||
|
| Instruction::I64Xor
|
||||||
|
| Instruction::I64Shl
|
||||||
|
| Instruction::I64ShrS
|
||||||
|
| Instruction::I64ShrU
|
||||||
|
| Instruction::I64Rotl
|
||||||
|
| Instruction::I64Rotr => {
|
||||||
|
reg.pop(2);
|
||||||
|
reg.push(1);
|
||||||
|
}
|
||||||
|
Instruction::F32Abs
|
||||||
|
| Instruction::F32Neg
|
||||||
|
| Instruction::F32Ceil
|
||||||
|
| Instruction::F32Floor
|
||||||
|
| Instruction::F32Trunc
|
||||||
|
| Instruction::F32Nearest
|
||||||
|
| Instruction::F32Sqrt => {
|
||||||
|
reg.pop(1);
|
||||||
|
reg.push(1);
|
||||||
|
}
|
||||||
|
Instruction::F32Add
|
||||||
|
| Instruction::F32Sub
|
||||||
|
| Instruction::F32Mul
|
||||||
|
| Instruction::F32Div
|
||||||
|
| Instruction::F32Min
|
||||||
|
| Instruction::F32Max => {
|
||||||
|
reg.pop(2);
|
||||||
|
reg.push(1);
|
||||||
|
}
|
||||||
|
Instruction::F32Copysign => {
|
||||||
|
reg.pop(1);
|
||||||
|
reg.push(1);
|
||||||
|
}
|
||||||
|
Instruction::F64Abs
|
||||||
|
| Instruction::F64Neg
|
||||||
|
| Instruction::F64Ceil
|
||||||
|
| Instruction::F64Floor
|
||||||
|
| Instruction::F64Trunc
|
||||||
|
| Instruction::F64Nearest
|
||||||
|
| Instruction::F64Sqrt => {
|
||||||
|
reg.pop(1);
|
||||||
|
reg.push(1);
|
||||||
|
}
|
||||||
|
Instruction::F64Add
|
||||||
|
| Instruction::F64Sub
|
||||||
|
| Instruction::F64Mul
|
||||||
|
| Instruction::F64Div
|
||||||
|
| Instruction::F64Min
|
||||||
|
| Instruction::F64Max => {
|
||||||
|
reg.pop(2);
|
||||||
|
reg.push(1);
|
||||||
|
}
|
||||||
|
Instruction::F64Copysign => {
|
||||||
|
reg.pop(1);
|
||||||
|
reg.push(1);
|
||||||
|
}
|
||||||
|
Instruction::I32WrapI64
|
||||||
|
| Instruction::I32TruncSF32
|
||||||
|
| Instruction::I32TruncUF32
|
||||||
|
| Instruction::I32TruncSF64
|
||||||
|
| Instruction::I32TruncUF64
|
||||||
|
| Instruction::I64ExtendSI32
|
||||||
|
| Instruction::I64ExtendUI32
|
||||||
|
| Instruction::I64TruncSF32
|
||||||
|
| Instruction::I64TruncUF32
|
||||||
|
| Instruction::I64TruncSF64
|
||||||
|
| Instruction::I64TruncUF64
|
||||||
|
| Instruction::F32ConvertSI32
|
||||||
|
| Instruction::F32ConvertUI32
|
||||||
|
| Instruction::F32ConvertSI64
|
||||||
|
| Instruction::F32ConvertUI64
|
||||||
|
| Instruction::F32DemoteF64
|
||||||
|
| Instruction::F64ConvertSI32
|
||||||
|
| Instruction::F64ConvertUI32
|
||||||
|
| Instruction::F64ConvertSI64
|
||||||
|
| Instruction::F64ConvertUI64
|
||||||
|
| Instruction::F64PromoteF32
|
||||||
|
| Instruction::I32ReinterpretF32
|
||||||
|
| Instruction::I64ReinterpretF64
|
||||||
|
| Instruction::F32ReinterpretI32
|
||||||
|
| Instruction::F64ReinterpretI64 => {
|
||||||
|
reg.pop(1);
|
||||||
|
reg.push(1);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reg.last
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user