summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--notes/todo216
-rw-r--r--src/lib.rs135
-rw-r--r--tests/from_brain.rs87
3 files changed, 321 insertions, 117 deletions
diff --git a/notes/todo b/notes/todo
index 3614359..4ad9a6b 100644
--- a/notes/todo
+++ b/notes/todo
@@ -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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/lib.rs b/src/lib.rs
index cfcd02c..98b6f17 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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]