#![allow(clippy::branches_sharing_code)]
use amplify_num::u4;
use crate::instr::{Arithmetics, IncDec, NumType};
use crate::reg::{Reg32, Reg8, RegA, RegBlock, RegR, Value};
use crate::{Blob, InstructionSet, LibSite, Reg16};
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Display)]
#[display("nop")]
pub enum NOp {
NOp,
}
#[derive(Clone, PartialEq, Eq, Hash, Debug, Display)]
#[display(inner)]
#[non_exhaustive]
pub enum Instr<Extension = NOp>
where
Extension: InstructionSet,
{
ControlFlow(ControlFlowOp),
Put(PutOp),
Move(MoveOp),
Cmp(CmpOp),
Arithmetic(ArithmeticOp),
Bitwise(BitwiseOp),
Bytes(BytesOp),
Digest(DigestOp),
#[cfg(feature = "secp256k1")]
Secp256k1(Secp256k1Op),
#[cfg(feature = "curve25519")]
Curve25519(Curve25519Op),
ExtensionCodes(Extension),
Nop,
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Display)]
pub enum ControlFlowOp {
#[display("fail")]
Fail,
#[display("succ")]
Succ,
#[display("jmp\t\t{0:#06X}")]
Jmp(u16),
#[display("jif\t\t{0:#06X}")]
Jif(u16),
#[display("routine\t{0:#06X}")]
Routine(u16),
#[display("call\t{0}")]
Call(LibSite),
#[display("exec\t{0}")]
Exec(LibSite),
#[display("ret")]
Ret,
}
#[derive(Clone, PartialEq, Eq, Hash, Debug, Display)]
pub enum PutOp {
#[display("zero\t{0}{1}")]
ZeroA(RegA, Reg32),
#[display("zero\t{0}{1}")]
ZeroR(RegR, Reg32),
#[display("cl\t\t{0}{1}")]
ClA(RegA, Reg32),
#[display("cl\t\t{0}{1}")]
ClR(RegR, Reg32),
#[display("put\t\t{0}{1}, {2}")]
PutA(RegA, Reg32, Value),
#[display("put\t\t{0}{1}, {2}")]
PutR(RegR, Reg32, Value),
#[display("putif\t{0}{1}, {2}")]
PutIfA(RegA, Reg32, Value),
#[display("putif\t{0}{1}, {2}")]
PutIfR(RegR, Reg32, Value),
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Display)]
pub enum MoveOp {
#[display("swp\t\t{0}{1},{2}{3}")]
SwpA(RegA, Reg32, RegA, Reg32),
#[display("swp\t\t{0}{1},{2}{3}")]
SwpR(RegR, Reg32, RegR, Reg32),
#[display("swp\t\t{0}{1},{2}{3}")]
SwpAR(RegA, Reg32, RegR, Reg32),
#[display("amov:{2}\t{0},{1}")]
AMov(RegA, RegA, NumType),
#[display("mov\t\t{0}{1},{2}{3}")]
MovA(RegA, Reg32, RegA, Reg32),
#[display("mov\t\t{0}{1},{2}{3}")]
MovR(RegR, Reg32, RegR, Reg32),
#[display("mov\t\t{0}{1},{2}{3}")]
MovAR(RegA, Reg32, RegR, Reg32),
#[display("mov\t\t{0}{1},{2}{3}")]
MovRA(RegR, Reg32, RegA, Reg32),
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Display)]
pub enum CmpOp {
#[display("gt:{0}\t\t{1}{2},{1}{3}")]
GtA(NumType, RegA, Reg32, Reg32),
#[display("gt\t\t{0}{1},{2}{3}")]
GtR(RegR, Reg16, RegR, Reg32),
#[display("lt:{0}\t\t{1}{2},{1}{3}")]
LtA(NumType, RegA, Reg32, Reg32),
#[display("lt\t\t{0}{1},{2}{3}")]
LtR(RegR, Reg16, RegR, Reg32),
#[display("eq\t\t{0}{1},{2}{3}")]
EqA(RegA, Reg32, RegA, Reg32),
#[display("eq\t\t{0}{1},{2}{3}")]
EqR(RegR, Reg32, RegR, Reg32),
#[display("len\t\t{0}{1}")]
Len(RegA, Reg32),
#[display("cnt\t\t{0}{1}")]
Cnt(RegA, Reg32),
#[display("st2a")]
St2A,
#[display("a2st")]
A2St,
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Display)]
pub enum ArithmeticOp {
#[display("neg\t\t{0}{1}")]
Neg(RegA, Reg32),
#[display("{0}:{1}\t{2}{3},{4}")]
Stp(IncDec, Arithmetics, RegA, Reg32, u4),
#[display("add:{0}\t{1}{2},{1}{3}")]
Add(Arithmetics, RegA, Reg32, Reg32),
#[display("sub:{0}\t{1}{2},{1}{3}")]
Sub(Arithmetics, RegA, Reg32, Reg32),
#[display("mul:{0}\t{1}{2},{1}{3}")]
Mul(Arithmetics, RegA, Reg32, Reg32),
#[display("div:{0}\t{1}{2},{1}{3}")]
Div(Arithmetics, RegA, Reg32, Reg32),
#[display("rem:{0}\t{1}{2},{1}{3}")]
Rem(Arithmetics, RegA, Reg32, Reg32),
#[display("abs\t\t{0}{1}")]
Abs(RegA, Reg32),
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Display)]
pub enum BitwiseOp {
#[display("and\t\t{0}{1},{0}{2},{0}{3}")]
And(
RegA,
Reg32,
Reg32,
Reg8,
),
#[display("or\t\t{0}{1},{0}{2},{0}{3}")]
Or(RegA, Reg32, Reg32, Reg8),
#[display("xor\t\t{0}{1},{0}{2},{0}{3}")]
Xor(RegA, Reg32, Reg32, Reg8),
#[display("not\t\t{0}{1}")]
Not(RegA, Reg32),
#[display("shl\t\t{0}{1},a8{2},{0}{3}")]
Shl(RegA, Reg32, Reg32 , Reg8),
#[display("shr\t\t{0}{1},a8{2},{0}{3}")]
Shr(RegA, Reg32, Reg32, Reg8),
#[display("scl\t\t{0}{1},a8{2},{0}{3}")]
Scl(RegA, Reg32, Reg32, Reg8),
#[display("scr\t\t{0}{1},a8{2},{0}{3}")]
Scr(RegA, Reg32, Reg32, Reg8),
}
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Display)]
pub enum BytesOp {
#[display("put\t\ts16[{0}],{1}")]
Put( u8, Blob),
#[display("mov\t\ts16[{0}],s16[{1}]")]
Mov( u8, u8),
#[display("swp\t\ts16[{0}],s16[{1}]")]
Swp( u8, u8),
#[display("fill\ts16[{0}],{1}..{2},{3}")]
Fill(
u8,
u16,
u16,
u8,
),
#[display("len\t\ts16[{0}],a16[0]")]
LenS( u8),
#[display("count\ts16[{0}],{1},a16[0]")]
Count( u8, u8),
#[display("cmp\t\ts16[{0}],s16[{0}]")]
Cmp(u8, u8),
#[display("comm\ts16[{0}],s16[{1}]")]
Comm(u8, u8),
#[display("find\ts16[{0}],s16[{1}],a16[0]")]
Find(
u8,
u8,
),
#[display("extr\ts16{0},a16{1},{2}{3}")]
Extr(
Reg32,
Reg32,
RegBlock,
Reg32,
),
#[display("extr\ts16{0},a16{1},{2}{3}")]
Inj(
Reg32,
Reg32,
RegBlock,
Reg32,
),
#[display("join\ts16[{0}],s16[{1}],s16[{2}]")]
Join(
u8,
u8,
u8,
),
#[display("split\ts16[{0}],{1},s16[{2}],s16[{3}]")]
Split(
u8,
u16,
u8,
u8,
),
#[display("ins\t\ts16[{0}],s16[{1}],{2}")]
Ins(
u8,
u8,
u16,
),
#[display("ins\t\ts16[{0}],{1}..{2}")]
Del(
u8,
u16,
u16,
),
#[display("transl\ts16[{0}],{1}..{2},s16[{3}]")]
Transl(
u8,
u16,
u16,
u8,
),
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Display)]
#[non_exhaustive]
pub enum DigestOp {
#[display("ripemd\ts16{0},r160{1}")]
Ripemd(
Reg32,
Reg8,
),
#[display("sha256\ts16{0},r256{1}")]
Sha256(
Reg32,
Reg8,
),
#[display("sha512\ts16{0},r512{1}")]
Sha512(
Reg32,
Reg8,
),
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Display)]
pub enum Secp256k1Op {
#[display("secpgen\tr256{0},r512{1}")]
Gen(
Reg32,
Reg8,
),
#[display("secpmul\t{0}256{1},r512{2},r512{3}")]
Mul(
RegBlock,
Reg32,
Reg32,
Reg32,
),
#[display("secpadd\tr512{0},r512{1}")]
Add( Reg32, Reg8),
#[display("secpneg\tr512{0},r512{1}")]
Neg(
Reg32,
Reg8,
),
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Display)]
pub enum Curve25519Op {
#[display("edgen\tr256{0},r512{1}")]
Gen(
Reg32,
Reg8,
),
#[display("edmul\t{0}256{1},r512{2},r512{3}")]
Mul(
RegBlock,
Reg32,
Reg32,
Reg32,
),
#[display("edadd\tr512{0},r512{1},r512{2},{3}")]
Add(
Reg32,
Reg32,
Reg32,
bool,
),
#[display("edneg\tr512{0},r512{1}")]
Neg(
Reg32,
Reg8,
),
}