diff --git a/examples/asm.rs b/examples/asm.rs index 0e38f42..1f72d27 100644 --- a/examples/asm.rs +++ b/examples/asm.rs @@ -34,7 +34,7 @@ fn main() { lt.r f64[5],f64[9] ; gt r160[5],r256[9] ; lt r160[5],r256[9] ; - eq.e a8[5],a8[9] ; + eq.e a8[5],a8[9] ; eq.n r160[5],r160[9] ; eq.e f64[19],f64[29] ; ifn a32[31] ; @@ -63,21 +63,21 @@ fn main() { abs f128[11] ; and a32[5],a32[6],a32[5] ; xor r128[5],r128[6],r128[5] ; - shr.u a256[12],a16[2] ; - shr.s a256[12],a16[2] ; - shl r256[24],a16[22] ; - shr r256[24],a16[22] ; - scr r256[24],a16[22] ; - scl r256[24],a16[22] ; + shr.u a16[2],a256[12] ; + shr.s a16[2],a256[12] ; + shl a16[22],r256[24] ; + shr a16[22],r256[24] ; + scr a16[22],r256[24] ; + scl a16[22],r256[24] ; rev a512[28] ; - ripemd r160[7],s16[9] ; - sha2 r256[2],s16[19] ; - secpgen r512[1],r256[1] ; + ripemd s16[9],r160[7] ; + sha2 s16[19],r256[2] ; + secpgen r256[1],r512[1] ; dup r512[1],r512[22] ; spy a512[1],r512[22] ; - secpmul r512[1],r256[1],r512[2] ; - secpadd r512[1],r512[22] ; - secpneg r512[3],r512[1] ; + secpmul r256[1],r512[1],r512[2] ; + secpadd r512[22],r512[1] ; + secpneg r512[1],r512[3] ; ifz a16[8] ; jif 190 ; call 56 @ alu07EnUZgFtu28sWqqH3womkTopXCkgAGsCLvLnYvNcPLRt ; diff --git a/src/macros.rs b/src/macros.rs index be1e6a9..f1e9559 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -108,6 +108,10 @@ macro_rules! aluasm_inner { $code.push($crate::instr!{ $op . $flag $( $arg [ $idx ] ),+ }); $crate::aluasm_inner! { $code => $( $tt )* } }; + { $code:ident => $op:ident $arglit:literal, $arg:ident [ $idx:literal ] ; $($tt:tt)* } => { + $code.push($crate::instr!{ $op $arglit , $arg [ $idx ] }); + $crate::aluasm_inner! { $code => $( $tt )* } + }; { $code:ident => $op:ident $arg:ident [ $idx:literal ] , $arglit:literal ; $($tt:tt)* } => { $code.push($crate::instr!{ $op $arg [ $idx ] , $arglit }); $crate::aluasm_inner! { $code => $( $tt )* } @@ -159,7 +163,7 @@ macro_rules! instr { )) }; - (extr $regr:ident[$regr_idx:literal],s16[$idx:literal],a16[$offset_idx:literal]) => { + (extr s16[$idx:literal], $regr:ident[$regr_idx:literal],a16[$offset_idx:literal]) => { Instr::Bytes(BytesOp::Extr( RegS::from($idx), $crate::_reg_ty!(Reg, $regr), @@ -188,20 +192,38 @@ macro_rules! instr { ExtendFlag::Fail, )) }}; - (len $rega:ident[$rega_idx:literal],s16[$s_idx:literal]) => {{ + (len s16[$s_idx:literal], $rega:ident[$rega_idx:literal]) => {{ Instr::Bytes(BytesOp::Len( RegS::from($s_idx), $crate::_reg_tya!(Reg, $rega), $crate::_reg_idx!($rega_idx), )) }}; - (cnt a16[$dst_idx:literal],s16[$s_idx:literal],a8[$byte_idx:literal]) => {{ + (cnt s16[$s_idx:literal],a8[$byte_idx:literal],a16[$dst_idx:literal]) => {{ Instr::Bytes(BytesOp::Cnt( RegS::from($s_idx), $crate::_reg_idx16!($byte_idx), $crate::_reg_idx16!($dst_idx), )) }}; + ( + con s16[$src1_idx:literal],s16[$src2_idx:literal],a16[$frag_idx:literal],a16[$offset_dst_idx:literal],a16[$len_dst_idx:literal] + ) => {{ + Instr::Bytes(BytesOp::Con( + RegS::from($src1_idx), + RegS::from($src2_idx), + $crate::_reg_idx!($frag_idx), + $crate::_reg_idx!($offset_dst_idx), + $crate::_reg_idx!($len_dst_idx), + )) + }}; + (find s16[$str_idx:literal],s16[$fragment_idx:literal],a16[$should_be_0:literal]) => {{ + assert_eq!(0, $should_be_0); + Instr::Bytes(BytesOp::Find(RegS::from($str_idx), RegS::from($fragment_idx))) + }}; + (rev s16[$src_idx:literal],s16[$dst_idx:literal]) => {{ + Instr::Bytes(BytesOp::Rev(RegS::from($src_idx), RegS::from($dst_idx))) + }}; (put $reg:ident[$idx:literal], $val:literal) => {{ let s = stringify!($val); let mut num = s.parse::().expect(&format!("invalid number literal `{}`", s)); @@ -231,7 +253,7 @@ macro_rules! instr { $crate::_reg_idx!($idx2), )) }}; - (mov $dst_reg:ident[$dst_idx:literal], $src_reg:ident[$src_idx:literal]) => {{ + (mov $src_reg:ident[$src_idx:literal], $dst_reg:ident[$dst_idx:literal]) => {{ if $crate::_reg_ty!(Reg, $src_reg) != $crate::_reg_ty!(Reg, $dst_reg) { panic!("Move operation must be performed between registers of the same type"); } @@ -241,7 +263,7 @@ macro_rules! instr { $crate::_reg_idx!($dst_idx), )) }}; - (dup $dst_reg:ident[$dst_idx:literal], $src_reg:ident[$src_idx:literal]) => {{ + (dup $src_reg:ident[$src_idx:literal], $dst_reg:ident[$dst_idx:literal]) => {{ if $crate::_reg_ty!(Reg, $src_reg) != $crate::_reg_ty!(Reg, $dst_reg) { panic!("Dup operation must be performed between registers of the same type"); } @@ -251,7 +273,7 @@ macro_rules! instr { $crate::_reg_idx!($dst_idx), )) }}; - (cpy $dst_reg:ident[$dst_idx:literal], $src_reg:ident[$src_idx:literal]) => {{ + (cpy $src_reg:ident[$src_idx:literal], $dst_reg:ident[$dst_idx:literal]) => {{ if $crate::_reg_ty!(Reg, $src_reg) != $crate::_reg_ty!(Reg, $dst_reg) { panic!("Copy operation must be performed between registers of the same type"); } @@ -262,7 +284,7 @@ macro_rules! instr { $crate::_reg_idx!($dst_idx), )) }}; - (cnv $dst_reg:ident[$dst_idx:literal], $src_reg:ident[$src_idx:literal]) => {{ + (cnv $src_reg:ident[$src_idx:literal], $dst_reg:ident[$dst_idx:literal]) => {{ match ($crate::_reg_block!($src_reg), $crate::_reg_block!($dst_reg)) { (RegBlockAFR::A, RegBlockAFR::F) => Instr::Move(MoveOp::CnvAF( $crate::_reg_tya!(Reg, $src_reg), @@ -291,7 +313,7 @@ macro_rules! instr { (_, _) => panic!("Conversion operation between unsupported register types"), } }}; - (spy $dst_reg:ident[$dst_idx:literal], $src_reg:ident[$src_idx:literal]) => {{ + (spy $src_reg:ident[$src_idx:literal], $dst_reg:ident[$dst_idx:literal]) => {{ match ($crate::_reg_block!($src_reg), $crate::_reg_block!($dst_reg)) { (RegBlockAFR::A, RegBlockAFR::R) => Instr::Move(MoveOp::SpyAR( $crate::_reg_tya!(Reg, $src_reg), @@ -523,7 +545,7 @@ macro_rules! instr { Instr::Cmp(CmpOp::StInv) }; - (add. $flag:ident $dst_reg:ident[$dst_idx:literal], $reg1:ident[$idx1:literal]) => { + (add. $flag:ident $reg1:ident[$idx1:literal], $dst_reg:ident[$dst_idx:literal]) => { match ($crate::_reg_block!($reg1), $crate::_reg_block!($dst_reg)) { (RegBlockAFR::A, RegBlockAFR::A) => Instr::Arithmetic(ArithmeticOp::AddA( $crate::_int_flags!($flag), @@ -544,7 +566,7 @@ macro_rules! instr { (_, _) => panic!("addition must be performed between registers of the same type"), } }; - (sub. $flag:ident $dst_reg:ident[$dst_idx:literal], $reg1:ident[$idx1:literal]) => { + (sub. $flag:ident $reg1:ident[$idx1:literal], $dst_reg:ident[$dst_idx:literal]) => { match ($crate::_reg_block!($reg1), $crate::_reg_block!($dst_reg)) { (RegBlockAFR::A, RegBlockAFR::A) => Instr::Arithmetic(ArithmeticOp::SubA( $crate::_int_flags!($flag), @@ -565,7 +587,7 @@ macro_rules! instr { (_, _) => panic!("subtraction must be performed between registers of the same type"), } }; - (mul. $flag:ident $dst_reg:ident[$dst_idx:literal], $reg1:ident[$idx1:literal]) => { + (mul. $flag:ident $reg1:ident[$idx1:literal], $dst_reg:ident[$dst_idx:literal]) => { match ($crate::_reg_block!($reg1), $crate::_reg_block!($dst_reg)) { (RegBlockAFR::A, RegBlockAFR::A) => Instr::Arithmetic(ArithmeticOp::MulA( $crate::_int_flags!($flag), @@ -586,7 +608,7 @@ macro_rules! instr { (_, _) => panic!("multiplication must be performed between registers of the same type"), } }; - (div. $flag:ident $dst_reg:ident[$dst_idx:literal], $reg1:ident[$idx1:literal]) => { + (div. $flag:ident $reg1:ident[$idx1:literal], $dst_reg:ident[$dst_idx:literal]) => { match ($crate::_reg_block!($reg1), $crate::_reg_block!($dst_reg)) { (RegBlockAFR::A, RegBlockAFR::A) => Instr::Arithmetic(ArithmeticOp::DivA( $crate::_int_flags!($flag), @@ -607,7 +629,7 @@ macro_rules! instr { (_, _) => panic!("division must be performed between registers of the same type"), } }; - (rem $dst_reg:ident[$dst_idx:literal], $reg1:ident[$idx1:literal]) => { + (rem $reg1:ident[$idx1:literal], $dst_reg:ident[$dst_idx:literal]) => { if $crate::_reg_block!($reg1) != RegBlockAFR::A || $crate::_reg_block!($dst_reg) != RegBlockAFR::A { @@ -664,9 +686,9 @@ macro_rules! instr { ( and - $dst_reg:ident[$dst_idx:literal], $reg1:ident[$idx1:literal], - $reg2:ident[$idx2:literal] + $reg2:ident[$idx2:literal], + $dst_reg:ident[$dst_idx:literal] ) => { if $crate::_reg_ty!(Reg, $reg1) != $crate::_reg_ty!(Reg, $reg2) || $crate::_reg_ty!(Reg, $reg2) != $crate::_reg_ty!(Reg, $dst_reg) @@ -686,7 +708,7 @@ macro_rules! instr { } }; ( - or $dst_reg:ident[$dst_idx:literal], $reg2:ident[$idx2:literal], $reg1:ident[$idx1:literal] + or $reg1:ident[$idx1:literal], $reg2:ident[$idx2:literal], $dst_reg:ident[$dst_idx:literal] ) => { if $crate::_reg_ty!(Reg, $reg1) != $crate::_reg_ty!(Reg, $reg2) || $crate::_reg_ty!(Reg, $reg2) != $crate::_reg_ty!(Reg, $dst_reg) @@ -707,9 +729,9 @@ macro_rules! instr { }; ( xor - $dst_reg:ident[$dst_idx:literal], + $reg1:ident[$idx1:literal], $reg2:ident[$idx2:literal], - $reg1:ident[$idx1:literal] + $dst_reg:ident[$dst_idx:literal] ) => { if $crate::_reg_ty!(Reg, $reg1) != $crate::_reg_ty!(Reg, $reg2) || $crate::_reg_ty!(Reg, $reg2) != $crate::_reg_ty!(Reg, $dst_reg) @@ -730,52 +752,52 @@ macro_rules! instr { }; (shl $reg1:ident[$idx1:literal], $reg2:ident[$idx2:literal]) => { Instr::Bitwise(BitwiseOp::Shl( - $crate::_reg_tya2!(Reg, $reg2), - $crate::_reg_idx!($idx2), - $crate::_reg_ty!(Reg, $reg1).into(), + $crate::_reg_tya2!(Reg, $reg1), $crate::_reg_idx!($idx1), + $crate::_reg_ty!(Reg, $reg2).into(), + $crate::_reg_idx!($idx2), )) }; (shr.u $reg1:ident[$idx1:literal], $reg2:ident[$idx2:literal]) => { Instr::Bitwise(BitwiseOp::ShrA( SignFlag::Unsigned, - $crate::_reg_tya2!(Reg, $reg2), - $crate::_reg_idx16!($idx2), - $crate::_reg_ty!(Reg, $reg1), - $crate::_reg_idx!($idx1), + $crate::_reg_tya2!(Reg, $reg1), + $crate::_reg_idx16!($idx1), + $crate::_reg_ty!(Reg, $reg2), + $crate::_reg_idx!($idx2), )) }; (shr.s $reg1:ident[$idx1:literal], $reg2:ident[$idx2:literal]) => { Instr::Bitwise(BitwiseOp::ShrA( SignFlag::Signed, - $crate::_reg_tya2!(Reg, $reg2), - $crate::_reg_idx16!($idx2), - $crate::_reg_ty!(Reg, $reg1), - $crate::_reg_idx!($idx1), + $crate::_reg_tya2!(Reg, $reg1), + $crate::_reg_idx16!($idx1), + $crate::_reg_ty!(Reg, $reg2), + $crate::_reg_idx!($idx2), )) }; (shr $reg1:ident[$idx1:literal], $reg2:ident[$idx2:literal]) => { Instr::Bitwise(BitwiseOp::ShrR( - $crate::_reg_tya2!(Reg, $reg2), - $crate::_reg_idx!($idx2), - $crate::_reg_ty!(Reg, $reg1), + $crate::_reg_tya2!(Reg, $reg1), $crate::_reg_idx!($idx1), + $crate::_reg_ty!(Reg, $reg2), + $crate::_reg_idx!($idx2), )) }; (scl $reg1:ident[$idx1:literal], $reg2:ident[$idx2:literal]) => { Instr::Bitwise(BitwiseOp::Scl( - $crate::_reg_tya2!(Reg, $reg2), - $crate::_reg_idx!($idx2), - $crate::_reg_ty!(Reg, $reg1).into(), + $crate::_reg_tya2!(Reg, $reg1), $crate::_reg_idx!($idx1), + $crate::_reg_ty!(Reg, $reg2).into(), + $crate::_reg_idx!($idx2), )) }; (scr $reg1:ident[$idx1:literal], $reg2:ident[$idx2:literal]) => { Instr::Bitwise(BitwiseOp::Scr( - $crate::_reg_tya2!(Reg, $reg2), - $crate::_reg_idx!($idx2), - $crate::_reg_ty!(Reg, $reg1).into(), + $crate::_reg_tya2!(Reg, $reg1), $crate::_reg_idx!($idx1), + $crate::_reg_ty!(Reg, $reg2).into(), + $crate::_reg_idx!($idx2), )) }; (rev $reg:ident[$idx:literal]) => { @@ -792,17 +814,17 @@ macro_rules! instr { } }; - (ripemd r160[$idx2:literal],s16[$idx1:literal]) => { + (ripemd s16[$idx1:literal],r160[$idx2:literal]) => { Instr::Digest(DigestOp::Ripemd(RegS::from($idx1), $crate::_reg_idx16!($idx2))) }; - (sha2 r256[$idx2:literal],s16[$idx1:literal]) => { + (sha2 s16[$idx1:literal],r256[$idx2:literal]) => { Instr::Digest(DigestOp::Sha256(RegS::from($idx1), $crate::_reg_idx16!($idx2))) }; - (sha2 r512[$idx2:literal],s16[$idx1:literal]) => { + (sha2 s16[$idx1:literal],r512[$idx2:literal]) => { Instr::Digest(DigestOp::Sha512(RegS::from($idx1), $crate::_reg_idx16!($idx2))) }; - (secpgen $reg2:ident[$idx2:literal], $reg1:ident[$idx1:literal]) => { + (secpgen $reg1:ident[$idx1:literal], $reg2:ident[$idx2:literal]) => { if $crate::_reg_block!($reg1) != RegBlockAFR::R || $crate::_reg_block!($reg2) != RegBlockAFR::R { @@ -813,9 +835,9 @@ macro_rules! instr { }; ( secpmul - $dst_reg:ident[$dst_idx:literal], $scalar_reg:ident[$scalar_idx:literal], - $src_reg:ident[$src_idx:literal] + $src_reg:ident[$src_idx:literal], + $dst_reg:ident[$dst_idx:literal] ) => { if $crate::_reg_ty!(Reg, $src_reg) != $crate::_reg_ty!(Reg, $dst_reg) { panic!("ecmul instruction can be used only with registers of the same type"); @@ -828,7 +850,7 @@ macro_rules! instr { )) } }; - (secpadd $reg2:ident[$idx2:literal], $reg1:ident[$idx1:literal]) => { + (secpadd $reg1:ident[$idx1:literal], $reg2:ident[$idx2:literal]) => { if $crate::_reg_block!($reg1) != RegBlockAFR::R || $crate::_reg_block!($reg2) != RegBlockAFR::R { @@ -837,7 +859,7 @@ macro_rules! instr { Instr::Secp256k1(Secp256k1Op::Add($crate::_reg_idx!($idx1), $crate::_reg_idx8!($idx2))) } }; - (secpneg $reg2:ident[$idx2:literal], $reg1:ident[$idx1:literal]) => { + (secpneg $reg1:ident[$idx1:literal], $reg2:ident[$idx2:literal]) => { if $crate::_reg_block!($reg1) != RegBlockAFR::R || $crate::_reg_block!($reg2) != RegBlockAFR::R { diff --git a/src/pipelines/compiler.rs b/src/pipelines/compiler.rs index 6487710..a9e8fff 100644 --- a/src/pipelines/compiler.rs +++ b/src/pipelines/compiler.rs @@ -683,9 +683,9 @@ impl<'i> Statement<'i> { RegAll::R(r) => Instr::Put(PutOp::PutR(r, idx! {0}, num! {1, r})), RegAll::S => Instr::Bytes(BytesOp::Put(idx! {0}, str! {1}, false)), }, - Operator::putif => match reg! {0} { - RegAR::A(a) => Instr::Put(PutOp::PutIfA(a, idx! {0}, num! {1, a})), - RegAR::R(r) => Instr::Put(PutOp::PutIfR(r, idx! {0}, num! {1, r})), + Operator::putif => match reg! {1} { + RegAR::A(a) => Instr::Put(PutOp::PutIfA(a, idx! {1}, num! {0, a})), + RegAR::R(r) => Instr::Put(PutOp::PutIfR(r, idx! {1}, num! {0, r})), }, // *** Move operations @@ -698,9 +698,9 @@ impl<'i> Statement<'i> { ); } match reg { - RegAFR::A(a) => Instr::Move(MoveOp::DupA(a, idx! {1}, idx! {0})), - RegAFR::F(f) => Instr::Move(MoveOp::DupF(f, idx! {1}, idx! {0})), - RegAFR::R(r) => Instr::Move(MoveOp::DupR(r, idx! {1}, idx! {0})), + RegAFR::A(a) => Instr::Move(MoveOp::DupA(a, idx! {0}, idx! {1})), + RegAFR::F(f) => Instr::Move(MoveOp::DupF(f, idx! {0}, idx! {1})), + RegAFR::R(r) => Instr::Move(MoveOp::DupR(r, idx! {0}, idx! {1})), } } Operator::mov => { @@ -712,27 +712,27 @@ impl<'i> Statement<'i> { ); } match reg { - RegAll::A(a) => Instr::Move(MoveOp::MovA(a, idx! {1}, idx! {0})), - RegAll::F(f) => Instr::Move(MoveOp::MovF(f, idx! {1}, idx! {0})), - RegAll::R(r) => Instr::Move(MoveOp::MovR(r, idx! {1}, idx! {0})), - RegAll::S => Instr::Bytes(BytesOp::Mov(idx! {1}, idx! {0})), + RegAll::A(a) => Instr::Move(MoveOp::MovA(a, idx! {0}, idx! {1})), + RegAll::F(f) => Instr::Move(MoveOp::MovF(f, idx! {0}, idx! {1})), + RegAll::R(r) => Instr::Move(MoveOp::MovR(r, idx! {0}, idx! {1})), + RegAll::S => Instr::Bytes(BytesOp::Mov(idx! {0}, idx! {1})), } } - Operator::cnv => match (reg! {1}, reg! {0}) { + Operator::cnv => match (reg! {0}, reg! {1}) { (RegAF::A(a1), RegAF::A(a2)) => { - Instr::Move(MoveOp::CnvA(a1, idx! {1}, a2, idx! {0})) + Instr::Move(MoveOp::CnvA(a1, idx! {0}, a2, idx! {1})) } (RegAF::F(f1), RegAF::F(f2)) => { - Instr::Move(MoveOp::CnvF(f1, idx! {1}, f2, idx! {0})) + Instr::Move(MoveOp::CnvF(f1, idx! {0}, f2, idx! {1})) } - (RegAF::A(a), RegAF::F(f)) => Instr::Move(MoveOp::CnvAF(a, idx! {1}, f, idx! {0})), - (RegAF::F(f), RegAF::A(a)) => Instr::Move(MoveOp::CnvFA(f, idx! {1}, a, idx! {0})), + (RegAF::A(a), RegAF::F(f)) => Instr::Move(MoveOp::CnvAF(a, idx! {0}, f, idx! {1})), + (RegAF::F(f), RegAF::A(a)) => Instr::Move(MoveOp::CnvFA(f, idx! {0}, a, idx! {1})), }, - Operator::cpy => match reg! {1} { - RegAR::A(a) => Instr::Move(MoveOp::CpyA(a, idx! {1}, reg! {0}, idx! {0})), - RegAR::R(r) => Instr::Move(MoveOp::CpyR(r, idx! {1}, reg! {0}, idx! {0})), + Operator::cpy => match reg! {0} { + RegAR::A(a) => Instr::Move(MoveOp::CpyA(a, idx! {0}, reg! {1}, idx! {1})), + RegAR::R(r) => Instr::Move(MoveOp::CpyR(r, idx! {0}, reg! {1}, idx! {1})), }, - Operator::spy => Instr::Move(MoveOp::SpyAR(reg! {1}, idx! {1}, reg! {0}, idx! {0})), + Operator::spy => Instr::Move(MoveOp::SpyAR(reg! {0}, idx! {0}, reg! {1}, idx! {1})), Operator::swp => { let reg = reg! {0}; if reg != reg! {1} { @@ -846,10 +846,10 @@ impl<'i> Statement<'i> { } match reg { RegAF::A(a) => { - Instr::Arithmetic(ArithmeticOp::AddA(flags!(), a, idx! {1}, idx! {0})) + Instr::Arithmetic(ArithmeticOp::AddA(flags!(), a, idx! {0}, idx! {1})) } RegAF::F(f) => { - Instr::Arithmetic(ArithmeticOp::AddF(flags!(), f, idx! {1}, idx! {0})) + Instr::Arithmetic(ArithmeticOp::AddF(flags!(), f, idx! {0}, idx! {1})) } } } @@ -1040,13 +1040,13 @@ impl<'i> Statement<'i> { Instr::Bytes(BytesOp::Fill(idx! {0}, idx! {1}, idx! {2}, idx! {3}, flags!())) } Operator::len => { - let _: RegS = reg! {1}; - Instr::Bytes(BytesOp::Len(idx! {1}, reg! {0}, idx! {0})) + let _: RegS = reg! {0}; + Instr::Bytes(BytesOp::Len(idx! {0}, reg! {1}, idx! {1})) } Operator::cnt => { - let _: RegS = reg! {1}; - let byte_reg: RegA = reg! {2}; - let dst_reg: RegA = reg! {0}; + let _: RegS = reg! {0}; + let byte_reg: RegA = reg! {1}; + let dst_reg: RegA = reg! {2}; if byte_reg != RegA::A8 { issues.push_error( SemanticError::OperandWrongReg { @@ -1054,7 +1054,7 @@ impl<'i> Statement<'i> { pos: 2, expected: "a8 register", }, - self.operands[1].as_span(), + self.operands[2].as_span(), ); } if dst_reg != RegA::A16 { @@ -1064,16 +1064,16 @@ impl<'i> Statement<'i> { pos: 0, expected: "a16 register", }, - self.operands[2].as_span(), + self.operands[0].as_span(), ); } - Instr::Bytes(BytesOp::Cnt(idx! {1}, idx! {2}, idx! {0})) + Instr::Bytes(BytesOp::Cnt(idx! {0}, idx! {1}, idx! {2})) } Operator::con => { let _: RegS = reg! {0}; let _: RegS = reg! {1}; - for n in 1..4 { - let reg: RegA = reg! {n+1}; + for n in 2..5 { + let reg: RegA = reg! {n}; if reg != RegA::A16 { issues.push_error( SemanticError::OperandWrongReg { @@ -1090,23 +1090,23 @@ impl<'i> Statement<'i> { Operator::find => { let _: RegS = reg! {0}; let _: RegS = reg! {1}; - let reg: RegA = reg! {3}; - let idx: Reg32 = idx! {3}; - if reg != RegA::A16 || idx != Reg32::Reg1 { + let reg: RegA = reg! {2}; + let idx: Reg32 = idx! {2}; + if reg != RegA::A16 || idx != Reg32::Reg0 { issues.push_error( SemanticError::OperandWrongReg { operator: self.operator.0, - pos: 3, + pos: 2, expected: "a16[0] register", }, - self.operands[3].as_span(), + self.operands[2].as_span(), ); } Instr::Bytes(BytesOp::Find(idx! {0}, idx! {1})) } Operator::extr => { - let _: RegS = reg! {1}; - Instr::Bytes(BytesOp::Extr(idx! {1}, reg! {0}, idx! {0}, idx! {2})) + let _: RegS = reg! {0}; + Instr::Bytes(BytesOp::Extr(idx! {0}, reg! {1}, idx! {1}, idx! {2})) } Operator::inj => { let _: RegS = reg! {0}; diff --git a/tests/asm.rs b/tests/asm.rs index 82d76a7..0977e6d 100644 --- a/tests/asm.rs +++ b/tests/asm.rs @@ -213,22 +213,22 @@ fn stp_sub() { #[test] fn float() { aluasm_succ! { - put f32[8],1.25; - put f32[9],1.5; - put f32[10],2.75; - add.f f32[9],f32[8]; - eq.e f32[9],f32[10]; - ret; + put f32[8],1.25; + put f32[9],1.5; + put f32[10],2.75; + add.f f32[8],f32[9]; + eq.e f32[9],f32[10]; + ret; } } #[test] fn bytes_put() { aluasm_succ! { - put s16[1],"aaa"; - put s16[2],"aaa"; - eq s16[1],s16[2]; - ret; + put s16[1],"aaa"; + put s16[2],"aaa"; + eq s16[1],s16[2]; + ret; } aluasm_fail! { put s16[1],"aaa"; @@ -247,68 +247,68 @@ fn bytes_put() { #[test] fn bytes_extr() { aluasm_succ! { - put s16[0],"################@@@@@@"; - put a16[0],0; - extr r128[0],s16[0],a16[0]; - put r128[1],0x23232323232323232323232323232323; - eq.n r128[0],r128[1]; - ret; + put s16[0],"################@@@@@@"; + put a16[0],0; + extr s16[0],r128[0],a16[0]; + put r128[1],0x23232323232323232323232323232323; + eq.n r128[0],r128[1]; + ret; }; aluasm_succ! { - put s16[0],"################@@@@@@"; - put a16[0],3; - extr r128[0],s16[0],a16[0]; - put r128[1],0x40404023232323232323232323232323; - eq.n r128[0],r128[1]; - ret; + put s16[0],"################@@@@@@"; + put a16[0],3; + extr s16[0],r128[0],a16[0]; + put r128[1],0x40404023232323232323232323232323; + eq.n r128[0],r128[1]; + ret; } } #[test] fn bytes_extr_offset_exceed() { aluasm_succ! { - put s16[0],"123456788901234567"; - put a16[0],0; - extr r128[0],s16[0],a16[0]; - ret; + put s16[0],"123456788901234567"; + put a16[0],0; + extr s16[0],r128[0],a16[0]; + ret; } aluasm_succ! { - put s16[0],"123456788901234567"; - put a16[0],1; - extr r128[0],s16[0],a16[0]; - ret; + put s16[0],"123456788901234567"; + put a16[0],1; + extr s16[0],r128[0],a16[0]; + ret; } aluasm_fail! { - put s16[0],"123456788901234567"; - put a16[0],2; - extr r128[0],s16[0],a16[0]; - ret; + put s16[0],"123456788901234567"; + put a16[0],2; + extr s16[0],r128[0],a16[0]; + ret; } aluasm_fail! { - put s16[0],"123456788901234567"; - put a16[0],2; - extr r128[0],s16[0],a16[0]; - ret; + put s16[0],"123456788901234567"; + put a16[0],2; + extr s16[0],r128[0],a16[0]; + ret; } aluasm_succ! { - put s16[0],"################@"; - put a16[0],1; - extr r128[0],s16[0],a16[0]; - put r128[1],0x40232323232323232323232323232323; - eq.n r128[0],r128[1]; - ret; + put s16[0],"################@"; + put a16[0],1; + extr s16[0],r128[0],a16[0]; + put r128[1],0x40232323232323232323232323232323; + eq.n r128[0],r128[1]; + ret; } aluasm_fail! { - put s16[0],"123456788901234567"; - put a16[0],100; - extr r128[0],s16[0],a16[0]; - ret; + put s16[0],"123456788901234567"; + put a16[0],100; + extr s16[0],r128[0],a16[0]; + ret; } aluasm_fail! { - put s16[0],"123"; - put a16[0],0; - extr r128[0],s16[0],a16[0]; - ret; + put s16[0],"123"; + put a16[0],0; + extr s16[0],r128[0],a16[0]; + ret; } } @@ -355,7 +355,7 @@ fn bytes_len() { aluasm_succ! { put s16[0],"aaaaaaaa"; put a16[0],8; - len a16[1],s16[0]; + len s16[0],a16[1]; eq.n a16[0],a16[1]; ret; } @@ -368,7 +368,7 @@ fn bytes_len_overflow() { put a16[1],255; put a8[0],97; fill.e s16[0],a16[0],a16[1],a8[0]; - len a8[2],s16[0]; + len s16[0],a8[2]; ret; } aluasm_fail! { @@ -376,7 +376,7 @@ fn bytes_len_overflow() { put a16[1],256; put a8[0],97; fill.e s16[0],a16[0],a16[1],a8[0]; - len a8[2],s16[0]; + len s16[0],a8[2]; ret; } aluasm_succ! { @@ -385,7 +385,7 @@ fn bytes_len_overflow() { put a8[0],97; put a8[2],1; fill.e s16[0],a16[0],a16[1],a8[0]; - len a8[2],s16[0]; + len s16[0],a8[2]; eq.e a8[2],a8[3]; ret; } @@ -397,7 +397,7 @@ fn bytes_cnt() { put s16[0],"hello world"; put a8[0],108; put a16[0],3; - cnt a16[1],s16[0],a8[0]; + cnt s16[0],a8[0],a16[1]; eq.n a16[0],a16[1]; ret; } @@ -407,13 +407,13 @@ fn bytes_cnt() { fn bytes_cnt_uninitialized_byte() { aluasm_fail! { put s16[0],"hello world"; - cnt a16[1],s16[0],a8[0]; + cnt s16[0],a8[0],a16[1]; ret; } aluasm_succ! { put s16[0],"hello world"; put a16[1],1; - cnt a16[1],s16[0],a8[0]; + cnt s16[0],a8[0],a16[1]; eq.e a16[0],a16[1]; ret; } @@ -423,7 +423,126 @@ fn bytes_cnt_uninitialized_byte() { fn bytes_cnt_empty_string() { aluasm_fail! { put s16[0],""; - cnt a16[1],s16[0],a8[0]; + cnt s16[0],a8[0],a16[1]; + ret; + } +} + +#[test] +fn bytes_con() { + aluasm_succ! { + put s16[0],"hello@world!!"; + put s16[1],"hello#world!"; + put a16[0],0; + put a16[1],5; + con s16[0],s16[1],a16[0],a16[2],a16[3]; + eq.n a16[0],a16[2]; + eq.n a16[1],a16[3]; + ret; + } + aluasm_succ! { + put s16[0],"hello@world!!"; + put s16[1],"hello#world!"; + put a16[0],1; + put a16[1],6; + con s16[0],s16[1],a16[0],a16[2],a16[3]; + eq.n a16[0],a16[2]; + eq.n a16[1],a16[3]; + ret; + } + aluasm_succ! { + put s16[0],"hello world"; + put s16[1],"hello world"; + put a16[0],0; + put a16[1],11; + con s16[0],s16[1],a16[0],a16[2],a16[3]; + eq.n a16[0],a16[2]; + eq.n a16[1],a16[3]; + ret; + } + aluasm_succ! { + put s16[0],"hello world"; + put s16[1],"hello world"; + put a16[0],1; + put a16[2],1000; + put a16[3],1000; + con s16[0],s16[1],a16[0],a16[2],a16[3]; + eq.e a16[0],a16[2]; + eq.e a16[1],a16[3]; + ret; + } + aluasm_succ! { + put a16[0],1; + put a16[2],1000; + put a16[3],1000; + con s16[0],s16[1],a16[0],a16[2],a16[3]; + eq.e a16[0],a16[2]; + eq.e a16[1],a16[3]; + ret; + } +} + +#[test] +fn bytes_find() { + aluasm_succ! { + put s16[0],"hello world"; + put s16[1],"l"; + put a16[1],3; + find s16[0],s16[1],a16[0]; + eq.n a16[0],a16[1]; + ret; + } + aluasm_succ! { + put s16[0],"hello world"; + put s16[1],"ll"; + put a16[1],1; + find s16[0],s16[1],a16[0]; + eq.n a16[0],a16[1]; + ret; + } + aluasm_succ! { + put s16[0],"hello world"; + put s16[1],"lll"; + put a16[1],0; + find s16[0],s16[1],a16[0]; + eq.n a16[0],a16[1]; + ret; + } + aluasm_succ! { + put s16[0],"hello world"; + put s16[1],"hello world!!!"; + put a16[1],0; + find s16[0],s16[1],a16[0]; + eq.n a16[0],a16[1]; + ret; + } +} + +#[test] +fn bytes_find_max() { + aluasm_succ! { + put a16[1],0; + put a16[2],65535; + put a8[0],97; + fill.e s16[0],a16[1],a16[2],a8[0]; + put s16[1],"a"; + find s16[0],s16[1],a16[0]; + eq.n a16[0],a16[2]; + ret; + } +} + +#[test] +fn bytes_rev() { + aluasm_succ! { + put s16[0],"abcd"; + put s16[1],"dcba"; + rev s16[0],s16[2]; + eq s16[1],s16[2]; + ret; + } + aluasm_fail! { + rev s16[0],s16[1]; ret; } }