rtvm_interpreter/instructions/
arithmetic.rs1use super::i256::{i256_div, i256_mod};
2use crate::{
3 gas,
4 primitives::{Spec, U256},
5 Host, Interpreter,
6};
7
8pub fn add<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) {
9 gas!(interpreter, gas::VERYLOW);
10 pop_top!(interpreter, op1, op2);
11 *op2 = op1.wrapping_add(*op2);
12}
13
14pub fn mul<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) {
15 gas!(interpreter, gas::LOW);
16 pop_top!(interpreter, op1, op2);
17 *op2 = op1.wrapping_mul(*op2);
18}
19
20pub fn sub<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) {
21 gas!(interpreter, gas::VERYLOW);
22 pop_top!(interpreter, op1, op2);
23 *op2 = op1.wrapping_sub(*op2);
24}
25
26pub fn div<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) {
27 gas!(interpreter, gas::LOW);
28 pop_top!(interpreter, op1, op2);
29 if *op2 != U256::ZERO {
30 *op2 = op1.wrapping_div(*op2);
31 }
32}
33
34pub fn sdiv<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) {
35 gas!(interpreter, gas::LOW);
36 pop_top!(interpreter, op1, op2);
37 *op2 = i256_div(op1, *op2);
38}
39
40pub fn rem<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) {
41 gas!(interpreter, gas::LOW);
42 pop_top!(interpreter, op1, op2);
43 if *op2 != U256::ZERO {
44 *op2 = op1.wrapping_rem(*op2);
45 }
46}
47
48pub fn smod<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) {
49 gas!(interpreter, gas::LOW);
50 pop_top!(interpreter, op1, op2);
51 *op2 = i256_mod(op1, *op2)
52}
53
54pub fn addmod<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) {
55 gas!(interpreter, gas::MID);
56 pop_top!(interpreter, op1, op2, op3);
57 *op3 = op1.add_mod(op2, *op3)
58}
59
60pub fn mulmod<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) {
61 gas!(interpreter, gas::MID);
62 pop_top!(interpreter, op1, op2, op3);
63 *op3 = op1.mul_mod(op2, *op3)
64}
65
66pub fn exp<H: Host + ?Sized, SPEC: Spec>(interpreter: &mut Interpreter, _host: &mut H) {
67 pop_top!(interpreter, op1, op2);
68 gas_or_fail!(interpreter, gas::exp_cost(SPEC::SPEC_ID, *op2));
69 *op2 = op1.pow(*op2);
70}
71
72pub fn signextend<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) {
88 gas!(interpreter, gas::LOW);
89 pop_top!(interpreter, ext, x);
90 if ext < U256::from(31) {
92 let ext = ext.as_limbs()[0];
93 let bit_index = (8 * ext + 7) as usize;
94 let bit = x.bit(bit_index);
95 let mask = (U256::from(1) << bit_index) - U256::from(1);
96 *x = if bit { *x | !mask } else { *x & mask };
97 }
98}