summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2025-03-22 14:11:37 -0700
committeriximeow <me@iximeow.net>2025-03-22 14:11:37 -0700
commitb8c530e402812f4fbce95695d0661994e3bc86d0 (patch)
tree998feda6c599014ab6f534936438edeb9c189105
parent7f315862ad9d88fefff0d420c93a34ece0cc9eb2 (diff)
more tests, support more loads/stores
-rw-r--r--notes/todo228
-rw-r--r--src/display.rs6
-rw-r--r--src/lib.rs267
-rw-r--r--tests/from_brain.rs71
4 files changed, 375 insertions, 197 deletions
diff --git a/notes/todo b/notes/todo
index e616890..3614359 100644
--- a/notes/todo
+++ b/notes/todo
@@ -283,20 +283,20 @@ 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)
-test |0 1 0 0|1 i i 0 0 0 0|i i i i i| P P |i t t t t t i i i|i i i i i| memb(gp+#u16:0)=Rt - ST/slot 0,1
-test |0 1 0 0|1 i i 0 0 1 0|i i i i i| P P |i t t t t t i i i|i i i i i| memh(gp+#u16:1)=Rt - ST/slot 0,1
-test |0 1 0 0|1 i i 0 0 1 1|i i i i i| P P |i t t t t t i i i|i i i i i| memh(gp+#u16:1)=Rt.H - ST/slot 0,1
-test |0 1 0 0|1 i i 0 1 0 0|i i i i i| P P |i t t t t t i i i|i i i i i| memw(gp+#u16:2)=Rt - ST/slot 0,1
-test |0 1 0 0|1 i i 0 1 0 1|i i i i i| P P |i 0 0 t t t i i i|i i i i i| memb(gp+#u16:0)=Nt.new - NV ST/slot 0
-test |0 1 0 0|1 i i 0 1 0 1|i i i i i| P P |i 0 1 t t t i i i|i i i i i| memh(gp+#u16:1)=Nt.new - NV ST/slot 0
-test |0 1 0 0|1 i i 0 1 0 1|i i i i i| P P |i 1 0 t t t i i i|i i i i i| memw(gp+#u16:2)=Nt.new - NV ST/slot 0
-test |0 1 0 0|1 i i 0 1 1 0|i i i i i| P P |i t t t t t i i i|i i i i i| memd(gp+#u16:3)=Rtt - ST/slot 0,1
-|0 1 0 0|1 i i 1 0 0 0|i i i i i| P P |i i i i i i i i i|d d d d d| Rd=memb(gp+#u16:3) - LD/slot 0,1
-|0 1 0 0|1 i i 1 0 0 1|i i i i i| P P |i i i i i i i i i|d d d d d| Rdd=memub(gp+#u16:3) - LD/slot 0,1
-|0 1 0 0|1 i i 1 0 1 0|i i i i i| P P |i i i i i i i i i|d d d d d| Rd=memh(gp+#u16:3) - LD/slot 0,1
-|0 1 0 0|1 i i 1 0 1 1|i i i i i| P P |i i i i i i i i i|d d d d d| Rdd=memuh(gp+#u16:3) - LD/slot 0,1
-|0 1 0 0|1 i i 1 1 0 0|i i i i i| P P |i i i i i i i i i|d d d d d| Rd=memw(gp+#u16:3) - LD/slot 0,1
-|0 1 0 0|1 i i 1 1 1 0|i i i i i| P P |i i i i i i i i i|d d d d d| Rdd=memd(gp+#u16:3) - LD/slot 0,1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -639,32 +639,32 @@ test |0 1 0 0|1 i i 0 1 1 0|i i i i i| P P |i t t t t t i i i|i i i i i| memd(gp
-|1 0 0 1|1 0 0 0 0 0 1|x x x x x| P P |u 0 - - 0 i i i i|d d d d d| Rd=membh(Rx++#s4:1:circ(Mu)) - LD/slot 0,1
-|1 0 0 1|1 0 0 0 0 1 0|x x x x x| P P |u 0 - - 0 i i i i|y y y y y| Ryy=memh_fifo(Rx++#s4:0:circ(Mu)) - LD/slot 0,1
-|1 0 0 1|1 0 0 0 0 1 1|x x x x x| P P |u 0 - - 0 i i i i|d d d d d| Rd=memubh(Rx++#s4:1:circ(Mu)) - LD/slot 0,1
-|1 0 0 1|1 0 0 0 1 0 0|x x x x x| P P |u 0 - - 0 i i i i|y y y y y| Ryy=memb_fifo(Rx++#s4:0:circ(Mu)) - LD/slot 0,1
-|1 0 0 1|1 0 0 0 1 0 1|x x x x x| P P |u 0 - - 0 i i i i|d d d d d| Rdd=memubh(Rx++#s4:2:circ(Mu)) - LD/slot 0,1
-|1 0 0 1|1 0 0 0 1 1 1|x x x x x| P P |u 0 - - 0 i i i i|d d d d d| Rdd=membh(Rx++#s4:2:circ(Mu)) - LD/slot 0,1
-|1 0 0 1|1 0 0 1 0 0 0|x x x x x| P P |u 0 - - 0 i i i i|d d d d d| Rd=memb(Rx++#s4:3:circ(Mu)) - LD/slot 0,1
-|1 0 0 1|1 0 0 1 0 0 1|x x x x x| P P |u 0 - - 0 i i i i|d d d d d| Rdd=memub(Rx++#s4:3:circ(Mu)) - LD/slot 0,1
-|1 0 0 1|1 0 0 1 0 1 0|x x x x x| P P |u 0 - - 0 i i i i|d d d d d| Rd=memh(Rx++#s4:3:circ(Mu)) - LD/slot 0,1
-|1 0 0 1|1 0 0 1 0 1 1|x x x x x| P P |u 0 - - 0 i i i i|d d d d d| Rdd=memuh(Rx++#s4:3:circ(Mu)) - LD/slot 0,1
-|1 0 0 1|1 0 0 1 1 0 0|x x x x x| P P |u 0 - - 0 i i i i|d d d d d| Rd=memw(Rx++#s4:3:circ(Mu)) - LD/slot 0,1
-|1 0 0 1|1 0 0 1 1 1 0|x x x x x| P P |u 0 - - 0 i i i i|d d d d d| Rdd=memd(Rx++#s4:3:circ(Mu)) - LD/slot 0,1
-|1 0 0 1|1 0 0 0 0 0 1|x x x x x| P P |u 0 - - 1 - 0 - -|d d d d d| Rd=membh(Rx++I:circ(Mu)) - LD/slot 0,1
-|1 0 0 1|1 0 0 0 0 1 0|x x x x x| P P |u 0 - - 1 - 0 - -|y y y y y| Ryy=memh_fifo(Rx++I:circ(Mu)) - LD/slot 0,1
-|1 0 0 1|1 0 0 0 0 1 1|x x x x x| P P |u 0 - - 1 - 0 - -|d d d d d| Rd=memubh(Rx++I:circ(Mu)) - LD/slot 0,1
-|1 0 0 1|1 0 0 0 1 0 0|x x x x x| P P |u 0 - - 1 - 0 - -|y y y y y| Ryy=memb_fifo(Rx++I:circ(Mu)) - LD/slot 0,1
-|1 0 0 1|1 0 0 0 1 0 1|x x x x x| P P |u 0 - - 1 - 0 - -|d d d d d| Rdd=memubh(Rx++I:circ(Mu)) - LD/slot 0,1
-|1 0 0 1|1 0 0 0 1 1 1|x x x x x| P P |u 0 - - 1 - 0 - -|d d d d d| Rdd=membh(Rx++I:circ(Mu)) - LD/slot 0,1
-|1 0 0 1|1 0 0 1 0 0 0|x x x x x| P P |u 0 - - 1 - 0 - -|d d d d d| Rd=memb(Rx++I:circ(Mu)) - LD/slot 0,1
-|1 0 0 1|1 0 0 1 0 0 1|x x x x x| P P |u 0 - - 1 - 0 - -|d d d d d| Rdd=memub(Rx++I:circ(Mu)) - LD/slot 0,1
-|1 0 0 1|1 0 0 1 0 1 0|x x x x x| P P |u 0 - - 1 - 0 - -|d d d d d| Rd=memh(Rx++I:circ(Mu)) - LD/slot 0,1
-|1 0 0 1|1 0 0 1 0 1 1|x x x x x| P P |u 0 - - 1 - 0 - -|d d d d d| Rdd=memuh(Rx++I:circ(Mu)) - LD/slot 0,1
-|1 0 0 1|1 0 0 1 1 0 0|x x x x x| P P |u 0 - - 1 - 0 - -|d d d d d| Rd=memw(Rx++I:circ(Mu)) - LD/slot 0,1
-|1 0 0 1|1 0 0 1 1 1 0|x x x x x| P P |u 0 - - 1 - 0 - -|d d d d d| Rdd=memd(Rx++I:circ(Mu)) - LD/slot 0,1
-|1 0 0 1|1 0 0 1 1 1 1|t t t t t| P P |0 s s s s s 0 0 1|d d d d d| Rdd=linecpy(Rs,Rtt) - LD/slot 0,1 - Solo
-|1 0 0 1|1 0 0 1 1 1 1|t t t t t| P P |0 x x x x x 0 0 0|d d d d d| Rdd=pmemcpy(Rx,Rtt) - LD/slot 0,1 - Solo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|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
@@ -672,47 +672,23 @@ test |0 1 0 0|1 i i 0 1 1 0|i i i i i| P P |i t t t t t i i i|i i i i i| memd(gp
|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 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 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 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 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
@@ -724,18 +700,6 @@ test |0 1 0 0|1 i i 0 1 1 0|i i i i i| P P |i t t t t t i i i|i i i i i| memd(gp
|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 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 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
@@ -749,6 +713,42 @@ test |0 1 0 0|1 i i 0 1 1 0|i i i i i| P P |i t t t t t i i i|i i i i i| memd(gp
|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
@@ -1416,39 +1416,39 @@ test |0 1 0 0|1 i i 0 1 1 0|i i i i i| P P |i t t t t t i i i|i i i i i| memd(gp
|1 1 1 0|1 1 1 1|1 1 0|s s s s s| P P |0 t t t t t|0 0 1|x x x x x| Rx|=xor(Rs,Rt) - XTYPE ALU/slot 2,3
|1 1 1 0|1 1 1 1|1 1 0|s s s s s| P P |0 t t t t t|0 1 0|x x x x x| Rx^=and(Rs,Rt) - XTYPE ALU/slot 2,3
|1 1 1 0|1 1 1 1|1 1 0|s s s s s| P P |0 t t t t t|0 1 1|x x x x x| Rx^=or(Rs,Rt) - XTYPE ALU/slot 2,3
-test |1 1 1 1|0 0 0 1 0 0 0|s s s s s| P P |- t t t t t - - -|d d d d d| Rd=and(Rs,Rt) - ALU32/slots 0 1 2 3
-test |1 1 1 1|0 0 0 1 0 0 1|s s s s s| P P |- t t t t t - - -|d d d d d| Rd=or(Rs,Rt) - ALU32/slots 0 1 2 3
-test |1 1 1 1|0 0 0 1 0 1 1|s s s s s| P P |- t t t t t - - -|d d d d d| Rd=xor(Rs,Rt) - ALU32/slots 0 1 2 3
-test |1 1 1 1|0 0 0 1 1 0 0|s s s s s| P P |- t t t t t - - -|d d d d d| Rd=and(Rt,~Rs) - ALU32/slots 0 1 2 3
-test |1 1 1 1|0 0 0 1 1 0 1|s s s s s| P P |- t t t t t - - -|d d d d d| Rd=or(Rt,~Rs) - ALU32/slots 0 1 2 3
-test |1 1 1 1|0 0 1 0 - 0 0|s s s s s| P P |- t t t t t - - -|0 0 0 d d| Pd=cmp.eq(Rs,Rt) - ALU32 PRED/slots 0 1 2 3
-test |1 1 1 1|0 0 1 0 - 0 0|s s s s s| P P |- t t t t t - - -|1 0 0 d d| Pd=!cmp.eq(Rs,Rt) - ALU32 PRED/slots 0 1 2 3
-test |1 1 1 1|0 0 1 0 - 1 0|s s s s s| P P |- t t t t t - - -|0 0 0 d d| Pd=cmp.gt(Rs,Rt) - ALU32 PRED/slots 0 1 2 3
-test |1 1 1 1|0 0 1 0 - 1 0|s s s s s| P P |- t t t t t - - -|1 0 0 d d| Pd=!cmp.gt(Rs,Rt) - ALU32 PRED/slots 0 1 2 3
-test |1 1 1 1|0 0 1 0 - 1 1|s s s s s| P P |- t t t t t - - -|0 0 0 d d| Pd=cmp.gtu(Rs,Rt) - ALU32 PRED/slots 0 1 2 3
-test |1 1 1 1|0 0 1 0 - 1 1|s s s s s| P P |- t t t t t - - -|1 0 0 d d| Pd=!cmp.gtu(Rs,Rt) - ALU32 PRED/slots 0 1 2 3
-test |1 1 1 1|0 0 1 1 0 0 0|s s s s s| P P |- t t t t t - - -|d d d d d| Rd=add(Rs,Rt) - ALU32/slots 0 1 2 3
-test |1 1 1 1|0 0 1 1 0 0 1|s s s s s| P P |- t t t t t - - -|d d d d d| Rd=sub(Rt,Rs) - ALU32/slots 0 1 2 3
-test |1 1 1 1|0 0 1 1 0 1 0|s s s s s| P P |- t t t t t - - -|d d d d d| Rd=cmp.eq(Rs,Rt) - ALU32 PRED/slots 0 1 2 3
-test |1 1 1 1|0 0 1 1 0 1 1|s s s s s| P P |- t t t t t - - -|d d d d d| Rd=!cmp.eq(Rs,Rt) - ALU32 PRED/slots 0 1 2 3
-test |1 1 1 1|0 0 1 1 1 0 0|s s s s s| P P |0 t t t t t - - -|d d d d d| Rd=combine(Rt.H,Rs.H) - ALU32 PERM/slots 0 1 2 3
-test |1 1 1 1|0 0 1 1 1 0 1|s s s s s| P P |0 t t t t t - - -|d d d d d| Rd=combine(Rt.H,Rs.L) - ALU32 PERM/slots 0 1 2 3
-test |1 1 1 1|0 0 1 1 1 1 0|s s s s s| P P |0 t t t t t - - -|d d d d d| Rd=combine(Rt.L,Rs.H) - ALU32 PERM/slots 0 1 2 3
-test |1 1 1 1|0 0 1 1 1 1 1|s s s s s| P P |0 t t t t t - - -|d d d d d| Rd=combine(Rt.L,Rs.L) - ALU32 PERM/slots 0 1 2 3
-test |1 1 1 1|0 1 0 0 - - -|s s s s s| P P |- t t t t t - u u|d d d d d| Rd=mux(Pu,Rs,Rt) - ALU32 PERM/slots 0 1 2 3
-test |1 1 1 1|0 1 0 1 0 - -|s s s s s| P P |0 t t t t t - - -|d d d d d| Rdd=combine(Rs,Rt) - ALU32 PERM/slots 0 1 2 3
-test |1 1 1 1|0 1 0 1 1 - -|s s s s s| P P |- t t t t t - - -|d d d d d| Rdd=packhl(Rs,Rt) - ALU32 PERM/slots 0 1 2 3
-test |1 1 1 1|0 1 1 0 0 0 0|s s s s s| P P |- t t t t t - - -|d d d d d| Rd=vaddh(Rs,Rt) - ALU32/slots 0 1 2 3 -
-test |1 1 1 1|0 1 1 0 0 0 1|s s s s s| P P |- t t t t t - - -|d d d d d| Rd=vaddh(Rs,Rt):sat - ALU32/slots 0 1 2 3 -
-test |1 1 1 1|0 1 1 0 0 1 0|s s s s s| P P |- t t t t t - - -|d d d d d| Rd=add(Rs,Rt):sat - ALU32/slots 0 1 2 3
-test |1 1 1 1|0 1 1 0 0 1 1|s s s s s| P P |- t t t t t - - -|d d d d d| Rd=vadduh(Rs,Rt):sat - ALU32/slots 0 1 2 3 -
-test |1 1 1 1|0 1 1 0 1 0 0|s s s s s| P P |- t t t t t - - -|d d d d d| Rd=vsubh(Rt,Rs) - ALU32/slots 0 1 2 3 -
-test |1 1 1 1|0 1 1 0 1 0 1|s s s s s| P P |- t t t t t - - -|d d d d d| Rd=vsubh(Rt,Rs):sat - ALU32/slots 0 1 2 3 -
-test |1 1 1 1|0 1 1 0 1 1 0|s s s s s| P P |- t t t t t - - -|d d d d d| Rd=sub(Rt,Rs):sat - ALU32/slots 0 1 2 3
-test |1 1 1 1|0 1 1 0 1 1 1|s s s s s| P P |- t t t t t - - -|d d d d d| Rd=vsubuh(Rt,Rs):sat - ALU32/slots 0 1 2 3 -
-test |1 1 1 1|0 1 1 1 - 0 0|s s s s s| P P |- t t t t t - - -|d d d d d| Rd=vavgh(Rs,Rt) - ALU32/slots 0 1 2 3 -
-test |1 1 1 1|0 1 1 1 - 0 1|s s s s s| P P |- t t t t t - - -|d d d d d| Rd=vavgh(Rs,Rt):sat - ALU32/slots 0 1 2 3 -
-test |1 1 1 1|0 1 1 1 - 1 1|s s s s s| P P |- t t t t t - - -|d d d d d| Rd=vnavgh(Rt,Rs) - ALU32/slots 0 1 2 3 -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/display.rs b/src/display.rs
index 5063350..cd5abfb 100644
--- a/src/display.rs
+++ b/src/display.rs
@@ -293,11 +293,11 @@ impl fmt::Display for Opcode {
Opcode::CmpGtu => { f.write_str("cmp.gtu") },
Opcode::Add => { f.write_str("add") },
Opcode::And => { f.write_str("and") },
- Opcode::And_nRR => { f.write_str("and_nRR") },
+ Opcode::And_nRR => { f.write_str("and") },
Opcode::And_RnR => { f.write_str("and_RnR") },
Opcode::Sub => { f.write_str("sub") },
Opcode::Or => { f.write_str("or") },
- Opcode::Or_nRR => { f.write_str("or_nRR") },
+ Opcode::Or_nRR => { f.write_str("or") },
Opcode::Or_RnR => { f.write_str("or_RnR") },
Opcode::Xor => { f.write_str("xor") },
Opcode::Contains => { f.write_str("contains") },
@@ -404,6 +404,8 @@ impl fmt::Display for Opcode {
Opcode::MemdLockedLoad => { f.write_str("memd_locked") },
Opcode::MemdStoreCond => { f.write_str("memd_locked") },
Opcode::MemdAq => { f.write_str("memd_aq") },
+ Opcode::Pmemcpy => { f.write_str("pmemcpy") },
+ Opcode::Linecpy => { f.write_str("linecpy") },
}
}
}
diff --git a/src/lib.rs b/src/lib.rs
index a046abd..b7b5660 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -543,6 +543,9 @@ pub enum Opcode {
MemdLockedLoad,
MemdStoreCond,
MemdAq,
+
+ Pmemcpy,
+ Linecpy,
}
impl Opcode {
@@ -830,6 +833,7 @@ pub enum Operand {
ImmU32 { imm: u32 },
+ // TODO: offset should be signed, check if test cases exercise this..
RegOffsetCirc { base: u8, offset: u32, mu: u8 },
RegCirc { base: u8, mu: u8 },
@@ -1897,7 +1901,6 @@ fn decode_instruction<
let op = (inst >> 21) & 0b1111;
let sssss = reg_b16(inst);
- eprintln!("op is {:04b}", op);
if op >= 0b1000 {
// predicated jumpr
opcode_check!(op == 0b0100 || op == 0b0101 || op == 0b0110 || op == 0b1010 || op == 0b1011);
@@ -2547,91 +2550,188 @@ fn decode_instruction<
}
0b1001 => {
if (inst >> 27) & 1 != 0 {
- todo!("other mem op");
- }
+ let opc_high = (inst >> 24) & 0b111;
- let ddddd = reg_b0(inst);
- let sssss = reg_b16(inst);
- let op = (inst >> 21) & 0b1111;
+ let op = (inst >> 21) & 0b111;
+
+ let ddddd = reg_b0(inst);
+ let xxxxx = reg_b16(inst);
+
+ match opc_high {
+ 0b000 => {
+ use Opcode::*;
+ static OPCODES: [Option<(Opcode, bool, u8)>; 8] = [
+ None, Some((Membh, false, 0x01)), Some((MemhFifo, true, 0x01)), Some((Memubh, false, 0x01)),
+ Some((MembFifo, true, 0x00)), Some((Memubh, true, 0x02)), None, Some((Membh, true, 0x02)),
+ ];
- if op == 0b0000 {
- // some special handling here
- let op_high = (inst >> 25) & 0b11;
- match op_high {
- 0b00 => {
- opcode_check!(inst & 0b10000_00000000 == 0);
+ let (op, wide, samt) = decode_opcode!(OPCODES[op as usize]);
+ let src_offset = (inst >> 9) & 1 == 0;
+ let iiii = (inst >> 5) & 0b1111;
+ let mu = ((inst >> 13) & 1) as u8;
- handler.on_source_decoded(Operand::gpr(sssss))?;
- handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
- handler.on_opcode_decoded(Opcode::DeallocFrame)?;
+
+ if src_offset {
+ let s4 = (iiii << 4) as i8 >> 4;
+ handler.on_source_decoded(Operand::RegOffsetCirc { base: xxxxx, offset: (s4 << samt) as u32, mu })?;
+ } else {
+ operand_check!(iiii & 0b0100 == 0);
+ handler.on_source_decoded(Operand::RegCirc { 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)?;
}
- 0b01 => {
- opcode_check!(inst & 0b100000_111_00000 == 0);
- let op_low = (inst >> 11) & 0b11;
- static OP: [Opcode; 4] = [
- Opcode::MemwLockedLoad, Opcode::MemwAq,
- Opcode::MemdLockedLoad, Opcode::MemdAq,
+ 0b001 => {
+ use Opcode::*;
+ static OPCODES: [Option<(Opcode, bool, u8)>; 8] = [
+ Some((Memb, false, 0x00)), Some((Memub, true, 0x00)), Some((Memh, false, 0x01)), Some((Memuh, true, 0x01)),
+ Some((Memw, false, 0x02)), None, Some((Memd, true, 0x03)), None,
];
- handler.on_source_decoded(Operand::gpr(sssss))?;
- if op_low > 0b01 {
+
+ if op == 0b111 {
+ let sssss = reg_b8(inst);
+ let ttttt = reg_b16(inst);
+ // a couple extra instructions are stashed in here...
+ // 1001 | 1001111 | ttttt | PP | 0 sssss OPC | ddddd |
+ handler.on_source_decoded(Operand::gpr(sssss))?;
+ handler.on_source_decoded(Operand::gprpair(ttttt)?)?;
handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
+
+ opcode_check!(inst & 0b0010_0000_0000_0000 == 0);
+ let opc = (inst >> 5) & 0b111;
+ let op = match opc {
+ 0b000 => Opcode::Pmemcpy,
+ 0b001 => Opcode::Linecpy,
+ _ => {
+ return Err(DecodeError::InvalidOpcode);
+ }
+ };
+ handler.on_opcode_decoded(op)?;
+ return Ok(());
+ }
+
+ let (op, wide, samt) = decode_opcode!(OPCODES[op as usize]);
+ let src_offset = (inst >> 9) & 1 == 0;
+ let iiii = (inst >> 5) & 0b1111;
+ let mu = ((inst >> 13) & 1) as u8;
+
+
+ if src_offset {
+ let s4 = (iiii << 4) as i8 >> 4;
+ handler.on_source_decoded(Operand::RegOffsetCirc { base: xxxxx, offset: (s4 << samt) as u32, mu })?;
} else {
+ operand_check!(iiii & 0b0100 == 0);
+ handler.on_source_decoded(Operand::RegCirc { 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[op_low as usize])?;
+ handler.on_opcode_decoded(op)?;
+ }
+ 0b010 => {
}
- 0b10 => {
- let i11 = inst & 0b111111_11111;
- handler.on_source_decoded(Operand::RegOffset { base: sssss, offset: i11 << 3 })?;
- handler.on_opcode_decoded(Opcode::Dcfetch)?;
+ 0b011 => {
+ }
+ 0b100 => {
}
- _ => { /* 0b11 */
- opcode_check!(inst & 0b1_00000_00000 == 0);
+ 0b101 => {
+ }
+ 0b110 => {
+ }
+ _ => {
+ todo!("other mem op");
+ }
+ }
+ } else {
+ let ddddd = reg_b0(inst);
+ let sssss = reg_b16(inst);
+ let op = (inst >> 21) & 0b1111;
- handler.on_source_decoded(Operand::gpr(sssss))?;
- handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
- handler.on_opcode_decoded(Opcode::DeallocReturn)?;
-
- let hints = (inst >> 11) & 0b111;
- if hints == 0 {
- // no predication, not hint, just deallocreturn().
- } else if hints == 0b100 {
- // hint 100 is not valid (would be unpredicated negated
- // dealloc_return()?)
- return Err(DecodeError::InvalidOpcode);
- } else {
- let dotnew = (hints & 0b001) != 0;
- let negated = (hints & 0b100) != 0;
- let pred = (inst >> 8) & 0b11;
-
- handler.inst_predicated(pred as u8, negated, dotnew)?;
- if dotnew {
- let taken = hints & 0b010 != 0;
- handler.branch_hint(taken)?;
+ if op == 0b0000 {
+ // some special handling here
+ let op_high = (inst >> 25) & 0b11;
+ match op_high {
+ 0b00 => {
+ opcode_check!(inst & 0b10000_00000000 == 0);
+
+ handler.on_source_decoded(Operand::gpr(sssss))?;
+ handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
+ handler.on_opcode_decoded(Opcode::DeallocFrame)?;
+ }
+ 0b01 => {
+ opcode_check!(inst & 0b100000_111_00000 == 0);
+ let op_low = (inst >> 11) & 0b11;
+ static OP: [Opcode; 4] = [
+ Opcode::MemwLockedLoad, Opcode::MemwAq,
+ Opcode::MemdLockedLoad, Opcode::MemdAq,
+ ];
+ handler.on_source_decoded(Operand::gpr(sssss))?;
+ if op_low > 0b01 {
+ handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
+ } else {
+ handler.on_dest_decoded(Operand::gpr(ddddd))?;
+ }
+ handler.on_opcode_decoded(OP[op_low as usize])?;
+ }
+ 0b10 => {
+ let i11 = inst & 0b111111_11111;
+ handler.on_source_decoded(Operand::RegOffset { base: sssss, offset: i11 << 3 })?;
+ handler.on_opcode_decoded(Opcode::Dcfetch)?;
+ }
+ _ => { /* 0b11 */
+ opcode_check!(inst & 0b1_00000_00000 == 0);
+
+ handler.on_source_decoded(Operand::gpr(sssss))?;
+ handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
+ handler.on_opcode_decoded(Opcode::DeallocReturn)?;
+
+ let hints = (inst >> 11) & 0b111;
+ if hints == 0 {
+ // no predication, not hint, just deallocreturn().
+ } else if hints == 0b100 {
+ // hint 100 is not valid (would be unpredicated negated
+ // dealloc_return()?)
+ return Err(DecodeError::InvalidOpcode);
+ } else {
+ let dotnew = (hints & 0b001) != 0;
+ let negated = (hints & 0b100) != 0;
+ let pred = (inst >> 8) & 0b11;
+
+ handler.inst_predicated(pred as u8, negated, dotnew)?;
+ if dotnew {
+ let taken = hints & 0b010 != 0;
+ handler.branch_hint(taken)?;
+ }
}
}
}
- }
- } else {
- let i_lo = (inst >> 5) & 0b1_1111_1111;
- let i_hi = (inst >> 25) & 0b11;
- let i = i_lo | (i_hi << 9);
-
- use Opcode::*;
- static OPCODES: [Option<(Opcode, bool, u8)>; 16] = [
- None, Some((Membh, false, 0x01)), Some((MemhFifo, true, 0x01)), Some((Memubh, false, 0x01)),
- Some((MembFifo, true, 0x00)), Some((Memubh, true, 0x02)), None, Some((Membh, true, 0x02)),
- Some((Memb, false, 0x03)), Some((Memub, true, 0x03)), Some((Memh, false, 0x03)), Some((Memuh, true, 0x03)),
- Some((Memw, false, 0x03)), None, Some((Memd, true, 0x03)), None,
- ];
- let (op, wide, samt) = decode_opcode!(OPCODES[op as usize]);
- handler.on_source_decoded(Operand::RegOffset { base: sssss, offset: (i as u32) << samt })?;
- if !wide {
- handler.on_dest_decoded(Operand::gpr(ddddd))?;
} else {
- handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
+ let i_lo = (inst >> 5) & 0b1_1111_1111;
+ let i_hi = (inst >> 25) & 0b11;
+ let i = i_lo | (i_hi << 9);
+
+ use Opcode::*;
+ static OPCODES: [Option<(Opcode, bool, u8)>; 16] = [
+ None, Some((Membh, false, 0x01)), Some((MemhFifo, true, 0x01)), Some((Memubh, false, 0x01)),
+ Some((MembFifo, true, 0x00)), Some((Memubh, true, 0x02)), None, Some((Membh, true, 0x02)),
+ Some((Memb, false, 0x03)), Some((Memub, true, 0x03)), Some((Memh, false, 0x03)), Some((Memuh, true, 0x03)),
+ Some((Memw, false, 0x03)), None, Some((Memd, true, 0x03)), None,
+ ];
+ let (op, wide, samt) = decode_opcode!(OPCODES[op as usize]);
+ handler.on_source_decoded(Operand::RegOffset { base: sssss, offset: (i as u32) << samt })?;
+ if !wide {
+ handler.on_dest_decoded(Operand::gpr(ddddd))?;
+ } else {
+ handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
+ }
+ handler.on_opcode_decoded(op)?;
}
- handler.on_opcode_decoded(op)?;
}
}
0b1010 => {
@@ -2973,8 +3073,8 @@ fn decode_instruction<
handler.on_source_decoded(Operand::gpr(sssss))?;
handler.on_source_decoded(Operand::gpr(ttttt))?;
static OPC: [Option<Opcode>; 8] = [
- Some(Opcode::And), Some(Opcode::Or), Some(Opcode::Xor), Some(Opcode::And_nRR),
- Some(Opcode::Or_nRR), None, None, None,
+ Some(Opcode::And), Some(Opcode::Or), None, Some(Opcode::Xor),
+ Some(Opcode::And_nRR), Some(Opcode::Or_nRR), None, None,
];
handler.on_opcode_decoded(decode_opcode!(OPC[minbits as usize]))?;
},
@@ -2989,8 +3089,8 @@ fn decode_instruction<
// TODO: probably want the negated forms to be their own opcodes for
// everyone's ease of mind, but for now track them as a negated result...
static OPC: [Option<Opcode>; 8] = [
- Some(Opcode::CmpEq), Some(Opcode::CmpEq), None, None,
- Some(Opcode::CmpGt), Some(Opcode::CmpGt), Some(Opcode::CmpGtu), Some(Opcode::CmpGtu),
+ Some(Opcode::CmpEq), None, Some(Opcode::CmpGt), Some(Opcode::CmpGtu),
+ Some(Opcode::CmpEq), None, Some(Opcode::CmpGt), Some(Opcode::CmpGtu),
];
if op_low == 1 {
handler.negate_result()?;
@@ -2998,24 +3098,29 @@ fn decode_instruction<
handler.on_opcode_decoded(decode_opcode!(OPC[minbits as usize]))?;
}
0b011 => {
- if minbits < 0b100 {
- handler.on_source_decoded(Operand::gpr(sssss))?;
- handler.on_source_decoded(Operand::gpr(ttttt))?;
- } else {
+ if minbits >= 0b100 {
handler.on_opcode_decoded(Opcode::Combine)?;
}
handler.on_dest_decoded(Operand::gpr(ddddd))?;
match minbits {
0b000 => {
+ handler.on_source_decoded(Operand::gpr(sssss))?;
+ handler.on_source_decoded(Operand::gpr(ttttt))?;
handler.on_opcode_decoded(Opcode::Add)?;
},
0b001 => {
+ handler.on_source_decoded(Operand::gpr(ttttt))?;
+ handler.on_source_decoded(Operand::gpr(sssss))?;
handler.on_opcode_decoded(Opcode::Sub)?;
}
0b010 => {
+ handler.on_source_decoded(Operand::gpr(sssss))?;
+ handler.on_source_decoded(Operand::gpr(ttttt))?;
handler.on_opcode_decoded(Opcode::CmpEq)?;
}
0b011 => {
+ handler.on_source_decoded(Operand::gpr(sssss))?;
+ handler.on_source_decoded(Operand::gpr(ttttt))?;
handler.on_opcode_decoded(Opcode::CmpEq)?;
handler.negate_result()?;
}
@@ -3076,7 +3181,7 @@ fn decode_instruction<
handler.on_source_decoded(Operand::gpr(sssss))?;
}
if opc & 0b11 != 0 {
- // TODO: hint sat somehow
+ handler.saturate()?;
}
}
0b111 => {
@@ -3085,15 +3190,15 @@ fn decode_instruction<
if (inst >> 22) & 1 == 0 {
handler.on_opcode_decoded(Vavgh)?;
if (inst >> 21) & 1 == 1 {
- // TODO: hint sat somehow
+ handler.saturate()?;
}
handler.on_source_decoded(Operand::gpr(sssss))?;
handler.on_source_decoded(Operand::gpr(ttttt))?;
} else {
handler.on_opcode_decoded(Vnavgh)?;
- opcode_check!((inst >> 21) & 1 == 0);
- handler.on_source_decoded(Operand::gpr(ttttt))?;
+ opcode_check!((inst >> 21) & 1 == 1);
handler.on_source_decoded(Operand::gpr(sssss))?;
+ handler.on_source_decoded(Operand::gpr(ttttt))?;
}
}
_ => {
diff --git a/tests/from_brain.rs b/tests/from_brain.rs
index 194ff8a..c3d6bce 100644
--- a/tests/from_brain.rs
+++ b/tests/from_brain.rs
@@ -441,6 +441,38 @@ fn inst_1001() {
test_invalid(&0b1001_0001101_00010_11_0_00100_000_00011u32.to_le_bytes(), DecodeError::InvalidOpcode);
test_display(&0b1001_0111110_00010_11_1001_00_000_10000u32.to_le_bytes(), "{ R17:16 = memd(R2+#14592) }");
test_invalid(&0b1001_0001111_00010_11_0_00100_000_00011u32.to_le_bytes(), DecodeError::InvalidOpcode);
+
+ // TODO: exercise these
+ test_display(&0b1001_1000001_00010_11_1000_00111_10000u32.to_le_bytes(), "{ R16 = membh(R2++#0xe:circ(M1)) }");
+ test_display(&0b1001_1000010_00010_11_1000_00111_10000u32.to_le_bytes(), "{ R17:16 = memh_fifo(R2++#0xe:circ(M1)) }");
+ test_display(&0b1001_1000011_00010_11_1000_00111_10000u32.to_le_bytes(), "{ R16 = memubh(R2++#0xe:circ(M1)) }");
+ test_display(&0b1001_1000100_00010_11_1000_00111_10000u32.to_le_bytes(), "{ R17:16 = memb_fifo(R2++#0x7:circ(M1)) }");
+ test_display(&0b1001_1000101_00010_11_1000_00111_10000u32.to_le_bytes(), "{ R17:16 = memubh(R2++#0x1c:circ(M1)) }");
+ test_display(&0b1001_1000111_00010_11_1000_00111_10000u32.to_le_bytes(), "{ R17:16 = membh(R2++#0x1c:circ(M1)) }");
+
+ test_display(&0b1001_1000001_00010_11_1000_10000_10000u32.to_le_bytes(), "{ R16 = membh(R2++I:circ(M1)) }");
+ test_display(&0b1001_1000010_00010_11_1000_10000_10000u32.to_le_bytes(), "{ R17:16 = memh_fifo(R2++I:circ(M1)) }");
+ test_display(&0b1001_1000011_00010_11_1000_10000_10000u32.to_le_bytes(), "{ R16 = memubh(R2++I:circ(M1)) }");
+ test_display(&0b1001_1000100_00010_11_1000_10000_10000u32.to_le_bytes(), "{ R17:16 = memb_fifo(R2++I:circ(M1)) }");
+ test_display(&0b1001_1000101_00010_11_1000_10000_10000u32.to_le_bytes(), "{ R17:16 = memubh(R2++I:circ(M1)) }");
+ test_display(&0b1001_1000111_00010_11_1000_10000_10000u32.to_le_bytes(), "{ R17:16 = membh(R2++I:circ(M1)) }");
+
+ test_display(&0b1001_1001000_00010_11_1000_00111_10000u32.to_le_bytes(), "{ R16 = memb(R2++#0x7:circ(M1)) }");
+ test_display(&0b1001_1001001_00010_11_1000_00111_10000u32.to_le_bytes(), "{ R17:16 = memub(R2++#0x7:circ(M1)) }");
+ test_display(&0b1001_1001010_00010_11_1000_00111_10000u32.to_le_bytes(), "{ R16 = memh(R2++#0xe:circ(M1)) }");
+ test_display(&0b1001_1001011_00010_11_1000_00111_10000u32.to_le_bytes(), "{ R17:16 = memuh(R2++#0xe:circ(M1)) }");
+ test_display(&0b1001_1001100_00010_11_1000_00111_10000u32.to_le_bytes(), "{ R16 = memw(R2++#0x1c:circ(M1)) }");
+ test_display(&0b1001_1001110_00010_11_1000_00111_10000u32.to_le_bytes(), "{ R17:16 = memd(R2++#0x38:circ(M1)) }");
+
+ test_display(&0b1001_1001000_00010_11_1000_10000_10000u32.to_le_bytes(), "{ R16 = memb(R2++I:circ(M1)) }");
+ test_display(&0b1001_1001001_00010_11_1000_10000_10000u32.to_le_bytes(), "{ R17:16 = memub(R2++I:circ(M1)) }");
+ test_display(&0b1001_1001010_00010_11_1000_10000_10000u32.to_le_bytes(), "{ R16 = memh(R2++I:circ(M1)) }");
+ test_display(&0b1001_1001011_00010_11_1000_10000_10000u32.to_le_bytes(), "{ R17:16 = memuh(R2++I:circ(M1)) }");
+ test_display(&0b1001_1001100_00010_11_1000_10000_10000u32.to_le_bytes(), "{ R16 = memw(R2++I:circ(M1)) }");
+ test_display(&0b1001_1001110_00010_11_1000_10000_10000u32.to_le_bytes(), "{ R17:16 = memd(R2++I:circ(M1)) }");
+ test_display(&0b1001_1001111_00010_11_0010_00000_10000u32.to_le_bytes(), "{ R17:16 = pmemcpy(R8, R3:2) }");
+ test_display(&0b1001_1001111_00010_11_0010_00001_10000u32.to_le_bytes(), "{ R17:16 = linecpy(R8, R3:2) }");
+ test_invalid(&0b1001_1001111_00010_11_0010_00010_10000u32.to_le_bytes(), DecodeError::InvalidOpcode);
}
#[test]
@@ -676,6 +708,45 @@ fn inst_1100() {
#[test]
fn inst_1111() {
+ test_display(&0b1111_0001000_00100_11_0_00011_000_00110u32.to_le_bytes(), "{ R6 = and(R4, R3) }");
+ test_display(&0b1111_0001001_00100_11_0_00011_000_00110u32.to_le_bytes(), "{ R6 = or(R4, R3) }");
+ test_display(&0b1111_0001011_00100_11_0_00011_000_00110u32.to_le_bytes(), "{ R6 = xor(R4, R3) }");
+ test_display(&0b1111_0001100_00100_11_0_00011_000_00110u32.to_le_bytes(), "{ R6 = and(R3, ~R4) }");
+ test_display(&0b1111_0001101_00100_11_0_00011_000_00110u32.to_le_bytes(), "{ R6 = or(R3, ~R4) }");
+
+ test_display(&0b1111_0010000_00100_11_0_00011_000_00010u32.to_le_bytes(), "{ P2 = cmp.eq(R4, R3) }");
+ test_display(&0b1111_0010000_00100_11_0_00011_000_10010u32.to_le_bytes(), "{ P2 = !cmp.eq(R4, R3) }");
+ test_display(&0b1111_0010010_00100_11_0_00011_000_00010u32.to_le_bytes(), "{ P2 = cmp.gt(R4, R3) }");
+ test_display(&0b1111_0010010_00100_11_0_00011_000_10010u32.to_le_bytes(), "{ P2 = !cmp.gt(R4, R3) }");
+ test_display(&0b1111_0010011_00100_11_0_00011_000_00010u32.to_le_bytes(), "{ P2 = cmp.gtu(R4, R3) }");
+ test_display(&0b1111_0010011_00100_11_0_00011_000_10010u32.to_le_bytes(), "{ P2 = !cmp.gtu(R4, R3) }");
+
+ test_display(&0b1111_0011000_00100_11_0_00011_000_00010u32.to_le_bytes(), "{ R2 = add(R4, R3) }");
+ test_display(&0b1111_0011001_00100_11_0_00011_000_00010u32.to_le_bytes(), "{ R2 = sub(R3, R4) }");
+ test_display(&0b1111_0011010_00100_11_0_00011_000_00010u32.to_le_bytes(), "{ R2 = cmp.eq(R4, R3) }");
+ test_display(&0b1111_0011011_00100_11_0_00011_000_00010u32.to_le_bytes(), "{ R2 = !cmp.eq(R4, R3) }");
+
+ test_display(&0b1111_0011100_00100_11_0_00011_000_00010u32.to_le_bytes(), "{ R2 = combine(R3.H, R4.H) }");
+ test_display(&0b1111_0011101_00100_11_0_00011_000_00010u32.to_le_bytes(), "{ R2 = combine(R3.H, R4.L) }");
+ test_display(&0b1111_0011110_00100_11_0_00011_000_00010u32.to_le_bytes(), "{ R2 = combine(R3.L, R4.H) }");
+ test_display(&0b1111_0011111_00100_11_0_00011_000_00010u32.to_le_bytes(), "{ R2 = combine(R3.L, R4.L) }");
+
+ test_display(&0b1111_0100000_00100_11_0_00011_001_00010u32.to_le_bytes(), "{ R2 = mux(P1, R4, R3) }");
+ test_display(&0b1111_0101000_00100_11_0_00011_000_00010u32.to_le_bytes(), "{ R3:2 = combine(R4, R3) }");
+ test_display(&0b1111_0101100_00100_11_0_00011_000_00010u32.to_le_bytes(), "{ R3:2 = packhl(R4, R3) }");
+ test_display(&0b1111_0110000_00100_11_0_00011_000_00010u32.to_le_bytes(), "{ R2 = vaddh(R4, R3) }");
+ test_display(&0b1111_0110001_00100_11_0_00011_000_00010u32.to_le_bytes(), "{ R2 = vaddh(R4, R3):sat }");
+ test_display(&0b1111_0110010_00100_11_0_00011_000_00010u32.to_le_bytes(), "{ R2 = add(R4, R3):sat }");
+ test_display(&0b1111_0110011_00100_11_0_00011_000_00010u32.to_le_bytes(), "{ R2 = vadduh(R4, R3):sat }");
+ test_display(&0b1111_0110100_00100_11_0_00011_000_00010u32.to_le_bytes(), "{ R2 = vsubh(R3, R4) }");
+ test_display(&0b1111_0110101_00100_11_0_00011_000_00010u32.to_le_bytes(), "{ R2 = vsubh(R3, R4):sat }");
+ test_display(&0b1111_0110110_00100_11_0_00011_000_00010u32.to_le_bytes(), "{ R2 = sub(R3, R4):sat }");
+ test_display(&0b1111_0110111_00100_11_0_00011_000_00010u32.to_le_bytes(), "{ R2 = vsubuh(R3, R4):sat }");
+ test_display(&0b1111_0111100_00100_11_0_00011_000_00010u32.to_le_bytes(), "{ R2 = vavgh(R4, R3) }");
+ test_display(&0b1111_0111101_00100_11_0_00011_000_00010u32.to_le_bytes(), "{ R2 = vavgh(R4, R3):sat }");
+ test_invalid(&0b1111_0111110_00100_11_0_00011_000_00010u32.to_le_bytes(), DecodeError::InvalidOpcode);
+ test_display(&0b1111_0111111_00100_11_0_00011_000_00010u32.to_le_bytes(), "{ R2 = vnavgh(R4, R3) }");
+
test_display(&0b1111_1001000_00100_11_1_00011_001_00110u32.to_le_bytes(), "{ if (P1.new) R6 = and(R4, R3) }");
test_display(&0b1111_1001001_00100_11_1_00011_001_00110u32.to_le_bytes(), "{ if (P1.new) R6 = or(R4, R3) }");
test_invalid(&0b1111_1001010_00100_11_1_00011_001_00110u32.to_le_bytes(), DecodeError::InvalidOpcode);