revm_interpreter/instructions/
arithmetic.rs1use super::i256::{i256_div, i256_mod};
2use crate::{
3 gas,
4 interpreter::Interpreter,
5 interpreter_types::{InterpreterTypes, LoopControl, RuntimeFlag, StackTr},
6 Host,
7};
8use primitives::U256;
9
10pub fn add<WIRE: InterpreterTypes, H: Host + ?Sized>(
11 interpreter: &mut Interpreter<WIRE>,
12 _host: &mut H,
13) {
14 gas!(interpreter, gas::VERYLOW);
15 popn_top!([op1], op2, interpreter);
16 *op2 = op1.wrapping_add(*op2);
17}
18
19pub fn mul<WIRE: InterpreterTypes, H: Host + ?Sized>(
20 interpreter: &mut Interpreter<WIRE>,
21 _host: &mut H,
22) {
23 gas!(interpreter, gas::LOW);
24 popn_top!([op1], op2, interpreter);
25 *op2 = op1.wrapping_mul(*op2);
26}
27
28pub fn sub<WIRE: InterpreterTypes, H: Host + ?Sized>(
29 interpreter: &mut Interpreter<WIRE>,
30 _host: &mut H,
31) {
32 gas!(interpreter, gas::VERYLOW);
33 popn_top!([op1], op2, interpreter);
34 *op2 = op1.wrapping_sub(*op2);
35}
36
37pub fn div<WIRE: InterpreterTypes, H: Host + ?Sized>(
38 interpreter: &mut Interpreter<WIRE>,
39 _host: &mut H,
40) {
41 gas!(interpreter, gas::LOW);
42 popn_top!([op1], op2, interpreter);
43 if !op2.is_zero() {
44 *op2 = op1.wrapping_div(*op2);
45 }
46}
47
48pub fn sdiv<WIRE: InterpreterTypes, H: Host + ?Sized>(
49 interpreter: &mut Interpreter<WIRE>,
50 _host: &mut H,
51) {
52 gas!(interpreter, gas::LOW);
53 popn_top!([op1], op2, interpreter);
54 *op2 = i256_div(op1, *op2);
55}
56
57pub fn rem<WIRE: InterpreterTypes, H: Host + ?Sized>(
58 interpreter: &mut Interpreter<WIRE>,
59 _host: &mut H,
60) {
61 gas!(interpreter, gas::LOW);
62 popn_top!([op1], op2, interpreter);
63 if !op2.is_zero() {
64 *op2 = op1.wrapping_rem(*op2);
65 }
66}
67
68pub fn smod<WIRE: InterpreterTypes, H: Host + ?Sized>(
69 interpreter: &mut Interpreter<WIRE>,
70 _host: &mut H,
71) {
72 gas!(interpreter, gas::LOW);
73 popn_top!([op1], op2, interpreter);
74 *op2 = i256_mod(op1, *op2)
75}
76
77pub fn addmod<WIRE: InterpreterTypes, H: Host + ?Sized>(
78 interpreter: &mut Interpreter<WIRE>,
79 _host: &mut H,
80) {
81 gas!(interpreter, gas::MID);
82 popn_top!([op1, op2], op3, interpreter);
83 *op3 = op1.add_mod(op2, *op3)
84}
85
86pub fn mulmod<WIRE: InterpreterTypes, H: Host + ?Sized>(
87 interpreter: &mut Interpreter<WIRE>,
88 _host: &mut H,
89) {
90 gas!(interpreter, gas::MID);
91 popn_top!([op1, op2], op3, interpreter);
92 *op3 = op1.mul_mod(op2, *op3)
93}
94
95pub fn exp<WIRE: InterpreterTypes, H: Host + ?Sized>(
96 interpreter: &mut Interpreter<WIRE>,
97 _host: &mut H,
98) {
99 let spec_id = interpreter.runtime_flag.spec_id();
100 popn_top!([op1], op2, interpreter);
101 gas_or_fail!(interpreter, gas::exp_cost(spec_id, *op2));
102 *op2 = op1.pow(*op2);
103}
104
105pub fn signextend<WIRE: InterpreterTypes, H: Host + ?Sized>(
135 interpreter: &mut Interpreter<WIRE>,
136 _host: &mut H,
137) {
138 gas!(interpreter, gas::LOW);
139 popn_top!([ext], x, interpreter);
140 if ext < U256::from(31) {
142 let ext = ext.as_limbs()[0];
143 let bit_index = (8 * ext + 7) as usize;
144 let bit = x.bit(bit_index);
145 let mask = (U256::from(1) << bit_index) - U256::from(1);
146 *x = if bit { *x | !mask } else { *x & mask };
147 }
148}