revm_interpreter/instructions/
arithmetic.rsuse super::i256::{i256_div, i256_mod};
use crate::{
gas,
interpreter::Interpreter,
interpreter_types::{InterpreterTypes, LoopControl, RuntimeFlag, StackTrait},
Host,
};
use primitives::U256;
pub fn add<WIRE: InterpreterTypes, H: Host + ?Sized>(
interpreter: &mut Interpreter<WIRE>,
_host: &mut H,
) {
gas!(interpreter, gas::VERYLOW);
popn_top!([op1], op2, interpreter);
*op2 = op1.wrapping_add(*op2);
}
pub fn mul<WIRE: InterpreterTypes, H: Host + ?Sized>(
interpreter: &mut Interpreter<WIRE>,
_host: &mut H,
) {
gas!(interpreter, gas::LOW);
popn_top!([op1], op2, interpreter);
*op2 = op1.wrapping_mul(*op2);
}
pub fn sub<WIRE: InterpreterTypes, H: Host + ?Sized>(
interpreter: &mut Interpreter<WIRE>,
_host: &mut H,
) {
gas!(interpreter, gas::VERYLOW);
popn_top!([op1], op2, interpreter);
*op2 = op1.wrapping_sub(*op2);
}
pub fn div<WIRE: InterpreterTypes, H: Host + ?Sized>(
interpreter: &mut Interpreter<WIRE>,
_host: &mut H,
) {
gas!(interpreter, gas::LOW);
popn_top!([op1], op2, interpreter);
if !op2.is_zero() {
*op2 = op1.wrapping_div(*op2);
}
}
pub fn sdiv<WIRE: InterpreterTypes, H: Host + ?Sized>(
interpreter: &mut Interpreter<WIRE>,
_host: &mut H,
) {
gas!(interpreter, gas::LOW);
popn_top!([op1], op2, interpreter);
*op2 = i256_div(op1, *op2);
}
pub fn rem<WIRE: InterpreterTypes, H: Host + ?Sized>(
interpreter: &mut Interpreter<WIRE>,
_host: &mut H,
) {
gas!(interpreter, gas::LOW);
popn_top!([op1], op2, interpreter);
if !op2.is_zero() {
*op2 = op1.wrapping_rem(*op2);
}
}
pub fn smod<WIRE: InterpreterTypes, H: Host + ?Sized>(
interpreter: &mut Interpreter<WIRE>,
_host: &mut H,
) {
gas!(interpreter, gas::LOW);
popn_top!([op1], op2, interpreter);
*op2 = i256_mod(op1, *op2)
}
pub fn addmod<WIRE: InterpreterTypes, H: Host + ?Sized>(
interpreter: &mut Interpreter<WIRE>,
_host: &mut H,
) {
gas!(interpreter, gas::MID);
popn_top!([op1, op2], op3, interpreter);
*op3 = op1.add_mod(op2, *op3)
}
pub fn mulmod<WIRE: InterpreterTypes, H: Host + ?Sized>(
interpreter: &mut Interpreter<WIRE>,
_host: &mut H,
) {
gas!(interpreter, gas::MID);
popn_top!([op1, op2], op3, interpreter);
*op3 = op1.mul_mod(op2, *op3)
}
pub fn exp<WIRE: InterpreterTypes, H: Host + ?Sized>(
interpreter: &mut Interpreter<WIRE>,
_host: &mut H,
) {
let spec_id = interpreter.runtime_flag.spec_id();
popn_top!([op1], op2, interpreter);
gas_or_fail!(interpreter, gas::exp_cost(spec_id, *op2));
*op2 = op1.pow(*op2);
}
pub fn signextend<WIRE: InterpreterTypes, H: Host + ?Sized>(
interpreter: &mut Interpreter<WIRE>,
_host: &mut H,
) {
gas!(interpreter, gas::LOW);
popn_top!([ext], x, interpreter);
if ext < U256::from(31) {
let ext = ext.as_limbs()[0];
let bit_index = (8 * ext + 7) as usize;
let bit = x.bit(bit_index);
let mask = (U256::from(1) << bit_index) - U256::from(1);
*x = if bit { *x | !mask } else { *x & mask };
}
}