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>) {
10 gas!(context.interpreter, gas::VERYLOW);
11 popn_top!([op1], op2, context.interpreter);
12 *op2 = op1.wrapping_add(*op2);
13}
14
15pub fn mul<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
16 gas!(context.interpreter, gas::LOW);
17 popn_top!([op1], op2, context.interpreter);
18 *op2 = op1.wrapping_mul(*op2);
19}
20
21pub fn sub<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
22 gas!(context.interpreter, gas::VERYLOW);
23 popn_top!([op1], op2, context.interpreter);
24 *op2 = op1.wrapping_sub(*op2);
25}
26
27pub fn div<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
28 gas!(context.interpreter, gas::LOW);
29 popn_top!([op1], op2, context.interpreter);
30 if !op2.is_zero() {
31 *op2 = op1.wrapping_div(*op2);
32 }
33}
34
35pub fn sdiv<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
36 gas!(context.interpreter, gas::LOW);
37 popn_top!([op1], op2, context.interpreter);
38 *op2 = i256_div(op1, *op2);
39}
40
41pub fn rem<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
42 gas!(context.interpreter, gas::LOW);
43 popn_top!([op1], op2, context.interpreter);
44 if !op2.is_zero() {
45 *op2 = op1.wrapping_rem(*op2);
46 }
47}
48
49pub fn smod<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
50 gas!(context.interpreter, gas::LOW);
51 popn_top!([op1], op2, context.interpreter);
52 *op2 = i256_mod(op1, *op2)
53}
54
55pub fn addmod<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
56 gas!(context.interpreter, gas::MID);
57 popn_top!([op1, op2], op3, context.interpreter);
58 *op3 = op1.add_mod(op2, *op3)
59}
60
61pub fn mulmod<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
62 gas!(context.interpreter, gas::MID);
63 popn_top!([op1, op2], op3, context.interpreter);
64 *op3 = op1.mul_mod(op2, *op3)
65}
66
67pub fn exp<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
68 let spec_id = context.interpreter.runtime_flag.spec_id();
69 popn_top!([op1], op2, context.interpreter);
70 gas_or_fail!(context.interpreter, gas::exp_cost(spec_id, *op2));
71 *op2 = op1.pow(*op2);
72}
73
74pub fn signextend<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
104 gas!(context.interpreter, gas::LOW);
105 popn_top!([ext], x, context.interpreter);
106 if ext < U256::from(31) {
108 let ext = ext.as_limbs()[0];
109 let bit_index = (8 * ext + 7) as usize;
110 let bit = x.bit(bit_index);
111 let mask = (U256::from(1) << bit_index) - U256::from(1);
112 *x = if bit { *x | !mask } else { *x & mask };
113 }
114}