diff options
-rw-r--r-- | notes/todo | 216 | ||||
-rw-r--r-- | src/lib.rs | 135 | ||||
-rw-r--r-- | tests/from_brain.rs | 87 |
3 files changed, 321 insertions, 117 deletions
@@ -665,114 +665,114 @@ A L I A S A L I A S A L I A S A L I A S A L I A S | Rd=zxtb(Rs) -|1 0 0 1|1 0 1 0 0 0 1|x x x x x| P P |0 0 - - - i i i i|d d d d d| Rd=membh(Rx++#s:4) - LD/slot 0,1 -|1 0 0 1|1 0 1 0 0 1 0|x x x x x| P P |0 0 - - - i i i i|y y y y y| Ryy=memh_fifo(Rx++#s4:0) - LD/slot 0,1 -|1 0 0 1|1 0 1 0 0 1 1|x x x x x| P P |0 0 - - - i i i i|d d d d d| Rd=memubh(Rx++#s:4) - LD/slot 0,1 -|1 0 0 1|1 0 1 0 1 0 0|x x x x x| P P |0 0 - - - i i i i|y y y y y| Ryy=memb_fifo(Rx++#s4:0) - LD/slot 0,1 -|1 0 0 1|1 0 1 0 1 0 1|x x x x x| P P |0 0 - - - i i i i|d d d d d| Rdd=memubh(Rx++#s:4) - LD/slot 0,1 -|1 0 0 1|1 0 1 0 1 1 1|x x x x x| P P |0 0 - - - i i i i|d d d d d| Rdd=membh(Rx++#s:4) - LD/slot 0,1 -|1 0 0 1|1 0 1 1 0 0 0|x x x x x| P P |0 0 - - - i i i i|d d d d d| Rd=memb(Rx++#s4:3) - LD/slot 0,1 -|1 0 0 1|1 0 1 1 0 0 1|x x x x x| P P |0 0 - - - i i i i|d d d d d| Rdd=memub(Rx++#s4:3) - LD/slot 0,1 -|1 0 0 1|1 0 1 1 0 1 0|x x x x x| P P |0 0 - - - i i i i|d d d d d| Rd=memh(Rx++#s4:3) - LD/slot 0,1 -|1 0 0 1|1 0 1 1 0 1 1|x x x x x| P P |0 0 - - - i i i i|d d d d d| Rdd=memuh(Rx++#s4:3) - LD/slot 0,1 -|1 0 0 1|1 0 1 1 1 0 0|x x x x x| P P |0 0 - - - i i i i|d d d d d| Rd=memw(Rx++#s4:3) - LD/slot 0,1 -|1 0 0 1|1 0 1 1 1 1 0|x x x x x| P P |0 0 - - - i i i i|d d d d d| Rdd=memd(Rx++#s4:3) - LD/slot 0,1 -|1 0 0 1|1 0 1 0 0 0 1|e e e e e| P P |0 1 l l l l - l l|d d d d d| Rd=membh(Re=#U6) - LD/slot 0,1 -|1 0 0 1|1 0 1 0 0 1 0|e e e e e| P P |0 1 l l l l - l l|y y y y y| Ryy=memh_fifo(Re=#U6) - LD/slot 0,1 -|1 0 0 1|1 0 1 0 0 1 1|e e e e e| P P |0 1 l l l l - l l|d d d d d| Rd=memubh(Re=#U6) - LD/slot 0,1 -|1 0 0 1|1 0 1 0 1 0 0|e e e e e| P P |0 1 l l l l - l l|y y y y y| Ryy=memb_fifo(Re=#U6) - LD/slot 0,1 -|1 0 0 1|1 0 1 0 1 0 1|e e e e e| P P |0 1 l l l l - l l|d d d d d| Rdd=memubh(Re=#U6) - LD/slot 0,1 -|1 0 0 1|1 0 1 0 1 1 1|e e e e e| P P |0 1 l l l l - l l|d d d d d| Rdd=membh(Re=#U6) - LD/slot 0,1 -|1 0 0 1|1 0 1 1 0 0 0|e e e e e| P P |0 1 l l l l - l l|d d d d d| Rd=memb(Re=#U6) - LD/slot 0,1 -|1 0 0 1|1 0 1 1 0 0 1|e e e e e| P P |0 1 l l l l - l l|d d d d d| Rdd=memub(Re=#U6) - LD/slot 0,1 -|1 0 0 1|1 0 1 1 0 1 0|e e e e e| P P |0 1 l l l l - l l|d d d d d| Rd=memh(Re=#U6) - LD/slot 0,1 -|1 0 0 1|1 0 1 1 0 1 1|e e e e e| P P |0 1 l l l l - l l|d d d d d| Rdd=memuh(Re=#U6) - LD/slot 0,1 -|1 0 0 1|1 0 1 1 1 0 0|e e e e e| P P |0 1 l l l l - l l|d d d d d| Rd=memw(Re=#U6) - LD/slot 0,1 -|1 0 0 1|1 0 1 1 1 1 0|e e e e e| P P |0 1 l l l l - l l|d d d d d| Rdd=memd(Re=#U6) - LD/slot 0,1 -|1 0 0 1|1 1 0 0 0 0 1|x x x x x| P P |u 0 - - - - 0 - -|d d d d d| Rd=membh(Rx++Mu) - LD/slot 0,1 -|1 0 0 1|1 1 0 0 0 1 0|x x x x x| P P |u 0 - - - - 0 - -|y y y y y| Ryy=memh_fifo(Rx++Mu) - LD/slot 0,1 -|1 0 0 1|1 1 0 0 0 1 1|x x x x x| P P |u 0 - - - - 0 - -|d d d d d| Rd=memubh(Rx++Mu) - LD/slot 0,1 -|1 0 0 1|1 1 0 0 1 0 0|x x x x x| P P |u 0 - - - - 0 - -|y y y y y| Ryy=memb_fifo(Rx++Mu) - LD/slot 0,1 -|1 0 0 1|1 1 0 0 1 0 1|x x x x x| P P |u 0 - - - - 0 - -|d d d d d| Rdd=memubh(Rx++Mu) - LD/slot 0,1 -|1 0 0 1|1 1 0 0 1 1 1|x x x x x| P P |u 0 - - - - 0 - -|d d d d d| Rdd=membh(Rx++Mu) - LD/slot 0,1 -|1 0 0 1|1 1 0 1 0 0 0|x x x x x| P P |u 0 - - - - 0 - -|d d d d d| Rd=memb(Rx++Mu) - LD/slot 0,1 -|1 0 0 1|1 1 0 1 0 0 1|x x x x x| P P |u 0 - - - - 0 - -|d d d d d| Rdd=memub(Rx++Mu) - LD/slot 0,1 -|1 0 0 1|1 1 0 1 0 1 0|x x x x x| P P |u 0 - - - - 0 - -|d d d d d| Rd=memh(Rx++Mu) - LD/slot 0,1 -|1 0 0 1|1 1 0 1 0 1 1|x x x x x| P P |u 0 - - - - 0 - -|d d d d d| Rdd=memuh(Rx++Mu) - LD/slot 0,1 -|1 0 0 1|1 1 0 1 1 0 0|x x x x x| P P |u 0 - - - - 0 - -|d d d d d| Rd=memw(Rx++Mu) - LD/slot 0,1 -|1 0 0 1|1 1 0 1 1 1 0|x x x x x| P P |u 0 - - - - 0 - -|d d d d d| Rdd=memd(Rx++Mu) - LD/slot 0,1 -|1 0 0 1|1 1 1 0 0 0 1|x x x x x| P P |u 0 - - - - 0 - -|d d d d d| Rd=membh(Rx++Mu:brev) - LD/slot 0,1 -|1 0 0 1|1 1 1 0 0 1 0|x x x x x| P P |u 0 - - - - 0 - -|y y y y y| Ryy=memh_fifo(Rx++Mu:brev) - LD/slot 0,1 -|1 0 0 1|1 1 1 0 0 1 1|x x x x x| P P |u 0 - - - - 0 - -|d d d d d| Rd=memubh(Rx++Mu:brev) - LD/slot 0,1 -|1 0 0 1|1 1 1 0 1 0 0|x x x x x| P P |u 0 - - - - 0 - -|y y y y y| Ryy=memb_fifo(Rx++Mu:brev) - LD/slot 0,1 -|1 0 0 1|1 1 1 0 1 0 1|x x x x x| P P |u 0 - - - - 0 - -|d d d d d| Rdd=memubh(Rx++Mu:brev) - LD/slot 0,1 -|1 0 0 1|1 1 1 0 1 1 1|x x x x x| P P |u 0 - - - - 0 - -|d d d d d| Rdd=membh(Rx++Mu:brev) - LD/slot 0,1 -|1 0 0 1|1 1 1 1 0 0 0|x x x x x| P P |u 0 - - - - 0 - -|d d d d d| Rd=memb(Rx++Mu:brev) - LD/slot 0,1 -|1 0 0 1|1 1 1 1 0 0 1|x x x x x| P P |u 0 - - - - 0 - -|d d d d d| Rdd=memub(Rx++Mu:brev) - LD/slot 0,1 -|1 0 0 1|1 1 1 1 0 1 0|x x x x x| P P |u 0 - - - - 0 - -|d d d d d| Rd=memh(Rx++Mu:brev) - LD/slot 0,1 -|1 0 0 1|1 1 1 1 0 1 1|x x x x x| P P |u 0 - - - - 0 - -|d d d d d| Rdd=memuh(Rx++Mu:brev) - LD/slot 0,1 -|1 0 0 1|1 1 1 1 1 0 0|x x x x x| P P |u 0 - - - - 0 - -|d d d d d| Rd=memw(Rx++Mu:brev) - LD/slot 0,1 -|1 0 0 1|1 1 1 1 1 1 0|x x x x x| P P |u 0 - - - - 0 - -|d d d d d| Rdd=memd(Rx++Mu:brev) - LD/slot 0,1 -|1 0 0 1|1 1 0 0 0 0 1|t t t t t| P P |i 1 l l l l i l l|d d d d d| Rd=membh(Rt<<#u2+#U6) - LD/slot 0,1 -|1 0 0 1|1 1 0 0 0 1 0|t t t t t| P P |i 1 l l l l i l l|y y y y y| Ryy=memh_fifo(Rt<<#u2+#U6) - LD/slot 0,1 -|1 0 0 1|1 1 0 0 0 1 1|t t t t t| P P |i 1 l l l l i l l|d d d d d| Rd=memubh(Rt<<#u2+#U6) - LD/slot 0,1 -|1 0 0 1|1 1 0 0 1 0 0|t t t t t| P P |i 1 l l l l i l l|y y y y y| Ryy=memb_fifo(Rt<<#u2+#U6) - LD/slot 0,1 -|1 0 0 1|1 1 0 0 1 0 1|t t t t t| P P |i 1 l l l l i l l|d d d d d| Rdd=memubh(Rt<<#u2+#U6) - LD/slot 0,1 -|1 0 0 1|1 1 0 0 1 1 1|t t t t t| P P |i 1 l l l l i l l|d d d d d| Rdd=membh(Rt<<#u2+#U6) - LD/slot 0,1 -|1 0 0 1|1 1 0 1 0 0 0|t t t t t| P P |i 1 l l l l i l l|d d d d d| Rd=memb(Rt<<#u2+#U6) - LD/slot 0,1 -|1 0 0 1|1 1 0 1 0 0 1|t t t t t| P P |i 1 l l l l i l l|d d d d d| Rdd=memub(Rt<<#u2+#U6) - LD/slot 0,1 -|1 0 0 1|1 1 0 1 0 1 0|t t t t t| P P |i 1 l l l l i l l|d d d d d| Rd=memh(Rt<<#u2+#U6) - LD/slot 0,1 -|1 0 0 1|1 1 0 1 0 1 1|t t t t t| P P |i 1 l l l l i l l|d d d d d| Rdd=memuh(Rt<<#u2+#U6) - LD/slot 0,1 -|1 0 0 1|1 1 0 1 1 0 0|t t t t t| P P |i 1 l l l l i l l|d d d d d| Rd=memw(Rt<<#u2+#U6) - LD/slot 0,1 -|1 0 0 1|1 1 0 1 1 1 0|t t t t t| P P |i 1 l l l l i l l|d d d d d| Rdd=memd(Rt<<#u2+#U6) - LD/slot 0,1 -|1 0 0 1|1 0 1 1 0 0 0|x x x x x| P P |1 0 0 t t i i i i|d d d d d| if (Pt) Rd=memb(Rx++#s4:3) - LD/slot 0,1 -|1 0 0 1|1 0 1 1 0 0 0|x x x x x| P P |1 0 1 t t i i i i|d d d d d| if (!Pt) Rd=memb(Rx++#s4:3) - LD/slot 0,1 -|1 0 0 1|1 0 1 1 0 0 0|x x x x x| P P |1 1 0 t t i i i i|d d d d d| if (Pt.new) Rd=memb(Rx++#s4:3) - LD/slot 0,1 -|1 0 0 1|1 0 1 1 0 0 0|x x x x x| P P |1 1 1 t t i i i i|d d d d d| if (!Pt.new) Rd=memb(Rx++#s4:3) - LD/slot 0,1 -|1 0 0 1|1 0 1 1 0 0 1|x x x x x| P P |1 0 0 t t i i i i|d d d d d| if (Pt) Rd=memub(Rx++#s4:3) - LD/slot 0,1 -|1 0 0 1|1 0 1 1 0 0 1|x x x x x| P P |1 0 1 t t i i i i|d d d d d| if (!Pt) Rd=memub(Rx++#s4:3) - LD/slot 0,1 -|1 0 0 1|1 0 1 1 0 0 1|x x x x x| P P |1 1 0 t t i i i i|d d d d d| if (Pt.new) Rd=memub(Rx++#s4:3) - LD/slot 0,1 -|1 0 0 1|1 0 1 1 0 0 1|x x x x x| P P |1 1 1 t t i i i i|d d d d d| if (!Pt.new) Rd=memub(Rx++#s4:3) - LD/slot 0,1 -|1 0 0 1|1 0 1 1 0 1 0|x x x x x| P P |1 0 0 t t i i i i|d d d d d| if (Pt) Rd=memh(Rx++#s4:3) - LD/slot 0,1 -|1 0 0 1|1 0 1 1 0 1 0|x x x x x| P P |1 0 1 t t i i i i|d d d d d| if (!Pt) Rd=memh(Rx++#s4:3) - LD/slot 0,1 -|1 0 0 1|1 0 1 1 0 1 0|x x x x x| P P |1 1 0 t t i i i i|d d d d d| if (Pt.new) Rd=memh(Rx++#s4:3) - LD/slot 0,1 -|1 0 0 1|1 0 1 1 0 1 0|x x x x x| P P |1 1 1 t t i i i i|d d d d d| if (!Pt.new) Rd=memh(Rx++#s4:3) - LD/slot 0,1 -|1 0 0 1|1 0 1 1 0 1 1|x x x x x| P P |1 0 0 t t i i i i|d d d d d| if (Pt) Rd=memuh(Rx++#s4:3) - LD/slot 0,1 -|1 0 0 1|1 0 1 1 0 1 1|x x x x x| P P |1 0 1 t t i i i i|d d d d d| if (!Pt) Rd=memuh(Rx++#s4:3) - LD/slot 0,1 -|1 0 0 1|1 0 1 1 0 1 1|x x x x x| P P |1 1 0 t t i i i i|d d d d d| if (Pt.new) Rd=memuh(Rx++#s4:3) - LD/slot 0,1 -|1 0 0 1|1 0 1 1 0 1 1|x x x x x| P P |1 1 1 t t i i i i|d d d d d| if (!Pt.new) Rd=memuh(Rx++#s4:3) - LD/slot 0,1 -|1 0 0 1|1 0 1 1 1 0 0|x x x x x| P P |1 0 0 t t i i i i|d d d d d| if (Pt) Rd=memw(Rx++#s4:3) - LD/slot 0,1 -|1 0 0 1|1 0 1 1 1 0 0|x x x x x| P P |1 0 1 t t i i i i|d d d d d| if (!Pt) Rd=memw(Rx++#s4:3) - LD/slot 0,1 -|1 0 0 1|1 0 1 1 1 0 0|x x x x x| P P |1 1 0 t t i i i i|d d d d d| if (Pt.new) Rd=memw(Rx++#s4:3) - LD/slot 0,1 -|1 0 0 1|1 0 1 1 1 0 0|x x x x x| P P |1 1 1 t t i i i i|d d d d d| if (!Pt.new) Rd=memw(Rx++#s4:3) - LD/slot 0,1 -|1 0 0 1|1 0 1 1 1 1 0|x x x x x| P P |1 0 0 t t i i i i|d d d d d| if (Pt) Rdd=memd(Rx++#s4:3) - LD/slot 0,1 -|1 0 0 1|1 0 1 1 1 1 0|x x x x x| P P |1 0 1 t t i i i i|d d d d d| if (!Pt) Rdd=memd(Rx++#s4:3) - LD/slot 0,1 -|1 0 0 1|1 0 1 1 1 1 0|x x x x x| P P |1 1 0 t t i i i i|d d d d d| if (Pt.new) Rdd=memd(Rx++#s4:3) - LD/slot 0,1 -|1 0 0 1|1 0 1 1 1 1 0|x x x x x| P P |1 1 1 t t i i i i|d d d d d| if (!Pt.new) Rdd=memd(Rx++#s4:3) - LD/slot 0,1 -|1 0 0 1|1 1 1 1 0 0 0|i i i i i| P P |1 0 0 t t i 1 - -|d d d d d| if (Pt) Rd=memb(#u6) - LD/slot 0,1 -|1 0 0 1|1 1 1 1 0 0 0|i i i i i| P P |1 0 1 t t i 1 - -|d d d d d| if (!Pt) Rd=memb(#u6) - LD/slot 0,1 -|1 0 0 1|1 1 1 1 0 0 0|i i i i i| P P |1 1 0 t t i 1 - -|d d d d d| if (Pt.new) Rd=memb(#u6) - LD/slot 0,1 -|1 0 0 1|1 1 1 1 0 0 0|i i i i i| P P |1 1 1 t t i 1 - -|d d d d d| if (!Pt.new) Rd=memb(#u6) - LD/slot 0,1 -|1 0 0 1|1 1 1 1 0 0 1|i i i i i| P P |1 0 0 t t i 1 - -|d d d d d| if (Pt) Rd=memub(#u6) - LD/slot 0,1 -|1 0 0 1|1 1 1 1 0 0 1|i i i i i| P P |1 0 1 t t i 1 - -|d d d d d| if (!Pt) Rd=memub(#u6) - LD/slot 0,1 -|1 0 0 1|1 1 1 1 0 0 1|i i i i i| P P |1 1 0 t t i 1 - -|d d d d d| if (Pt.new) Rd=memub(#u6) - LD/slot 0,1 -|1 0 0 1|1 1 1 1 0 0 1|i i i i i| P P |1 1 1 t t i 1 - -|d d d d d| if (!Pt.new) Rd=memub(#u6) - LD/slot 0,1 -|1 0 0 1|1 1 1 1 0 1 0|i i i i i| P P |1 0 0 t t i 1 - -|d d d d d| if (Pt) Rd=memh(#u6) - LD/slot 0,1 -|1 0 0 1|1 1 1 1 0 1 0|i i i i i| P P |1 0 1 t t i 1 - -|d d d d d| if (!Pt) Rd=memh(#u6) - LD/slot 0,1 -|1 0 0 1|1 1 1 1 0 1 0|i i i i i| P P |1 1 0 t t i 1 - -|d d d d d| if (Pt.new) Rd=memh(#u6) - LD/slot 0,1 -|1 0 0 1|1 1 1 1 0 1 0|i i i i i| P P |1 1 1 t t i 1 - -|d d d d d| if (!Pt.new) Rd=memh(#u6) - LD/slot 0,1 -|1 0 0 1|1 1 1 1 0 1 1|i i i i i| P P |1 0 0 t t i 1 - -|d d d d d| if (Pt) Rd=memuh(#u6) - LD/slot 0,1 -|1 0 0 1|1 1 1 1 0 1 1|i i i i i| P P |1 0 1 t t i 1 - -|d d d d d| if (!Pt) Rd=memuh(#u6) - LD/slot 0,1 -|1 0 0 1|1 1 1 1 0 1 1|i i i i i| P P |1 1 0 t t i 1 - -|d d d d d| if (Pt.new) Rd=memuh(#u6) - LD/slot 0,1 -|1 0 0 1|1 1 1 1 0 1 1|i i i i i| P P |1 1 1 t t i 1 - -|d d d d d| if (!Pt.new) Rd=memuh(#u6) - LD/slot 0,1 -|1 0 0 1|1 1 1 1 1 0 0|i i i i i| P P |1 0 0 t t i 1 - -|d d d d d| if (Pt) Rd=memw(#u6) - LD/slot 0,1 -|1 0 0 1|1 1 1 1 1 0 0|i i i i i| P P |1 0 1 t t i 1 - -|d d d d d| if (!Pt) Rd=memw(#u6) - LD/slot 0,1 -|1 0 0 1|1 1 1 1 1 0 0|i i i i i| P P |1 1 0 t t i 1 - -|d d d d d| if (Pt.new) Rd=memw(#u6) - LD/slot 0,1 -|1 0 0 1|1 1 1 1 1 0 0|i i i i i| P P |1 1 1 t t i 1 - -|d d d d d| if (!Pt.new) Rd=memw(#u6) - LD/slot 0,1 -|1 0 0 1|1 1 1 1 1 1 0|i i i i i| P P |1 0 0 t t i 1 - -|d d d d d| if (Pt) Rdd=memd(#u6) - LD/slot 0,1 -|1 0 0 1|1 1 1 1 1 1 0|i i i i i| P P |1 0 1 t t i 1 - -|d d d d d| if (!Pt) Rdd=memd(#u6) - LD/slot 0,1 -|1 0 0 1|1 1 1 1 1 1 0|i i i i i| P P |1 1 0 t t i 1 - -|d d d d d| if (Pt.new) Rdd=memd(#u6) - LD/slot 0,1 -|1 0 0 1|1 1 1 1 1 1 0|i i i i i| P P |1 1 1 t t i 1 - -|d d d d d| if (!Pt.new) Rdd=memd(#u6) - LD/slot 0,1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2655,34 +2655,151 @@ fn decode_instruction< handler.on_opcode_decoded(op)?; } 0b011 => { - opcode_check!(inst & 0b0010_0000_0000_0000 == 0); + let predicated = inst & 0b0010_0000_0000_0000 != 0; let (op, wide, samt) = decode_opcode!(MEM_OPCODES[op as usize]); - if inst & 0b0001_0000_0000_0000 == 0 { + if !predicated { + if inst & 0b0001_0000_0000_0000 == 0 { + let iiii = (inst >> 5) & 0b1111; + handler.on_source_decoded(Operand::RegOffsetInc { base: xxxxx, offset: (iiii << samt) })?; + } else { + let u2 = (inst >> 5) & 0b11; + let u4 = (inst >> 8) & 0b1111; + let uuuuuu = (u2 | (u4 << 2)) as u16; + handler.on_source_decoded(Operand::RegStoreAssign { base: xxxxx, addr: uuuuuu })?; + } + if !wide { + handler.on_dest_decoded(Operand::gpr(ddddd))?; + } else { + handler.on_dest_decoded(Operand::gprpair(ddddd)?)?; + } + handler.on_opcode_decoded(op)?; + } else { let iiii = (inst >> 5) & 0b1111; + let tt = (inst >> 9) & 0b11; + let negated = (inst >> 11) & 0b1 != 0; + let dotnew = (inst >> 12) & 0b1 != 0; + + handler.inst_predicated(tt as u8, negated, dotnew)?; handler.on_source_decoded(Operand::RegOffsetInc { base: xxxxx, offset: (iiii << samt) })?; + if !wide { + handler.on_dest_decoded(Operand::gpr(ddddd))?; + } else { + handler.on_dest_decoded(Operand::gprpair(ddddd)?)?; + } + handler.on_opcode_decoded(op)?; + } + } + 0b100 => { + let shifted_reg = inst & 0b0001_0000_0000_0000 != 0; + + let (op, wide, samt) = decode_opcode!(MEM_FIFO_OPS[op as usize]); + + if !wide { + handler.on_dest_decoded(Operand::gpr(ddddd))?; + } else { + handler.on_dest_decoded(Operand::gprpair(ddddd)?)?; + } + handler.on_opcode_decoded(op)?; + + if !shifted_reg { + operand_check!(inst & 0b0000_0000_1000_0000 == 0); + + let mu = ((inst >> 13) & 1) as u8; + + handler.on_source_decoded(Operand::RegMemIndexed { base: xxxxx, mu })?; } else { + let i_hi = (inst >> 13) & 1; + let i_lo = (inst >> 7) & 1; + let ii = ((i_hi << 1) | i_lo) as u8; + let u2 = (inst >> 5) & 0b11; let u4 = (inst >> 8) & 0b1111; - let uuuuuu = (u2 | (u4 << 2)) as u16; - handler.on_source_decoded(Operand::RegStoreAssign { base: xxxxx, addr: uuuuuu })?; + let uuuuuu = (u2 | (u4 << 2)) as i16; + + handler.on_source_decoded(Operand::RegShiftOffset { base: xxxxx, shift: ii, offset: uuuuuu })?; } + } + 0b101 => { + let shifted_reg = inst & 0b0001_0000_0000_0000 != 0; + + let (op, wide, samt) = decode_opcode!(MEM_OPCODES[op as usize]); + if !wide { handler.on_dest_decoded(Operand::gpr(ddddd))?; } else { handler.on_dest_decoded(Operand::gprpair(ddddd)?)?; } handler.on_opcode_decoded(op)?; - } - 0b100 => { - } - 0b101 => { + + if !shifted_reg { + operand_check!(inst & 0b0000_0000_1000_0000 == 0); + + let mu = ((inst >> 13) & 1) as u8; + + handler.on_source_decoded(Operand::RegMemIndexed { base: xxxxx, mu })?; + } else { + let i_hi = (inst >> 13) & 1; + let i_lo = (inst >> 7) & 1; + let ii = ((i_hi << 1) | i_lo) as u8; + + let u2 = (inst >> 5) & 0b11; + let u4 = (inst >> 8) & 0b1111; + let uuuuuu = (u2 | (u4 << 2)) as i16; + + handler.on_source_decoded(Operand::RegShiftOffset { base: xxxxx, shift: ii, offset: uuuuuu })?; + } } 0b110 => { + operand_check!(inst & 0b0001_0000_1000_0000 == 0); + + let (op, wide, samt) = decode_opcode!(MEM_FIFO_OPS[op as usize]); + + let mu = ((inst >> 13) & 1) as u8; + handler.on_source_decoded(Operand::RegMemIndexedBrev { base: xxxxx, mu })?; + if !wide { + handler.on_dest_decoded(Operand::gpr(ddddd))?; + } else { + handler.on_dest_decoded(Operand::gprpair(ddddd)?)?; + } + handler.on_opcode_decoded(op)?; } _ => { - todo!("other mem op"); + // 0b111 + let predicated = inst & 0b0000_0000_1000_0000 != 0; + + let (op, wide, samt) = decode_opcode!(MEM_OPCODES[op as usize]); + + if !predicated { + operand_check!(inst & 0b0001_0000_0000_0000 == 0); + let mu = ((inst >> 13) & 1) as u8; + handler.on_source_decoded(Operand::RegMemIndexedBrev { base: xxxxx, mu })?; + if !wide { + handler.on_dest_decoded(Operand::gpr(ddddd))?; + } else { + handler.on_dest_decoded(Operand::gprpair(ddddd)?)?; + } + handler.on_opcode_decoded(op)?; + } else { + let i5 = reg_b16(inst); + let i = ((inst >> 8) & 1) as u8; + let iiiiii = (i5 << 1) | i; + let ddddd = reg_b0(inst); + + let tt = (inst >> 9) & 0b11; + let negated = (inst >> 11) & 0b1 != 0; + let dotnew = (inst >> 12) & 0b1 != 0; + + handler.inst_predicated(tt as u8, negated, dotnew)?; + handler.on_source_decoded(Operand::RegStoreAssign { base: xxxxx, addr: iiiiii as u16 })?; + if !wide { + handler.on_dest_decoded(Operand::gpr(ddddd))?; + } else { + handler.on_dest_decoded(Operand::gprpair(ddddd)?)?; + } + handler.on_opcode_decoded(op)?; + } } } } else { diff --git a/tests/from_brain.rs b/tests/from_brain.rs index 1cd15c8..d87ac2e 100644 --- a/tests/from_brain.rs +++ b/tests/from_brain.rs @@ -501,6 +501,93 @@ fn inst_1001() { test_display(&0b1001_1011011_00010_11_0110_00011_10000u32.to_le_bytes(), "{ R16 = memuh(R2=#0x23) }"); test_display(&0b1001_1011100_00010_11_0110_00011_10000u32.to_le_bytes(), "{ R16 = memw(R2=#0x23) }"); test_display(&0b1001_1011110_00010_11_0110_00011_10000u32.to_le_bytes(), "{ R17:16 = memd(R2=#0x23) }"); + + test_display(&0b1001_1011000_00010_11_1001_00011_10000u32.to_le_bytes(), "{ if (P2) R16 = memb(R2++#0x3) }"); + test_display(&0b1001_1011000_00010_11_1011_00011_10000u32.to_le_bytes(), "{ if (!P2) R16 = memb(R2++#0x3) }"); + test_display(&0b1001_1011000_00010_11_1101_00011_10000u32.to_le_bytes(), "{ if (P2.new) R16 = memb(R2++#0x3) }"); + test_display(&0b1001_1011000_00010_11_1111_00011_10000u32.to_le_bytes(), "{ if (!P2.new) R16 = memb(R2++#0x3) }"); + test_display(&0b1001_1011011_00010_11_1001_00011_10000u32.to_le_bytes(), "{ if (P2) R16 = memuh(R2++#0x6) }"); + test_display(&0b1001_1011011_00010_11_1011_00011_10000u32.to_le_bytes(), "{ if (!P2) R16 = memuh(R2++#0x6) }"); + test_display(&0b1001_1011011_00010_11_1101_00011_10000u32.to_le_bytes(), "{ if (P2.new) R16 = memuh(R2++#0x6) }"); + test_display(&0b1001_1011011_00010_11_1111_00011_10000u32.to_le_bytes(), "{ if (!P2.new) R16 = memuh(R2++#0x6) }"); + test_display(&0b1001_1011110_00010_11_1001_00011_10000u32.to_le_bytes(), "{ if (P2) R17:16 = memd(R2++#0x18) }"); + test_display(&0b1001_1011110_00010_11_1011_00011_10000u32.to_le_bytes(), "{ if (!P2) R17:16 = memd(R2++#0x18) }"); + test_display(&0b1001_1011110_00010_11_1101_00011_10000u32.to_le_bytes(), "{ if (P2.new) R17:16 = memd(R2++#0x18) }"); + test_display(&0b1001_1011110_00010_11_1111_00011_10000u32.to_le_bytes(), "{ if (!P2.new) R17:16 = memd(R2++#0x18) }"); + + // 1001_1100 + test_display(&0b1001_1100001_00010_11_1000_00000_10000u32.to_le_bytes(), "{ R16 = membh(R2++M1) }"); + test_display(&0b1001_1100010_00010_11_1000_00000_10000u32.to_le_bytes(), "{ R17:16 = memh_fifo(R2++M1) }"); + test_display(&0b1001_1100011_00010_11_1000_00000_10000u32.to_le_bytes(), "{ R16 = memubh(R2++M1) }"); + test_display(&0b1001_1100100_00010_11_1000_00000_10000u32.to_le_bytes(), "{ R17:16 = memb_fifo(R2++M1) }"); + test_display(&0b1001_1100101_00010_11_1000_00000_10000u32.to_le_bytes(), "{ R17:16 = memubh(R2++M1) }"); + test_display(&0b1001_1100111_00010_11_1000_00000_10000u32.to_le_bytes(), "{ R17:16 = membh(R2++M1) }"); + + test_display(&0b1001_1100001_00010_11_0110_00111_10000u32.to_le_bytes(), "{ R16 = membh(R2<<1 + 0x23) }"); + test_display(&0b1001_1100010_00010_11_0110_00111_10000u32.to_le_bytes(), "{ R17:16 = memh_fifo(R2<<1 + 0x23) }"); + test_display(&0b1001_1100011_00010_11_0110_00111_10000u32.to_le_bytes(), "{ R16 = memubh(R2<<1 + 0x23) }"); + test_display(&0b1001_1100100_00010_11_0110_00111_10000u32.to_le_bytes(), "{ R17:16 = memb_fifo(R2<<1 + 0x23) }"); + test_display(&0b1001_1100101_00010_11_0110_00111_10000u32.to_le_bytes(), "{ R17:16 = memubh(R2<<1 + 0x23) }"); + test_display(&0b1001_1100111_00010_11_0110_00111_10000u32.to_le_bytes(), "{ R17:16 = membh(R2<<1 + 0x23) }"); + + // 1001_1101 + test_display(&0b1001_1101000_00010_11_1000_00000_10000u32.to_le_bytes(), "{ R16 = memb(R2++M1) }"); + test_display(&0b1001_1101001_00010_11_1000_00000_10000u32.to_le_bytes(), "{ R16 = memub(R2++M1) }"); + test_display(&0b1001_1101010_00010_11_1000_00000_10000u32.to_le_bytes(), "{ R16 = memh(R2++M1) }"); + test_display(&0b1001_1101011_00010_11_1000_00000_10000u32.to_le_bytes(), "{ R16 = memuh(R2++M1) }"); + test_display(&0b1001_1101100_00010_11_1000_00000_10000u32.to_le_bytes(), "{ R16 = memw(R2++M1) }"); + test_invalid(&0b1001_1101101_00010_11_1000_00000_10000u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_display(&0b1001_1101110_00010_11_1000_00000_10000u32.to_le_bytes(), "{ R17:16 = memd(R2++M1) }"); + test_invalid(&0b1001_1101111_00010_11_1000_00000_10000u32.to_le_bytes(), DecodeError::InvalidOpcode); + + test_display(&0b1001_1101000_00010_11_0110_00111_10000u32.to_le_bytes(), "{ R16 = memb(R2<<1 + 0x23) }"); + test_display(&0b1001_1101001_00010_11_0110_00111_10000u32.to_le_bytes(), "{ R16 = memub(R2<<1 + 0x23) }"); + test_display(&0b1001_1101010_00010_11_0110_00111_10000u32.to_le_bytes(), "{ R16 = memh(R2<<1 + 0x23) }"); + test_display(&0b1001_1101011_00010_11_0110_00111_10000u32.to_le_bytes(), "{ R16 = memuh(R2<<1 + 0x23) }"); + test_display(&0b1001_1101100_00010_11_0110_00111_10000u32.to_le_bytes(), "{ R16 = memw(R2<<1 + 0x23) }"); + test_invalid(&0b1001_1101101_00010_11_0110_00111_10000u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_display(&0b1001_1101110_00010_11_0110_00111_10000u32.to_le_bytes(), "{ R17:16 = memd(R2<<1 + 0x23) }"); + test_invalid(&0b1001_1101111_00010_11_0110_00111_10000u32.to_le_bytes(), DecodeError::InvalidOpcode); + + // skipped forward to 1001_1110 + test_invalid(&0b1001_1110000_00010_11_1001_01000_10000u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_display(&0b1001_1110001_00010_11_1001_01000_10000u32.to_le_bytes(), "{ R16 = membh(R2++M1:brev) }"); + test_display(&0b1001_1110010_00010_11_1001_01000_10000u32.to_le_bytes(), "{ R17:16 = memh_fifo(R2++M1:brev) }"); + test_display(&0b1001_1110011_00010_11_1001_01000_10000u32.to_le_bytes(), "{ R16 = memubh(R2++M1:brev) }"); + test_display(&0b1001_1110100_00010_11_1001_01000_10000u32.to_le_bytes(), "{ R17:16 = memb_fifo(R2++M1:brev) }"); + test_display(&0b1001_1110101_00010_11_1001_01000_10000u32.to_le_bytes(), "{ R17:16 = memubh(R2++M1:brev) }"); + test_invalid(&0b1001_1110110_00010_11_1001_01000_10000u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_display(&0b1001_1110111_00010_11_1001_01000_10000u32.to_le_bytes(), "{ R17:16 = membh(R2++M1:brev) }"); + + test_invalid(&0b1001_1110000_00010_11_1001_01100_10000u32.to_le_bytes(), DecodeError::InvalidOperand); + test_invalid(&0b1001_1110001_00010_11_1001_01100_10000u32.to_le_bytes(), DecodeError::InvalidOperand); + test_invalid(&0b1001_1110010_00010_11_1001_01100_10000u32.to_le_bytes(), DecodeError::InvalidOperand); + test_invalid(&0b1001_1110011_00010_11_1001_01100_10000u32.to_le_bytes(), DecodeError::InvalidOperand); + test_invalid(&0b1001_1110100_00010_11_1001_01100_10000u32.to_le_bytes(), DecodeError::InvalidOperand); + test_invalid(&0b1001_1110101_00010_11_1001_01100_10000u32.to_le_bytes(), DecodeError::InvalidOperand); + test_invalid(&0b1001_1110110_00010_11_1001_01100_10000u32.to_le_bytes(), DecodeError::InvalidOperand); + test_invalid(&0b1001_1110111_00010_11_1001_01100_10000u32.to_le_bytes(), DecodeError::InvalidOperand); + + test_display(&0b1001_1111000_00010_11_1001_01000_10000u32.to_le_bytes(), "{ R16 = memb(R2++M1:brev) }"); + test_display(&0b1001_1111001_00010_11_1001_01000_10000u32.to_le_bytes(), "{ R16 = memub(R2++M1:brev) }"); + test_display(&0b1001_1111010_00010_11_1001_01000_10000u32.to_le_bytes(), "{ R16 = memh(R2++M1:brev) }"); + test_display(&0b1001_1111011_00010_11_1001_01000_10000u32.to_le_bytes(), "{ R16 = memuh(R2++M1:brev) }"); + test_display(&0b1001_1111100_00010_11_1001_01000_10000u32.to_le_bytes(), "{ R16 = memw(R2++M1:brev) }"); + test_invalid(&0b1001_1111101_00010_11_1001_01000_10000u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_display(&0b1001_1111110_00010_11_1001_01000_10000u32.to_le_bytes(), "{ R17:16 = memd(R2++M1:brev) }"); + + test_display(&0b1001_1111000_00010_11_1001_01100_10000u32.to_le_bytes(), "{ if (P2) R16 = memb(R2=#0x5) }"); + test_display(&0b1001_1111000_00010_11_1011_01100_10000u32.to_le_bytes(), "{ if (!P2) R16 = memb(R2=#0x5) }"); + test_display(&0b1001_1111000_00010_11_1101_01100_10000u32.to_le_bytes(), "{ if (P2.new) R16 = memb(R2=#0x5) }"); + test_display(&0b1001_1111000_00010_11_1111_01100_10000u32.to_le_bytes(), "{ if (!P2.new) R16 = memb(R2=#0x5) }"); + test_display(&0b1001_1111011_00010_11_1001_01100_10000u32.to_le_bytes(), "{ if (P2) R16 = memuh(R2=#0x5) }"); + test_display(&0b1001_1111011_00010_11_1011_01100_10000u32.to_le_bytes(), "{ if (!P2) R16 = memuh(R2=#0x5) }"); + test_display(&0b1001_1111011_00010_11_1101_01100_10000u32.to_le_bytes(), "{ if (P2.new) R16 = memuh(R2=#0x5) }"); + test_display(&0b1001_1111011_00010_11_1111_01100_10000u32.to_le_bytes(), "{ if (!P2.new) R16 = memuh(R2=#0x5) }"); + test_display(&0b1001_1111110_00010_11_1001_01100_10000u32.to_le_bytes(), "{ if (P2) R17:16 = memd(R2=#0x5) }"); + test_display(&0b1001_1111110_00010_11_1011_01100_10000u32.to_le_bytes(), "{ if (!P2) R17:16 = memd(R2=#0x5) }"); + test_display(&0b1001_1111110_00010_11_1101_01100_10000u32.to_le_bytes(), "{ if (P2.new) R17:16 = memd(R2=#0x5) }"); + test_display(&0b1001_1111110_00010_11_1111_01100_10000u32.to_le_bytes(), "{ if (!P2.new) R17:16 = memd(R2=#0x5) }"); } #[test] |