From 3dca3441fd3a21290eb2920b3d8c03cb9ea241f8 Mon Sep 17 00:00:00 2001 From: iximeow Date: Mon, 23 Dec 2024 01:16:44 -0800 Subject: checkpoint --- notes/todo | 344 ++++++++++++++++++++++++------------------------ src/display.rs | 55 ++++++-- src/lib.rs | 92 ++++++++++--- tests/from_brain.rs | 373 ++++++++++++++++++++++++++++++++++++++++++---------- 4 files changed, 591 insertions(+), 273 deletions(-) diff --git a/notes/todo b/notes/todo index 0ca6245..21bb583 100644 --- a/notes/todo +++ b/notes/todo @@ -227,7 +227,7 @@ 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) |0 0 1 1|1 1 1 1 - 1 0|s s s s s| P P |0 i i i i i i 0 1|l l l l l| memw(Rs+#u6:0)-=Rt - MEMOP/slot 0 |0 0 1 1|1 1 1 1 - 1 0|s s s s s| P P |0 i i i i i i 1 0|l l l l l| memw(Rs+#u6:0)=clrbit(#U5) - MEMOP/slot 0 |0 0 1 1|1 1 1 1 - 1 0|s s s s s| P P |0 i i i i i i 1 1|l l l l l| memw(Rs+#u6:0)=setbit(#U5) - MEMOP/slot 0 -|0 1 0 0|0 0 0 0 0 0 0|s s s s s| P P |i t t t t t i i i|i i 0 v v| if (Pv) memb(Rs+#u6:0)=Rt - ST/slot 0,1 +test |0 1 0 0|0 0 0 0 0 0 0|s s s s s| P P |i t t t t t i i i|i i 0 v v| if (Pv) memb(Rs+#u6:0)=Rt - ST/slot 0,1 |0 1 0 0|0 0 0 0 0 1 0|s s s s s| P P |i t t t t t i i i|i i 0 v v| if (Pv) memh(Rs+#u6:1)=Rt - ST/slot 0,1 |0 1 0 0|0 0 0 0 0 1 1|s s s s s| P P |i t t t t t i i i|i i 0 v v| if (Pv) memh(Rs+#u6:1)=Rt.H - ST/slot 0,1 |0 1 0 0|0 0 0 0 1 0 0|s s s s s| P P |i t t t t t i i i|i i 0 v v| if (Pv) memw(Rs+#u6:2)=Rt - ST/slot 0,1 @@ -616,31 +616,29 @@ 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 0|1 1 1 0|1 0 -|s s s s s| P P |0 i i i i i|0 1 0|x x x x x| Rx^=asl(Rs,#u5) - XTYPE PERM/slot 2,3 |1 0 0 0|1 1 1 0|1 0 -|s s s s s| P P |0 i i i i i|0 1 1|x x x x x| Rx^=rol(Rs,#u5) - XTYPE PERM/slot 2,3 -+|1 0 0 1|0 0 0 0 0 0 0|s s s s s| P P |0 - - - - - - - -|d d d d d| Rdd=deallocframe(Rs):raw - LD/slot 0,1 -+|1 0 0 1|0 0 1 0 0 0 0|s s s s s| P P |0 0 0 - - - 0 0 0|d d d d d| Rd=memw_locked(Rs) - SYSTEM/slot 0 -+|1 0 0 1|0 0 1 0 0 0 0|s s s s s| P P |0 0 1 - - - 0 0 0|d d d d d| Rd=memw_aq(Rs) - LD/slot 0 -+|1 0 0 1|0 0 1 0 0 0 0|s s s s s| P P |0 1 0 - - - 0 0 0|d d d d d| Rdd=memd_locked(Rs) - SYSTEM/slot 0 -+|1 0 0 1|0 0 1 0 0 0 0|s s s s s| P P |0 1 1 - - - 0 0 0|d d d d d| Rdd=memd_aq(Rs) - LD/slot 0 -+|1 0 0 1|0 1 0 0 0 0 0|s s s s s| P P |0 - - i i i i i i|i i i i i| dcfetch(Rs+#u11:3) - SYSTEM/slot 0 -+|1 0 0 1|0 1 1 0 0 0 0|s s s s s| P P |0 0 0 0 - - - - -|d d d d d| Rdd=dealloc_return(Rs):raw - LD/slot 0 -+|1 0 0 1|0 1 1 0 0 0 0|s s s s s| P P |0 0 1 0 v v - - -|d d d d d| if (Pv.new) Rdd=dealloc_return(Rs):nt:raw - LD/slot 0 -+|1 0 0 1|0 1 1 0 0 0 0|s s s s s| P P |0 1 0 0 v v - - -|d d d d d| if (Pv) Rdd=dealloc_return(Rs):raw - LD/slot 0 -+|1 0 0 1|0 1 1 0 0 0 0|s s s s s| P P |0 1 1 0 v v - - -|d d d d d| if (Pv.new) Rdd=dealloc_return(Rs):t:raw - LD/slot 0 -+|1 0 0 1|0 1 1 0 0 0 0|s s s s s| P P |1 0 1 0 v v - - -|d d d d d| if (!Pv.new) Rdd=dealloc_return(Rs):nt:raw - LD/slot 0 -+|1 0 0 1|0 1 1 0 0 0 0|s s s s s| P P |1 1 0 0 v v - - -|d d d d d| if (!Pv) Rdd=dealloc_return(Rs):raw - LD/slot 0 -+|1 0 0 1|0 1 1 0 0 0 0|s s s s s| P P |1 1 1 0 v v - - -|d d d d d| if (!Pv.new) Rdd=dealloc_return(Rs):t:raw - LD/slot 0 -+|1 0 0 1|0 i i 0 0 0 1|s s s s s| P P |i i i i i i i i i|d d d d d| Rd=membh(Rs+#s11:1) - LD/slot 0,1 -+|1 0 0 1|0 i i 0 0 1 0|s s s s s| P P |i i i i i i i i i|y y y y y| Ryy=memh_fifo(Rs+#s11:1) - LD/slot 0,1 -+|1 0 0 1|0 i i 0 0 1 1|s s s s s| P P |i i i i i i i i i|d d d d d| Rd=memubh(Rs+#s11:1) - LD/slot 0,1 -+|1 0 0 1|0 i i 0 1 0 0|s s s s s| P P |i i i i i i i i i|y y y y y| Ryy=memb_fifo(Rs+#s11:0) - LD/slot 0,1 -+|1 0 0 1|0 i i 0 1 0 1|s s s s s| P P |i i i i i i i i i|d d d d d| Rdd=memubh(Rs+#s11:2) - LD/slot 0,1 -+|1 0 0 1|0 i i 0 1 1 1|s s s s s| P P |i i i i i i i i i|d d d d d| Rdd=membh(Rs+#s11:2) - LD/slot 0,1 -+|1 0 0 1|0 i i 1 0 0 0|s s s s s| P P |i i i i i i i i i|d d d d d| Rd=memb(Rs+#s11:3) - LD/slot 0,1 -+|1 0 0 1|0 i i 1 0 0 1|s s s s s| P P |i i i i i i i i i|d d d d d| Rdd=memub(Rs+#s11:3) - LD/slot 0,1 -+|1 0 0 1|0 i i 1 0 1 0|s s s s s| P P |i i i i i i i i i|d d d d d| Rd=memh(Rs+#s11:3) - LD/slot 0,1 -+|1 0 0 1|0 i i 1 0 1 1|s s s s s| P P |i i i i i i i i i|d d d d d| Rdd=memuh(Rs+#s11:3) - LD/slot 0,1 -+|1 0 0 1|0 i i 1 1 0 0|s s s s s| P P |i i i i i i i i i|d d d d d| Rd=memw(Rs+#s11:3) - LD/slot 0,1 -+|1 0 0 1|0 i i 1 1 1 0|s s s s s| P P |i i i i i i i i i|d d d d d| Rdd=memd(Rs+#s11:3) - LD/slot 0,1 + + + + + + + + + + + + + + + + + + + + + + + |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 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 - - 0 i i i i|y y y y y| Ryy=memh_fifo(Rx++#s4:0:circ(Mu)) - LD/slot 0,1 @@ -775,153 +773,153 @@ 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 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 |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 -test |1 0 1 0|0 0 0 0 0 0 0|s s s s s| P P |- - - - - - - - -|- - - - -| dccleana(Rs) - SYSTEM/slot 0 -test |1 0 1 0|0 0 0 0 0 0 1|s s s s s| P P |- - - - - - - - -|- - - - -| dcinva(Rs) - SYSTEM/slot 0 -test |1 0 1 0|0 0 0 0 0 1 0|s s s s s| P P |- - - - - - - - -|- - - - -| dccleaninva(Rs) - SYSTEM/slot 0 -test |1 0 1 0|0 0 0 0 0 1 1|s s s s s| P P |0 t t t t t - - 0|0 1 1 d d| release(Rs):at - ST/slot 0 -test |1 0 1 0|0 0 0 0 0 1 1|s s s s s| P P |0 t t t t t - - 1|0 1 1 d d| release(Rs):st - ST/slot 0 -test |1 0 1 0|0 0 0 0 1 0 0|x x x x x| P P |0 0 0 i i i i i i|i i i i i| allocframe(Rx,#u11:3):raw - ST/slot 0,1 -+|1 0 1 0|0 0 0 0 1 0 1|s s s s s| P P |- t t t t t - - -|- 0 0 d d| memw_locked(Rs,Pd)=Rt - SYSTEM/slot 0 -test |1 0 1 0|0 0 0 0 1 0 1|s s s s s| P P |- t t t t t - - 0|0 1 0 d d| memw_rl(Rs):at=Rt - ST/slot 0 -test |1 0 1 0|0 0 0 0 1 0 1|s s s s s| P P |- t t t t t - - 1|0 1 0 d d| memw_rl(Rs):st=Rt - ST/slot 0 -test |1 0 1 0|0 0 0 0 1 1 0|s s s s s| P P |0 - - - - - - - -|- - - - -| dczeroa(Rs) - SYSTEM/slot 0 -+|1 0 1 0|0 0 0 0 1 1 1|s s s s s| P P |0 t t t t t - - -|- 0 0 d d| memd_locked(Rs,Pd)=Rtt - SYSTEM/slot 0 -test |1 0 1 0|0 0 0 0 1 1 1|s s s s s| P P |0 t t t t t - - 0|0 1 0 d d| memd_rl(Rs):at=Rtt - ST/slot 0 -test |1 0 1 0|0 0 0 0 1 1 1|s s s s s| P P |0 t t t t t - - 1|0 1 0 d d| memd_rl(Rs):st=Rtt - ST/slot 0 -test |1 0 1 0|0 1 1 0 0 0 0|s s s s s| P P |- t t t t t 0 0 0|- - - - -| l2fetch(Rs,Rt) - SYSTEM/slot 0 -test |1 0 1 0|0 1 1 0 1 0 0|s s s s s| P P |- t t t t t - - -|- - - - -| l2fetch(Rs,Rtt) - SYSTEM/slot 0 -test |1 0 1 0|0 i i 1 0 0 0|s s s s s| P P |i t t t t t i i i|i i i i i| memb(Rs+#s11:0)=Rt - ST/slot 0,1 -test |1 0 1 0|0 i i 1 0 1 0|s s s s s| P P |i t t t t t i i i|i i i i i| memh(Rs+#s11:1)=Rt - ST/slot 0,1 -test |1 0 1 0|0 i i 1 0 1 1|s s s s s| P P |i t t t t t i i i|i i i i i| memh(Rs+#s11:1)=Rt.H - ST/slot 0,1 -test |1 0 1 0|0 i i 1 1 0 0|s s s s s| P P |i t t t t t i i i|i i i i i| memw(Rs+#s11:2)=Rt - ST/slot 0,1 -test |1 0 1 0|0 i i 1 1 0 1|s s s s s| P P |i 0 0 t t t i i i|i i i i i| memb(Rs+#s11:0)=Nt.new - NV ST/slot 0 -test |1 0 1 0|0 i i 1 1 0 1|s s s s s| P P |i 0 1 t t t i i i|i i i i i| memh(Rs+#s11:1)=Nt.new - NV ST/slot 0 -test |1 0 1 0|0 i i 1 1 0 1|s s s s s| P P |i 1 0 t t t i i i|i i i i i| memw(Rs+#s11:2)=Nt.new - NV ST/slot 0 -test |1 0 1 0|0 i i 1 1 1 0|s s s s s| P P |i t t t t t i i i|i i i i i| memd(Rs+#s11:3)=Rtt - ST/slot 0,1 -test |1 0 1 0|1 0 0 0 0 0 0|- - - - -| P P |- - - - - - 0 0 0|- - - - -| barrier - SYSTEM/slot 0 -test |1 0 1 0|1 0 0 0 0 0 0|- - - - -| P P |- - - - - 0 1 1 1|d d d d d| Rd=dmsyncht - SYSTEM/slot 0 -test |1 0 1 0|1 0 0 0 0 1 0|- - - - -| P P |- - - - - - - - -|- - - - -| syncht - SYSTEM/slot 0 -test |1 0 1 0|1 0 0 1 0 0 0|x x x x x| P P |u t t t t t 0 - -|- - - 1 -| memb(Rx++I:circ(Mu))=Rt - ST/slot 0,1 -test |1 0 1 0|1 0 0 1 0 1 0|x x x x x| P P |u t t t t t 0 - -|- - - 1 -| memh(Rx++I:circ(Mu))=Rt - ST/slot 0,1 -test |1 0 1 0|1 0 0 1 0 1 1|x x x x x| P P |u t t t t t 0 - -|- - - 1 -| memh(Rx++I:circ(Mu))=Rt.H - ST/slot 0,1 -test |1 0 1 0|1 0 0 1 1 0 0|x x x x x| P P |u t t t t t 0 - -|- - - 1 -| memw(Rx++I:circ(Mu))=Rt - ST/slot 0,1 -test |1 0 1 0|1 0 0 1 1 0 1|x x x x x| P P |u 0 0 t t t 0 - -|- - - 1 -| memb(Rx++I:circ(Mu))=Nt.new - NV ST/slot 0 -test |1 0 1 0|1 0 0 1 1 0 1|x x x x x| P P |u 0 1 t t t 0 - -|- - - 1 -| memh(Rx++I:circ(Mu))=Nt.new - NV ST/slot 0 -test |1 0 1 0|1 0 0 1 1 0 1|x x x x x| P P |u 1 0 t t t 0 - -|- - - 1 -| memw(Rx++I:circ(Mu))=Nt.new - NV ST/slot 0 -test |1 0 1 0|1 0 0 1 1 1 0|x x x x x| P P |u t t t t t 0 - -|- - - 1 -| memd(Rx++I:circ(Mu))=Rtt - ST/slot 0,1 -test |1 0 1 0|1 0 0 1 0 0 0|x x x x x| P P |u t t t t t 0 i i|i i - 0 -| memb(Rx++#s4:0:circ(Mu))=Rt - ST/slot 0,1 -test |1 0 1 0|1 0 0 1 0 1 0|x x x x x| P P |u t t t t t 0 i i|i i - 0 -| memh(Rx++#s4:1:circ(Mu))=Rt - ST/slot 0,1 -test |1 0 1 0|1 0 0 1 0 1 1|x x x x x| P P |u t t t t t 0 i i|i i - 0 -| memh(Rx++#s4:1:circ(Mu))=Rt.H - ST/slot 0,1 -test |1 0 1 0|1 0 0 1 1 0 0|x x x x x| P P |u t t t t t 0 i i|i i - 0 -| memw(Rx++#s4:2:circ(Mu))=Rt - ST/slot 0,1 -test |1 0 1 0|1 0 0 1 1 0 1|x x x x x| P P |u 0 0 t t t 0 i i|i i - 0 -| memb(Rx++#s4:0:circ(Mu))=Nt.new - NV ST/slot 0 -test |1 0 1 0|1 0 0 1 1 0 1|x x x x x| P P |u 0 1 t t t 0 i i|i i - 0 -| memh(Rx++#s4:1:circ(Mu))=Nt.new - NV ST/slot 0 -test |1 0 1 0|1 0 0 1 1 0 1|x x x x x| P P |u 1 0 t t t 0 i i|i i - 0 -| memw(Rx++#s4:2:circ(Mu))=Nt.new - NV ST/slot 0 -test |1 0 1 0|1 0 0 1 1 1 0|x x x x x| P P |u t t t t t 0 i i|i i - 0 -| memd(Rx++#s4:3:circ(Mu))=Rtt - ST/slot 0,1 -test |1 0 1 0|1 0 1 1 0 0 0|x x x x x| P P |0 t t t t t 0 i i|i i - 0 -| memb(Rx++#s4:0)=Rt - ST/slot 0,1 -test |1 0 1 0|1 0 1 1 0 1 0|x x x x x| P P |0 t t t t t 0 i i|i i - 0 -| memh(Rx++#s4:1)=Rt - ST/slot 0,1 -test |1 0 1 0|1 0 1 1 0 1 1|x x x x x| P P |0 t t t t t 0 i i|i i - 0 -| memh(Rx++#s4:1)=Rt.H - ST/slot 0,1 -test |1 0 1 0|1 0 1 1 1 0 0|x x x x x| P P |0 t t t t t 0 i i|i i - 0 -| memw(Rx++#s4:2)=Rt - ST/slot 0,1 -test |1 0 1 0|1 0 1 1 1 0 1|x x x x x| P P |0 0 0 t t t 0 i i|i i - 0 -| memb(Rx++#s4:0)=Nt.new - NV ST/slot 0 -test |1 0 1 0|1 0 1 1 1 0 1|x x x x x| P P |0 0 1 t t t 0 i i|i i - 0 -| memh(Rx++#s4:1)=Nt.new - NV ST/slot 0 -test |1 0 1 0|1 0 1 1 1 0 1|x x x x x| P P |0 1 0 t t t 0 i i|i i - 0 -| memw(Rx++#s4:2)=Nt.new - NV ST/slot 0 -test |1 0 1 0|1 0 1 1 1 1 0|x x x x x| P P |0 t t t t t 0 i i|i i - 0 -| memd(Rx++#s4:3)=Rtt - ST/slot 0,1 -test |1 0 1 0|1 0 1 1 0 0 0|e e e e e| P P |0 t t t t t 1 - l|l l l l l| memb(Re=#U6)=Rt - ST/slot 0,1 -test |1 0 1 0|1 0 1 1 0 1 0|e e e e e| P P |0 t t t t t 1 - l|l l l l l| memh(Re=#U6)=Rt - ST/slot 0,1 -test |1 0 1 0|1 0 1 1 0 1 1|e e e e e| P P |0 t t t t t 1 - l|l l l l l| memh(Re=#U6)=Rt.H - ST/slot 0,1 -test |1 0 1 0|1 0 1 1 1 0 0|e e e e e| P P |0 t t t t t 1 - l|l l l l l| memw(Re=#U6)=Rt - ST/slot 0,1 -test |1 0 1 0|1 0 1 1 1 0 1|e e e e e| P P |0 0 0 t t t 1 - l|l l l l l| memb(Re=#U6)=Nt.new - NV ST/slot 0 -test |1 0 1 0|1 0 1 1 1 0 1|e e e e e| P P |0 0 1 t t t 1 - l|l l l l l| memh(Re=#U6)=Nt.new - NV ST/slot 0 -test |1 0 1 0|1 0 1 1 1 0 1|e e e e e| P P |0 1 0 t t t 1 - l|l l l l l| memw(Re=#U6)=Nt.new - NV ST/slot 0 -test |1 0 1 0|1 0 1 1 1 1 0|e e e e e| P P |0 t t t t t 1 - l|l l l l l| memd(Re=#U6)=Rtt - ST/slot 0,1 -test |1 0 1 0|1 0 1 1 0 0 0|x x x x x| P P |1 t t t t t 0 i i|i i 0 v v| if (Pv) memb(Rx++#s4:0)=Rt - ST/slot 0,1 -test |1 0 1 0|1 0 1 1 0 0 0|x x x x x| P P |1 t t t t t 0 i i|i i 1 v v| if (!Pv) memb(Rx++#s4:0)=Rt - ST/slot 0,1 -test |1 0 1 0|1 0 1 1 0 1 0|x x x x x| P P |1 t t t t t 0 i i|i i 0 v v| if (Pv) memh(Rx++#s4:1)=Rt - ST/slot 0,1 -test |1 0 1 0|1 0 1 1 0 1 0|x x x x x| P P |1 t t t t t 0 i i|i i 1 v v| if (!Pv) memh(Rx++#s4:1)=Rt - ST/slot 0,1 -test |1 0 1 0|1 0 1 1 0 1 1|x x x x x| P P |1 t t t t t 0 i i|i i 0 v v| if (Pv) memh(Rx++#s4:1)=Rt.H - ST/slot 0,1 -test |1 0 1 0|1 0 1 1 0 1 1|x x x x x| P P |1 t t t t t 0 i i|i i 1 v v| if (!Pv) memh(Rx++#s4:1)=Rt.H - ST/slot 0,1 -test |1 0 1 0|1 0 1 1 1 0 0|x x x x x| P P |1 t t t t t 0 i i|i i 0 v v| if (Pv) memw(Rx++#s4:2)=Rt - ST/slot 0,1 -test |1 0 1 0|1 0 1 1 1 0 0|x x x x x| P P |1 t t t t t 0 i i|i i 1 v v| if (!Pv) memw(Rx++#s4:2)=Rt - ST/slot 0,1 -test |1 0 1 0|1 0 1 1 0 0 0|x x x x x| P P |1 t t t t t 1 i i|i i 0 v v| if (Pv.new) memb(Rx++#s4:0)=Rt - ST/slot 0,1 -test |1 0 1 0|1 0 1 1 0 0 0|x x x x x| P P |1 t t t t t 1 i i|i i 1 v v| if (!Pv.new) memb(Rx++#s4:0)=Rt - ST/slot 0,1 -test |1 0 1 0|1 0 1 1 0 1 0|x x x x x| P P |1 t t t t t 1 i i|i i 0 v v| if (Pv.new) memh(Rx++#s4:1)=Rt - ST/slot 0,1 -test |1 0 1 0|1 0 1 1 0 1 0|x x x x x| P P |1 t t t t t 1 i i|i i 1 v v| if (!Pv.new) memh(Rx++#s4:1)=Rt - ST/slot 0,1 -test |1 0 1 0|1 0 1 1 0 1 1|x x x x x| P P |1 t t t t t 1 i i|i i 0 v v| if (Pv.new) memh(Rx++#s4:1)=Rt.H - ST/slot 0,1 -test |1 0 1 0|1 0 1 1 0 1 1|x x x x x| P P |1 t t t t t 1 i i|i i 1 v v| if (!Pv.new) memh(Rx++#s4:1)=Rt.H - ST/slot 0,1 -test |1 0 1 0|1 0 1 1 1 0 0|x x x x x| P P |1 t t t t t 1 i i|i i 0 v v| if (Pv.new) memw(Rx++#s4:2)=Rt - ST/slot 0,1 -test |1 0 1 0|1 0 1 1 1 0 0|x x x x x| P P |1 t t t t t 1 i i|i i 1 v v| if (!Pv.new) memw(Rx++#s4:2)=Rt - ST/slot 0,1 -test |1 0 1 0|1 0 1 1 1 0 1|x x x x x| P P |1 0 0 t t t 0 i i|i i 0 v v| if (Pv) memb(Rx++#s4:0)=Nt.new - NV/slot 0 -test |1 0 1 0|1 0 1 1 1 0 1|x x x x x| P P |1 0 0 t t t 0 i i|i i 1 v v| if (!Pv) memb(Rx++#s4:0)=Nt.new - NV/slot 0 -test |1 0 1 0|1 0 1 1 1 0 1|x x x x x| P P |1 0 0 t t t 1 i i|i i 0 v v| if (Pv.new) memb(Rx++#s4:0)=Nt.new - NV/slot 0 -test |1 0 1 0|1 0 1 1 1 0 1|x x x x x| P P |1 0 0 t t t 1 i i|i i 1 v v| if (!Pv.new) memb(Rx++#s4:0)=Nt.new - NV/slot 0 -test |1 0 1 0|1 0 1 1 1 0 1|x x x x x| P P |1 0 1 t t t 0 i i|i i 0 v v| if (Pv) memh(Rx++#s4:1)=Nt.new - NV/slot 0 -test |1 0 1 0|1 0 1 1 1 0 1|x x x x x| P P |1 0 1 t t t 0 i i|i i 1 v v| if (!Pv) memh(Rx++#s4:1)=Nt.new - NV/slot 0 -test |1 0 1 0|1 0 1 1 1 0 1|x x x x x| P P |1 0 1 t t t 1 i i|i i 0 v v| if (Pv.new) memh(Rx++#s4:1)=Nt.new - NV/slot 0 -test |1 0 1 0|1 0 1 1 1 0 1|x x x x x| P P |1 0 1 t t t 1 i i|i i 1 v v| if (!Pv.new) memh(Rx++#s4:1)=Nt.new - NV/slot 0 -test |1 0 1 0|1 0 1 1 1 0 1|x x x x x| P P |1 1 0 t t t 0 i i|i i 0 v v| if (Pv) memw(Rx++#s4:2)=Nt.new - NV/slot 0 -test |1 0 1 0|1 0 1 1 1 0 1|x x x x x| P P |1 1 0 t t t 0 i i|i i 1 v v| if (!Pv) memw(Rx++#s4:2)=Nt.new - NV/slot 0 -test |1 0 1 0|1 0 1 1 1 0 1|x x x x x| P P |1 1 0 t t t 1 i i|i i 0 v v| if (Pv.new) memw(Rx++#s4:2)=Nt.new - NV/slot 0 -test |1 0 1 0|1 0 1 1 1 0 1|x x x x x| P P |1 1 0 t t t 1 i i|i i 1 v v| if (!Pv.new) memw(Rx++#s4:2)=Nt.new - NV/slot 0 -test |1 0 1 0|1 0 1 1 1 1 0|x x x x x| P P |1 t t t t t 0 i i|i i 0 v v| if (Pv) memd(Rx++#s4:2)=Rtt - ST/slot 0,1 -test |1 0 1 0|1 0 1 1 1 1 0|x x x x x| P P |1 t t t t t 0 i i|i i 1 v v| if (!Pv) memd(Rx++#s4:2)=Rtt - ST/slot 0,1 -test |1 0 1 0|1 0 1 1 1 1 0|x x x x x| P P |1 t t t t t 1 i i|i i 0 v v| if (Pv.new) memd(Rx++#s4:2)=Rtt - ST/slot 0,1 -test |1 0 1 0|1 0 1 1 1 1 0|x x x x x| P P |1 t t t t t 1 i i|i i 1 v v| if (!Pv.new) memd(Rx++#s4:2)=Rtt - ST/slot 0,1 -test |1 0 1 0|1 1 0 1 0 0 0|x x x x x| P P |u t t t t t 0 - -|- - - - -| memb(Rx++Mu)=Rt - ST/slot 0,1 -test |1 0 1 0|1 1 0 1 0 1 0|x x x x x| P P |u t t t t t 0 - -|- - - - -| memh(Rx++Mu)=Rt - ST/slot 0,1 -test |1 0 1 0|1 1 0 1 0 1 1|x x x x x| P P |u t t t t t 0 - -|- - - - -| memh(Rx++Mu)=Rt.H - ST/slot 0,1 -test |1 0 1 0|1 1 0 1 1 0 0|x x x x x| P P |u t t t t t 0 - -|- - - - -| memw(Rx++Mu)=Rt - ST/slot 0,1 -test |1 0 1 0|1 1 0 1 1 0 1|x x x x x| P P |u 0 0 t t t 0 - -|- - - - -| memb(Rx++Mu)=Nt.new - NV ST/slot 0 -test |1 0 1 0|1 1 0 1 1 0 1|x x x x x| P P |u 0 1 t t t 0 - -|- - - - -| memh(Rx++Mu)=Nt.new - NV ST/slot 0 -test |1 0 1 0|1 1 0 1 1 0 1|x x x x x| P P |u 1 0 t t t 0 - -|- - - - -| memw(Rx++Mu)=Nt.new - NV ST/slot 0 -test |1 0 1 0|1 1 0 1 1 1 0|x x x x x| P P |u t t t t t 0 - -|- - - - -| memd(Rx++Mu)=Rtt - ST/slot 0,1 -test |1 0 1 0|1 1 0 1 0 0 0|u u u u u| P P |i t t t t t 1 i l|l l l l l| memb(Ru<<#u2+#U6)=Rt - ST/slot 0,1 -test |1 0 1 0|1 1 0 1 0 1 0|u u u u u| P P |i t t t t t 1 i l|l l l l l| memh(Ru<<#u2+#U6)=Rt - ST/slot 0,1 -test |1 0 1 0|1 1 0 1 0 1 1|u u u u u| P P |i t t t t t 1 i l|l l l l l| memh(Ru<<#u2+#U6)=Rt.H - ST/slot 0,1 -test |1 0 1 0|1 1 0 1 1 0 0|u u u u u| P P |i t t t t t 1 i l|l l l l l| memw(Ru<<#u2+#U6)=Rt - ST/slot 0,1 -test |1 0 1 0|1 1 0 1 1 0 1|u u u u u| P P |i 0 0 t t t 1 i l|l l l l l| memb(Ru<<#u2+#U6)=Nt.new - NV ST/slot 0 -test |1 0 1 0|1 1 0 1 1 0 1|u u u u u| P P |i 0 1 t t t 1 i l|l l l l l| memh(Ru<<#u2+#U6)=Nt.new - NV ST/slot 0 -test |1 0 1 0|1 1 0 1 1 0 1|u u u u u| P P |i 1 0 t t t 1 i l|l l l l l| memw(Ru<<#u2+#U6)=Nt.new - NV ST/slot 0 -test |1 0 1 0|1 1 0 1 1 1 0|u u u u u| P P |i t t t t t 1 i l|l l l l l| memd(Ru<<#u2+#U6)=Rtt - ST/slot 0,1 - -test |1 0 1 0|1 1 1 1 0 0 0|x x x x x| P P |u t t t t t 0 - -|- - - - -| memb(Rx++Mu:brev)=Rt - ST/slot 0,1 -test |1 0 1 0|1 1 1 1 0 1 0|x x x x x| P P |u t t t t t 0 - -|- - - - -| memh(Rx++Mu:brev)=Rt - ST/slot 0,1 -test |1 0 1 0|1 1 1 1 0 1 1|x x x x x| P P |u t t t t t 0 - -|- - - - -| memh(Rx++Mu:brev)=Rt.H - ST/slot 0,1 -test |1 0 1 0|1 1 1 1 1 0 0|x x x x x| P P |u t t t t t 0 - -|- - - - -| memw(Rx++Mu:brev)=Rt - ST/slot 0,1 -test |1 0 1 0|1 1 1 1 1 0 1|x x x x x| P P |u 0 0 t t t 0 - -|- - - - -| memb(Rx++Mu:brev)=Nt.new - NV ST/slot 0 -test |1 0 1 0|1 1 1 1 1 0 1|x x x x x| P P |u 0 1 t t t 0 - -|- - - - -| memh(Rx++Mu:brev)=Nt.new - NV ST/slot 0 -test |1 0 1 0|1 1 1 1 1 0 1|x x x x x| P P |u 1 0 t t t 0 - -|- - - - -| memw(Rx++Mu:brev)=Nt.new - NV ST/slot 0 -test |1 0 1 0|1 1 1 1 1 1 0|x x x x x| P P |u t t t t t 0 - -|- - - - -| memd(Rx++Mu:brev)=Rtt - ST/slot 0,1 -test |1 0 1 0|1 1 1 1 0 0 0|- - - i i| P P |0 t t t t t 1 i i|i i 0 v v| if (Pv) memb(#u6)=Rt - ST/slot 0,1 -test |1 0 1 0|1 1 1 1 0 0 0|- - - i i| P P |0 t t t t t 1 i i|i i 1 v v| if (!Pv) memb(#u6)=Rt - ST/slot 0,1 -test |1 0 1 0|1 1 1 1 0 0 0|- - - i i| P P |1 t t t t t 1 i i|i i 0 v v| if (Pv.new) memb(#u6)=Rt - ST/slot 0,1 -test |1 0 1 0|1 1 1 1 0 0 0|- - - i i| P P |1 t t t t t 1 i i|i i 1 v v| if (!Pv.new) memb(#u6)=Rt - ST/slot 0,1 -test |1 0 1 0|1 1 1 1 0 1 0|- - - i i| P P |0 t t t t t 1 i i|i i 0 v v| if (Pv) memh(#u6)=Rt - ST/slot 0,1 -test |1 0 1 0|1 1 1 1 0 1 0|- - - i i| P P |0 t t t t t 1 i i|i i 1 v v| if (!Pv) memh(#u6)=Rt - ST/slot 0,1 -test |1 0 1 0|1 1 1 1 0 1 0|- - - i i| P P |1 t t t t t 1 i i|i i 0 v v| if (Pv.new) memh(#u6)=Rt - ST/slot 0,1 -test |1 0 1 0|1 1 1 1 0 1 0|- - - i i| P P |1 t t t t t 1 i i|i i 1 v v| if (!Pv.new) memh(#u6)=Rt - ST/slot 0,1 -test |1 0 1 0|1 1 1 1 0 1 1|- - - i i| P P |0 t t t t t 1 i i|i i 0 v v| if (Pv) memh(#u6)=Rt.H - ST/slot 0,1 -test |1 0 1 0|1 1 1 1 0 1 1|- - - i i| P P |0 t t t t t 1 i i|i i 1 v v| if (!Pv) memh(#u6)=Rt.H - ST/slot 0,1 -test |1 0 1 0|1 1 1 1 0 1 1|- - - i i| P P |1 t t t t t 1 i i|i i 0 v v| if (Pv.new) memh(#u6)=Rt.H - ST/slot 0,1 -test |1 0 1 0|1 1 1 1 0 1 1|- - - i i| P P |1 t t t t t 1 i i|i i 1 v v| if (!Pv.new) memh(#u6)=Rt.H - ST/slot 0,1 -test |1 0 1 0|1 1 1 1 1 0 0|- - - i i| P P |0 t t t t t 1 i i|i i 0 v v| if (Pv) memw(#u6)=Rt - ST/slot 0,1 -test |1 0 1 0|1 1 1 1 1 0 0|- - - i i| P P |0 t t t t t 1 i i|i i 1 v v| if (!Pv) memw(#u6)=Rt - ST/slot 0,1 -test |1 0 1 0|1 1 1 1 1 0 0|- - - i i| P P |1 t t t t t 1 i i|i i 0 v v| if (Pv.new) memw(#u6)=Rt - ST/slot 0,1 -test |1 0 1 0|1 1 1 1 1 0 0|- - - i i| P P |1 t t t t t 1 i i|i i 1 v v| if (!Pv.new) memw(#u6)=Rt - ST/slot 0,1 -test |1 0 1 0|1 1 1 1 1 0 1|- - - i i| P P |0 0 0 t t t 1 i i|i i 0 v v| if (Pv) memb(#u6)=Nt.new - NV/slot 0 -test |1 0 1 0|1 1 1 1 1 0 1|- - - i i| P P |0 0 0 t t t 1 i i|i i 1 v v| if (!Pv) memb(#u6)=Nt.new - NV/slot 0 -test |1 0 1 0|1 1 1 1 1 0 1|- - - i i| P P |0 0 1 t t t 1 i i|i i 0 v v| if (Pv) memh(#u6)=Nt.new - NV/slot 0 -test |1 0 1 0|1 1 1 1 1 0 1|- - - i i| P P |0 0 1 t t t 1 i i|i i 1 v v| if (!Pv) memh(#u6)=Nt.new - NV/slot 0 -test |1 0 1 0|1 1 1 1 1 0 1|- - - i i| P P |0 1 0 t t t 1 i i|i i 0 v v| if (Pv) memw(#u6)=Nt.new - NV/slot 0 -test |1 0 1 0|1 1 1 1 1 0 1|- - - i i| P P |0 1 0 t t t 1 i i|i i 1 v v| if (!Pv) memw(#u6)=Nt.new - NV/slot 0 -test |1 0 1 0|1 1 1 1 1 0 1|- - - i i| P P |1 0 0 t t t 1 i i|i i 0 v v| if (Pv.new) memb(#u6)=Nt.new - NV/slot 0 -test |1 0 1 0|1 1 1 1 1 0 1|- - - i i| P P |1 0 0 t t t 1 i i|i i 1 v v| if (!Pv.new) memb(#u6)=Nt.new - NV/slot 0 -test |1 0 1 0|1 1 1 1 1 0 1|- - - i i| P P |1 0 1 t t t 1 i i|i i 0 v v| if (Pv.new) memh(#u6)=Nt.new - NV/slot 0 -test |1 0 1 0|1 1 1 1 1 0 1|- - - i i| P P |1 0 1 t t t 1 i i|i i 1 v v| if (!Pv.new) memh(#u6)=Nt.new - NV/slot 0 -test |1 0 1 0|1 1 1 1 1 0 1|- - - i i| P P |1 1 0 t t t 1 i i|i i 0 v v| if (Pv.new) memw(#u6)=Nt.new - NV/slot 0 -test |1 0 1 0|1 1 1 1 1 0 1|- - - i i| P P |1 1 0 t t t 1 i i|i i 1 v v| if (!Pv.new) memw(#u6)=Nt.new - NV/slot 0 -test |1 0 1 0|1 1 1 1 1 1 0|- - - i i| P P |0 t t t t t 1 i i|i i 0 v v| if (Pv) memd(#u6)=Rtt - ST/slot 0,1 -test |1 0 1 0|1 1 1 1 1 1 0|- - - i i| P P |0 t t t t t 1 i i|i i 1 v v| if (!Pv) memd(#u6)=Rtt - ST/slot 0,1 -test |1 0 1 0|1 1 1 1 1 1 0|- - - i i| P P |1 t t t t t 1 i i|i i 0 v v| if (Pv.new) memd(#u6)=Rtt - ST/slot 0,1 -test |1 0 1 0|1 1 1 1 1 1 0|- - - i i| P P |1 t t t t t 1 i i|i i 1 v v| if (!Pv.new) memd(#u6)=Rtt - ST/slot 0,1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + |1 1 0 0|0 0 0 0|0 - -|s s s s s| P P |- t t t t t|i i i|d d d d d| Rdd=valignb(Rtt,Rss,#u3) - XTYPE PERM/slot 2,3 |1 1 0 0|0 0 0 0|1 - -|s s s s s| P P |- t t t t t|i i i|d d d d d| Rdd=vspliceb(Rss,Rtt,#u3) - XTYPE PERM/slot 2,3 diff --git a/src/display.rs b/src/display.rs index bc3a418..46fd534 100644 --- a/src/display.rs +++ b/src/display.rs @@ -1,6 +1,7 @@ use core::fmt; use crate::{Instruction, InstructionPacket, Opcode, Operand}; +use crate::{BranchHint, DomainHint}; impl fmt::Display for InstructionPacket { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -74,11 +75,29 @@ impl fmt::Display for Instruction { // stores put the mnemonic on LHS static STORES: &[Opcode] = &[ - Opcode::StoreMemb, Opcode::StoreMemh, Opcode::StoreMemw, Opcode::StoreMemd + Opcode::StoreMemb, Opcode::StoreMemh, Opcode::StoreMemw, Opcode::StoreMemd, Opcode::MemwRl, Opcode::MemdRl ]; if STORES.contains(&self.opcode) { - write!(f, "{}({}) = {}", + write!(f, "{}({}){} = {}", self.opcode, self.dest.expect("TODO: unreachable; store has a destination"), + match self.flags.threads { + Some(DomainHint::Same) => { ":st" }, + Some(DomainHint::All) => { ":at" }, + None => { "" } + }, + self.sources[0] + )?; + return Ok(()); + } + + static SC_STORES: &[Opcode] = &[ + Opcode::MemwStoreCond, Opcode::MemdStoreCond, + ]; + if SC_STORES.contains(&self.opcode) { + write!(f, "{}({}, {}) = {}", + self.opcode, + self.dest.expect("TODO: unreachable; store has a destination"), + self.alt_dest.expect("TODO: unreachable; store-conditional has a predicate reg"), self.sources[0] )?; return Ok(()); @@ -94,8 +113,6 @@ impl fmt::Display for Instruction { return Ok(()); } - use crate::BranchHint; - static CONDITIONAL_JUMPS: &[Opcode] = &[ Opcode::JumpEq, Opcode::JumpNeq, Opcode::JumpGt, Opcode::JumpLe, Opcode::JumpGtu, Opcode::JumpLeu, Opcode::JumpBitSet, Opcode::JumpBitClear, @@ -179,11 +196,17 @@ impl fmt::Display for Instruction { Some(BranchHint::Taken) => { f.write_str(":t")? }, Some(BranchHint::NotTaken) => { f.write_str(":nt")? }, None => {} - }; + } + + match self.flags.threads { + Some(DomainHint::Same) => { f.write_str(":st")? }, + Some(DomainHint::All) => { f.write_str(":at")? }, + None => {} + } // DeallocateFrame is shown with `:raw` as a suffix, but after the taken/not-taken hint // same for DeallocReturn - if self.opcode == Opcode::DeallocFrame || self.opcode == Opcode::DeallocReturn { + if self.opcode == Opcode::AllocFrame || self.opcode == Opcode::DeallocFrame || self.opcode == Opcode::DeallocReturn { f.write_str(":raw")?; } Ok(()) @@ -328,23 +351,29 @@ impl fmt::Display for Opcode { Opcode::DcInvA => { f.write_str("dcinva") }, Opcode::DcCleanInvA => { f.write_str("dccleaninva") }, Opcode::DcZeroA => { f.write_str("dczeroa") }, - Opcode::L2Fetch => { f.write_str("l2fet_ch") }, - Opcode::DmSyncHt => { f.write_str("dmsyncht_") }, - Opcode::SyncHt => { f.write_str("syncht_") }, + Opcode::L2Fetch => { f.write_str("l2fetch") }, + Opcode::DmSyncHt => { f.write_str("dmsyncht") }, + Opcode::SyncHt => { f.write_str("syncht") }, Opcode::Release => { f.write_str("release") }, Opcode::Barrier => { f.write_str("barrier") }, Opcode::AllocFrame => { f.write_str("allocframe") }, - Opcode::MemwRl => { f.write_str("memwrl") }, - Opcode::MemdRl => { f.write_str("memdrl") }, + Opcode::MemwRl => { f.write_str("memw_rl") }, + Opcode::MemdRl => { f.write_str("memd_rl") }, Opcode::DeallocFrame => { f.write_str("deallocframe") }, Opcode::DeallocReturn => { f.write_str("dealloc_return") }, Opcode::Dcfetch => { f.write_str("dcfetch") }, - Opcode::MemwLocked => { f.write_str("memw_locked") }, + // LL/SC ops are distinguished by where they are in an instruction, not by their + // textual representation + Opcode::MemwLockedLoad => { f.write_str("memw_locked") }, + Opcode::MemwStoreCond => { f.write_str("memw_locked") }, Opcode::MemwAq => { f.write_str("memw_aq") }, - Opcode::MemdLocked => { f.write_str("memd_locked") }, + // LL/SC ops are distinguished by where they are in an instruction, not by their + // textual representation + Opcode::MemdLockedLoad => { f.write_str("memd_locked") }, + Opcode::MemdStoreCond => { f.write_str("memd_locked") }, Opcode::MemdAq => { f.write_str("memd_aq") }, } } diff --git a/src/lib.rs b/src/lib.rs index 8159273..9cec564 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -261,11 +261,14 @@ pub struct Instruction { opcode: Opcode, dest: Option, // an alternate destination operand for the handful of instructions that write to two - // destinations. in all cases, these are very close to duplex instructions (some operation; + // destinations. in most cases, these are very close to duplex instructions (some operation; // some other related operation), but it's not clear if instruction packets would error if // these instruction cohabitate with three other instructions in a packet. for duplex // instructions, it is simply an error to have duplex + 3 more slots, so duplex can be much // more simply decoded into a series of instrucitons.. + // + // the outliers here are store-conditional, where one operand is a register (address) and the + // other is a predicate register updated to indicate the successfulness of the store. alt_dest: Option, flags: InstFlags, @@ -296,6 +299,13 @@ struct InstFlags { saturate: bool, chop: bool, rounded: Option, + threads: Option, +} + +#[derive(Debug, Copy, Clone)] +enum DomainHint { + Same, + All, } impl Default for InstFlags { @@ -307,6 +317,7 @@ impl Default for InstFlags { saturate: false, chop: false, rounded: None, + threads: None, } } } @@ -513,9 +524,11 @@ pub enum Opcode { DeallocReturn, Dcfetch, - MemwLocked, + MemwLockedLoad, + MemwStoreCond, MemwAq, - MemdLocked, + MemdLockedLoad, + MemdStoreCond, MemdAq, } @@ -985,6 +998,7 @@ trait DecodeHandler::Address, ::Wor fn negate_result(&mut self) -> Result<(), ::DecodeError> { Ok(()) } fn saturate(&mut self) -> Result<(), ::DecodeError> { Ok(()) } fn branch_hint(&mut self, hint_taken: bool) -> Result<(), ::DecodeError> { Ok(()) } + fn domain_hint(&mut self, domain: DomainHint) -> Result<(), ::DecodeError> { Ok(()) } fn rounded(&mut self, mode: RoundingMode) -> Result<(), ::DecodeError> { Ok(()) } fn chop(&mut self) -> Result<(), ::DecodeError> { Ok(()) } fn on_word_read(&mut self, _word: ::Word) {} @@ -1048,6 +1062,12 @@ impl::Address, ::Word } Ok(()) } + fn domain_hint(&mut self, domain: DomainHint) -> Result<(), ::DecodeError> { + let mut flags = &mut self.instructions[self.instruction_count as usize].flags; + assert!(flags.threads.is_none()); + flags.threads = Some(domain); + Ok(()) + } fn rounded(&mut self, mode: RoundingMode) -> Result<(), ::DecodeError> { let mut flags = &mut self.instructions[self.instruction_count as usize].flags; assert!(flags.rounded.is_none()); @@ -1104,8 +1124,8 @@ fn decode_store_ops< handler.on_source_decoded(Operand::gpr_new(srcreg & 0b111))?; let opbits = (srcreg >> 3) & 0b11; static OPS: [Option; 4] = [ - Some(Opcode::StoreMemb), Some(Opcode::StoreMemw), - Some(Opcode::StoreMemd), None, + Some(Opcode::StoreMemb), Some(Opcode::StoreMemh), + Some(Opcode::StoreMemw), None, ]; handler.on_opcode_decoded(decode_opcode!(OPS[opbits as usize]))?; handler.on_dest_decoded(dest_op(opbits))?; @@ -2362,8 +2382,8 @@ fn decode_instruction< opcode_check!(inst & 0b100000_111_00000 == 0); let op_low = (inst >> 11) & 0b11; static OP: [Opcode; 4] = [ - Opcode::MemwLocked, Opcode::MemwAq, - Opcode::MemdLocked, Opcode::MemdAq, + Opcode::MemwLockedLoad, Opcode::MemwAq, + Opcode::MemdLockedLoad, Opcode::MemdAq, ]; handler.on_source_decoded(Operand::gpr(sssss))?; if op_low > 0b01 { @@ -2428,57 +2448,86 @@ fn decode_instruction< } } 0b1010 => { - if inst >> 26 & 1 == 0 { + if inst >> 27 & 1 == 0 { // lower chunk: 1010|0 .... // may also be xxxxx, depends on instruction. let sssss = reg_b16(inst); + let Rs = Operand::gpr(sssss); if inst >> 24 & 1 == 0 { // 1010|0..0... these are semi-special memory operations. - handler.on_source_decoded(Operand::gpr(sssss))?; let opc_upper = inst >> 25 & 0b11; if opc_upper == 0b00 { let opc_lower = (inst >> 21) & 0b111; match opc_lower { 0b000 => { handler.on_opcode_decoded(Opcode::DcCleanA)?; + handler.on_source_decoded(Rs)?; }, 0b001 => { handler.on_opcode_decoded(Opcode::DcInvA)?; + handler.on_source_decoded(Rs)?; }, 0b010 => { handler.on_opcode_decoded(Opcode::DcCleanInvA)?; + handler.on_source_decoded(Rs)?; }, 0b011 => { + opcode_check!(inst & 0b11100 == 0b01100); handler.on_opcode_decoded(Opcode::Release)?; + handler.on_source_decoded(Rs)?; if (inst >> 5) & 1 == 0 { - //TODO: hint :at + handler.domain_hint(DomainHint::All)?; } else { - //TODO: hint :st + handler.domain_hint(DomainHint::Same)?; } }, 0b100 => { handler.on_opcode_decoded(Opcode::AllocFrame)?; + let i11 = inst & 0b111_11111111; + operand_check!(inst & 0b111000_00000000 == 0); + handler.on_source_decoded(Rs)?; + handler.on_source_decoded(Operand::imm_u16((i11 as u16) << 3))?; } 0b101 => { - handler.on_opcode_decoded(Opcode::MemwRl)?; - if (inst >> 5) & 1 == 0 { - //TODO: hint :at + handler.on_dest_decoded(Rs)?; + handler.on_source_decoded(Operand::gpr((inst >> 8) as u8 & 0b11111))?; + if inst & 0b1100 == 0b0000 { + handler.on_opcode_decoded(Opcode::MemwStoreCond)?; + handler.on_dest_decoded(Operand::pred(inst as u8 & 0b11))?; + } else if inst & 0b11100 == 0b01000 { + handler.on_opcode_decoded(Opcode::MemwRl)?; + if (inst >> 5) & 1 == 0 { + handler.domain_hint(DomainHint::All)?; + } else { + handler.domain_hint(DomainHint::Same)?; + } } else { - //TODO: hint :st + return Err(DecodeError::InvalidOpcode); } }, 0b110 => { + opcode_check!((inst >> 13) & 1 == 0); handler.on_opcode_decoded(Opcode::DcZeroA)?; + handler.on_source_decoded(Rs)?; } _ => { // 1010|0000|111 - handler.on_opcode_decoded(Opcode::MemdRl)?; - if (inst >> 5) & 1 == 0 { - //TODO: hint :at + handler.on_dest_decoded(Rs)?; + handler.on_source_decoded(Operand::gprpair((inst >> 8) as u8 & 0b11111)?)?; + if inst & 0b1100 == 0b0000 { + handler.on_opcode_decoded(Opcode::MemdStoreCond)?; + handler.on_dest_decoded(Operand::pred(inst as u8 & 0b11))?; + } else if inst & 0b11100 == 0b01000 { + handler.on_opcode_decoded(Opcode::MemdRl)?; + if (inst >> 5) & 1 == 0 { + handler.domain_hint(DomainHint::All)?; + } else { + handler.domain_hint(DomainHint::Same)?; + } } else { - //TODO: hint :st + return Err(DecodeError::InvalidOpcode); } }, } @@ -2491,6 +2540,7 @@ fn decode_instruction< opcode_check!(opc_lower & 0b11 == 0b00); handler.on_opcode_decoded(Opcode::L2Fetch)?; + handler.on_source_decoded(Rs)?; let ttttt = reg_b8(inst); if opc_lower == 0b100 { handler.on_source_decoded(Operand::gprpair(ttttt)?)?; @@ -2620,14 +2670,14 @@ fn decode_instruction< Operand::RegMemIndexedBrev { base: xxxxx, mu: u as u8 } })?; } else { - // 1010|1011...|.....|PP|1... + // 1010|1111...|.....|PP|1... // predicated store let vv = inst & 0b11; let negated = (inst >> 2) & 1 == 1; let iiii = ((inst >> 3) & 0b1111) as u8; let ii_high = xxxxx & 0b11; let i6 = ((ii_high << 4) | iiii) as i8; - let dotnew = (inst >> 7) & 1 == 1; + let dotnew = (inst >> 13) & 1 == 1; decode_store_ops(handler, minbits, ttttt, |_shamt| { Operand::Absolute { addr: i6 } })?; diff --git a/tests/from_brain.rs b/tests/from_brain.rs index 8955543..90a3d1d 100644 --- a/tests/from_brain.rs +++ b/tests/from_brain.rs @@ -37,8 +37,10 @@ fn supervisor() { test_display(&0b0110_1100111_00010_11_0_00000000_01000u32.to_le_bytes(), "{ R8 = tlboc(R3:2) }"); } +// tests grouped by prefix. not very principled but it's something. + #[test] -fn general() { +fn inst_0001() { test_display(&0b0001_0110000_01001_11_00_0111_000_00100u32.to_le_bytes(), "{ R17 = #7; jump $+#8 }"); test_display(&0b0001_0111000_01001_11_00_0111_000_00100u32.to_le_bytes(), "{ R7 = R17; jump $+#8 }"); @@ -49,52 +51,31 @@ fn general() { test_display(&0b0001_0101011_11001_11_10_0111_000_00010u32.to_le_bytes(), "{ P0 = cmp.gtu(R17, R7); if (!P0.new) jump:t $+#-508 }"); test_display(&0b0001_0101011_11001_11_11_0111_000_00010u32.to_le_bytes(), "{ P1 = cmp.gtu(R17, R7); if (!P1.new) jump:t $+#-508 }"); +} - test_invalid(&0b0111_0000010_00000_11_0_0_0000_000_00000u32.to_le_bytes(), DecodeError::InvalidOpcode); - - test_display(&0b0111_0000000_00011_11_1_0_1101_000_00100u32.to_le_bytes(), "{ if (!P1.new) R4 = aslh(R3) }"); - test_display(&0b0111_0000011_00001_11_0_0_0000_000_00100u32.to_le_bytes(), "{ R4 = R1 }"); - - test_display(&0b0111_0001011_00010_11_0_0_0000_001_00000u32.to_le_bytes(), "{ R2.L = #0x4020 }"); - test_display(&0b0111_0001101_00010_11_0_0_0000_001_00000u32.to_le_bytes(), "{ R2.L = #0x8020 }"); - test_display(&0b0111_0010101_00010_11_0_0_0000_001_00000u32.to_le_bytes(), "{ R2.H = #0x8020 }"); - - test_display(&0b0111_0011001_00110_11_0_0_0000_111_10000u32.to_le_bytes(), "{ R16 = mux(P1, R6, #7) }"); - test_display(&0b0111_0011101_00110_11_0_0_0000_111_10000u32.to_le_bytes(), "{ R16 = mux(P1, #7, R6) }"); - - test_display(&0b0111_0011000_00110_11_1_0_0000_111_10000u32.to_le_bytes(), "{ R17:16 = combine(R6, #7) }"); - test_display(&0b0111_0011001_00110_11_1_0_0000_111_10000u32.to_le_bytes(), "{ R17:16 = combine(#7, R6) }"); - test_display(&0b0111_0011010_00110_11_1_0_0000_111_10000u32.to_le_bytes(), "{ R16 = cmp.eq(R6, #7) }"); - test_display(&0b0111_0011011_00110_11_1_0_0000_111_10000u32.to_le_bytes(), "{ R16 = !cmp.eq(R6, #7) }"); - - test_display(&0b0111_0100010_00110_11_0_0_0000_111_10000u32.to_le_bytes(), "{ if (P2) R16 = add(R6, #7) }"); - test_display(&0b0111_0100010_00110_11_1_0_0000_111_10000u32.to_le_bytes(), "{ if (P2.new) R16 = add(R6, #7) }"); - test_display(&0b0111_0100110_00110_11_1_0_0000_111_10000u32.to_le_bytes(), "{ if (!P2.new) R16 = add(R6, #7) }"); - - test_display(&0b0111_0101001_00110_11_1_0_0000_111_00001u32.to_le_bytes(), "{ P1 = cmp.eq(R6, #-249) }"); - test_display(&0b0111_0101001_00110_11_1_0_0000_111_10001u32.to_le_bytes(), "{ P1 = !cmp.eq(R6, #-249) }"); - test_display(&0b0111_0101011_00110_11_1_0_0000_111_10001u32.to_le_bytes(), "{ P1 = !cmp.gt(R6, #-249) }"); - test_display(&0b0111_0101100_00110_11_1_0_0000_111_10001u32.to_le_bytes(), "{ P1 = !cmp.gtu(R6, #0x107) }"); - test_invalid(&0b0111_0101101_00110_11_1_0_0000_111_10001u32.to_le_bytes(), DecodeError::InvalidOperand); - test_invalid(&0b0111_0101110_00110_11_1_0_0000_111_10001u32.to_le_bytes(), DecodeError::InvalidOpcode); - - test_display(&0b0111_0110001_00110_11_1_0_0000_111_10001u32.to_le_bytes(), "{ R17 = and(R6, #-249) }"); - test_display(&0b0111_0110011_00110_11_1_0_0000_111_10001u32.to_le_bytes(), "{ R17 = sub(#-249, R6) }"); - test_display(&0b0111_0110101_00110_11_1_0_0000_111_10001u32.to_le_bytes(), "{ R17 = or(R6, #-249) }"); - test_invalid(&0b0111_0110111_00110_11_1_0_0000_111_10001u32.to_le_bytes(), DecodeError::InvalidOpcode); - - test_invalid(&0b0111_0111111_00110_11_1_0_0000_111_10001u32.to_le_bytes(), DecodeError::InvalidOpcode); - - test_display(&0b0111_1000110_00110_11_1_0_0000_111_10001u32.to_le_bytes(), "{ R17 = #-15929 }"); - - test_display(&0b0111_1100010_00000_11_1_0_0000_111_10000u32.to_le_bytes(), "{ R17:16 = combine(#7, #-127) }"); - test_display(&0b0111_1100100_10000_11_1_0_0000_111_10000u32.to_le_bytes(), "{ R17:16 = combine(#7, #0x21) }"); - - test_invalid(&0b0111_1101100_10000_11_1_0_0000_111_10000u32.to_le_bytes(), DecodeError::InvalidOpcode); - - test_display(&0b0111_1110010_00100_11_0_0_0000_111_10000u32.to_le_bytes(), "{ if (P2) R16 = #1031 }"); - test_display(&0b0111_1110110_00100_11_1_0_0000_111_10000u32.to_le_bytes(), "{ if (!P2.new) R16 = #1031 }"); +#[test] +fn inst_0010() { + test_display(&0b0010_00000001_0100_11_0_00010_100_10110u32.to_le_bytes(), "{ if (cmp.eq(R4.new, R2)) jump:nt $+#812 }"); + test_display(&0b0010_00000001_0100_11_1_00010_100_10110u32.to_le_bytes(), "{ if (cmp.eq(R4.new, R2)) jump:t $+#812 }"); + test_display(&0b0010_00000101_0100_11_0_00010_100_10110u32.to_le_bytes(), "{ if (!cmp.eq(R4.new, R2)) jump:nt $+#812 }"); + test_display(&0b0010_00001001_0100_11_0_00010_100_10110u32.to_le_bytes(), "{ if (cmp.gt(R4.new, R2)) jump:nt $+#812 }"); + test_display(&0b0010_00001101_0100_11_0_00010_100_10110u32.to_le_bytes(), "{ if (!cmp.gt(R4.new, R2)) jump:nt $+#812 }"); + test_display(&0b0010_00010001_0100_11_0_00010_100_10110u32.to_le_bytes(), "{ if (cmp.gtu(R4.new, R2)) jump:nt $+#812 }"); + test_display(&0b0010_00010101_0100_11_0_00010_100_10110u32.to_le_bytes(), "{ if (!cmp.gtu(R4.new, R2)) jump:nt $+#812 }"); + test_display(&0b0010_00011001_0100_11_0_00010_100_10110u32.to_le_bytes(), "{ if (cmp.gt(R2, R4.new)) jump:nt $+#812 }"); + test_display(&0b0010_00100101_0100_11_0_00010_100_10110u32.to_le_bytes(), "{ if (!cmp.gtu(R2, R4.new)) jump:nt $+#812 }"); + test_invalid(&0b0010_00101101_0100_11_0_00010_100_10110u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_invalid(&0b0010_00110101_0100_11_0_00010_100_10110u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_invalid(&0b0010_00111101_0100_11_0_00010_100_10110u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_display(&0b0010_01000001_0100_11_0_00010_100_10110u32.to_le_bytes(), "{ if (cmp.eq(R4.new, #2)) jump:nt $+#812 }"); + test_display(&0b0010_01010101_0100_11_1_00010_100_10110u32.to_le_bytes(), "{ if (!cmp.gtu(R4.new, #2)) jump:t $+#812 }"); + test_display(&0b0010_01011001_0100_11_0_00010_100_10110u32.to_le_bytes(), "{ if (tstbit(R4.new, #0)) jump:nt $+#812 }"); + test_display(&0b0010_01011101_0100_11_1_00010_100_10110u32.to_le_bytes(), "{ if (!tstbit(R4.new, #0)) jump:t $+#812 }"); + test_display(&0b0010_01101101_0100_11_1_00010_100_10110u32.to_le_bytes(), "{ if (!cmp.gt(R4.new, #-1)) jump:t $+#812 }"); +} +#[test] +fn inst_0011() { test_display(&0b0011_0010110_00100_11_1_0_0010_101_10000u32.to_le_bytes(), "{ if (P1.new) R17:16 = memd(R4 + R2<<3) }"); test_display(&0b0011_0010110_00100_11_1_0_0010_101_10000u32.to_le_bytes(), "{ if (P1.new) R17:16 = memd(R4 + R2<<3) }"); @@ -119,25 +100,10 @@ fn general() { test_display(&0b0011_1011010_00100_11_1_0_0010_100_11110u32.to_le_bytes(), "{ memh(R4 + R2<<3) = R30 }"); test_display(&0b0011_1011011_00100_11_1_0_0010_100_11110u32.to_le_bytes(), "{ memh(R4 + R2<<3) = R30.H }"); test_display(&0b0011_1011101_00100_11_1_0_0010_100_10110u32.to_le_bytes(), "{ memw(R4 + R2<<3) = R6.new }"); +} - test_display(&0b0010_00000001_0100_11_0_00010_100_10110u32.to_le_bytes(), "{ if (cmp.eq(R4.new, R2)) jump:nt $+#812 }"); - test_display(&0b0010_00000001_0100_11_1_00010_100_10110u32.to_le_bytes(), "{ if (cmp.eq(R4.new, R2)) jump:t $+#812 }"); - test_display(&0b0010_00000101_0100_11_0_00010_100_10110u32.to_le_bytes(), "{ if (!cmp.eq(R4.new, R2)) jump:nt $+#812 }"); - test_display(&0b0010_00001001_0100_11_0_00010_100_10110u32.to_le_bytes(), "{ if (cmp.gt(R4.new, R2)) jump:nt $+#812 }"); - test_display(&0b0010_00001101_0100_11_0_00010_100_10110u32.to_le_bytes(), "{ if (!cmp.gt(R4.new, R2)) jump:nt $+#812 }"); - test_display(&0b0010_00010001_0100_11_0_00010_100_10110u32.to_le_bytes(), "{ if (cmp.gtu(R4.new, R2)) jump:nt $+#812 }"); - test_display(&0b0010_00010101_0100_11_0_00010_100_10110u32.to_le_bytes(), "{ if (!cmp.gtu(R4.new, R2)) jump:nt $+#812 }"); - test_display(&0b0010_00011001_0100_11_0_00010_100_10110u32.to_le_bytes(), "{ if (cmp.gt(R2, R4.new)) jump:nt $+#812 }"); - test_display(&0b0010_00100101_0100_11_0_00010_100_10110u32.to_le_bytes(), "{ if (!cmp.gtu(R2, R4.new)) jump:nt $+#812 }"); - test_invalid(&0b0010_00101101_0100_11_0_00010_100_10110u32.to_le_bytes(), DecodeError::InvalidOpcode); - test_invalid(&0b0010_00110101_0100_11_0_00010_100_10110u32.to_le_bytes(), DecodeError::InvalidOpcode); - test_invalid(&0b0010_00111101_0100_11_0_00010_100_10110u32.to_le_bytes(), DecodeError::InvalidOpcode); - test_display(&0b0010_01000001_0100_11_0_00010_100_10110u32.to_le_bytes(), "{ if (cmp.eq(R4.new, #2)) jump:nt $+#812 }"); - test_display(&0b0010_01010101_0100_11_1_00010_100_10110u32.to_le_bytes(), "{ if (!cmp.gtu(R4.new, #2)) jump:t $+#812 }"); - test_display(&0b0010_01011001_0100_11_0_00010_100_10110u32.to_le_bytes(), "{ if (tstbit(R4.new, #0)) jump:nt $+#812 }"); - test_display(&0b0010_01011101_0100_11_1_00010_100_10110u32.to_le_bytes(), "{ if (!tstbit(R4.new, #0)) jump:t $+#812 }"); - test_display(&0b0010_01101101_0100_11_1_00010_100_10110u32.to_le_bytes(), "{ if (!cmp.gt(R4.new, #-1)) jump:t $+#812 }"); - +#[test] +fn inst_0101() { test_invalid(&0b0101_000_0100_00001_11_0_00000_000_00000u32.to_le_bytes(), DecodeError::InvalidOpcode); test_display(&0b0101_000_0101_00001_11_0_00000_000_00000u32.to_le_bytes(), "{ callr R1 }"); test_display(&0b0101_000_0110_00001_11_0_00000_000_00000u32.to_le_bytes(), "{ callrh R1 }"); @@ -173,13 +139,67 @@ fn general() { test_display(&0b0101_110_0001_00000_11_0_01001_000_00010u32.to_le_bytes(), "{ if (!P1.new) jump:nt $+#4 }"); test_display(&0b0101_110_1001_00000_11_0_00001_000_00010u32.to_le_bytes(), "{ if (!P1) call $+#4 }"); test_invalid(&0b0101_110_1001_00000_11_0_01001_000_00010u32.to_le_bytes(), DecodeError::InvalidOpcode); +} +#[test] +fn inst_0110() { test_display(&0b0110_0010001_00110_11_0_000101_00_10110u32.to_le_bytes(), "{ C22 = R6 }"); test_display(&0b0110_0011001_00110_11_0_000101_00_10110u32.to_le_bytes(), "{ C23:22 = R7:6 }"); test_display(&0b0110_1000000_00110_11_0_000101_00_10110u32.to_le_bytes(), "{ R23:22 = C7:6 }"); test_display(&0b0110_1010000_00110_11_0_000101_00_10110u32.to_le_bytes(), "{ R22 = C6 }"); test_display(&0b0110_1010010_01001_11_0_000101_00_10110u32.to_le_bytes(), "{ R22 = add(pc, #0x5) }"); +} + +#[test] +fn inst_0111() { + test_invalid(&0b0111_0000010_00000_11_0_0_0000_000_00000u32.to_le_bytes(), DecodeError::InvalidOpcode); + + test_display(&0b0111_0000000_00011_11_1_0_1101_000_00100u32.to_le_bytes(), "{ if (!P1.new) R4 = aslh(R3) }"); + test_display(&0b0111_0000011_00001_11_0_0_0000_000_00100u32.to_le_bytes(), "{ R4 = R1 }"); + + test_display(&0b0111_0001011_00010_11_0_0_0000_001_00000u32.to_le_bytes(), "{ R2.L = #0x4020 }"); + test_display(&0b0111_0001101_00010_11_0_0_0000_001_00000u32.to_le_bytes(), "{ R2.L = #0x8020 }"); + test_display(&0b0111_0010101_00010_11_0_0_0000_001_00000u32.to_le_bytes(), "{ R2.H = #0x8020 }"); + + test_display(&0b0111_0011001_00110_11_0_0_0000_111_10000u32.to_le_bytes(), "{ R16 = mux(P1, R6, #7) }"); + test_display(&0b0111_0011101_00110_11_0_0_0000_111_10000u32.to_le_bytes(), "{ R16 = mux(P1, #7, R6) }"); + + test_display(&0b0111_0011000_00110_11_1_0_0000_111_10000u32.to_le_bytes(), "{ R17:16 = combine(R6, #7) }"); + test_display(&0b0111_0011001_00110_11_1_0_0000_111_10000u32.to_le_bytes(), "{ R17:16 = combine(#7, R6) }"); + test_display(&0b0111_0011010_00110_11_1_0_0000_111_10000u32.to_le_bytes(), "{ R16 = cmp.eq(R6, #7) }"); + test_display(&0b0111_0011011_00110_11_1_0_0000_111_10000u32.to_le_bytes(), "{ R16 = !cmp.eq(R6, #7) }"); + + test_display(&0b0111_0100010_00110_11_0_0_0000_111_10000u32.to_le_bytes(), "{ if (P2) R16 = add(R6, #7) }"); + test_display(&0b0111_0100010_00110_11_1_0_0000_111_10000u32.to_le_bytes(), "{ if (P2.new) R16 = add(R6, #7) }"); + test_display(&0b0111_0100110_00110_11_1_0_0000_111_10000u32.to_le_bytes(), "{ if (!P2.new) R16 = add(R6, #7) }"); + + test_display(&0b0111_0101001_00110_11_1_0_0000_111_00001u32.to_le_bytes(), "{ P1 = cmp.eq(R6, #-249) }"); + test_display(&0b0111_0101001_00110_11_1_0_0000_111_10001u32.to_le_bytes(), "{ P1 = !cmp.eq(R6, #-249) }"); + test_display(&0b0111_0101011_00110_11_1_0_0000_111_10001u32.to_le_bytes(), "{ P1 = !cmp.gt(R6, #-249) }"); + test_display(&0b0111_0101100_00110_11_1_0_0000_111_10001u32.to_le_bytes(), "{ P1 = !cmp.gtu(R6, #0x107) }"); + test_invalid(&0b0111_0101101_00110_11_1_0_0000_111_10001u32.to_le_bytes(), DecodeError::InvalidOperand); + test_invalid(&0b0111_0101110_00110_11_1_0_0000_111_10001u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_display(&0b0111_0110001_00110_11_1_0_0000_111_10001u32.to_le_bytes(), "{ R17 = and(R6, #-249) }"); + test_display(&0b0111_0110011_00110_11_1_0_0000_111_10001u32.to_le_bytes(), "{ R17 = sub(#-249, R6) }"); + test_display(&0b0111_0110101_00110_11_1_0_0000_111_10001u32.to_le_bytes(), "{ R17 = or(R6, #-249) }"); + test_invalid(&0b0111_0110111_00110_11_1_0_0000_111_10001u32.to_le_bytes(), DecodeError::InvalidOpcode); + + test_invalid(&0b0111_0111111_00110_11_1_0_0000_111_10001u32.to_le_bytes(), DecodeError::InvalidOpcode); + + test_display(&0b0111_1000110_00110_11_1_0_0000_111_10001u32.to_le_bytes(), "{ R17 = #-15929 }"); + + test_display(&0b0111_1100010_00000_11_1_0_0000_111_10000u32.to_le_bytes(), "{ R17:16 = combine(#7, #-127) }"); + test_display(&0b0111_1100100_10000_11_1_0_0000_111_10000u32.to_le_bytes(), "{ R17:16 = combine(#7, #0x21) }"); + + test_invalid(&0b0111_1101100_10000_11_1_0_0000_111_10000u32.to_le_bytes(), DecodeError::InvalidOpcode); + + test_display(&0b0111_1110010_00100_11_0_0_0000_111_10000u32.to_le_bytes(), "{ if (P2) R16 = #1031 }"); + test_display(&0b0111_1110110_00100_11_1_0_0000_111_10000u32.to_le_bytes(), "{ if (!P2.new) R16 = #1031 }"); +} + +#[test] +fn inst_1000() { test_display(&0b1000_0000000_00100_11_000110_000_10110u32.to_le_bytes(), "{ R23:22 = asr(R5:4, #0x6) }"); test_display(&0b1000_0000000_00100_11_000110_001_10110u32.to_le_bytes(), "{ R23:22 = lsr(R5:4, #0x6) }"); test_display(&0b1000_0000000_00100_11_000110_010_10110u32.to_le_bytes(), "{ R23:22 = asl(R5:4, #0x6) }"); @@ -238,7 +258,10 @@ fn general() { test_display(&0b1000_0001101_00100_11_000110_111_10110u32.to_le_bytes(), "{ R23:22 = extractu(R5:4, #0x6, #0x2f) }"); test_display(&0b1000_1111011_00100_11_000110_111_10110u32.to_le_bytes(), "{ R22 = insert(R4, #0x6, #0x1f) }"); +} +#[test] +fn inst_1001() { test_display(&0b1001_0000000_00010_11_0_00000_000_11110u32.to_le_bytes(), "{ R31:30 = deallocframe(R2):raw }"); test_display(&0b1001_0010000_00010_11_000_000_000_00011u32.to_le_bytes(), "{ R3 = memw_locked(R2) }"); test_display(&0b1001_0010000_00010_11_001_000_000_00011u32.to_le_bytes(), "{ R3 = memw_aq(R2) }"); @@ -281,14 +304,232 @@ fn general() { 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); +} - test_display(&0b1010_0000101_00010_11_0_00100_000_00011u32.to_le_bytes(), "{ memw_locked(R2, P3)=R4 }"); +#[test] +fn inst_1010() { + test_display(&0b1010_0000000_00010_11_0_00100_000_00011u32.to_le_bytes(), "{ dccleana(R2) }"); + test_display(&0b1010_0000001_00010_11_0_00100_000_00011u32.to_le_bytes(), "{ dcinva(R2) }"); + test_display(&0b1010_0000010_00010_11_0_00100_000_00011u32.to_le_bytes(), "{ dccleaninva(R2) }"); + test_invalid(&0b1010_0000011_00010_11_0_00100_000_00011u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_display(&0b1010_0000011_00010_11_0_00100_000_01111u32.to_le_bytes(), "{ release(R2):at }"); + test_display(&0b1010_0000011_00010_11_0_00100_001_01111u32.to_le_bytes(), "{ release(R2):st }"); + test_display(&0b1010_0000100_00010_11_0_00000_001_01111u32.to_le_bytes(), "{ allocframe(R2, #0x178):raw }"); + test_invalid(&0b1010_0000100_00010_11_0_01000_001_01111u32.to_le_bytes(), DecodeError::InvalidOperand); + test_display(&0b1010_0000101_00010_11_0_00100_000_00011u32.to_le_bytes(), "{ memw_locked(R2, P3) = R4 }"); test_invalid(&0b1010_0000101_00010_11_0_00100_000_00111u32.to_le_bytes(), DecodeError::InvalidOpcode); - test_display(&0b1010_0000111_00010_11_0_00100_000_00011u32.to_le_bytes(), "{ memd_locked(R2, P3)=R5:R4 }"); + test_display(&0b1010_0000101_00010_11_0_00100_000_01011u32.to_le_bytes(), "{ memw_rl(R2):at = R4 }"); + test_display(&0b1010_0000101_00010_11_0_00100_001_01011u32.to_le_bytes(), "{ memw_rl(R2):st = R4 }"); + test_display(&0b1010_0000110_00010_11_0_00000_001_01111u32.to_le_bytes(), "{ dczeroa(R2) }"); + test_invalid(&0b1010_0000110_00010_11_1_00000_001_01111u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_display(&0b1010_0000111_00010_11_0_00100_000_00011u32.to_le_bytes(), "{ memd_locked(R2, P3) = R5:4 }"); test_invalid(&0b1010_0000111_00010_11_0_00100_000_00111u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_display(&0b1010_0000111_00010_11_0_00100_000_01011u32.to_le_bytes(), "{ memd_rl(R2):at = R5:4 }"); + test_display(&0b1010_0000111_00010_11_0_00100_001_01011u32.to_le_bytes(), "{ memd_rl(R2):st = R5:4 }"); + test_display(&0b1010_0110000_00010_11_0_00100_000_01011u32.to_le_bytes(), "{ l2fetch(R2, R4) }"); + test_invalid(&0b1010_0110000_00010_11_0_00100_001_01011u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_display(&0b1010_0110100_00010_11_0_00100_000_01011u32.to_le_bytes(), "{ l2fetch(R2, R5:4) }"); + + test_display(&0b1010_0101000_00010_11_1_00100_000_01011u32.to_le_bytes(), "{ memb(R2+#1291) = R4 }"); + test_display(&0b1010_0101010_00010_11_1_00100_000_01011u32.to_le_bytes(), "{ memh(R2+#2582) = R4 }"); + test_display(&0b1010_0101011_00010_11_1_00100_000_01011u32.to_le_bytes(), "{ memh(R2+#2582) = R4.H }"); + test_display(&0b1010_0101100_00010_11_1_00100_000_01011u32.to_le_bytes(), "{ memw(R2+#5164) = R4 }"); + test_display(&0b1010_0101101_00010_11_1_00100_000_01011u32.to_le_bytes(), "{ memb(R2+#1291) = R4.new }"); + test_display(&0b1010_0101101_00010_11_1_01100_000_01011u32.to_le_bytes(), "{ memh(R2+#2582) = R4.new }"); + test_display(&0b1010_0101101_00010_11_1_10100_000_01011u32.to_le_bytes(), "{ memw(R2+#5164) = R4.new }"); + test_invalid(&0b1010_0101101_00010_11_1_11100_000_01011u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_display(&0b1010_0101110_00010_11_1_00100_000_01011u32.to_le_bytes(), "{ memd(R2+#10328) = R5:4 }"); + test_invalid(&0b1010_0101111_00010_11_1_11100_000_01011u32.to_le_bytes(), DecodeError::InvalidOpcode); + + test_display(&0b1010_1000000_00010_11_1_00000_000_01011u32.to_le_bytes(), "{ barrier }"); + test_display(&0b1010_1000000_00010_11_1_00000_111_01011u32.to_le_bytes(), "{ R11 = dmsyncht }"); + test_invalid(&0b1010_1000000_00010_11_1_00000_001_01011u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_invalid(&0b1010_1000000_00010_11_1_00000_010_01011u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_invalid(&0b1010_1000000_00010_11_1_00000_100_01011u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_invalid(&0b1010_1000001_00010_11_1_00000_100_01011u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_display(&0b1010_1000010_00010_11_1_00000_111_01011u32.to_le_bytes(), "{ syncht }"); + + test_display(&0b1010_1001000_00010_11_1_00011_000_00010u32.to_le_bytes(), "{ memb(R2++I:circ(M1)) = R3 }"); + test_invalid(&0b1010_1001001_00010_11_1_00011_000_00010u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_display(&0b1010_1001010_00010_11_1_00011_000_00010u32.to_le_bytes(), "{ memh(R2++I:circ(M1)) = R3 }"); + test_display(&0b1010_1001011_00010_11_1_00011_000_00010u32.to_le_bytes(), "{ memh(R2++I:circ(M1)) = R3.H }"); + test_display(&0b1010_1001100_00010_11_1_00011_000_00010u32.to_le_bytes(), "{ memw(R2++I:circ(M1)) = R3 }"); + test_display(&0b1010_1001101_00010_11_1_00011_000_00010u32.to_le_bytes(), "{ memb(R2++I:circ(M1)) = R3.new }"); + test_display(&0b1010_1001101_00010_11_1_01011_000_00010u32.to_le_bytes(), "{ memh(R2++I:circ(M1)) = R3.new }"); + test_display(&0b1010_1001101_00010_11_1_10011_000_00010u32.to_le_bytes(), "{ memw(R2++I:circ(M1)) = R3.new }"); + test_display(&0b1010_1001101_00010_11_0_10011_000_00010u32.to_le_bytes(), "{ memw(R2++I:circ(M0)) = R3.new }"); + test_invalid(&0b1010_1001101_00010_11_1_11011_000_00010u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_display(&0b1010_1001110_00010_11_1_00100_000_00010u32.to_le_bytes(), "{ memd(R2++I:circ(M1)) = R5:4 }"); + test_invalid(&0b1010_1001111_00010_11_1_00100_000_00010u32.to_le_bytes(), DecodeError::InvalidOpcode); + + test_display(&0b1010_1001000_00010_11_1_00011_010_01000u32.to_le_bytes(), "{ memb(R2++#0x9:circ(M1)) = R3 }"); + test_invalid(&0b1010_1001001_00010_11_1_00011_010_01000u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_display(&0b1010_1001010_00010_11_1_00011_010_01000u32.to_le_bytes(), "{ memh(R2++#0x12:circ(M1)) = R3 }"); + test_display(&0b1010_1001011_00010_11_1_00011_010_01000u32.to_le_bytes(), "{ memh(R2++#0x12:circ(M1)) = R3.H }"); + test_display(&0b1010_1001100_00010_11_1_00011_010_01000u32.to_le_bytes(), "{ memw(R2++#0x24:circ(M1)) = R3 }"); + test_display(&0b1010_1001101_00010_11_1_00011_010_01000u32.to_le_bytes(), "{ memb(R2++#0x9:circ(M1)) = R3.new }"); + test_display(&0b1010_1001101_00010_11_1_01011_010_01000u32.to_le_bytes(), "{ memh(R2++#0x12:circ(M1)) = R3.new }"); + test_display(&0b1010_1001101_00010_11_1_10011_010_01000u32.to_le_bytes(), "{ memw(R2++#0x24:circ(M1)) = R3.new }"); + test_display(&0b1010_1001101_00010_11_0_10011_010_01000u32.to_le_bytes(), "{ memw(R2++#0x24:circ(M0)) = R3.new }"); + test_invalid(&0b1010_1001101_00010_11_1_11011_010_01000u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_display(&0b1010_1001110_00010_11_1_00100_010_01000u32.to_le_bytes(), "{ memd(R2++#0x48:circ(M1)) = R5:4 }"); + test_invalid(&0b1010_1001111_00010_11_1_00100_010_01000u32.to_le_bytes(), DecodeError::InvalidOpcode); + + test_display(&0b1010_1011000_00010_11_0_00011_010_01000u32.to_le_bytes(), "{ memb(R2+#9) = R3 }"); + test_invalid(&0b1010_1011001_00010_11_0_00011_010_01000u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_display(&0b1010_1011010_00010_11_0_00011_010_01000u32.to_le_bytes(), "{ memh(R2+#18) = R3 }"); + test_display(&0b1010_1011011_00010_11_0_00011_010_01000u32.to_le_bytes(), "{ memh(R2+#18) = R3.H }"); + test_display(&0b1010_1011100_00010_11_0_00011_010_01000u32.to_le_bytes(), "{ memw(R2+#36) = R3 }"); + test_display(&0b1010_1011101_00010_11_0_00011_010_01000u32.to_le_bytes(), "{ memb(R2+#9) = R3.new }"); + test_display(&0b1010_1011101_00010_11_0_01011_010_01000u32.to_le_bytes(), "{ memh(R2+#18) = R3.new }"); + test_display(&0b1010_1011101_00010_11_0_10011_010_01000u32.to_le_bytes(), "{ memw(R2+#36) = R3.new }"); + test_display(&0b1010_1011101_00010_11_0_10011_010_01000u32.to_le_bytes(), "{ memw(R2+#36) = R3.new }"); + test_invalid(&0b1010_1011101_00010_11_0_11011_010_01000u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_display(&0b1010_1011110_00010_11_0_00100_010_01000u32.to_le_bytes(), "{ memd(R2+#72) = R5:4 }"); + test_invalid(&0b1010_1011111_00010_11_0_00100_010_01000u32.to_le_bytes(), DecodeError::InvalidOpcode); + + test_display(&0b1010_1011000_00010_11_0_00011_101_01001u32.to_le_bytes(), "{ memb(R2=#0x29) = R3 }"); + test_invalid(&0b1010_1011001_00010_11_0_00011_101_01001u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_display(&0b1010_1011010_00010_11_0_00011_101_01001u32.to_le_bytes(), "{ memh(R2=#0x29) = R3 }"); + test_display(&0b1010_1011011_00010_11_0_00011_101_01001u32.to_le_bytes(), "{ memh(R2=#0x29) = R3.H }"); + test_display(&0b1010_1011100_00010_11_0_00011_101_01001u32.to_le_bytes(), "{ memw(R2=#0x29) = R3 }"); + test_display(&0b1010_1011101_00010_11_0_00011_101_01001u32.to_le_bytes(), "{ memb(R2=#0x29) = R3.new }"); + test_display(&0b1010_1011101_00010_11_0_01011_101_01001u32.to_le_bytes(), "{ memh(R2=#0x29) = R3.new }"); + test_display(&0b1010_1011101_00010_11_0_10011_101_01001u32.to_le_bytes(), "{ memw(R2=#0x29) = R3.new }"); + test_display(&0b1010_1011101_00010_11_0_10011_101_01001u32.to_le_bytes(), "{ memw(R2=#0x29) = R3.new }"); + test_invalid(&0b1010_1011101_00010_11_0_11011_101_01001u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_display(&0b1010_1011110_00010_11_0_00100_101_01001u32.to_le_bytes(), "{ memd(R2=#0x29) = R5:4 }"); + test_invalid(&0b1010_1011111_00010_11_0_00100_101_01001u32.to_le_bytes(), DecodeError::InvalidOpcode); + + test_display(&0b1010_1011000_00010_11_1_00100_010_01011u32.to_le_bytes(), "{ if (P3) memb(R2+#9) = R4 }"); + test_display(&0b1010_1011000_00010_11_1_00100_010_01111u32.to_le_bytes(), "{ if (!P3) memb(R2+#9) = R4 }"); + test_display(&0b1010_1011010_00010_11_1_00100_010_01011u32.to_le_bytes(), "{ if (P3) memh(R2+#18) = R4 }"); + test_display(&0b1010_1011010_00010_11_1_00100_010_01111u32.to_le_bytes(), "{ if (!P3) memh(R2+#18) = R4 }"); + test_display(&0b1010_1011011_00010_11_1_00100_010_01011u32.to_le_bytes(), "{ if (P3) memh(R2+#18) = R4.H }"); + test_display(&0b1010_1011011_00010_11_1_00100_010_01111u32.to_le_bytes(), "{ if (!P3) memh(R2+#18) = R4.H }"); + test_display(&0b1010_1011100_00010_11_1_00100_010_01011u32.to_le_bytes(), "{ if (P3) memw(R2+#36) = R4 }"); + test_display(&0b1010_1011100_00010_11_1_00100_010_01111u32.to_le_bytes(), "{ if (!P3) memw(R2+#36) = R4 }"); + + test_display(&0b1010_1011000_00010_11_1_00100_110_01011u32.to_le_bytes(), "{ if (P3.new) memb(R2+#9) = R4 }"); + test_display(&0b1010_1011000_00010_11_1_00100_110_01111u32.to_le_bytes(), "{ if (!P3.new) memb(R2+#9) = R4 }"); + test_display(&0b1010_1011010_00010_11_1_00100_110_01011u32.to_le_bytes(), "{ if (P3.new) memh(R2+#18) = R4 }"); + test_display(&0b1010_1011010_00010_11_1_00100_110_01111u32.to_le_bytes(), "{ if (!P3.new) memh(R2+#18) = R4 }"); + test_display(&0b1010_1011011_00010_11_1_00100_110_01011u32.to_le_bytes(), "{ if (P3.new) memh(R2+#18) = R4.H }"); + test_display(&0b1010_1011011_00010_11_1_00100_110_01111u32.to_le_bytes(), "{ if (!P3.new) memh(R2+#18) = R4.H }"); + test_display(&0b1010_1011100_00010_11_1_00100_110_01011u32.to_le_bytes(), "{ if (P3.new) memw(R2+#36) = R4 }"); + test_display(&0b1010_1011100_00010_11_1_00100_110_01111u32.to_le_bytes(), "{ if (!P3.new) memw(R2+#36) = R4 }"); + + test_display(&0b1010_1011101_00010_11_1_00100_010_01011u32.to_le_bytes(), "{ if (P3) memb(R2+#9) = R4.new }"); + test_display(&0b1010_1011101_00010_11_1_00100_010_01111u32.to_le_bytes(), "{ if (!P3) memb(R2+#9) = R4.new }"); + test_display(&0b1010_1011101_00010_11_1_00100_110_01011u32.to_le_bytes(), "{ if (P3.new) memb(R2+#9) = R4.new }"); + test_display(&0b1010_1011101_00010_11_1_00100_110_01111u32.to_le_bytes(), "{ if (!P3.new) memb(R2+#9) = R4.new }"); + test_display(&0b1010_1011101_00010_11_1_01100_010_01011u32.to_le_bytes(), "{ if (P3) memh(R2+#18) = R4.new }"); + test_display(&0b1010_1011101_00010_11_1_01100_010_01111u32.to_le_bytes(), "{ if (!P3) memh(R2+#18) = R4.new }"); + test_display(&0b1010_1011101_00010_11_1_01100_110_01011u32.to_le_bytes(), "{ if (P3.new) memh(R2+#18) = R4.new }"); + test_display(&0b1010_1011101_00010_11_1_01100_110_01111u32.to_le_bytes(), "{ if (!P3.new) memh(R2+#18) = R4.new }"); + test_display(&0b1010_1011101_00010_11_1_10100_010_01011u32.to_le_bytes(), "{ if (P3) memw(R2+#36) = R4.new }"); + test_display(&0b1010_1011101_00010_11_1_10100_010_01111u32.to_le_bytes(), "{ if (!P3) memw(R2+#36) = R4.new }"); + test_display(&0b1010_1011101_00010_11_1_10100_110_01011u32.to_le_bytes(), "{ if (P3.new) memw(R2+#36) = R4.new }"); + test_display(&0b1010_1011101_00010_11_1_10100_110_01111u32.to_le_bytes(), "{ if (!P3.new) memw(R2+#36) = R4.new }"); + test_invalid(&0b1010_1011101_00010_11_1_11100_010_01011u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_invalid(&0b1010_1011101_00010_11_1_11100_010_01111u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_invalid(&0b1010_1011101_00010_11_1_11100_110_01011u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_invalid(&0b1010_1011101_00010_11_1_11100_110_01111u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_display(&0b1010_1011110_00010_11_1_10100_010_01011u32.to_le_bytes(), "{ if (P3) memd(R2+#72) = R21:20 }"); + test_display(&0b1010_1011110_00010_11_1_10100_010_01111u32.to_le_bytes(), "{ if (!P3) memd(R2+#72) = R21:20 }"); + test_display(&0b1010_1011110_00010_11_1_10100_110_01011u32.to_le_bytes(), "{ if (P3.new) memd(R2+#72) = R21:20 }"); + test_display(&0b1010_1011110_00010_11_1_10100_110_01111u32.to_le_bytes(), "{ if (!P3.new) memd(R2+#72) = R21:20 }"); + + test_display(&0b1010_1101000_00010_11_1_00110_001_01001u32.to_le_bytes(), "{ memb(R2++M1) = R6 }"); + test_invalid(&0b1010_1101001_00010_11_1_00110_001_01001u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_display(&0b1010_1101010_00010_11_1_00110_001_01001u32.to_le_bytes(), "{ memh(R2++M1) = R6 }"); + test_display(&0b1010_1101011_00010_11_1_00110_001_01001u32.to_le_bytes(), "{ memh(R2++M1) = R6.H }"); + test_display(&0b1010_1101100_00010_11_1_00110_001_01001u32.to_le_bytes(), "{ memw(R2++M1) = R6 }"); + test_display(&0b1010_1101101_00010_11_1_00110_001_01001u32.to_le_bytes(), "{ memb(R2++M1) = R6.new }"); + test_display(&0b1010_1101101_00010_11_1_01110_001_01001u32.to_le_bytes(), "{ memh(R2++M1) = R6.new }"); + test_display(&0b1010_1101101_00010_11_1_10110_001_01001u32.to_le_bytes(), "{ memw(R2++M1) = R6.new }"); + test_invalid(&0b1010_1101101_00010_11_1_11110_001_01001u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_display(&0b1010_1101110_00010_11_1_00110_001_01001u32.to_le_bytes(), "{ memd(R2++M1) = R7:6 }"); + test_invalid(&0b1010_1101111_00010_11_1_11110_001_01001u32.to_le_bytes(), DecodeError::InvalidOpcode); + + test_display(&0b1010_1101000_00010_11_1_00110_101_01001u32.to_le_bytes(), "{ memb(R2<<2 + 0x29) = R6 }"); + test_invalid(&0b1010_1101001_00010_11_1_00110_101_01001u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_display(&0b1010_1101010_00010_11_1_00110_101_01001u32.to_le_bytes(), "{ memh(R2<<2 + 0x29) = R6 }"); + test_display(&0b1010_1101011_00010_11_1_00110_101_01001u32.to_le_bytes(), "{ memh(R2<<2 + 0x29) = R6.H }"); + test_display(&0b1010_1101100_00010_11_1_00110_101_01001u32.to_le_bytes(), "{ memw(R2<<2 + 0x29) = R6 }"); + test_display(&0b1010_1101101_00010_11_1_00110_101_01001u32.to_le_bytes(), "{ memb(R2<<2 + 0x29) = R6.new }"); + test_display(&0b1010_1101101_00010_11_1_01110_101_01001u32.to_le_bytes(), "{ memh(R2<<2 + 0x29) = R6.new }"); + test_display(&0b1010_1101101_00010_11_1_10110_101_01001u32.to_le_bytes(), "{ memw(R2<<2 + 0x29) = R6.new }"); + test_invalid(&0b1010_1101101_00010_11_1_11110_101_01001u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_display(&0b1010_1101110_00010_11_1_00110_101_01001u32.to_le_bytes(), "{ memd(R2<<2 + 0x29) = R7:6 }"); + test_invalid(&0b1010_1101111_00010_11_1_11110_101_01001u32.to_le_bytes(), DecodeError::InvalidOpcode); + + test_display(&0b1010_1111000_00010_11_1_00110_001_01001u32.to_le_bytes(), "{ memb(R2++M1:brev) = R6 }"); + test_invalid(&0b1010_1111001_00010_11_1_00110_001_01001u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_display(&0b1010_1111010_00010_11_1_00110_001_01001u32.to_le_bytes(), "{ memh(R2++M1:brev) = R6 }"); + test_display(&0b1010_1111011_00010_11_1_00110_001_01001u32.to_le_bytes(), "{ memh(R2++M1:brev) = R6.H }"); + test_display(&0b1010_1111100_00010_11_1_00110_001_01001u32.to_le_bytes(), "{ memw(R2++M1:brev) = R6 }"); + test_display(&0b1010_1111101_00010_11_1_00110_001_01001u32.to_le_bytes(), "{ memb(R2++M1:brev) = R6.new }"); + test_display(&0b1010_1111101_00010_11_1_01110_001_01001u32.to_le_bytes(), "{ memh(R2++M1:brev) = R6.new }"); + test_display(&0b1010_1111101_00010_11_1_10110_001_01001u32.to_le_bytes(), "{ memw(R2++M1:brev) = R6.new }"); + test_invalid(&0b1010_1111101_00010_11_1_11110_001_01001u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_display(&0b1010_1111110_00010_11_1_00110_001_01001u32.to_le_bytes(), "{ memd(R2++M1:brev) = R7:6 }"); + test_invalid(&0b1010_1111111_00010_11_1_11110_001_01001u32.to_le_bytes(), DecodeError::InvalidOpcode); + + test_display(&0b1010_1111000_00010_11_0_00110_110_01001u32.to_le_bytes(), "{ if (P1) memb(#0x29) = R6 }"); + test_display(&0b1010_1111000_00010_11_0_00110_110_01101u32.to_le_bytes(), "{ if (!P1) memb(#0x29) = R6 }"); + test_display(&0b1010_1111000_00010_11_1_00110_110_01001u32.to_le_bytes(), "{ if (P1.new) memb(#0x29) = R6 }"); + test_display(&0b1010_1111000_00010_11_1_00110_110_01101u32.to_le_bytes(), "{ if (!P1.new) memb(#0x29) = R6 }"); + test_invalid(&0b1010_1111001_00010_11_0_00110_110_01001u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_invalid(&0b1010_1111001_00010_11_0_00110_110_01101u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_invalid(&0b1010_1111001_00010_11_1_00110_110_01001u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_invalid(&0b1010_1111001_00010_11_1_00110_110_01101u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_display(&0b1010_1111010_00010_11_0_00110_110_01001u32.to_le_bytes(), "{ if (P1) memh(#0x29) = R6 }"); + test_display(&0b1010_1111010_00010_11_0_00110_110_01101u32.to_le_bytes(), "{ if (!P1) memh(#0x29) = R6 }"); + test_display(&0b1010_1111010_00010_11_1_00110_110_01001u32.to_le_bytes(), "{ if (P1.new) memh(#0x29) = R6 }"); + test_display(&0b1010_1111010_00010_11_1_00110_110_01101u32.to_le_bytes(), "{ if (!P1.new) memh(#0x29) = R6 }"); + test_display(&0b1010_1111011_00010_11_0_00110_110_01001u32.to_le_bytes(), "{ if (P1) memh(#0x29) = R6.H }"); + test_display(&0b1010_1111011_00010_11_0_00110_110_01101u32.to_le_bytes(), "{ if (!P1) memh(#0x29) = R6.H }"); + test_display(&0b1010_1111011_00010_11_1_00110_110_01001u32.to_le_bytes(), "{ if (P1.new) memh(#0x29) = R6.H }"); + test_display(&0b1010_1111011_00010_11_1_00110_110_01101u32.to_le_bytes(), "{ if (!P1.new) memh(#0x29) = R6.H }"); + test_display(&0b1010_1111100_00010_11_0_00110_110_01001u32.to_le_bytes(), "{ if (P1) memw(#0x29) = R6 }"); + test_display(&0b1010_1111100_00010_11_0_00110_110_01101u32.to_le_bytes(), "{ if (!P1) memw(#0x29) = R6 }"); + test_display(&0b1010_1111100_00010_11_1_00110_110_01001u32.to_le_bytes(), "{ if (P1.new) memw(#0x29) = R6 }"); + test_display(&0b1010_1111100_00010_11_1_00110_110_01101u32.to_le_bytes(), "{ if (!P1.new) memw(#0x29) = R6 }"); + + test_display(&0b1010_1111101_00010_11_000_110_110_01001u32.to_le_bytes(), "{ if (P1) memb(#0x29) = R6.new }"); + test_display(&0b1010_1111101_00010_11_000_110_110_01101u32.to_le_bytes(), "{ if (!P1) memb(#0x29) = R6.new }"); + test_display(&0b1010_1111101_00010_11_001_110_110_01001u32.to_le_bytes(), "{ if (P1) memh(#0x29) = R6.new }"); + test_display(&0b1010_1111101_00010_11_001_110_110_01101u32.to_le_bytes(), "{ if (!P1) memh(#0x29) = R6.new }"); + test_display(&0b1010_1111101_00010_11_010_110_110_01001u32.to_le_bytes(), "{ if (P1) memw(#0x29) = R6.new }"); + test_display(&0b1010_1111101_00010_11_010_110_110_01101u32.to_le_bytes(), "{ if (!P1) memw(#0x29) = R6.new }"); + test_invalid(&0b1010_1111101_00010_11_011_110_110_01001u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_invalid(&0b1010_1111101_00010_11_011_110_110_01101u32.to_le_bytes(), DecodeError::InvalidOpcode); + + test_display(&0b1010_1111101_00010_11_100_110_110_01001u32.to_le_bytes(), "{ if (P1.new) memb(#0x29) = R6.new }"); + test_display(&0b1010_1111101_00010_11_100_110_110_01101u32.to_le_bytes(), "{ if (!P1.new) memb(#0x29) = R6.new }"); + test_display(&0b1010_1111101_00010_11_101_110_110_01001u32.to_le_bytes(), "{ if (P1.new) memh(#0x29) = R6.new }"); + test_display(&0b1010_1111101_00010_11_101_110_110_01101u32.to_le_bytes(), "{ if (!P1.new) memh(#0x29) = R6.new }"); + test_display(&0b1010_1111101_00010_11_110_110_110_01001u32.to_le_bytes(), "{ if (P1.new) memw(#0x29) = R6.new }"); + test_display(&0b1010_1111101_00010_11_110_110_110_01101u32.to_le_bytes(), "{ if (!P1.new) memw(#0x29) = R6.new }"); + test_invalid(&0b1010_1111101_00010_11_111_110_110_01001u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_invalid(&0b1010_1111101_00010_11_111_110_110_01101u32.to_le_bytes(), DecodeError::InvalidOpcode); + + test_display(&0b1010_1111110_00010_11_0_00110_110_01001u32.to_le_bytes(), "{ if (P1) memd(#0x29) = R7:6 }"); + test_display(&0b1010_1111110_00010_11_0_00110_110_01101u32.to_le_bytes(), "{ if (!P1) memd(#0x29) = R7:6 }"); + test_display(&0b1010_1111110_00010_11_1_00110_110_01001u32.to_le_bytes(), "{ if (P1.new) memd(#0x29) = R7:6 }"); + test_display(&0b1010_1111110_00010_11_1_00110_110_01101u32.to_le_bytes(), "{ if (!P1.new) memd(#0x29) = R7:6 }"); +} + +#[test] +fn inst_1011() { test_display(&0b1011_1000001_00100_11_1_0_0000_001_10110u32.to_le_bytes(), "{ R22 = add(R4, #-31999) }"); +} + +#[test] +fn inst_1111() { 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); @@ -299,6 +540,6 @@ fn general() { test_invalid(&0b1111_1011101_00100_11_1_00011_001_00110u32.to_le_bytes(), DecodeError::InvalidOpcode); test_display(&0b1111_1101000_00100_11_1_00011_001_00110u32.to_le_bytes(), "{ if (P1.new) R7:6 = contains(R4, R3) }"); +} // TODO: testcase for Rn=add(pc,#nn) -} -- cgit v1.1