1use super::i256::i256_cmp;
2use crate::{
3 gas,
4 interpreter::Interpreter,
5 interpreter_types::{InterpreterTypes, LoopControl, RuntimeFlag, StackTr},
6 Host,
7};
8use core::cmp::Ordering;
9use primitives::U256;
10
11pub fn lt<WIRE: InterpreterTypes, H: Host + ?Sized>(
12 interpreter: &mut Interpreter<WIRE>,
13 _host: &mut H,
14) {
15 gas!(interpreter, gas::VERYLOW);
16 popn_top!([op1], op2, interpreter);
17 *op2 = U256::from(op1 < *op2);
18}
19
20pub fn gt<WIRE: InterpreterTypes, H: Host + ?Sized>(
21 interpreter: &mut Interpreter<WIRE>,
22 _host: &mut H,
23) {
24 gas!(interpreter, gas::VERYLOW);
25 popn_top!([op1], op2, interpreter);
26
27 *op2 = U256::from(op1 > *op2);
28}
29
30pub fn slt<WIRE: InterpreterTypes, H: Host + ?Sized>(
31 interpreter: &mut Interpreter<WIRE>,
32 _host: &mut H,
33) {
34 gas!(interpreter, gas::VERYLOW);
35 popn_top!([op1], op2, interpreter);
36
37 *op2 = U256::from(i256_cmp(&op1, op2) == Ordering::Less);
38}
39
40pub fn sgt<WIRE: InterpreterTypes, H: Host + ?Sized>(
41 interpreter: &mut Interpreter<WIRE>,
42 _host: &mut H,
43) {
44 gas!(interpreter, gas::VERYLOW);
45 popn_top!([op1], op2, interpreter);
46
47 *op2 = U256::from(i256_cmp(&op1, op2) == Ordering::Greater);
48}
49
50pub fn eq<WIRE: InterpreterTypes, H: Host + ?Sized>(
51 interpreter: &mut Interpreter<WIRE>,
52 _host: &mut H,
53) {
54 gas!(interpreter, gas::VERYLOW);
55 popn_top!([op1], op2, interpreter);
56
57 *op2 = U256::from(op1 == *op2);
58}
59
60pub fn iszero<WIRE: InterpreterTypes, H: Host + ?Sized>(
61 interpreter: &mut Interpreter<WIRE>,
62 _host: &mut H,
63) {
64 gas!(interpreter, gas::VERYLOW);
65 popn_top!([], op1, interpreter);
66 *op1 = U256::from(op1.is_zero());
67}
68
69pub fn bitand<WIRE: InterpreterTypes, H: Host + ?Sized>(
70 interpreter: &mut Interpreter<WIRE>,
71 _host: &mut H,
72) {
73 gas!(interpreter, gas::VERYLOW);
74 popn_top!([op1], op2, interpreter);
75 *op2 = op1 & *op2;
76}
77
78pub fn bitor<WIRE: InterpreterTypes, H: Host + ?Sized>(
79 interpreter: &mut Interpreter<WIRE>,
80 _host: &mut H,
81) {
82 gas!(interpreter, gas::VERYLOW);
83 popn_top!([op1], op2, interpreter);
84
85 *op2 = op1 | *op2;
86}
87
88pub fn bitxor<WIRE: InterpreterTypes, H: Host + ?Sized>(
89 interpreter: &mut Interpreter<WIRE>,
90 _host: &mut H,
91) {
92 gas!(interpreter, gas::VERYLOW);
93 popn_top!([op1], op2, interpreter);
94
95 *op2 = op1 ^ *op2;
96}
97
98pub fn not<WIRE: InterpreterTypes, H: Host + ?Sized>(
99 interpreter: &mut Interpreter<WIRE>,
100 _host: &mut H,
101) {
102 gas!(interpreter, gas::VERYLOW);
103 popn_top!([], op1, interpreter);
104
105 *op1 = !*op1;
106}
107
108pub fn byte<WIRE: InterpreterTypes, H: Host + ?Sized>(
109 interpreter: &mut Interpreter<WIRE>,
110 _host: &mut H,
111) {
112 gas!(interpreter, gas::VERYLOW);
113 popn_top!([op1], op2, interpreter);
114
115 let o1 = as_usize_saturated!(op1);
116 *op2 = if o1 < 32 {
117 U256::from(op2.byte(31 - o1))
119 } else {
120 U256::ZERO
121 };
122}
123
124pub fn shl<WIRE: InterpreterTypes, H: Host + ?Sized>(
126 interpreter: &mut Interpreter<WIRE>,
127 _host: &mut H,
128) {
129 check!(interpreter, CONSTANTINOPLE);
130 gas!(interpreter, gas::VERYLOW);
131 popn_top!([op1], op2, interpreter);
132
133 let shift = as_usize_saturated!(op1);
134 *op2 = if shift < 256 {
135 *op2 << shift
136 } else {
137 U256::ZERO
138 }
139}
140
141pub fn shr<WIRE: InterpreterTypes, H: Host + ?Sized>(
143 interpreter: &mut Interpreter<WIRE>,
144 _host: &mut H,
145) {
146 check!(interpreter, CONSTANTINOPLE);
147 gas!(interpreter, gas::VERYLOW);
148 popn_top!([op1], op2, interpreter);
149
150 let shift = as_usize_saturated!(op1);
151 *op2 = if shift < 256 {
152 *op2 >> shift
153 } else {
154 U256::ZERO
155 }
156}
157
158pub fn sar<WIRE: InterpreterTypes, H: Host + ?Sized>(
160 interpreter: &mut Interpreter<WIRE>,
161 _host: &mut H,
162) {
163 check!(interpreter, CONSTANTINOPLE);
164 gas!(interpreter, gas::VERYLOW);
165 popn_top!([op1], op2, interpreter);
166
167 let shift = as_usize_saturated!(op1);
168 *op2 = if shift < 256 {
169 op2.arithmetic_shr(shift)
170 } else if op2.bit(255) {
171 U256::MAX
172 } else {
173 U256::ZERO
174 };
175}
176
177#[cfg(test)]
178mod tests {
179 use crate::{
180 host::DummyHost,
181 instructions::bitwise::{byte, sar, shl, shr},
182 interpreter_types::LoopControl,
183 Interpreter,
184 };
185 use primitives::{uint, U256};
186
187 #[test]
188 fn test_shift_left() {
189 let mut host = DummyHost;
190 let mut interpreter = Interpreter::default();
191
192 struct TestCase {
193 value: U256,
194 shift: U256,
195 expected: U256,
196 }
197
198 uint! {
199 let test_cases = [
200 TestCase {
201 value: 0x0000000000000000000000000000000000000000000000000000000000000001_U256,
202 shift: 0x00_U256,
203 expected: 0x0000000000000000000000000000000000000000000000000000000000000001_U256,
204 },
205 TestCase {
206 value: 0x0000000000000000000000000000000000000000000000000000000000000001_U256,
207 shift: 0x01_U256,
208 expected: 0x0000000000000000000000000000000000000000000000000000000000000002_U256,
209 },
210 TestCase {
211 value: 0x0000000000000000000000000000000000000000000000000000000000000001_U256,
212 shift: 0xff_U256,
213 expected: 0x8000000000000000000000000000000000000000000000000000000000000000_U256,
214 },
215 TestCase {
216 value: 0x0000000000000000000000000000000000000000000000000000000000000001_U256,
217 shift: 0x0100_U256,
218 expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256,
219 },
220 TestCase {
221 value: 0x0000000000000000000000000000000000000000000000000000000000000001_U256,
222 shift: 0x0101_U256,
223 expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256,
224 },
225 TestCase {
226 value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
227 shift: 0x00_U256,
228 expected: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
229 },
230 TestCase {
231 value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
232 shift: 0x01_U256,
233 expected: 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe_U256,
234 },
235 TestCase {
236 value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
237 shift: 0xff_U256,
238 expected: 0x8000000000000000000000000000000000000000000000000000000000000000_U256,
239 },
240 TestCase {
241 value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
242 shift: 0x0100_U256,
243 expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256,
244 },
245 TestCase {
246 value: 0x0000000000000000000000000000000000000000000000000000000000000000_U256,
247 shift: 0x01_U256,
248 expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256,
249 },
250 TestCase {
251 value: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
252 shift: 0x01_U256,
253 expected: 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe_U256,
254 },
255 ];
256 }
257
258 for test in test_cases {
259 push!(interpreter, test.value);
260 push!(interpreter, test.shift);
261 shl(&mut interpreter, &mut host);
262 let res = interpreter.stack.pop().unwrap();
263 assert_eq!(res, test.expected);
264 }
265 }
266
267 #[test]
268 fn test_logical_shift_right() {
269 let mut host = DummyHost;
270 let mut interpreter = Interpreter::default();
271
272 struct TestCase {
273 value: U256,
274 shift: U256,
275 expected: U256,
276 }
277
278 uint! {
279 let test_cases = [
280 TestCase {
281 value: 0x0000000000000000000000000000000000000000000000000000000000000001_U256,
282 shift: 0x00_U256,
283 expected: 0x0000000000000000000000000000000000000000000000000000000000000001_U256,
284 },
285 TestCase {
286 value: 0x0000000000000000000000000000000000000000000000000000000000000001_U256,
287 shift: 0x01_U256,
288 expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256,
289 },
290 TestCase {
291 value: 0x8000000000000000000000000000000000000000000000000000000000000000_U256,
292 shift: 0x01_U256,
293 expected: 0x4000000000000000000000000000000000000000000000000000000000000000_U256,
294 },
295 TestCase {
296 value: 0x8000000000000000000000000000000000000000000000000000000000000000_U256,
297 shift: 0xff_U256,
298 expected: 0x0000000000000000000000000000000000000000000000000000000000000001_U256,
299 },
300 TestCase {
301 value: 0x8000000000000000000000000000000000000000000000000000000000000000_U256,
302 shift: 0x0100_U256,
303 expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256,
304 },
305 TestCase {
306 value: 0x8000000000000000000000000000000000000000000000000000000000000000_U256,
307 shift: 0x0101_U256,
308 expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256,
309 },
310 TestCase {
311 value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
312 shift: 0x00_U256,
313 expected: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
314 },
315 TestCase {
316 value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
317 shift: 0x01_U256,
318 expected: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
319 },
320 TestCase {
321 value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
322 shift: 0xff_U256,
323 expected: 0x0000000000000000000000000000000000000000000000000000000000000001_U256,
324 },
325 TestCase {
326 value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
327 shift: 0x0100_U256,
328 expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256,
329 },
330 TestCase {
331 value: 0x0000000000000000000000000000000000000000000000000000000000000000_U256,
332 shift: 0x01_U256,
333 expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256,
334 },
335 ];
336 }
337
338 for test in test_cases {
339 push!(interpreter, test.value);
340 push!(interpreter, test.shift);
341 shr(&mut interpreter, &mut host);
342 let res = interpreter.stack.pop().unwrap();
343 assert_eq!(res, test.expected);
344 }
345 }
346
347 #[test]
348 fn test_arithmetic_shift_right() {
349 let mut host = DummyHost;
350 let mut interpreter = Interpreter::default();
351
352 struct TestCase {
353 value: U256,
354 shift: U256,
355 expected: U256,
356 }
357
358 uint! {
359 let test_cases = [
360 TestCase {
361 value: 0x0000000000000000000000000000000000000000000000000000000000000001_U256,
362 shift: 0x00_U256,
363 expected: 0x0000000000000000000000000000000000000000000000000000000000000001_U256,
364 },
365 TestCase {
366 value: 0x0000000000000000000000000000000000000000000000000000000000000001_U256,
367 shift: 0x01_U256,
368 expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256,
369 },
370 TestCase {
371 value: 0x8000000000000000000000000000000000000000000000000000000000000000_U256,
372 shift: 0x01_U256,
373 expected: 0xc000000000000000000000000000000000000000000000000000000000000000_U256,
374 },
375 TestCase {
376 value: 0x8000000000000000000000000000000000000000000000000000000000000000_U256,
377 shift: 0xff_U256,
378 expected: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
379 },
380 TestCase {
381 value: 0x8000000000000000000000000000000000000000000000000000000000000000_U256,
382 shift: 0x0100_U256,
383 expected: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
384 },
385 TestCase {
386 value: 0x8000000000000000000000000000000000000000000000000000000000000000_U256,
387 shift: 0x0101_U256,
388 expected: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
389 },
390 TestCase {
391 value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
392 shift: 0x00_U256,
393 expected: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
394 },
395 TestCase {
396 value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
397 shift: 0x01_U256,
398 expected: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
399 },
400 TestCase {
401 value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
402 shift: 0xff_U256,
403 expected: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
404 },
405 TestCase {
406 value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
407 shift: 0x0100_U256,
408 expected: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
409 },
410 TestCase {
411 value: 0x0000000000000000000000000000000000000000000000000000000000000000_U256,
412 shift: 0x01_U256,
413 expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256,
414 },
415 TestCase {
416 value: 0x4000000000000000000000000000000000000000000000000000000000000000_U256,
417 shift: 0xfe_U256,
418 expected: 0x0000000000000000000000000000000000000000000000000000000000000001_U256,
419 },
420 TestCase {
421 value: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
422 shift: 0xf8_U256,
423 expected: 0x000000000000000000000000000000000000000000000000000000000000007f_U256,
424 },
425 TestCase {
426 value: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
427 shift: 0xfe_U256,
428 expected: 0x0000000000000000000000000000000000000000000000000000000000000001_U256,
429 },
430 TestCase {
431 value: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
432 shift: 0xff_U256,
433 expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256,
434 },
435 TestCase {
436 value: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
437 shift: 0x0100_U256,
438 expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256,
439 },
440 ];
441 }
442
443 for test in test_cases {
444 push!(interpreter, test.value);
445 push!(interpreter, test.shift);
446 sar(&mut interpreter, &mut host);
447 let res = interpreter.stack.pop().unwrap();
448 assert_eq!(res, test.expected);
449 }
450 }
451
452 #[test]
453 fn test_byte() {
454 struct TestCase {
455 input: U256,
456 index: usize,
457 expected: U256,
458 }
459
460 let mut host = DummyHost;
461 let mut interpreter = Interpreter::default();
462
463 let input_value = U256::from(0x1234567890abcdef1234567890abcdef_u128);
464 let test_cases = (0..32)
465 .map(|i| {
466 let byte_pos = 31 - i;
467
468 let shift_amount = U256::from(byte_pos * 8);
469 let byte_value = (input_value >> shift_amount) & U256::from(0xFF);
470 TestCase {
471 input: input_value,
472 index: i,
473 expected: byte_value,
474 }
475 })
476 .collect::<Vec<_>>();
477
478 for test in test_cases.iter() {
479 push!(interpreter, test.input);
480 push!(interpreter, U256::from(test.index));
481 byte(&mut interpreter, &mut host);
482 let res = interpreter.stack.pop().unwrap();
483 assert_eq!(res, test.expected, "Failed at index: {}", test.index);
484 }
485 }
486}