Skip to content
This repository was archived by the owner on Oct 3, 2025. It is now read-only.

Commit ec486df

Browse files
feat: more bit operations
Signed-off-by: Henry <[email protected]>
1 parent ba30264 commit ec486df

File tree

7 files changed

+174
-121
lines changed

7 files changed

+174
-121
lines changed

Cargo.lock

Lines changed: 10 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/tinywasm/src/runtime/executor/macros.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,29 @@ macro_rules! arithmetic_method {
7070
}};
7171
}
7272

73+
macro_rules! arithmetic_method_self {
74+
($op:ident, $ty:ty, $stack:ident) => {{
75+
let a: $ty = $stack.values.pop()?.into();
76+
let result = a.$op();
77+
$stack.values.push((result as $ty).into());
78+
}};
79+
}
80+
81+
macro_rules! arithmetic_method_cast {
82+
($op:ident, $ty:ty, $ty2:ty, $stack:ident) => {{
83+
let [a, b] = $stack.values.pop_n_const::<2>()?;
84+
let a: $ty = a.into();
85+
let b: $ty = b.into();
86+
87+
// Cast to unsigned type before operation
88+
let a_unsigned: $ty2 = a as $ty2;
89+
let b_unsigned: $ty2 = b as $ty2;
90+
91+
let result = a_unsigned.$op(b_unsigned);
92+
$stack.values.push((result as $ty).into());
93+
}};
94+
}
95+
7396
/// Apply an arithmetic operation to two values on the stack
7497
macro_rules! checked_arithmetic_method {
7598
($op:ident, $ty:ty, $stack:ident, $trap:expr) => {{
@@ -105,6 +128,8 @@ macro_rules! checked_arithmetic_method_cast {
105128
}
106129

107130
pub(super) use arithmetic_method;
131+
pub(super) use arithmetic_method_cast;
132+
pub(super) use arithmetic_method_self;
108133
pub(super) use arithmetic_op;
109134
pub(super) use checked_arithmetic_method;
110135
pub(super) use checked_arithmetic_method_cast;

crates/tinywasm/src/runtime/executor/mod.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -326,8 +326,23 @@ fn exec_one(
326326
I64Or => arithmetic_method!(bitor, i64, stack),
327327
I32Xor => arithmetic_method!(bitxor, i32, stack),
328328
I64Xor => arithmetic_method!(bitxor, i64, stack),
329-
I32Shl => arithmetic_method!(shl_i32, i32, stack),
330-
I64Shl => arithmetic_method!(shl_i64, i64, stack),
329+
I32Shl => arithmetic_method!(wrapping_shl_self, i32, stack),
330+
I64Shl => arithmetic_method!(wrapping_shl_self, i64, stack),
331+
I32ShrS => arithmetic_method!(wrapping_shr_self, i32, stack),
332+
I64ShrS => arithmetic_method!(wrapping_shr_self, i64, stack),
333+
I32ShrU => arithmetic_method_cast!(wrapping_shr_self, i32, u32, stack),
334+
I64ShrU => arithmetic_method_cast!(wrapping_shr_self, i64, u64, stack),
335+
I32Rotl => arithmetic_method!(wrapping_rotl_self, i32, stack),
336+
I64Rotl => arithmetic_method!(wrapping_rotl_self, i64, stack),
337+
I32Rotr => arithmetic_method!(wrapping_rotr_self, i32, stack),
338+
I64Rotr => arithmetic_method!(wrapping_rotr_self, i64, stack),
339+
340+
I32Clz => arithmetic_method_self!(leading_zeros, i32, stack),
341+
I64Clz => arithmetic_method_self!(leading_zeros, i64, stack),
342+
I32Ctz => arithmetic_method_self!(trailing_zeros, i32, stack),
343+
I64Ctz => arithmetic_method_self!(trailing_zeros, i64, stack),
344+
I32Popcnt => arithmetic_method_self!(count_ones, i32, stack),
345+
I64Popcnt => arithmetic_method_self!(count_ones, i64, stack),
331346

332347
F32ConvertI32S => conv_1!(i32, f32, stack),
333348
F32ConvertI64S => conv_1!(i64, f32, stack),

crates/tinywasm/src/runtime/executor/traits.rs

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,41 @@ where
55
fn checked_wrapping_rem(self, rhs: Self) -> Option<Self>;
66
}
77

8-
pub(crate) trait ShlI32 {
9-
fn shl_i32(self, rhs: i32) -> Self;
8+
pub(crate) trait WrappingSelfOps {
9+
fn wrapping_shl_self(self, rhs: Self) -> Self;
10+
fn wrapping_shr_self(self, rhs: Self) -> Self;
11+
fn wrapping_rotl_self(self, rhs: Self) -> Self;
12+
fn wrapping_rotr_self(self, rhs: Self) -> Self;
1013
}
1114

12-
impl ShlI32 for i32 {
13-
#[inline]
14-
fn shl_i32(self, rhs: i32) -> Self {
15-
self.wrapping_shl(rhs as u32)
16-
}
17-
}
15+
macro_rules! impl_wrapping_self_sh {
16+
($($t:ty)*) => ($(
17+
impl WrappingSelfOps for $t {
18+
#[inline]
19+
fn wrapping_shl_self(self, rhs: Self) -> Self {
20+
self.wrapping_shl(rhs as u32)
21+
}
1822

19-
pub(crate) trait ShlI64 {
20-
fn shl_i64(self, rhs: i64) -> Self;
21-
}
23+
#[inline]
24+
fn wrapping_shr_self(self, rhs: Self) -> Self {
25+
self.wrapping_shr(rhs as u32)
26+
}
2227

23-
impl ShlI64 for i64 {
24-
#[inline]
25-
fn shl_i64(self, rhs: i64) -> Self {
26-
self.wrapping_shl(rhs as u32)
27-
}
28+
#[inline]
29+
fn wrapping_rotl_self(self, rhs: Self) -> Self {
30+
self.rotate_left(rhs as u32)
31+
}
32+
33+
#[inline]
34+
fn wrapping_rotr_self(self, rhs: Self) -> Self {
35+
self.rotate_right(rhs as u32)
36+
}
37+
}
38+
)*)
2839
}
2940

41+
impl_wrapping_self_sh! { i32 i64 u32 u64 }
42+
3043
macro_rules! impl_checked_wrapping_rem {
3144
($($t:ty)*) => ($(
3245
impl CheckedWrappingRem for $t {
@@ -42,4 +55,4 @@ macro_rules! impl_checked_wrapping_rem {
4255
)*)
4356
}
4457

45-
impl_checked_wrapping_rem! { i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize }
58+
impl_checked_wrapping_rem! { i32 i64 u32 u64 }

0 commit comments

Comments
 (0)