1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
use primitive_types::U256;
use crate::utils::{Sign, I256};
#[inline]
pub fn slt(op1: U256, op2: U256) -> U256 {
let op1: I256 = op1.into();
let op2: I256 = op2.into();
if op1.lt(&op2) {
U256::one()
} else {
U256::zero()
}
}
#[inline]
pub fn sgt(op1: U256, op2: U256) -> U256 {
let op1: I256 = op1.into();
let op2: I256 = op2.into();
if op1.gt(&op2) {
U256::one()
} else {
U256::zero()
}
}
#[inline]
pub fn iszero(op1: U256) -> U256 {
if op1 == U256::zero() {
U256::one()
} else {
U256::zero()
}
}
#[inline]
pub fn not(op1: U256) -> U256 {
!op1
}
#[inline]
pub fn byte(op1: U256, op2: U256) -> U256 {
let mut ret = U256::zero();
for i in 0..256 {
if i < 8 && op1 < 32.into() {
let o: usize = op1.as_usize();
let t = 255 - (7 - i + 8 * o);
let bit_mask = U256::one() << t;
let value = (op2 & bit_mask) >> t;
ret = ret.overflowing_add(value << i).0;
}
}
ret
}
#[inline]
pub fn shl(shift: U256, value: U256) -> U256 {
let ret = if value == U256::zero() || shift >= U256::from(256) {
U256::zero()
} else {
let shift: u64 = shift.as_u64();
value << shift as usize
};
ret
}
#[inline]
pub fn shr(shift: U256, value: U256) -> U256 {
let ret = if value == U256::zero() || shift >= U256::from(256) {
U256::zero()
} else {
let shift: u64 = shift.as_u64();
value >> shift as usize
};
ret
}
#[inline]
pub fn sar(shift: U256, value: U256) -> U256 {
let value = I256::from(value);
let ret = if value == I256::zero() || shift >= U256::from(256) {
let I256(sign, _) = value;
match sign {
Sign::Plus | Sign::NoSign => U256::zero(),
Sign::Minus => I256(Sign::Minus, U256::one()).into(),
}
} else {
let shift: u64 = shift.as_u64();
match value.0 {
Sign::Plus | Sign::NoSign => value.1 >> shift as usize,
Sign::Minus => {
let shifted = ((value.1.overflowing_sub(U256::one()).0) >> shift as usize)
.overflowing_add(U256::one()).0;
I256(Sign::Minus, shifted).into()
}
}
};
ret
}