revm_interpreter/instructions/bitwise.rs
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 // `31 - o1` because `byte` returns LE, while we want BE
118 U256::from(op2.byte(31 - o1))
119 } else {
120 U256::ZERO
121 };
122}
123
124/// EIP-145: Bitwise shifting instructions in EVM
125pub 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
141/// EIP-145: Bitwise shifting instructions in EVM
142pub 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
158/// EIP-145: Bitwise shifting instructions in EVM
159pub 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// TODO : Tests
178/*
179#[cfg(test)]
180mod tests {
181 use crate::instructions::bitwise::{byte, sar, shl, shr};
182 use crate::interpreter_wiring::StackTr;
183 use crate::{Contract, DummyHost, Interpreter};
184 use primitives::{uint, U256};
185 use specification::hardfork::LatestSpec;
186 use context_interface::{default::Env, DefaultEthereumWiring};
187
188 #[test]
189 fn test_shift_left() {
190 let mut host = DummyHost::new(Env::default());
191 let mut interpreter = Interpreter::new(Contract::default(), u64::MAX, false);
192
193 struct TestCase {
194 value: U256,
195 shift: U256,
196 expected: U256,
197 }
198
199 uint! {
200 let test_cases = [
201 TestCase {
202 value: 0x0000000000000000000000000000000000000000000000000000000000000001_U256,
203 shift: 0x00_U256,
204 expected: 0x0000000000000000000000000000000000000000000000000000000000000001_U256,
205 },
206 TestCase {
207 value: 0x0000000000000000000000000000000000000000000000000000000000000001_U256,
208 shift: 0x01_U256,
209 expected: 0x0000000000000000000000000000000000000000000000000000000000000002_U256,
210 },
211 TestCase {
212 value: 0x0000000000000000000000000000000000000000000000000000000000000001_U256,
213 shift: 0xff_U256,
214 expected: 0x8000000000000000000000000000000000000000000000000000000000000000_U256,
215 },
216 TestCase {
217 value: 0x0000000000000000000000000000000000000000000000000000000000000001_U256,
218 shift: 0x0100_U256,
219 expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256,
220 },
221 TestCase {
222 value: 0x0000000000000000000000000000000000000000000000000000000000000001_U256,
223 shift: 0x0101_U256,
224 expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256,
225 },
226 TestCase {
227 value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
228 shift: 0x00_U256,
229 expected: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
230 },
231 TestCase {
232 value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
233 shift: 0x01_U256,
234 expected: 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe_U256,
235 },
236 TestCase {
237 value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
238 shift: 0xff_U256,
239 expected: 0x8000000000000000000000000000000000000000000000000000000000000000_U256,
240 },
241 TestCase {
242 value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
243 shift: 0x0100_U256,
244 expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256,
245 },
246 TestCase {
247 value: 0x0000000000000000000000000000000000000000000000000000000000000000_U256,
248 shift: 0x01_U256,
249 expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256,
250 },
251 TestCase {
252 value: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
253 shift: 0x01_U256,
254 expected: 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe_U256,
255 },
256 ];
257 }
258
259 for test in test_cases {
260 host.clear();
261 push!(interpreter, test.value);
262 push!(interpreter, test.shift);
263 shl::<Interpreter, DummyHost<DefaultEthereumWiring>>(&mut interpreter, &mut host);
264 let res = interpreter.stack.pop().unwrap();
265 assert_eq!(res, test.expected);
266 }
267 }
268
269 #[test]
270 fn test_logical_shift_right() {
271 let mut host = DummyHost::new(Env::default());
272 let mut interpreter = Interpreter::new(Contract::default(), u64::MAX, false);
273
274 struct TestCase {
275 value: U256,
276 shift: U256,
277 expected: U256,
278 }
279
280 uint! {
281 let test_cases = [
282 TestCase {
283 value: 0x0000000000000000000000000000000000000000000000000000000000000001_U256,
284 shift: 0x00_U256,
285 expected: 0x0000000000000000000000000000000000000000000000000000000000000001_U256,
286 },
287 TestCase {
288 value: 0x0000000000000000000000000000000000000000000000000000000000000001_U256,
289 shift: 0x01_U256,
290 expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256,
291 },
292 TestCase {
293 value: 0x8000000000000000000000000000000000000000000000000000000000000000_U256,
294 shift: 0x01_U256,
295 expected: 0x4000000000000000000000000000000000000000000000000000000000000000_U256,
296 },
297 TestCase {
298 value: 0x8000000000000000000000000000000000000000000000000000000000000000_U256,
299 shift: 0xff_U256,
300 expected: 0x0000000000000000000000000000000000000000000000000000000000000001_U256,
301 },
302 TestCase {
303 value: 0x8000000000000000000000000000000000000000000000000000000000000000_U256,
304 shift: 0x0100_U256,
305 expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256,
306 },
307 TestCase {
308 value: 0x8000000000000000000000000000000000000000000000000000000000000000_U256,
309 shift: 0x0101_U256,
310 expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256,
311 },
312 TestCase {
313 value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
314 shift: 0x00_U256,
315 expected: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
316 },
317 TestCase {
318 value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
319 shift: 0x01_U256,
320 expected: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
321 },
322 TestCase {
323 value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
324 shift: 0xff_U256,
325 expected: 0x0000000000000000000000000000000000000000000000000000000000000001_U256,
326 },
327 TestCase {
328 value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
329 shift: 0x0100_U256,
330 expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256,
331 },
332 TestCase {
333 value: 0x0000000000000000000000000000000000000000000000000000000000000000_U256,
334 shift: 0x01_U256,
335 expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256,
336 },
337 ];
338 }
339
340 for test in test_cases {
341 host.clear();
342 push!(interpreter, test.value);
343 push!(interpreter, test.shift);
344 shr::<Interpreter, DummyHost<DefaultEthereumWiring>>(&mut interpreter, &mut host);
345 let res = interpreter.stack.pop().unwrap();
346 assert_eq!(res, test.expected);
347 }
348 }
349
350 #[test]
351 fn test_arithmetic_shift_right() {
352 let mut host = DummyHost::new(Env::default());
353 let mut interpreter = Interpreter::new(Contract::default(), u64::MAX, false);
354
355 struct TestCase {
356 value: U256,
357 shift: U256,
358 expected: U256,
359 }
360
361 uint! {
362 let test_cases = [
363 TestCase {
364 value: 0x0000000000000000000000000000000000000000000000000000000000000001_U256,
365 shift: 0x00_U256,
366 expected: 0x0000000000000000000000000000000000000000000000000000000000000001_U256,
367 },
368 TestCase {
369 value: 0x0000000000000000000000000000000000000000000000000000000000000001_U256,
370 shift: 0x01_U256,
371 expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256,
372 },
373 TestCase {
374 value: 0x8000000000000000000000000000000000000000000000000000000000000000_U256,
375 shift: 0x01_U256,
376 expected: 0xc000000000000000000000000000000000000000000000000000000000000000_U256,
377 },
378 TestCase {
379 value: 0x8000000000000000000000000000000000000000000000000000000000000000_U256,
380 shift: 0xff_U256,
381 expected: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
382 },
383 TestCase {
384 value: 0x8000000000000000000000000000000000000000000000000000000000000000_U256,
385 shift: 0x0100_U256,
386 expected: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
387 },
388 TestCase {
389 value: 0x8000000000000000000000000000000000000000000000000000000000000000_U256,
390 shift: 0x0101_U256,
391 expected: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
392 },
393 TestCase {
394 value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
395 shift: 0x00_U256,
396 expected: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
397 },
398 TestCase {
399 value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
400 shift: 0x01_U256,
401 expected: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
402 },
403 TestCase {
404 value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
405 shift: 0xff_U256,
406 expected: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
407 },
408 TestCase {
409 value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
410 shift: 0x0100_U256,
411 expected: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
412 },
413 TestCase {
414 value: 0x0000000000000000000000000000000000000000000000000000000000000000_U256,
415 shift: 0x01_U256,
416 expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256,
417 },
418 TestCase {
419 value: 0x4000000000000000000000000000000000000000000000000000000000000000_U256,
420 shift: 0xfe_U256,
421 expected: 0x0000000000000000000000000000000000000000000000000000000000000001_U256,
422 },
423 TestCase {
424 value: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
425 shift: 0xf8_U256,
426 expected: 0x000000000000000000000000000000000000000000000000000000000000007f_U256,
427 },
428 TestCase {
429 value: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
430 shift: 0xfe_U256,
431 expected: 0x0000000000000000000000000000000000000000000000000000000000000001_U256,
432 },
433 TestCase {
434 value: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
435 shift: 0xff_U256,
436 expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256,
437 },
438 TestCase {
439 value: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256,
440 shift: 0x0100_U256,
441 expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256,
442 },
443 ];
444 }
445
446 for test in test_cases {
447 host.clear();
448 push!(interpreter, test.value);
449 push!(interpreter, test.shift);
450 sar::<Interpreter, DummyHost<DefaultEthereumWiring>>(&mut interpreter, &mut host);
451 let res = interpreter.stack.pop().unwrap();
452 assert_eq!(res, test.expected);
453 }
454 }
455
456 #[test]
457 fn test_byte() {
458 struct TestCase {
459 input: U256,
460 index: usize,
461 expected: U256,
462 }
463
464 let mut host = DummyHost::<DefaultEthereumWiring>::new(Env::default());
465 let mut interpreter = Interpreter::new(Contract::default(), u64::MAX, false);
466
467 let input_value = U256::from(0x1234567890abcdef1234567890abcdef_u128);
468 let test_cases = (0..32)
469 .map(|i| {
470 let byte_pos = 31 - i;
471
472 let shift_amount = U256::from(byte_pos * 8);
473 let byte_value = (input_value >> shift_amount) & U256::from(0xFF);
474 TestCase {
475 input: input_value,
476 index: i,
477 expected: byte_value,
478 }
479 })
480 .collect::<Vec<_>>();
481
482 for test in test_cases.iter() {
483 push!(interpreter, test.input);
484 push!(interpreter, U256::from(test.index));
485 byte(&mut interpreter, &mut host);
486 let res = interpreter.stack.pop().unwrap();
487 assert_eq!(res, test.expected, "Failed at index: {}", test.index);
488 }
489 }
490}
491*/