diff --git a/fuel-asm/src/args/wideint.rs b/fuel-asm/src/args/wideint.rs index 747a82f318..b8cd7aa657 100644 --- a/fuel-asm/src/args/wideint.rs +++ b/fuel-asm/src/args/wideint.rs @@ -140,6 +140,40 @@ impl MulArgs { } } +/// Additional arguments for WDEX and WQEX instructions. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[cfg_attr(feature = "typescript", wasm_bindgen::prelude::wasm_bindgen)] +#[must_use] +pub struct ExpArgs { + /// Load LHSS from register if true, otherwise zero-extend register value + pub indirect_lhs: bool, + /// Load RHS from register if true, otherwise zero-extend register value + pub indirect_rhs: bool, +} + +impl ExpArgs { + /// Convert to immediate value. + pub fn to_imm(self) -> Imm06 { + let mut bits = 0u8; + bits |= (self.indirect_lhs as u8) << 4; + bits |= (self.indirect_rhs as u8) << 5; + Imm06(bits) + } + + /// Construct from `Imm06`. Returns `None` if the value has reserved flags set. + pub fn from_imm(bits: Imm06) -> Option { + let indirect_lhs = ((bits.0 >> 4) & 1) == 1; + let indirect_rhs = ((bits.0 >> 5) & 1) == 1; + if (bits.0 & 0b1111) != 0 { + return None; + } + Some(Self { + indirect_lhs, + indirect_rhs, + }) + } +} + /// Additional arguments for WMDV and WDDV instructions. #[derive(Debug, Clone, Copy, PartialEq, Eq)] #[cfg_attr(feature = "typescript", wasm_bindgen::prelude::wasm_bindgen)] @@ -234,6 +268,29 @@ mod tests { } } + #[rstest::rstest] + fn encode_decode_exp( + #[values(true, false)] indirect_lhs: bool, + #[values(true, false)] indirect_rhs: bool, + ) { + let orig = ExpArgs { + indirect_lhs, + indirect_rhs, + }; + let decoded = ExpArgs::from_imm(orig.to_imm()).expect("decode error"); + assert_eq!(orig, decoded); + } + + #[test] + fn decode_encode_exp() { + for imm in 0..Imm06::MAX.0 { + let bits = Imm06::from(imm); + if let Some(decoded) = ExpArgs::from_imm(bits) { + assert_eq!(decoded.to_imm().0, imm); + } + } + } + #[rstest::rstest] fn encode_decode_div(#[values(true, false)] indirect_rhs: bool) { let orig = DivArgs { indirect_rhs }; diff --git a/fuel-asm/src/lib.rs b/fuel-asm/src/lib.rs index 9c89930cc5..1d990db8ef 100644 --- a/fuel-asm/src/lib.rs +++ b/fuel-asm/src/lib.rs @@ -337,6 +337,10 @@ impl_instructions! { 0xac WDMM wdmm [dst: RegId mul_lhs: RegId mul_rhs: RegId modulo: RegId] "MulMod 256bit" 0xad WQMM wqmm [dst: RegId mul_lhs: RegId mul_rhs: RegId modulo: RegId] + "Exponentiate 128bit" + 0xae WDEX wdex [dst: RegId base: RegId exp: RegId flags: Imm06] + "Exponentiate 256bit" + 0xaf WQEX wqex [dst: RegId base: RegId exp: RegId flags: Imm06] "Call external function" 0xb0 ECAL ecal [a: RegId b: RegId c: RegId d: RegId] @@ -696,12 +700,12 @@ impl Opcode { match self { ADD | AND | DIV | EQ | EXP | GT | LT | MLOG | MROO | MOD | MOVE | MUL | NOT | OR | SLL | SRL | SUB | XOR | WDCM | WQCM | WDOP | WQOP | WDML - | WQML | WDDV | WQDV | WDMD | WQMD | WDAM | WQAM | WDMM | WQMM | PSHH - | PSHL | POPH | POPL | RET | ALOC | MCL | MCP | MEQ | ECK1 | ECR1 | ED19 - | K256 | S256 | NOOP | FLAG | ADDI | ANDI | DIVI | EXPI | MODI | MULI - | MLDV | ORI | SLLI | SRLI | SUBI | XORI | JNEI | LB | LW | SB | SW - | MCPI | MCLI | GM | MOVI | JNZI | JI | JMP | JNE | JMPF | JMPB | JNZF - | JNZB | JNEF | JNEB | CFEI | CFSI | CFE | CFS | GTF => true, + | WQML | WDDV | WQDV | WDMD | WQMD | WDAM | WQAM | WDMM | WQMM | WDEX + | WQEX | PSHH | PSHL | POPH | POPL | RET | ALOC | MCL | MCP | MEQ | ECK1 + | ECR1 | ED19 | K256 | S256 | NOOP | FLAG | ADDI | ANDI | DIVI | EXPI + | MODI | MULI | MLDV | ORI | SLLI | SRLI | SUBI | XORI | JNEI | LB | LW + | SB | SW | MCPI | MCLI | GM | MOVI | JNZI | JI | JMP | JNE | JMPF | JMPB + | JNZF | JNZB | JNEF | JNEB | CFEI | CFSI | CFE | CFS | GTF => true, _ => false, } } diff --git a/fuel-tx/src/transaction/consensus_parameters/gas.rs b/fuel-tx/src/transaction/consensus_parameters/gas.rs index d3b4c11d77..596b2499d6 100644 --- a/fuel-tx/src/transaction/consensus_parameters/gas.rs +++ b/fuel-tx/src/transaction/consensus_parameters/gas.rs @@ -80,6 +80,8 @@ pub enum GasCostsValues { V3(GasCostsValuesV3), /// Version 4 of the gas costs. V4(GasCostsValuesV4), + /// Version 5 of the gas costs. + V5(GasCostsValuesV5), } /// Gas cost for this instruction is not defined for this version. @@ -99,6 +101,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.add, GasCostsValues::V3(v3) => v3.add, GasCostsValues::V4(v4) => v4.add, + GasCostsValues::V5(v5) => v5.add, } } @@ -108,6 +111,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.addi, GasCostsValues::V3(v3) => v3.addi, GasCostsValues::V4(v4) => v4.addi, + GasCostsValues::V5(v5) => v5.addi, } } @@ -117,6 +121,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.and, GasCostsValues::V3(v3) => v3.and, GasCostsValues::V4(v4) => v4.and, + GasCostsValues::V5(v5) => v5.and, } } @@ -126,6 +131,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.andi, GasCostsValues::V3(v3) => v3.andi, GasCostsValues::V4(v4) => v4.andi, + GasCostsValues::V5(v5) => v5.andi, } } @@ -135,6 +141,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.bal, GasCostsValues::V3(v3) => v3.bal, GasCostsValues::V4(v4) => v4.bal, + GasCostsValues::V5(v5) => v5.bal, } } @@ -144,6 +151,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.bhei, GasCostsValues::V3(v3) => v3.bhei, GasCostsValues::V4(v4) => v4.bhei, + GasCostsValues::V5(v5) => v5.bhei, } } @@ -153,6 +161,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.bhsh, GasCostsValues::V3(v3) => v3.bhsh, GasCostsValues::V4(v4) => v4.bhsh, + GasCostsValues::V5(v5) => v5.bhsh, } } @@ -162,6 +171,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.burn, GasCostsValues::V3(v3) => v3.burn, GasCostsValues::V4(v4) => v4.burn, + GasCostsValues::V5(v5) => v5.burn, } } @@ -171,6 +181,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.cb, GasCostsValues::V3(v3) => v3.cb, GasCostsValues::V4(v4) => v4.cb, + GasCostsValues::V5(v5) => v5.cb, } } @@ -180,6 +191,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.cfsi, GasCostsValues::V3(v3) => v3.cfsi, GasCostsValues::V4(v4) => v4.cfsi, + GasCostsValues::V5(v5) => v5.cfsi, } } @@ -189,6 +201,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.div, GasCostsValues::V3(v3) => v3.div, GasCostsValues::V4(v4) => v4.div, + GasCostsValues::V5(v5) => v5.div, } } @@ -198,6 +211,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.divi, GasCostsValues::V3(v3) => v3.divi, GasCostsValues::V4(v4) => v4.divi, + GasCostsValues::V5(v5) => v5.divi, } } @@ -207,6 +221,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.eck1, GasCostsValues::V3(v3) => v3.eck1, GasCostsValues::V4(v4) => v4.eck1, + GasCostsValues::V5(v5) => v5.eck1, } } @@ -216,6 +231,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.ecr1, GasCostsValues::V3(v3) => v3.ecr1, GasCostsValues::V4(v4) => v4.ecr1, + GasCostsValues::V5(v5) => v5.ecr1, } } @@ -225,6 +241,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.eq, GasCostsValues::V3(v3) => v3.eq, GasCostsValues::V4(v4) => v4.eq, + GasCostsValues::V5(v5) => v5.eq, } } @@ -234,6 +251,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.exp, GasCostsValues::V3(v3) => v3.exp, GasCostsValues::V4(v4) => v4.exp, + GasCostsValues::V5(v5) => v5.exp, } } @@ -243,6 +261,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.expi, GasCostsValues::V3(v3) => v3.expi, GasCostsValues::V4(v4) => v4.expi, + GasCostsValues::V5(v5) => v5.expi, } } @@ -252,6 +271,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.flag, GasCostsValues::V3(v3) => v3.flag, GasCostsValues::V4(v4) => v4.flag, + GasCostsValues::V5(v5) => v5.flag, } } @@ -261,6 +281,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.gm, GasCostsValues::V3(v3) => v3.gm, GasCostsValues::V4(v4) => v4.gm, + GasCostsValues::V5(v5) => v5.gm, } } @@ -270,6 +291,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.gt, GasCostsValues::V3(v3) => v3.gt, GasCostsValues::V4(v4) => v4.gt, + GasCostsValues::V5(v5) => v5.gt, } } @@ -279,6 +301,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.gtf, GasCostsValues::V3(v3) => v3.gtf, GasCostsValues::V4(v4) => v4.gtf, + GasCostsValues::V5(v5) => v5.gtf, } } @@ -288,6 +311,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.ji, GasCostsValues::V3(v3) => v3.ji, GasCostsValues::V4(v4) => v4.ji, + GasCostsValues::V5(v5) => v5.ji, } } @@ -297,6 +321,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.jmp, GasCostsValues::V3(v3) => v3.jmp, GasCostsValues::V4(v4) => v4.jmp, + GasCostsValues::V5(v5) => v5.jmp, } } @@ -306,6 +331,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.jne, GasCostsValues::V3(v3) => v3.jne, GasCostsValues::V4(v4) => v4.jne, + GasCostsValues::V5(v5) => v5.jne, } } @@ -315,6 +341,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.jnei, GasCostsValues::V3(v3) => v3.jnei, GasCostsValues::V4(v4) => v4.jnei, + GasCostsValues::V5(v5) => v5.jnei, } } @@ -324,6 +351,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.jnzi, GasCostsValues::V3(v3) => v3.jnzi, GasCostsValues::V4(v4) => v4.jnzi, + GasCostsValues::V5(v5) => v5.jnzi, } } @@ -333,6 +361,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.jmpf, GasCostsValues::V3(v3) => v3.jmpf, GasCostsValues::V4(v4) => v4.jmpf, + GasCostsValues::V5(v5) => v5.jmpf, } } @@ -342,6 +371,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.jmpb, GasCostsValues::V3(v3) => v3.jmpb, GasCostsValues::V4(v4) => v4.jmpb, + GasCostsValues::V5(v5) => v5.jmpb, } } @@ -351,6 +381,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.jnzf, GasCostsValues::V3(v3) => v3.jnzf, GasCostsValues::V4(v4) => v4.jnzf, + GasCostsValues::V5(v5) => v5.jnzf, } } @@ -360,6 +391,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.jnzb, GasCostsValues::V3(v3) => v3.jnzb, GasCostsValues::V4(v4) => v4.jnzb, + GasCostsValues::V5(v5) => v5.jnzb, } } @@ -369,6 +401,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.jnef, GasCostsValues::V3(v3) => v3.jnef, GasCostsValues::V4(v4) => v4.jnef, + GasCostsValues::V5(v5) => v5.jnef, } } @@ -378,6 +411,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.jneb, GasCostsValues::V3(v3) => v3.jneb, GasCostsValues::V4(v4) => v4.jneb, + GasCostsValues::V5(v5) => v5.jneb, } } @@ -387,6 +421,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.lb, GasCostsValues::V3(v3) => v3.lb, GasCostsValues::V4(v4) => v4.lb, + GasCostsValues::V5(v5) => v5.lb, } } @@ -396,6 +431,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.log, GasCostsValues::V3(v3) => v3.log, GasCostsValues::V4(v4) => v4.log, + GasCostsValues::V5(v5) => v5.log, } } @@ -405,6 +441,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.lt, GasCostsValues::V3(v3) => v3.lt, GasCostsValues::V4(v4) => v4.lt, + GasCostsValues::V5(v5) => v5.lt, } } @@ -414,6 +451,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.lw, GasCostsValues::V3(v3) => v3.lw, GasCostsValues::V4(v4) => v4.lw, + GasCostsValues::V5(v5) => v5.lw, } } @@ -423,6 +461,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.mint, GasCostsValues::V3(v3) => v3.mint, GasCostsValues::V4(v4) => v4.mint, + GasCostsValues::V5(v5) => v5.mint, } } @@ -432,6 +471,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.mlog, GasCostsValues::V3(v3) => v3.mlog, GasCostsValues::V4(v4) => v4.mlog, + GasCostsValues::V5(v5) => v5.mlog, } } @@ -441,6 +481,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.mod_op, GasCostsValues::V3(v3) => v3.mod_op, GasCostsValues::V4(v4) => v4.mod_op, + GasCostsValues::V5(v5) => v5.mod_op, } } @@ -450,6 +491,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.modi, GasCostsValues::V3(v3) => v3.modi, GasCostsValues::V4(v4) => v4.modi, + GasCostsValues::V5(v5) => v5.modi, } } @@ -459,6 +501,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.move_op, GasCostsValues::V3(v3) => v3.move_op, GasCostsValues::V4(v4) => v4.move_op, + GasCostsValues::V5(v5) => v5.move_op, } } @@ -468,6 +511,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.movi, GasCostsValues::V3(v3) => v3.movi, GasCostsValues::V4(v4) => v4.movi, + GasCostsValues::V5(v5) => v5.movi, } } @@ -477,6 +521,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.mroo, GasCostsValues::V3(v3) => v3.mroo, GasCostsValues::V4(v4) => v4.mroo, + GasCostsValues::V5(v5) => v5.mroo, } } @@ -486,6 +531,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.mul, GasCostsValues::V3(v3) => v3.mul, GasCostsValues::V4(v4) => v4.mul, + GasCostsValues::V5(v5) => v5.mul, } } @@ -495,6 +541,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.muli, GasCostsValues::V3(v3) => v3.muli, GasCostsValues::V4(v4) => v4.muli, + GasCostsValues::V5(v5) => v5.muli, } } @@ -504,6 +551,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.mldv, GasCostsValues::V3(v3) => v3.mldv, GasCostsValues::V4(v4) => v4.mldv, + GasCostsValues::V5(v5) => v5.mldv, } } @@ -513,6 +561,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.noop, GasCostsValues::V3(v3) => v3.noop, GasCostsValues::V4(v4) => v4.noop, + GasCostsValues::V5(v5) => v5.noop, } } @@ -522,6 +571,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.not, GasCostsValues::V3(v3) => v3.not, GasCostsValues::V4(v4) => v4.not, + GasCostsValues::V5(v5) => v5.not, } } @@ -531,6 +581,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.or, GasCostsValues::V3(v3) => v3.or, GasCostsValues::V4(v4) => v4.or, + GasCostsValues::V5(v5) => v5.or, } } @@ -540,6 +591,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.ori, GasCostsValues::V3(v3) => v3.ori, GasCostsValues::V4(v4) => v4.ori, + GasCostsValues::V5(v5) => v5.ori, } } @@ -549,6 +601,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.poph, GasCostsValues::V3(v3) => v3.poph, GasCostsValues::V4(v4) => v4.poph, + GasCostsValues::V5(v5) => v5.poph, } } @@ -558,6 +611,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.popl, GasCostsValues::V3(v3) => v3.popl, GasCostsValues::V4(v4) => v4.popl, + GasCostsValues::V5(v5) => v5.popl, } } @@ -567,6 +621,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.pshh, GasCostsValues::V3(v3) => v3.pshh, GasCostsValues::V4(v4) => v4.pshh, + GasCostsValues::V5(v5) => v5.pshh, } } @@ -576,6 +631,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.pshl, GasCostsValues::V3(v3) => v3.pshl, GasCostsValues::V4(v4) => v4.pshl, + GasCostsValues::V5(v5) => v5.pshl, } } @@ -585,6 +641,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.ret, GasCostsValues::V3(v3) => v3.ret, GasCostsValues::V4(v4) => v4.ret, + GasCostsValues::V5(v5) => v5.ret, } } @@ -594,6 +651,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.rvrt, GasCostsValues::V3(v3) => v3.rvrt, GasCostsValues::V4(v4) => v4.rvrt, + GasCostsValues::V5(v5) => v5.rvrt, } } @@ -603,6 +661,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.sb, GasCostsValues::V3(v3) => v3.sb, GasCostsValues::V4(v4) => v4.sb, + GasCostsValues::V5(v5) => v5.sb, } } @@ -612,6 +671,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.sll, GasCostsValues::V3(v3) => v3.sll, GasCostsValues::V4(v4) => v4.sll, + GasCostsValues::V5(v5) => v5.sll, } } @@ -621,6 +681,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.slli, GasCostsValues::V3(v3) => v3.slli, GasCostsValues::V4(v4) => v4.slli, + GasCostsValues::V5(v5) => v5.slli, } } @@ -630,6 +691,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.srl, GasCostsValues::V3(v3) => v3.srl, GasCostsValues::V4(v4) => v4.srl, + GasCostsValues::V5(v5) => v5.srl, } } @@ -639,6 +701,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.srli, GasCostsValues::V3(v3) => v3.srli, GasCostsValues::V4(v4) => v4.srli, + GasCostsValues::V5(v5) => v5.srli, } } @@ -648,6 +711,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.srw, GasCostsValues::V3(v3) => v3.srw, GasCostsValues::V4(v4) => v4.srw, + GasCostsValues::V5(v5) => v5.srw, } } @@ -657,6 +721,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.sub, GasCostsValues::V3(v3) => v3.sub, GasCostsValues::V4(v4) => v4.sub, + GasCostsValues::V5(v5) => v5.sub, } } @@ -666,6 +731,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.subi, GasCostsValues::V3(v3) => v3.subi, GasCostsValues::V4(v4) => v4.subi, + GasCostsValues::V5(v5) => v5.subi, } } @@ -675,6 +741,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.sw, GasCostsValues::V3(v3) => v3.sw, GasCostsValues::V4(v4) => v4.sw, + GasCostsValues::V5(v5) => v5.sw, } } @@ -684,6 +751,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.sww, GasCostsValues::V3(v3) => v3.sww, GasCostsValues::V4(v4) => v4.sww, + GasCostsValues::V5(v5) => v5.sww, } } @@ -693,6 +761,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.time, GasCostsValues::V3(v3) => v3.time, GasCostsValues::V4(v4) => v4.time, + GasCostsValues::V5(v5) => v5.time, } } @@ -702,6 +771,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.tr, GasCostsValues::V3(v3) => v3.tr, GasCostsValues::V4(v4) => v4.tr, + GasCostsValues::V5(v5) => v5.tr, } } @@ -711,6 +781,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.tro, GasCostsValues::V3(v3) => v3.tro, GasCostsValues::V4(v4) => v4.tro, + GasCostsValues::V5(v5) => v5.tro, } } @@ -720,6 +791,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.wdcm, GasCostsValues::V3(v3) => v3.wdcm, GasCostsValues::V4(v4) => v4.wdcm, + GasCostsValues::V5(v5) => v5.wdcm, } } @@ -729,6 +801,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.wqcm, GasCostsValues::V3(v3) => v3.wqcm, GasCostsValues::V4(v4) => v4.wqcm, + GasCostsValues::V5(v5) => v5.wqcm, } } @@ -738,6 +811,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.wdop, GasCostsValues::V3(v3) => v3.wdop, GasCostsValues::V4(v4) => v4.wdop, + GasCostsValues::V5(v5) => v5.wdop, } } @@ -747,6 +821,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.wqop, GasCostsValues::V3(v3) => v3.wqop, GasCostsValues::V4(v4) => v4.wqop, + GasCostsValues::V5(v5) => v5.wqop, } } @@ -756,6 +831,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.wdml, GasCostsValues::V3(v3) => v3.wdml, GasCostsValues::V4(v4) => v4.wdml, + GasCostsValues::V5(v5) => v5.wdml, } } @@ -765,6 +841,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.wqml, GasCostsValues::V3(v3) => v3.wqml, GasCostsValues::V4(v4) => v4.wqml, + GasCostsValues::V5(v5) => v5.wqml, } } @@ -774,6 +851,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.wddv, GasCostsValues::V3(v3) => v3.wddv, GasCostsValues::V4(v4) => v4.wddv, + GasCostsValues::V5(v5) => v5.wddv, } } @@ -783,6 +861,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.wqdv, GasCostsValues::V3(v3) => v3.wqdv, GasCostsValues::V4(v4) => v4.wqdv, + GasCostsValues::V5(v5) => v5.wqdv, } } @@ -792,6 +871,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.wdmd, GasCostsValues::V3(v3) => v3.wdmd, GasCostsValues::V4(v4) => v4.wdmd, + GasCostsValues::V5(v5) => v5.wdmd, } } @@ -801,6 +881,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.wqmd, GasCostsValues::V3(v3) => v3.wqmd, GasCostsValues::V4(v4) => v4.wqmd, + GasCostsValues::V5(v5) => v5.wqmd, } } @@ -810,6 +891,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.wdam, GasCostsValues::V3(v3) => v3.wdam, GasCostsValues::V4(v4) => v4.wdam, + GasCostsValues::V5(v5) => v5.wdam, } } @@ -819,6 +901,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.wqam, GasCostsValues::V3(v3) => v3.wqam, GasCostsValues::V4(v4) => v4.wqam, + GasCostsValues::V5(v5) => v5.wqam, } } @@ -828,6 +911,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.wdmm, GasCostsValues::V3(v3) => v3.wdmm, GasCostsValues::V4(v4) => v4.wdmm, + GasCostsValues::V5(v5) => v5.wdmm, } } @@ -837,6 +921,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.wqmm, GasCostsValues::V3(v3) => v3.wqmm, GasCostsValues::V4(v4) => v4.wqmm, + GasCostsValues::V5(v5) => v5.wqmm, } } @@ -846,6 +931,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.xor, GasCostsValues::V3(v3) => v3.xor, GasCostsValues::V4(v4) => v4.xor, + GasCostsValues::V5(v5) => v5.xor, } } @@ -855,6 +941,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.xori, GasCostsValues::V3(v3) => v3.xori, GasCostsValues::V4(v4) => v4.xori, + GasCostsValues::V5(v5) => v5.xori, } } @@ -867,6 +954,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.aloc, GasCostsValues::V3(v3) => v3.aloc, GasCostsValues::V4(v4) => v4.aloc, + GasCostsValues::V5(v5) => v5.aloc, } } @@ -882,6 +970,7 @@ impl GasCostsValues { }, GasCostsValues::V3(v3) => v3.cfe, GasCostsValues::V4(v4) => v4.cfe, + GasCostsValues::V5(v5) => v5.cfe, } } @@ -897,6 +986,7 @@ impl GasCostsValues { }, GasCostsValues::V3(v3) => v3.cfei, GasCostsValues::V4(v4) => v4.cfei, + GasCostsValues::V5(v5) => v5.cfei, } } @@ -906,6 +996,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.call, GasCostsValues::V3(v3) => v3.call, GasCostsValues::V4(v4) => v4.call, + GasCostsValues::V5(v5) => v5.call, } } @@ -915,6 +1006,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.ccp, GasCostsValues::V3(v3) => v3.ccp, GasCostsValues::V4(v4) => v4.ccp, + GasCostsValues::V5(v5) => v5.ccp, } } @@ -924,6 +1016,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.croo, GasCostsValues::V3(v3) => v3.croo, GasCostsValues::V4(v4) => v4.croo, + GasCostsValues::V5(v5) => v5.croo, } } @@ -933,6 +1026,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.csiz, GasCostsValues::V3(v3) => v3.csiz, GasCostsValues::V4(v4) => v4.csiz, + GasCostsValues::V5(v5) => v5.csiz, } } @@ -951,6 +1045,7 @@ impl GasCostsValues { gas_per_unit: 0, }, GasCostsValues::V4(v4) => v4.ed19, + GasCostsValues::V5(v5) => v5.ed19, } } @@ -960,6 +1055,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.k256, GasCostsValues::V3(v3) => v3.k256, GasCostsValues::V4(v4) => v4.k256, + GasCostsValues::V5(v5) => v5.k256, } } @@ -969,6 +1065,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.ldc, GasCostsValues::V3(v3) => v3.ldc, GasCostsValues::V4(v4) => v4.ldc, + GasCostsValues::V5(v5) => v5.ldc, } } @@ -978,6 +1075,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.logd, GasCostsValues::V3(v3) => v3.logd, GasCostsValues::V4(v4) => v4.logd, + GasCostsValues::V5(v5) => v5.logd, } } @@ -987,6 +1085,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.mcl, GasCostsValues::V3(v3) => v3.mcl, GasCostsValues::V4(v4) => v4.mcl, + GasCostsValues::V5(v5) => v5.mcl, } } @@ -996,6 +1095,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.mcli, GasCostsValues::V3(v3) => v3.mcli, GasCostsValues::V4(v4) => v4.mcli, + GasCostsValues::V5(v5) => v5.mcli, } } @@ -1005,6 +1105,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.mcp, GasCostsValues::V3(v3) => v3.mcp, GasCostsValues::V4(v4) => v4.mcp, + GasCostsValues::V5(v5) => v5.mcp, } } @@ -1014,6 +1115,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.mcpi, GasCostsValues::V3(v3) => v3.mcpi, GasCostsValues::V4(v4) => v4.mcpi, + GasCostsValues::V5(v5) => v5.mcpi, } } @@ -1023,6 +1125,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.meq, GasCostsValues::V3(v3) => v3.meq, GasCostsValues::V4(v4) => v4.meq, + GasCostsValues::V5(v5) => v5.meq, } } @@ -1032,6 +1135,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.retd, GasCostsValues::V3(v3) => v3.retd, GasCostsValues::V4(v4) => v4.retd, + GasCostsValues::V5(v5) => v5.retd, } } @@ -1041,6 +1145,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.s256, GasCostsValues::V3(v3) => v3.s256, GasCostsValues::V4(v4) => v4.s256, + GasCostsValues::V5(v5) => v5.s256, } } @@ -1050,6 +1155,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.scwq, GasCostsValues::V3(v3) => v3.scwq, GasCostsValues::V4(v4) => v4.scwq, + GasCostsValues::V5(v5) => v5.scwq, } } @@ -1059,6 +1165,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.smo, GasCostsValues::V3(v3) => v3.smo, GasCostsValues::V4(v4) => v4.smo, + GasCostsValues::V5(v5) => v5.smo, } } @@ -1068,6 +1175,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.srwq, GasCostsValues::V3(v3) => v3.srwq, GasCostsValues::V4(v4) => v4.srwq, + GasCostsValues::V5(v5) => v5.srwq, } } @@ -1077,6 +1185,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.swwq, GasCostsValues::V3(v3) => v3.swwq, GasCostsValues::V4(v4) => v4.swwq, + GasCostsValues::V5(v5) => v5.swwq, } } @@ -1086,6 +1195,7 @@ impl GasCostsValues { GasCostsValues::V2(_v2) => Err(GasCostNotDefined), GasCostsValues::V3(_v3) => Err(GasCostNotDefined), GasCostsValues::V4(v4) => Ok(v4.bsiz), + GasCostsValues::V5(v4) => Ok(v4.bsiz), } } @@ -1095,6 +1205,27 @@ impl GasCostsValues { GasCostsValues::V2(_v2) => Err(GasCostNotDefined), GasCostsValues::V3(_v3) => Err(GasCostNotDefined), GasCostsValues::V4(v4) => Ok(v4.bldd), + GasCostsValues::V5(v4) => Ok(v4.bldd), + } + } + + pub fn wdex(&self) -> Result { + match self { + GasCostsValues::V1(_v1) => Err(GasCostNotDefined), + GasCostsValues::V2(_v2) => Err(GasCostNotDefined), + GasCostsValues::V3(_v3) => Err(GasCostNotDefined), + GasCostsValues::V4(_v4) => Err(GasCostNotDefined), + GasCostsValues::V5(v5) => Ok(v5.wdex), + } + } + + pub fn wqex(&self) -> Result { + match self { + GasCostsValues::V1(_v1) => Err(GasCostNotDefined), + GasCostsValues::V2(_v2) => Err(GasCostNotDefined), + GasCostsValues::V3(_v3) => Err(GasCostNotDefined), + GasCostsValues::V4(_v4) => Err(GasCostNotDefined), + GasCostsValues::V5(v5) => Ok(v5.wqex), } } @@ -1104,6 +1235,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.contract_root, GasCostsValues::V3(v3) => v3.contract_root, GasCostsValues::V4(v4) => v4.contract_root, + GasCostsValues::V5(v5) => v5.contract_root, } } @@ -1113,6 +1245,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.state_root, GasCostsValues::V3(v3) => v3.state_root, GasCostsValues::V4(v4) => v4.state_root, + GasCostsValues::V5(v5) => v5.state_root, } } @@ -1122,6 +1255,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.new_storage_per_byte, GasCostsValues::V3(v3) => v3.new_storage_per_byte, GasCostsValues::V4(v4) => v4.new_storage_per_byte, + GasCostsValues::V5(v5) => v5.new_storage_per_byte, } } @@ -1131,6 +1265,7 @@ impl GasCostsValues { GasCostsValues::V2(v2) => v2.vm_initialization, GasCostsValues::V3(v3) => v3.vm_initialization, GasCostsValues::V4(v4) => v4.vm_initialization, + GasCostsValues::V5(v5) => v5.vm_initialization, } } } @@ -1651,6 +1786,139 @@ pub struct GasCostsValuesV4 { pub vm_initialization: DependentCost, } +/// Gas costs for every op. +/// The difference with [`GasCostsValuesV4`]: +/// - Added `wdex`, `wqex` instructions +#[allow(missing_docs)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] +#[serde(default = "GasCostsValuesV5::unit")] +pub struct GasCostsValuesV5 { + pub add: Word, + pub addi: Word, + pub and: Word, + pub andi: Word, + pub bal: Word, + pub bhei: Word, + pub bhsh: Word, + pub burn: Word, + pub cb: Word, + pub cfsi: Word, + pub div: Word, + pub divi: Word, + pub eck1: Word, + pub ecr1: Word, + pub eq: Word, + pub exp: Word, + pub expi: Word, + pub flag: Word, + pub gm: Word, + pub gt: Word, + pub gtf: Word, + pub ji: Word, + pub jmp: Word, + pub jne: Word, + pub jnei: Word, + pub jnzi: Word, + pub jmpf: Word, + pub jmpb: Word, + pub jnzf: Word, + pub jnzb: Word, + pub jnef: Word, + pub jneb: Word, + pub lb: Word, + pub log: Word, + pub lt: Word, + pub lw: Word, + pub mint: Word, + pub mlog: Word, + #[cfg_attr(feature = "serde", serde(rename = "mod"))] + pub mod_op: Word, + pub modi: Word, + #[cfg_attr(feature = "serde", serde(rename = "move"))] + pub move_op: Word, + pub movi: Word, + pub mroo: Word, + pub mul: Word, + pub muli: Word, + pub mldv: Word, + pub noop: Word, + pub not: Word, + pub or: Word, + pub ori: Word, + pub poph: Word, + pub popl: Word, + pub pshh: Word, + pub pshl: Word, + #[cfg_attr(feature = "serde", serde(rename = "ret_contract"))] + pub ret: Word, + #[cfg_attr(feature = "serde", serde(rename = "rvrt_contract"))] + pub rvrt: Word, + pub sb: Word, + pub sll: Word, + pub slli: Word, + pub srl: Word, + pub srli: Word, + pub srw: Word, + pub sub: Word, + pub subi: Word, + pub sw: Word, + pub sww: Word, + pub time: Word, + pub tr: Word, + pub tro: Word, + pub wdcm: Word, + pub wqcm: Word, + pub wdop: Word, + pub wqop: Word, + pub wdml: Word, + pub wqml: Word, + pub wddv: Word, + pub wqdv: Word, + pub wdmd: Word, + pub wqmd: Word, + pub wdam: Word, + pub wqam: Word, + pub wdmm: Word, + pub wqmm: Word, + pub xor: Word, + pub xori: Word, + + // Dependent + pub aloc: DependentCost, + pub bsiz: DependentCost, + pub bldd: DependentCost, + pub cfe: DependentCost, + pub cfei: DependentCost, + pub call: DependentCost, + pub ccp: DependentCost, + pub croo: DependentCost, + pub csiz: DependentCost, + pub ed19: DependentCost, + pub k256: DependentCost, + pub ldc: DependentCost, + pub logd: DependentCost, + pub mcl: DependentCost, + pub mcli: DependentCost, + pub mcp: DependentCost, + pub mcpi: DependentCost, + pub meq: DependentCost, + #[cfg_attr(feature = "serde", serde(rename = "retd_contract"))] + pub retd: DependentCost, + pub s256: DependentCost, + pub scwq: DependentCost, + pub smo: DependentCost, + pub srwq: DependentCost, + pub swwq: DependentCost, + pub wdex: DependentCost, + pub wqex: DependentCost, + + // Non-opcode costs + pub contract_root: DependentCost, + pub state_root: DependentCost, + pub new_storage_per_byte: Word, + pub vm_initialization: DependentCost, +} + /// Dependent cost is a cost that depends on the number of units. #[derive( Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize, @@ -2664,6 +2932,254 @@ impl GasCostsValuesV4 { } } +impl GasCostsValuesV5 { + /// Create costs that are all set to zero. + pub fn free() -> Self { + Self { + add: 0, + addi: 0, + and: 0, + andi: 0, + bal: 0, + bhei: 0, + bhsh: 0, + burn: 0, + cb: 0, + cfsi: 0, + div: 0, + divi: 0, + eck1: 0, + ecr1: 0, + eq: 0, + exp: 0, + expi: 0, + flag: 0, + gm: 0, + gt: 0, + gtf: 0, + ji: 0, + jmp: 0, + jne: 0, + jnei: 0, + jnzi: 0, + jmpf: 0, + jmpb: 0, + jnzf: 0, + jnzb: 0, + jnef: 0, + jneb: 0, + lb: 0, + log: 0, + lt: 0, + lw: 0, + mint: 0, + mlog: 0, + mod_op: 0, + modi: 0, + move_op: 0, + movi: 0, + mroo: 0, + mul: 0, + muli: 0, + mldv: 0, + noop: 0, + not: 0, + or: 0, + ori: 0, + poph: 0, + popl: 0, + pshh: 0, + pshl: 0, + ret: 0, + rvrt: 0, + sb: 0, + sll: 0, + slli: 0, + srl: 0, + srli: 0, + srw: 0, + sub: 0, + subi: 0, + sw: 0, + sww: 0, + time: 0, + tr: 0, + tro: 0, + wdcm: 0, + wqcm: 0, + wdop: 0, + wqop: 0, + wdml: 0, + wqml: 0, + wddv: 0, + wqdv: 0, + wdmd: 0, + wqmd: 0, + wdam: 0, + wqam: 0, + wdmm: 0, + wqmm: 0, + xor: 0, + xori: 0, + aloc: DependentCost::free(), + bsiz: DependentCost::free(), + bldd: DependentCost::free(), + cfe: DependentCost::free(), + cfei: DependentCost::free(), + call: DependentCost::free(), + ccp: DependentCost::free(), + croo: DependentCost::free(), + csiz: DependentCost::free(), + ed19: DependentCost::free(), + k256: DependentCost::free(), + ldc: DependentCost::free(), + logd: DependentCost::free(), + mcl: DependentCost::free(), + mcli: DependentCost::free(), + mcp: DependentCost::free(), + mcpi: DependentCost::free(), + meq: DependentCost::free(), + retd: DependentCost::free(), + s256: DependentCost::free(), + scwq: DependentCost::free(), + smo: DependentCost::free(), + srwq: DependentCost::free(), + swwq: DependentCost::free(), + wdex: DependentCost::free(), + wqex: DependentCost::free(), + + // Non-opcode costs + contract_root: DependentCost::free(), + state_root: DependentCost::free(), + new_storage_per_byte: 0, + vm_initialization: DependentCost::free(), + } + } + + /// Create costs that are all set to one. + pub fn unit() -> Self { + Self { + add: 1, + addi: 1, + and: 1, + andi: 1, + bal: 1, + bhei: 1, + bhsh: 1, + burn: 1, + cb: 1, + cfsi: 1, + div: 1, + divi: 1, + eck1: 1, + ecr1: 1, + eq: 1, + exp: 1, + expi: 1, + flag: 1, + gm: 1, + gt: 1, + gtf: 1, + ji: 1, + jmp: 1, + jne: 1, + jnei: 1, + jnzi: 1, + jmpf: 1, + jmpb: 1, + jnzf: 1, + jnzb: 1, + jnef: 1, + jneb: 1, + lb: 1, + log: 1, + lt: 1, + lw: 1, + mint: 1, + mlog: 1, + mod_op: 1, + modi: 1, + move_op: 1, + movi: 1, + mroo: 1, + mul: 1, + muli: 1, + mldv: 1, + noop: 1, + not: 1, + or: 1, + ori: 1, + ret: 1, + poph: 1, + popl: 1, + pshh: 1, + pshl: 1, + rvrt: 1, + sb: 1, + sll: 1, + slli: 1, + srl: 1, + srli: 1, + srw: 1, + sub: 1, + subi: 1, + sw: 1, + sww: 1, + time: 1, + tr: 1, + tro: 1, + wdcm: 1, + wqcm: 1, + wdop: 1, + wqop: 1, + wdml: 1, + wqml: 1, + wddv: 1, + wqdv: 1, + wdmd: 1, + wqmd: 1, + wdam: 1, + wqam: 1, + wdmm: 1, + wqmm: 1, + xor: 1, + xori: 1, + aloc: DependentCost::unit(), + bsiz: DependentCost::unit(), + bldd: DependentCost::unit(), + cfe: DependentCost::unit(), + cfei: DependentCost::unit(), + call: DependentCost::unit(), + ccp: DependentCost::unit(), + croo: DependentCost::unit(), + csiz: DependentCost::unit(), + ed19: DependentCost::unit(), + k256: DependentCost::unit(), + ldc: DependentCost::unit(), + logd: DependentCost::unit(), + mcl: DependentCost::unit(), + mcli: DependentCost::unit(), + mcp: DependentCost::unit(), + mcpi: DependentCost::unit(), + meq: DependentCost::unit(), + retd: DependentCost::unit(), + s256: DependentCost::unit(), + scwq: DependentCost::unit(), + smo: DependentCost::unit(), + srwq: DependentCost::unit(), + swwq: DependentCost::unit(), + wdex: DependentCost::unit(), + wqex: DependentCost::unit(), + + // Non-opcode costs + contract_root: DependentCost::unit(), + state_root: DependentCost::unit(), + new_storage_per_byte: 1, + vm_initialization: DependentCost::unit(), + } + } +} + impl DependentCost { /// Create costs that make operations free. pub fn free() -> Self { diff --git a/fuel-vm/src/interpreter/alu/wideint.rs b/fuel-vm/src/interpreter/alu/wideint.rs index 0b755ac9c5..26dd151a67 100644 --- a/fuel-vm/src/interpreter/alu/wideint.rs +++ b/fuel-vm/src/interpreter/alu/wideint.rs @@ -165,6 +165,54 @@ macro_rules! wideint_ops { Ok(inc_pc(pc)?) } + pub(crate) fn []( + &mut self, + gas_cost: fuel_tx::DependentCost, + dest_addr: Word, + b: Word, + c: Word, + args: ExpArgs, + ) -> SimpleResult<()> { + // LHS is only indirect if the flag is set + let lhs: $t = if args.indirect_lhs { + $t::from_be_bytes(self.memory.as_ref().read_bytes(b)?) + } else { + b.into() + }; + // RHS is only indirect if the flag is set + let rhs: $t = if args.indirect_rhs { + $t::from_be_bytes(self.memory.as_ref().read_bytes(c)?) + } else { + c.into() + }; + + // Handle exponents >u32::MAX separately + let (wrapped, overflow) = if let Ok(rhs) = u32::try_from(rhs) { + self.dependent_gas_charge(gas_cost, rhs as Word)?; + $t::overflowing_pow(lhs, rhs) + } else if lhs < 2 { + self.dependent_gas_charge(gas_cost, 0)?; + (lhs, false) + } else { + self.dependent_gas_charge(gas_cost, 0)?; + ($t::MIN, true) + }; + + let owner_regs = self.ownership_registers(); + let (SystemRegisters { flag, mut of, mut err, pc, .. }, _) = split_registers(&mut self.registers); + + if overflow && !is_wrapping(flag.into()) { + return Err(PanicReason::ArithmeticOverflow.into()); + } + + *of = overflow as Word; + *err = 0; + + self.memory.as_mut().write_bytes(owner_regs, dest_addr, wrapped.to_be_bytes())?; + + Ok(inc_pc(pc)?) + } + pub(crate) fn []( &mut self, dest_addr: Word, diff --git a/fuel-vm/src/interpreter/executors/instruction.rs b/fuel-vm/src/interpreter/executors/instruction.rs index bc7c7b8cfa..5f49602b63 100644 --- a/fuel-vm/src/interpreter/executors/instruction.rs +++ b/fuel-vm/src/interpreter/executors/instruction.rs @@ -281,6 +281,24 @@ where let (a, b, c, d) = wqmm.unpack(); self.alu_wideint_mulmod_u256(r!(a), r!(b), r!(c), r!(d))?; } + Instruction::WDEX(wdex) => { + let (a, b, c, imm) = wdex.unpack(); + let args = wideint::ExpArgs::from_imm(imm) + .ok_or(PanicReason::InvalidImmediateValue)?; + // Gas charge done in the inner function, as it's dependent on a loaded + // value + let gas_cost = self.gas_costs().wdex().map_err(PanicReason::from)?; + self.alu_wideint_exp_u128(gas_cost, r!(a), r!(b), r!(c), args)?; + } + Instruction::WQEX(wqex) => { + let (a, b, c, imm) = wqex.unpack(); + let args = wideint::ExpArgs::from_imm(imm) + .ok_or(PanicReason::InvalidImmediateValue)?; + // Gas charge done in the inner function, as it's dependent on a loaded + // value + let gas_cost = self.gas_costs().wdex().map_err(PanicReason::from)?; + self.alu_wideint_exp_u256(gas_cost, r!(a), r!(b), r!(c), args)?; + } Instruction::MLOG(mlog) => { self.gas_charge(self.gas_costs().mlog())?; diff --git a/fuel-vm/src/interpreter/executors/instruction/tests/reserved_registers.rs b/fuel-vm/src/interpreter/executors/instruction/tests/reserved_registers.rs index d2a87c7c98..9ce35e8af5 100644 --- a/fuel-vm/src/interpreter/executors/instruction/tests/reserved_registers.rs +++ b/fuel-vm/src/interpreter/executors/instruction/tests/reserved_registers.rs @@ -180,6 +180,8 @@ fn writes_to_ra(opcode: Opcode) -> bool { Opcode::WQAM => false, Opcode::WDMM => false, Opcode::WQMM => false, + Opcode::WDEX => false, + Opcode::WQEX => false, Opcode::XOR => true, Opcode::XORI => true, Opcode::JI => false, @@ -297,6 +299,8 @@ fn writes_to_rb(opcode: Opcode) -> bool { Opcode::WQAM => false, Opcode::WDMM => false, Opcode::WQMM => false, + Opcode::WDEX => false, + Opcode::WQEX => false, Opcode::XOR => false, Opcode::XORI => false, Opcode::JI => false,