revm_interpreter/instructions/
arithmetic.rs1use super::i256::{i256_div, i256_mod};
2use crate::{
3 gas,
4 interpreter_types::{InterpreterTypes, RuntimeFlag, StackTr},
5 InstructionContext,
6};
7use primitives::U256;
8
9pub fn add<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
11 gas!(context.interpreter, gas::VERYLOW);
12 popn_top!([op1], op2, context.interpreter);
13 *op2 = op1.wrapping_add(*op2);
14}
15
16pub fn mul<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
18 gas!(context.interpreter, gas::LOW);
19 popn_top!([op1], op2, context.interpreter);
20 *op2 = op1.wrapping_mul(*op2);
21}
22
23pub fn sub<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
25 gas!(context.interpreter, gas::VERYLOW);
26 popn_top!([op1], op2, context.interpreter);
27 *op2 = op1.wrapping_sub(*op2);
28}
29
30pub fn div<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
32 gas!(context.interpreter, gas::LOW);
33 popn_top!([op1], op2, context.interpreter);
34 if !op2.is_zero() {
35 *op2 = op1.wrapping_div(*op2);
36 }
37}
38
39pub fn sdiv<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
43 gas!(context.interpreter, gas::LOW);
44 popn_top!([op1], op2, context.interpreter);
45 *op2 = i256_div(op1, *op2);
46}
47
48pub fn rem<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
52 gas!(context.interpreter, gas::LOW);
53 popn_top!([op1], op2, context.interpreter);
54 if !op2.is_zero() {
55 *op2 = op1.wrapping_rem(*op2);
56 }
57}
58
59pub fn smod<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
63 gas!(context.interpreter, gas::LOW);
64 popn_top!([op1], op2, context.interpreter);
65 *op2 = i256_mod(op1, *op2)
66}
67
68pub fn addmod<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
72 gas!(context.interpreter, gas::MID);
73 popn_top!([op1, op2], op3, context.interpreter);
74 *op3 = op1.add_mod(op2, *op3)
75}
76
77pub fn mulmod<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
81 gas!(context.interpreter, gas::MID);
82 popn_top!([op1, op2], op3, context.interpreter);
83 *op3 = op1.mul_mod(op2, *op3)
84}
85
86pub fn exp<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
88 let spec_id = context.interpreter.runtime_flag.spec_id();
89 popn_top!([op1], op2, context.interpreter);
90 gas_or_fail!(context.interpreter, gas::exp_cost(spec_id, *op2));
91 *op2 = op1.pow(*op2);
92}
93
94pub fn signextend<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
124 gas!(context.interpreter, gas::LOW);
125 popn_top!([ext], x, context.interpreter);
126 if ext < U256::from(31) {
128 let ext = ext.as_limbs()[0];
129 let bit_index = (8 * ext + 7) as usize;
130 let bit = x.bit(bit_index);
131 let mask = (U256::from(1) << bit_index) - U256::from(1);
132 *x = if bit { *x | !mask } else { *x & mask };
133 }
134}