| 1 | /* |
| 2 | * Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved. |
| 3 | * |
| 4 | * This program is free software; you can redistribute it and/or modify |
| 5 | * it under the terms of the GNU General Public License as published by |
| 6 | * the Free Software Foundation; either version 2 of the License, or |
| 7 | * (at your option) any later version. |
| 8 | * |
| 9 | * This program is distributed in the hope that it will be useful, |
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | * GNU General Public License for more details. |
| 13 | * |
| 14 | * You should have received a copy of the GNU General Public License |
| 15 | * along with this program; if not, see <http://www.gnu.org/licenses/>. |
| 16 | */ |
| 17 | |
| 18 | |
| 19 | /*********************************************/ |
| 20 | /* Jump instructions */ |
| 21 | /*********************************************/ |
| 22 | |
| 23 | #define A_JDIR A_JUMP |
| 24 | #define A_CJNEWDIR A_JUMP |
| 25 | #define A_CJOLDDIR A_JUMP |
| 26 | #define A_NEWVALUEJ A_JUMP,A_DOTNEWVALUE,A_MEMLIKE_PACKET_RULES |
| 27 | #define A_JINDIR A_JUMP,A_INDIRECT |
| 28 | #define A_JINDIRNEW A_JUMP,A_INDIRECT |
| 29 | #define A_JINDIROLD A_JUMP,A_INDIRECT |
| 30 | |
| 31 | Q6INSN(J2_jump,"jump #r22:2",ATTRIBS(A_JDIR), "direct unconditional jump", |
| 32 | {fIMMEXT(riV); fPCALIGN(riV); fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}) |
| 33 | |
| 34 | Q6INSN(J2_jumpr,"jumpr Rs32",ATTRIBS(A_JINDIR), "indirect unconditional jump", |
| 35 | {fJUMPR(RsN,RsV,COF_TYPE_JUMPR);}) |
| 36 | |
| 37 | Q6INSN(J2_jumprh,"jumprh Rs32",ATTRIBS(A_JINDIR, A_HINTED_COF), "indirect unconditional jump", |
| 38 | {fJUMPR(RsN,RsV,COF_TYPE_JUMPR);}) |
| 39 | |
| 40 | #define OLDCOND_JUMP(TAG,OPER,OPER2,ATTRIB,DESCR,SEMANTICS) \ |
| 41 | Q6INSN(TAG##t,"if (Pu4) "OPER":nt "OPER2,ATTRIB,DESCR,{fBRANCH_SPECULATE_STALL(fLSBOLD(PuV),,SPECULATE_NOT_TAKEN,12,0); if (fLSBOLD(PuV)) { SEMANTICS; }}) \ |
| 42 | Q6INSN(TAG##f,"if (!Pu4) "OPER":nt "OPER2,ATTRIB,DESCR,{fBRANCH_SPECULATE_STALL(fLSBOLDNOT(PuV),,SPECULATE_NOT_TAKEN,12,0); if (fLSBOLDNOT(PuV)) { SEMANTICS; }}) \ |
| 43 | Q6INSN(TAG##tpt,"if (Pu4) "OPER":t "OPER2,ATTRIB,DESCR,{fBRANCH_SPECULATE_STALL(fLSBOLD(PuV),,SPECULATE_TAKEN,12,0); if (fLSBOLD(PuV)) { SEMANTICS; }}) \ |
| 44 | Q6INSN(TAG##fpt,"if (!Pu4) "OPER":t "OPER2,ATTRIB,DESCR,{fBRANCH_SPECULATE_STALL(fLSBOLDNOT(PuV),,SPECULATE_TAKEN,12,0); if (fLSBOLDNOT(PuV)) { SEMANTICS; }}) |
| 45 | |
| 46 | OLDCOND_JUMP(J2_jump,"jump","#r15:2",ATTRIBS(A_CJOLDDIR),"direct conditional jump", |
| 47 | fIMMEXT(riV);fPCALIGN(riV); fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);) |
| 48 | |
| 49 | OLDCOND_JUMP(J2_jumpr,"jumpr","Rs32",ATTRIBS(A_JINDIROLD),"indirect conditional jump", |
| 50 | fJUMPR(RsN,RsV,COF_TYPE_JUMPR);) |
| 51 | |
| 52 | #define NEWCOND_JUMP(TAG,OPER,OPER2,ATTRIB,DESCR,SEMANTICS)\ |
| 53 | Q6INSN(TAG##tnew,"if (Pu4.new) "OPER":nt "OPER2,ATTRIB,DESCR,{fBRANCH_SPECULATE_STALL(fLSBNEW(PuN),, SPECULATE_NOT_TAKEN , 12,0)} {if(fLSBNEW(PuN)){SEMANTICS;}})\ |
| 54 | Q6INSN(TAG##fnew,"if (!Pu4.new) "OPER":nt "OPER2,ATTRIB,DESCR,{fBRANCH_SPECULATE_STALL(fLSBNEWNOT(PuN),, SPECULATE_NOT_TAKEN , 12,0)} {if(fLSBNEWNOT(PuN)){SEMANTICS;}})\ |
| 55 | Q6INSN(TAG##tnewpt,"if (Pu4.new) "OPER":t "OPER2,ATTRIB,DESCR,{fBRANCH_SPECULATE_STALL(fLSBNEW(PuN),, SPECULATE_TAKEN , 12,0)} {if(fLSBNEW(PuN)){SEMANTICS;}})\ |
| 56 | Q6INSN(TAG##fnewpt,"if (!Pu4.new) "OPER":t "OPER2,ATTRIB,DESCR,{fBRANCH_SPECULATE_STALL(fLSBNEWNOT(PuN),, SPECULATE_TAKEN , 12,0)} {if(fLSBNEWNOT(PuN)){SEMANTICS;}}) |
| 57 | |
| 58 | NEWCOND_JUMP(J2_jump,"jump","#r15:2",ATTRIBS(A_CJNEWDIR,A_ARCHV2),"direct conditional jump", |
| 59 | fIMMEXT(riV); fPCALIGN(riV); fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMPNEW);) |
| 60 | |
| 61 | NEWCOND_JUMP(J2_jumpr,"jumpr","Rs32",ATTRIBS(A_JINDIRNEW,A_ARCHV3),"indirect conditional jump", |
| 62 | fJUMPR(RsN,RsV,COF_TYPE_JUMPR);) |
| 63 | |
| 64 | |
| 65 | |
| 66 | Q6INSN(J4_hintjumpr,"hintjr(Rs32)",ATTRIBS(A_JINDIR),"hint indirect conditional jump", |
| 67 | {fHINTJR(RsV);}) |
| 68 | |
| 69 | |
| 70 | /*********************************************/ |
| 71 | /* Compound Compare-Jumps */ |
| 72 | /*********************************************/ |
| 73 | Q6INSN(J2_jumprz,"if (Rs32!=#0) jump:nt #r13:2",ATTRIBS(A_CJNEWDIR,A_ARCHV3),"direct conditional jump if register true", |
| 74 | {fBRANCH_SPECULATE_STALL((RsV!=0), , SPECULATE_NOT_TAKEN,12,0) if (RsV != 0) { fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}}) |
| 75 | |
| 76 | Q6INSN(J2_jumprnz,"if (Rs32==#0) jump:nt #r13:2",ATTRIBS(A_CJNEWDIR,A_ARCHV3),"direct conditional jump if register false", |
| 77 | {fBRANCH_SPECULATE_STALL((RsV==0), , SPECULATE_NOT_TAKEN,12,0) if (RsV == 0) {fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}}) |
| 78 | |
| 79 | Q6INSN(J2_jumprzpt,"if (Rs32!=#0) jump:t #r13:2",ATTRIBS(A_CJNEWDIR,A_ARCHV3),"direct conditional jump if register true", |
| 80 | {fBRANCH_SPECULATE_STALL((RsV!=0), , SPECULATE_TAKEN,12,0) if (RsV != 0) { fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}}) |
| 81 | |
| 82 | Q6INSN(J2_jumprnzpt,"if (Rs32==#0) jump:t #r13:2",ATTRIBS(A_CJNEWDIR,A_ARCHV3),"direct conditional jump if register false", |
| 83 | {fBRANCH_SPECULATE_STALL((RsV==0), , SPECULATE_TAKEN,12,0) if (RsV == 0) {fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}}) |
| 84 | |
| 85 | Q6INSN(J2_jumprgtez,"if (Rs32>=#0) jump:nt #r13:2",ATTRIBS(A_CJNEWDIR,A_ARCHV3),"direct conditional jump if register greater or equal to zero", |
| 86 | {fBRANCH_SPECULATE_STALL((RsV>=0), , SPECULATE_NOT_TAKEN,12,0) if (RsV>=0) { fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}}) |
| 87 | |
| 88 | Q6INSN(J2_jumprgtezpt,"if (Rs32>=#0) jump:t #r13:2",ATTRIBS(A_CJNEWDIR,A_ARCHV3),"direct conditional jump if register greater or equal to zero", |
| 89 | {fBRANCH_SPECULATE_STALL((RsV>=0), , SPECULATE_TAKEN,12,0) if (RsV>=0) { fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}}) |
| 90 | |
| 91 | Q6INSN(J2_jumprltez,"if (Rs32<=#0) jump:nt #r13:2",ATTRIBS(A_CJNEWDIR,A_ARCHV3),"direct conditional jump if register less than or equal to zero", |
| 92 | {fBRANCH_SPECULATE_STALL((RsV<=0), , SPECULATE_NOT_TAKEN,12,0) if (RsV<=0) { fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}}) |
| 93 | |
| 94 | Q6INSN(J2_jumprltezpt,"if (Rs32<=#0) jump:t #r13:2",ATTRIBS(A_CJNEWDIR,A_ARCHV3),"direct conditional jump if register less than or equal to zero", |
| 95 | {fBRANCH_SPECULATE_STALL((RsV<=0), , SPECULATE_TAKEN,12,0) if (RsV<=0) { fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}}) |
| 96 | |
| 97 | |
| 98 | |
| 99 | /*********************************************/ |
| 100 | /* V4 Compound Compare-Jumps */ |
| 101 | /*********************************************/ |
| 102 | |
| 103 | |
| 104 | /* V4 compound compare jumps (CJ) */ |
| 105 | #define STD_CMPJUMP(TAG,TST,TSTSEM)\ |
| 106 | Q6INSN(J4_##TAG##_tp0_jump_nt, "p0="TST"; if (p0.new) jump:nt #r9:2", ATTRIBS(A_CJNEWDIR,A_NEWCMPJUMP),"compound compare-jump", {fPART1(fWRITE_P0(f8BITSOF(TSTSEM))) fBRANCH_SPECULATE_STALL(fLSBNEW0,,SPECULATE_NOT_TAKEN,13,0) if (fLSBNEW0) {fIMMEXT(riV); fPCALIGN(riV); fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}})\ |
| 107 | Q6INSN(J4_##TAG##_fp0_jump_nt, "p0="TST"; if (!p0.new) jump:nt #r9:2", ATTRIBS(A_CJNEWDIR,A_NEWCMPJUMP),"compound compare-jump",{fPART1(fWRITE_P0(f8BITSOF(TSTSEM))) fBRANCH_SPECULATE_STALL(fLSBNEW0NOT,,SPECULATE_NOT_TAKEN,13,0) if (fLSBNEW0NOT) {fIMMEXT(riV); fPCALIGN(riV); fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}})\ |
| 108 | Q6INSN(J4_##TAG##_tp0_jump_t, "p0="TST"; if (p0.new) jump:t #r9:2", ATTRIBS(A_CJNEWDIR,A_NEWCMPJUMP),"compound compare-jump", {fPART1(fWRITE_P0(f8BITSOF(TSTSEM))) fBRANCH_SPECULATE_STALL(fLSBNEW0,,SPECULATE_TAKEN,13,0) if (fLSBNEW0) {fIMMEXT(riV); fPCALIGN(riV); fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}})\ |
| 109 | Q6INSN(J4_##TAG##_fp0_jump_t, "p0="TST"; if (!p0.new) jump:t #r9:2", ATTRIBS(A_CJNEWDIR,A_NEWCMPJUMP),"compound compare-jump", {fPART1(fWRITE_P0(f8BITSOF(TSTSEM))) fBRANCH_SPECULATE_STALL(fLSBNEW0NOT,,SPECULATE_TAKEN,13,0) if (fLSBNEW0NOT) {fIMMEXT(riV); fPCALIGN(riV); fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}})\ |
| 110 | Q6INSN(J4_##TAG##_tp1_jump_nt, "p1="TST"; if (p1.new) jump:nt #r9:2", ATTRIBS(A_CJNEWDIR,A_NEWCMPJUMP),"compound compare-jump", {fPART1(fWRITE_P1(f8BITSOF(TSTSEM))) fBRANCH_SPECULATE_STALL(fLSBNEW1,,SPECULATE_NOT_TAKEN,13,0) if (fLSBNEW1) {fIMMEXT(riV); fPCALIGN(riV); fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}})\ |
| 111 | Q6INSN(J4_##TAG##_fp1_jump_nt, "p1="TST"; if (!p1.new) jump:nt #r9:2", ATTRIBS(A_CJNEWDIR,A_NEWCMPJUMP),"compound compare-jump",{fPART1(fWRITE_P1(f8BITSOF(TSTSEM))) fBRANCH_SPECULATE_STALL(fLSBNEW1NOT,,SPECULATE_NOT_TAKEN,13,0) if (fLSBNEW1NOT) {fIMMEXT(riV); fPCALIGN(riV); fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}})\ |
| 112 | Q6INSN(J4_##TAG##_tp1_jump_t, "p1="TST"; if (p1.new) jump:t #r9:2", ATTRIBS(A_CJNEWDIR,A_NEWCMPJUMP),"compound compare-jump", {fPART1(fWRITE_P1(f8BITSOF(TSTSEM))) fBRANCH_SPECULATE_STALL(fLSBNEW1,,SPECULATE_TAKEN,13,0) if (fLSBNEW1) {fIMMEXT(riV); fPCALIGN(riV); fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}})\ |
| 113 | Q6INSN(J4_##TAG##_fp1_jump_t, "p1="TST"; if (!p1.new) jump:t #r9:2", ATTRIBS(A_CJNEWDIR,A_NEWCMPJUMP),"compound compare-jump", {fPART1(fWRITE_P1(f8BITSOF(TSTSEM))) fBRANCH_SPECULATE_STALL(fLSBNEW1NOT,,SPECULATE_TAKEN,13,0) if (fLSBNEW1NOT) {fIMMEXT(riV); fPCALIGN(riV); fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}}) |
| 114 | |
| 115 | |
| 116 | STD_CMPJUMP(cmpeqi,"cmp.eq(Rs16,#U5)",(RsV==UiV)) |
| 117 | STD_CMPJUMP(cmpgti,"cmp.gt(Rs16,#U5)",(RsV>UiV)) |
| 118 | STD_CMPJUMP(cmpgtui,"cmp.gtu(Rs16,#U5)",(fCAST4u(RsV)>UiV)) |
| 119 | |
| 120 | STD_CMPJUMP(cmpeqn1,"cmp.eq(Rs16,#-1)",(RsV==-1)) |
| 121 | STD_CMPJUMP(cmpgtn1,"cmp.gt(Rs16,#-1)",(RsV>-1)) |
| 122 | STD_CMPJUMP(tstbit0,"tstbit(Rs16,#0)",(RsV & 1)) |
| 123 | |
| 124 | STD_CMPJUMP(cmpeq,"cmp.eq(Rs16,Rt16)",(RsV==RtV)) |
| 125 | STD_CMPJUMP(cmpgt,"cmp.gt(Rs16,Rt16)",(RsV>RtV)) |
| 126 | STD_CMPJUMP(cmpgtu,"cmp.gtu(Rs16,Rt16)",(fCAST4u(RsV)>RtV)) |
| 127 | |
| 128 | |
| 129 | |
| 130 | /* V4 jump and transfer (CJ) */ |
| 131 | Q6INSN(J4_jumpseti,"Rd16=#U6 ; jump #r9:2",ATTRIBS(A_JDIR), "direct unconditional jump and set register to immediate", |
| 132 | {fIMMEXT(riV); fPCALIGN(riV); RdV=UiV; fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}) |
| 133 | |
| 134 | Q6INSN(J4_jumpsetr,"Rd16=Rs16 ; jump #r9:2",ATTRIBS(A_JDIR), "direct unconditional jump and transfer register", |
| 135 | {fIMMEXT(riV); fPCALIGN(riV); RdV=RsV; fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}) |
| 136 | |
| 137 | |
| 138 | /* V4 new-value jumps (NCJ) */ |
| 139 | #define STD_CMPJUMPNEWRS(TAG,TST,TSTSEM)\ |
| 140 | Q6INSN(J4_##TAG##_jumpnv_t, "if ("TST") jump:t #r9:2", ATTRIBS(A_NEWVALUEJ),"compound compare-jump",{fBRANCH_SPECULATE_STALL(TSTSEM,,SPECULATE_TAKEN,13,0);if (TSTSEM) {fIMMEXT(riV); fPCALIGN(riV); fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}})\ |
| 141 | Q6INSN(J4_##TAG##_jumpnv_nt,"if ("TST") jump:nt #r9:2",ATTRIBS(A_NEWVALUEJ),"compound compare-jump",{fBRANCH_SPECULATE_STALL(TSTSEM,,SPECULATE_NOT_TAKEN,13,0); if (TSTSEM) {fIMMEXT(riV); fPCALIGN(riV); fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}}) |
| 142 | |
| 143 | |
| 144 | |
| 145 | |
| 146 | STD_CMPJUMPNEWRS(cmpeqi_t,"cmp.eq(Ns8.new,#U5)",(fNEWREG(NsN)==(UiV))) |
| 147 | STD_CMPJUMPNEWRS(cmpeqi_f,"!cmp.eq(Ns8.new,#U5)",(fNEWREG(NsN)!=(UiV))) |
| 148 | STD_CMPJUMPNEWRS(cmpgti_t,"cmp.gt(Ns8.new,#U5)",(fNEWREG(NsN)>(UiV))) |
| 149 | STD_CMPJUMPNEWRS(cmpgti_f,"!cmp.gt(Ns8.new,#U5)",!(fNEWREG(NsN)>(UiV))) |
| 150 | STD_CMPJUMPNEWRS(cmpgtui_t,"cmp.gtu(Ns8.new,#U5)",(fCAST4u(fNEWREG(NsN))>(UiV))) |
| 151 | STD_CMPJUMPNEWRS(cmpgtui_f,"!cmp.gtu(Ns8.new,#U5)",!(fCAST4u(fNEWREG(NsN))>(UiV))) |
| 152 | |
| 153 | |
| 154 | STD_CMPJUMPNEWRS(cmpeqn1_t,"cmp.eq(Ns8.new,#-1)",(fNEWREG(NsN)==(-1))) |
| 155 | STD_CMPJUMPNEWRS(cmpeqn1_f,"!cmp.eq(Ns8.new,#-1)",(fNEWREG(NsN)!=(-1))) |
| 156 | STD_CMPJUMPNEWRS(cmpgtn1_t,"cmp.gt(Ns8.new,#-1)",(fNEWREG(NsN)>(-1))) |
| 157 | STD_CMPJUMPNEWRS(cmpgtn1_f,"!cmp.gt(Ns8.new,#-1)",!(fNEWREG(NsN)>(-1))) |
| 158 | STD_CMPJUMPNEWRS(tstbit0_t,"tstbit(Ns8.new,#0)",((fNEWREG(NsN)) & 1)) |
| 159 | STD_CMPJUMPNEWRS(tstbit0_f,"!tstbit(Ns8.new,#0)",!((fNEWREG(NsN)) & 1)) |
| 160 | |
| 161 | |
| 162 | STD_CMPJUMPNEWRS(cmpeq_t, "cmp.eq(Ns8.new,Rt32)", (fNEWREG(NsN)==RtV)) |
| 163 | STD_CMPJUMPNEWRS(cmpgt_t, "cmp.gt(Ns8.new,Rt32)", (fNEWREG(NsN)>RtV)) |
| 164 | STD_CMPJUMPNEWRS(cmpgtu_t,"cmp.gtu(Ns8.new,Rt32)",(fCAST4u(fNEWREG(NsN))>fCAST4u(RtV))) |
| 165 | STD_CMPJUMPNEWRS(cmplt_t, "cmp.gt(Rt32,Ns8.new)", (RtV>fNEWREG(NsN))) |
| 166 | STD_CMPJUMPNEWRS(cmpltu_t,"cmp.gtu(Rt32,Ns8.new)",(fCAST4u(RtV)>fCAST4u(fNEWREG(NsN)))) |
| 167 | STD_CMPJUMPNEWRS(cmpeq_f, "!cmp.eq(Ns8.new,Rt32)", (fNEWREG(NsN)!=RtV)) |
| 168 | STD_CMPJUMPNEWRS(cmpgt_f, "!cmp.gt(Ns8.new,Rt32)", !(fNEWREG(NsN)>RtV)) |
| 169 | STD_CMPJUMPNEWRS(cmpgtu_f,"!cmp.gtu(Ns8.new,Rt32)",!(fCAST4u(fNEWREG(NsN))>fCAST4u(RtV))) |
| 170 | STD_CMPJUMPNEWRS(cmplt_f, "!cmp.gt(Rt32,Ns8.new)", !(RtV>fNEWREG(NsN))) |
| 171 | STD_CMPJUMPNEWRS(cmpltu_f,"!cmp.gtu(Rt32,Ns8.new)",!(fCAST4u(RtV)>fCAST4u(fNEWREG(NsN)))) |
| 172 | |
| 173 | |
| 174 | |
| 175 | |
| 176 | |
| 177 | /*********************************************/ |
| 178 | /* Subroutine Call instructions */ |
| 179 | /*********************************************/ |
| 180 | |
| 181 | #define CDIR_STD A_CALL |
| 182 | #define CINDIR_STD A_CALL,A_INDIRECT |
| 183 | |
| 184 | Q6INSN(J2_call,"call #r22:2",ATTRIBS(CDIR_STD), "direct unconditional call", |
| 185 | {fIMMEXT(riV); fPCALIGN(riV); fCALL(fREAD_PC()+riV); }) |
| 186 | |
| 187 | Q6INSN(J2_callt,"if (Pu4) call #r15:2",ATTRIBS(CDIR_STD),"direct conditional call if true", |
| 188 | {fIMMEXT(riV); fPCALIGN(riV); fBRANCH_SPECULATE_STALL(fLSBOLD(PuV),,SPECULATE_NOT_TAKEN,12,0); if (fLSBOLD(PuV)) { fCALL(fREAD_PC()+riV); }}) |
| 189 | |
| 190 | Q6INSN(J2_callf,"if (!Pu4) call #r15:2",ATTRIBS(CDIR_STD),"direct conditional call if false", |
| 191 | {fIMMEXT(riV); fPCALIGN(riV); fBRANCH_SPECULATE_STALL(fLSBOLDNOT(PuV),,SPECULATE_NOT_TAKEN,12,0);if (fLSBOLDNOT(PuV)) { fCALL(fREAD_PC()+riV); }}) |
| 192 | |
| 193 | Q6INSN(J2_callr,"callr Rs32",ATTRIBS(CINDIR_STD), "indirect unconditional call", |
| 194 | { fCALLR(RsV); }) |
| 195 | |
| 196 | Q6INSN(J2_callrt,"if (Pu4) callr Rs32",ATTRIBS(CINDIR_STD),"indirect conditional call if true", |
| 197 | {fBRANCH_SPECULATE_STALL(fLSBOLD(PuV),,SPECULATE_NOT_TAKEN,12,0);if (fLSBOLD(PuV)) { fCALLR(RsV); }}) |
| 198 | |
| 199 | Q6INSN(J2_callrf,"if (!Pu4) callr Rs32",ATTRIBS(CINDIR_STD),"indirect conditional call if false", |
| 200 | {fBRANCH_SPECULATE_STALL(fLSBOLDNOT(PuV),,SPECULATE_NOT_TAKEN,12,0);if (fLSBOLDNOT(PuV)) { fCALLR(RsV); }}) |
| 201 | |
| 202 | Q6INSN(J2_callrh,"callrh Rs32",ATTRIBS(CINDIR_STD, A_HINTED_COF), "hinted indirect unconditional call", |
| 203 | { fCALLR(RsV); }) |
| 204 | |
| 205 | |
| 206 | |
| 207 | /*********************************************/ |
| 208 | /* HW Loop instructions */ |
| 209 | /*********************************************/ |
| 210 | |
| 211 | Q6INSN(J2_loop0r,"loop0(#r7:2,Rs32)",ATTRIBS(),"Initialize HW loop 0", |
| 212 | { fIMMEXT(riV); fPCALIGN(riV); |
| 213 | fWRITE_LOOP_REGS0(/*sa,lc*/ fREAD_PC()+riV, RsV); |
| 214 | fSET_LPCFG(0); |
| 215 | }) |
| 216 | |
| 217 | Q6INSN(J2_loop1r,"loop1(#r7:2,Rs32)",ATTRIBS(),"Initialize HW loop 1", |
| 218 | { fIMMEXT(riV); fPCALIGN(riV); |
| 219 | fWRITE_LOOP_REGS1(/*sa,lc*/ fREAD_PC()+riV, RsV); |
| 220 | }) |
| 221 | |
| 222 | Q6INSN(J2_loop0i,"loop0(#r7:2,#U10)",ATTRIBS(),"Initialize HW loop 0", |
| 223 | { fIMMEXT(riV); fPCALIGN(riV); |
| 224 | fWRITE_LOOP_REGS0(/*sa,lc*/ fREAD_PC()+riV, UiV); |
| 225 | fSET_LPCFG(0); |
| 226 | }) |
| 227 | |
| 228 | Q6INSN(J2_loop1i,"loop1(#r7:2,#U10)",ATTRIBS(),"Initialize HW loop 1", |
| 229 | { fIMMEXT(riV); fPCALIGN(riV); |
| 230 | fWRITE_LOOP_REGS1(/*sa,lc*/ fREAD_PC()+riV, UiV); |
| 231 | }) |
| 232 | |
| 233 | |
| 234 | Q6INSN(J2_ploop1sr,"p3=sp1loop0(#r7:2,Rs32)",ATTRIBS(A_ARCHV2),"Initialize HW loop 0", |
| 235 | { fIMMEXT(riV); fPCALIGN(riV); |
| 236 | fWRITE_LOOP_REGS0(/*sa,lc*/ fREAD_PC()+riV, RsV); |
| 237 | fSET_LPCFG(1); |
| 238 | fWRITE_P3(0); |
| 239 | }) |
| 240 | Q6INSN(J2_ploop1si,"p3=sp1loop0(#r7:2,#U10)",ATTRIBS(A_ARCHV2),"Initialize HW loop 0", |
| 241 | { fIMMEXT(riV); fPCALIGN(riV); |
| 242 | fWRITE_LOOP_REGS0(/*sa,lc*/ fREAD_PC()+riV, UiV); |
| 243 | fSET_LPCFG(1); |
| 244 | fWRITE_P3(0); |
| 245 | }) |
| 246 | |
| 247 | Q6INSN(J2_ploop2sr,"p3=sp2loop0(#r7:2,Rs32)",ATTRIBS(A_ARCHV2),"Initialize HW loop 0", |
| 248 | { fIMMEXT(riV); fPCALIGN(riV); |
| 249 | fWRITE_LOOP_REGS0(/*sa,lc*/ fREAD_PC()+riV, RsV); |
| 250 | fSET_LPCFG(2); |
| 251 | fWRITE_P3(0); |
| 252 | }) |
| 253 | Q6INSN(J2_ploop2si,"p3=sp2loop0(#r7:2,#U10)",ATTRIBS(A_ARCHV2),"Initialize HW loop 0", |
| 254 | { fIMMEXT(riV); fPCALIGN(riV); |
| 255 | fWRITE_LOOP_REGS0(/*sa,lc*/ fREAD_PC()+riV, UiV); |
| 256 | fSET_LPCFG(2); |
| 257 | fWRITE_P3(0); |
| 258 | }) |
| 259 | |
| 260 | Q6INSN(J2_ploop3sr,"p3=sp3loop0(#r7:2,Rs32)",ATTRIBS(A_ARCHV2),"Initialize HW loop 0", |
| 261 | { fIMMEXT(riV); fPCALIGN(riV); |
| 262 | fWRITE_LOOP_REGS0(/*sa,lc*/ fREAD_PC()+riV, RsV); |
| 263 | fSET_LPCFG(3); |
| 264 | fWRITE_P3(0); |
| 265 | }) |
| 266 | Q6INSN(J2_ploop3si,"p3=sp3loop0(#r7:2,#U10)",ATTRIBS(A_ARCHV2),"Initialize HW loop 0", |
| 267 | { fIMMEXT(riV); fPCALIGN(riV); |
| 268 | fWRITE_LOOP_REGS0(/*sa,lc*/ fREAD_PC()+riV, UiV); |
| 269 | fSET_LPCFG(3); |
| 270 | fWRITE_P3(0); |
| 271 | }) |
| 272 | |
| 273 | |
| 274 | |
| 275 | Q6INSN(J2_endloop01,"endloop01",ATTRIBS(A_HWLOOP0_END,A_HWLOOP1_END),"Loopend for inner and outer loop", |
| 276 | { |
| 277 | |
| 278 | /* V2: With predicate control */ |
| 279 | if (fGET_LPCFG) { |
| 280 | fHIDE( if (fGET_LPCFG >= 2) { /* Nothing */ } else ) |
| 281 | if (fGET_LPCFG==1) { |
| 282 | fWRITE_P3(0xff); |
| 283 | } |
| 284 | fSET_LPCFG(fGET_LPCFG-1); |
| 285 | } |
| 286 | |
| 287 | /* check if iterate */ |
| 288 | if (fREAD_LC0>1) { |
| 289 | fBRANCH(fREAD_SA0,COF_TYPE_LOOPEND0); |
| 290 | /* decrement loop count */ |
| 291 | fWRITE_LC0(fREAD_LC0-1); |
| 292 | } else { |
| 293 | /* check if iterate */ |
| 294 | if (fREAD_LC1>1) { |
| 295 | fBRANCH(fREAD_SA1,COF_TYPE_LOOPEND1); |
| 296 | /* decrement loop count */ |
| 297 | fWRITE_LC1(fREAD_LC1-1); |
| 298 | } |
| 299 | } |
| 300 | |
| 301 | }) |
| 302 | |
| 303 | Q6INSN(J2_endloop0,"endloop0",ATTRIBS(A_HWLOOP0_END),"Loopend for inner loop", |
| 304 | { |
| 305 | |
| 306 | /* V2: With predicate control */ |
| 307 | if (fGET_LPCFG) { |
| 308 | fHIDE( if (fGET_LPCFG >= 2) { /* Nothing */ } else ) |
| 309 | if (fGET_LPCFG==1) { |
| 310 | fWRITE_P3(0xff); |
| 311 | } |
| 312 | fSET_LPCFG(fGET_LPCFG-1); |
| 313 | } |
| 314 | |
| 315 | /* check if iterate */ |
| 316 | if (fREAD_LC0>1) { |
| 317 | fBRANCH(fREAD_SA0,COF_TYPE_LOOPEND0); |
| 318 | /* decrement loop count */ |
| 319 | fWRITE_LC0(fREAD_LC0-1); |
| 320 | } |
| 321 | }) |
| 322 | |
| 323 | Q6INSN(J2_endloop1,"endloop1",ATTRIBS(A_HWLOOP1_END),"Loopend for outer loop", |
| 324 | { |
| 325 | /* check if iterate */ |
| 326 | if (fREAD_LC1>1) { |
| 327 | fBRANCH(fREAD_SA1,COF_TYPE_LOOPEND1); |
| 328 | /* decrement loop count */ |
| 329 | fWRITE_LC1(fREAD_LC1-1); |
| 330 | } |
| 331 | }) |