Skip to content

Commit

Permalink
Merge branch 'feature/i32-bitwise-operations' of https://github.com/d…
Browse files Browse the repository at this point in the history
  • Loading branch information
nerodesu017 committed Jul 11, 2024
2 parents eb2c7d0 + ead749d commit 8955ab6
Show file tree
Hide file tree
Showing 4 changed files with 597 additions and 0 deletions.
100 changes: 100 additions & 0 deletions src/execution/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,30 @@ where
trace!("Instruction: i32.const [] -> [{constant}]");
stack.push_value(constant.into());
}
// i32.clz: [i32] -> [i32]
0x67 => {
let v1: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let res = v1.leading_zeros() as i32;

trace!("Instruction: i32.clz [{v1}] -> [{res}]");
stack.push_value(res.into());
}
// i32.ctz: [i32] -> [i32]
0x68 => {
let v1: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let res = v1.trailing_zeros() as i32;

trace!("Instruction: i32.ctz [{v1}] -> [{res}]");
stack.push_value(res.into());
}
// i32.popcnt: [i32] -> [i32]
0x69 => {
let v1: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let res = v1.count_ones() as i32;

trace!("Instruction: i32.popcnt [{v1}] -> [{res}]");
stack.push_value(res.into());
}
// i32.add: [i32 i32] -> [i32]
0x6A => {
let v1: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
Expand All @@ -243,6 +267,82 @@ where
trace!("Instruction: i32.mul [{v1} {v2}] -> [{res}]");
stack.push_value(res.into());
}
// i32.and: [i32 i32] -> [i32]
0x71 => {
let v1: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let v2: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let res = v1 & v2;

trace!("Instruction: i32.and [{v1} {v2}] -> [{res}]");
stack.push_value(res.into());
}
// i32.or: [i32 i32] -> [i32]
0x72 => {
let v1: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let v2: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let res = v1 | v2;

trace!("Instruction: i32.or [{v1} {v2}] -> [{res}]");
stack.push_value(res.into());
}
// i32.xor: [i32 i32] -> [i32]
0x73 => {
let v1: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let v2: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let res = v1 ^ v2;

trace!("Instruction: i32.xor [{v1} {v2}] -> [{res}]");
stack.push_value(res.into());
}
// i32.shl: [i32 i32] -> [i32]
0x74 => {
let v1: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let v2: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let res = v2.wrapping_shl(v1 as u32);

trace!("Instruction: i32.shl [{v2} {v1}] -> [{res}]");
stack.push_value(res.into());
}
// i32.shr_s: [i32 i32] -> [i32]
0x75 => {
let v1: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let v2: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();

let res = v2.wrapping_shr(v1 as u32);

trace!("Instruction: i32.shr_s [{v2} {v1}] -> [{res}]");
stack.push_value(res.into());
}
// i32.shr_u: [i32 i32] -> [i32]
0x76 => {
let v1: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let v2: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();

let res = (v2 as u32).wrapping_shr(v1 as u32) as i32;

trace!("Instruction: i32.shr_u [{v2} {v1}] -> [{res}]");
stack.push_value(res.into());
}
// i32.rotl: [i32 i32] -> [i32]
0x77 => {
let v1: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let v2: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();

let res = v2.rotate_left(v1 as u32);

trace!("Instruction: i32.rotl [{v2} {v1}] -> [{res}]");
stack.push_value(res.into());
}
// i32.rotr: [i32 i32] -> [i32]
0x78 => {
let v1: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let v2: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();

let res = v2.rotate_right(v1 as u32);

trace!("Instruction: i32.rotr [{v2} {v1}] -> [{res}]");
stack.push_value(res.into());
}
// i32.div_s: [i32 i32] -> [i32]
0x6D => {
let dividend: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
Expand Down
74 changes: 74 additions & 0 deletions src/validation/code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,80 @@ fn read_instructions(
let _num = wasm.read_var_i32()?;
value_stack.push_back(ValType::NumType(NumType::I32));
}
// i32.clz: [i32] -> [i32]
0x67 => {
assert_pop_value_stack(value_stack, ValType::NumType(NumType::I32))?;

value_stack.push_back(ValType::NumType(NumType::I32));
}
// i32.ctz: [i32] -> [i32]
0x68 => {
assert_pop_value_stack(value_stack, ValType::NumType(NumType::I32))?;

value_stack.push_back(ValType::NumType(NumType::I32));
}
// i32.popcnt: [i32] -> [i32]
0x69 => {
assert_pop_value_stack(value_stack, ValType::NumType(NumType::I32))?;

value_stack.push_back(ValType::NumType(NumType::I32));
}
// i32.and: [i32 i32] -> [i32]
0x71 => {
assert_pop_value_stack(value_stack, ValType::NumType(NumType::I32))?;
assert_pop_value_stack(value_stack, ValType::NumType(NumType::I32))?;

value_stack.push_back(ValType::NumType(NumType::I32));
}
// i32.or: [i32 i32] -> [i32]
0x72 => {
assert_pop_value_stack(value_stack, ValType::NumType(NumType::I32))?;
assert_pop_value_stack(value_stack, ValType::NumType(NumType::I32))?;

value_stack.push_back(ValType::NumType(NumType::I32));
}
// i32.xor: [i32 i32] -> [i32]
0x73 => {
assert_pop_value_stack(value_stack, ValType::NumType(NumType::I32))?;
assert_pop_value_stack(value_stack, ValType::NumType(NumType::I32))?;

value_stack.push_back(ValType::NumType(NumType::I32));
}
// i32.shl: [i32 i32] -> [i32]
0x74 => {
assert_pop_value_stack(value_stack, ValType::NumType(NumType::I32))?;
assert_pop_value_stack(value_stack, ValType::NumType(NumType::I32))?;

value_stack.push_back(ValType::NumType(NumType::I32));
}
// i32.shr_s: [i32 i32] -> [i32]
0x75 => {
assert_pop_value_stack(value_stack, ValType::NumType(NumType::I32))?;
assert_pop_value_stack(value_stack, ValType::NumType(NumType::I32))?;

value_stack.push_back(ValType::NumType(NumType::I32));
}
// i32.shr_u: [i32 i32] -> [i32]
0x76 => {
assert_pop_value_stack(value_stack, ValType::NumType(NumType::I32))?;
assert_pop_value_stack(value_stack, ValType::NumType(NumType::I32))?;

value_stack.push_back(ValType::NumType(NumType::I32));
}
// i32.rotl: [i32 i32] -> [i32]
0x77 => {
assert_pop_value_stack(value_stack, ValType::NumType(NumType::I32))?;
assert_pop_value_stack(value_stack, ValType::NumType(NumType::I32))?;

value_stack.push_back(ValType::NumType(NumType::I32));
}
// i32.rotr: [i32 i32] -> [i32]
0x78 => {
assert_pop_value_stack(value_stack, ValType::NumType(NumType::I32))?;
assert_pop_value_stack(value_stack, ValType::NumType(NumType::I32))?;

value_stack.push_back(ValType::NumType(NumType::I32));
}
other => {
return Err(Error::InvalidInstr(other));
}
Expand Down
Loading

0 comments on commit 8955ab6

Please sign in to comment.