seq_runtime/arithmetic/
bitwise.rs1use crate::stack::{Stack, pop, pop_two, push};
6use crate::value::Value;
7
8#[unsafe(no_mangle)]
19pub unsafe extern "C" fn patch_seq_band(stack: Stack) -> Stack {
20 let (rest, a, b) = unsafe { pop_two(stack, "band") };
21 match (a, b) {
22 (Value::Int(a_val), Value::Int(b_val)) => unsafe { push(rest, Value::Int(a_val & b_val)) },
23 _ => panic!("band: expected two integers on stack"),
24 }
25}
26
27#[unsafe(no_mangle)]
34pub unsafe extern "C" fn patch_seq_bor(stack: Stack) -> Stack {
35 let (rest, a, b) = unsafe { pop_two(stack, "bor") };
36 match (a, b) {
37 (Value::Int(a_val), Value::Int(b_val)) => unsafe { push(rest, Value::Int(a_val | b_val)) },
38 _ => panic!("bor: expected two integers on stack"),
39 }
40}
41
42#[unsafe(no_mangle)]
49pub unsafe extern "C" fn patch_seq_bxor(stack: Stack) -> Stack {
50 let (rest, a, b) = unsafe { pop_two(stack, "bxor") };
51 match (a, b) {
52 (Value::Int(a_val), Value::Int(b_val)) => unsafe { push(rest, Value::Int(a_val ^ b_val)) },
53 _ => panic!("bxor: expected two integers on stack"),
54 }
55}
56
57#[unsafe(no_mangle)]
64pub unsafe extern "C" fn patch_seq_bnot(stack: Stack) -> Stack {
65 assert!(!stack.is_null(), "bnot: stack is empty");
66 let (rest, a) = unsafe { pop(stack) };
67 match a {
68 Value::Int(a_val) => unsafe { push(rest, Value::Int(!a_val)) },
69 _ => panic!("bnot: expected integer on stack"),
70 }
71}
72
73#[unsafe(no_mangle)]
81pub unsafe extern "C" fn patch_seq_shl(stack: Stack) -> Stack {
82 let (rest, value, count) = unsafe { pop_two(stack, "shl") };
83 match (value, count) {
84 (Value::Int(v), Value::Int(c)) => {
85 let result = if c < 0 {
88 0
89 } else {
90 v.checked_shl(c as u32).unwrap_or(0)
91 };
92 unsafe { push(rest, Value::Int(result)) }
93 }
94 _ => panic!("shl: expected two integers on stack"),
95 }
96}
97
98#[unsafe(no_mangle)]
107pub unsafe extern "C" fn patch_seq_shr(stack: Stack) -> Stack {
108 let (rest, value, count) = unsafe { pop_two(stack, "shr") };
109 match (value, count) {
110 (Value::Int(v), Value::Int(c)) => {
111 let result = if c < 0 {
114 0
115 } else {
116 (v as u64).checked_shr(c as u32).unwrap_or(0) as i64
117 };
118 unsafe { push(rest, Value::Int(result)) }
119 }
120 _ => panic!("shr: expected two integers on stack"),
121 }
122}
123
124#[unsafe(no_mangle)]
131pub unsafe extern "C" fn patch_seq_popcount(stack: Stack) -> Stack {
132 assert!(!stack.is_null(), "popcount: stack is empty");
133 let (rest, a) = unsafe { pop(stack) };
134 match a {
135 Value::Int(v) => unsafe { push(rest, Value::Int(v.count_ones() as i64)) },
136 _ => panic!("popcount: expected integer on stack"),
137 }
138}
139
140#[unsafe(no_mangle)]
147pub unsafe extern "C" fn patch_seq_clz(stack: Stack) -> Stack {
148 assert!(!stack.is_null(), "clz: stack is empty");
149 let (rest, a) = unsafe { pop(stack) };
150 match a {
151 Value::Int(v) => unsafe { push(rest, Value::Int(v.leading_zeros() as i64)) },
152 _ => panic!("clz: expected integer on stack"),
153 }
154}
155
156#[unsafe(no_mangle)]
163pub unsafe extern "C" fn patch_seq_ctz(stack: Stack) -> Stack {
164 assert!(!stack.is_null(), "ctz: stack is empty");
165 let (rest, a) = unsafe { pop(stack) };
166 match a {
167 Value::Int(v) => unsafe { push(rest, Value::Int(v.trailing_zeros() as i64)) },
168 _ => panic!("ctz: expected integer on stack"),
169 }
170}
171
172#[unsafe(no_mangle)]
179pub unsafe extern "C" fn patch_seq_int_bits(stack: Stack) -> Stack {
180 unsafe { push(stack, Value::Int(64)) }
181}