summaryrefslogtreecommitdiff
path: root/crates/parser/src
diff options
context:
space:
mode:
authorHenry Gressmann <mail@henrygressmann.de>2024-05-09 22:36:14 +0200
committerHenry Gressmann <mail@henrygressmann.de>2024-05-09 22:36:14 +0200
commit53bb44f45cfda750250e0835425307e3a1d763bc (patch)
tree4085c249714d76b82157c7a888baa2151fe8f190 /crates/parser/src
parent11271a201633d3b07adacd07e407ac8d07e5fce3 (diff)
feat: implement I32StoreLocal & I32LocalGetConstAdd
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
Diffstat (limited to 'crates/parser/src')
-rw-r--r--crates/parser/src/visit.rs56
1 files changed, 43 insertions, 13 deletions
diff --git a/crates/parser/src/visit.rs b/crates/parser/src/visit.rs
index 80dc789..48eba30 100644
--- a/crates/parser/src/visit.rs
+++ b/crates/parser/src/visit.rs
@@ -162,7 +162,7 @@ impl<'a> wasmparser::VisitOperator<'a> for FunctionBuilder {
visit_i64_load16_u, I64Load16U,
visit_i64_load32_s, I64Load32S,
visit_i64_load32_u, I64Load32U,
- visit_i32_store, I32Store,
+ // visit_i32_store, I32Store,
visit_i64_store, I64Store,
visit_f32_store, F32Store,
visit_f64_store, F64Store,
@@ -321,6 +321,37 @@ impl<'a> wasmparser::VisitOperator<'a> for FunctionBuilder {
visit_i64_trunc_sat_f64_u, Instruction::I64TruncSatF64U
}
+ fn visit_i32_store(&mut self, memarg: wasmparser::MemArg) -> Self::Output {
+ let arg = convert_memarg(memarg);
+ let i32store = Instruction::I32Store { offset: arg.offset, mem_addr: arg.mem_addr };
+
+ if self.instructions.len() < 3 {
+ return self.visit(i32store);
+ }
+
+ #[cold]
+ fn cold() {}
+
+ if arg.mem_addr > 0xFF || arg.offset > 0xFFFF_FFFF {
+ cold();
+ return self.visit(i32store);
+ }
+
+ match self.instructions[self.instructions.len() - 2..] {
+ [Instruction::LocalGet(a), Instruction::I32Const(b)] => {
+ self.instructions.pop();
+ self.instructions.pop();
+ self.visit(Instruction::I32StoreLocal {
+ local: a,
+ consti32: b,
+ offset: arg.offset as u32,
+ mem_addr: arg.mem_addr as u8,
+ })
+ }
+ _ => self.visit(i32store),
+ }
+ }
+
fn visit_local_get(&mut self, idx: u32) -> Self::Output {
if let Some(instruction) = self.instructions.last_mut() {
match instruction {
@@ -369,19 +400,18 @@ impl<'a> wasmparser::VisitOperator<'a> for FunctionBuilder {
}
fn visit_i32_add(&mut self) -> Self::Output {
- self.visit(Instruction::I32Add)
- // if self.instructions.len() < 2 {
- // return self.visit(Instruction::I32Add);
- // }
+ if self.instructions.len() < 2 {
+ return self.visit(Instruction::I32Add);
+ }
- // match self.instructions[self.instructions.len() - 2..] {
- // // [Instruction::LocalGet(a), Instruction::I32Const(b)] => {
- // // self.instructions.pop();
- // // self.instructions.pop();
- // // self.visit(Instruction::I32LocalGetConstAdd(a, b))
- // // }
- // _ => self.visit(Instruction::I32Add),
- // }
+ match self.instructions[self.instructions.len() - 2..] {
+ [Instruction::LocalGet(a), Instruction::I32Const(b)] => {
+ self.instructions.pop();
+ self.instructions.pop();
+ self.visit(Instruction::I32LocalGetConstAdd(a, b))
+ }
+ _ => self.visit(Instruction::I32Add),
+ }
}
fn visit_block(&mut self, blockty: wasmparser::BlockType) -> Self::Output {