qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

shift.idef (30695B)


      1 /*
      2  *  Copyright(c) 2019-2021 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  * S-type Instructions
     20  */
     21 
     22 /**********************************************/
     23 /* SHIFTS                                     */
     24 /**********************************************/
     25 
     26 /* NOTE: Rdd = Rs *right* shifts don't make sense */
     27 /* NOTE: Rd[d] = Rs[s] *right* shifts with saturation don't make sense */
     28 
     29 
     30 #define RSHIFTTYPES(TAGEND,REGD,REGS,REGSTYPE,ACC,ACCSRC,SAT,SATOPT,ATTRS) \
     31 Q6INSN(S2_asr_r_##TAGEND,#REGD "32" #ACC "=asr(" #REGS "32,Rt32)" #SATOPT,ATTRIBS(ATTRS), \
     32     "Arithmetic Shift Right by Register", \
     33     {  \
     34         fHIDE(size4s_t) shamt=fSXTN(7,32,RtV);\
     35         REGD##V = SAT(ACCSRC ACC fBIDIR_ASHIFTR(REGS##V,shamt,REGSTYPE));  \
     36     })\
     37 \
     38 Q6INSN(S2_asl_r_##TAGEND,#REGD "32" #ACC "=asl(" #REGS "32,Rt32)" #SATOPT,ATTRIBS(ATTRS), \
     39     "Arithmetic Shift Left by Register", \
     40     {  \
     41         fHIDE(size4s_t) shamt=fSXTN(7,32,RtV);\
     42         REGD##V = SAT(ACCSRC ACC fBIDIR_ASHIFTL(REGS##V,shamt,REGSTYPE));  \
     43     })\
     44 \
     45 Q6INSN(S2_lsr_r_##TAGEND,#REGD "32" #ACC "=lsr(" #REGS "32,Rt32)" #SATOPT,ATTRIBS(ATTRS), \
     46     "Logical Shift Right by Register", \
     47     {  \
     48         fHIDE(size4s_t) shamt=fSXTN(7,32,RtV);\
     49         REGD##V = SAT(ACCSRC ACC fBIDIR_LSHIFTR(REGS##V,shamt,REGSTYPE));  \
     50     })\
     51 \
     52 Q6INSN(S2_lsl_r_##TAGEND,#REGD "32" #ACC "=lsl(" #REGS "32,Rt32)" #SATOPT,ATTRIBS(ATTRS), \
     53     "Logical Shift Left by Register", \
     54     {  \
     55         fHIDE(size4s_t) shamt=fSXTN(7,32,RtV);\
     56         REGD##V = SAT(ACCSRC ACC fBIDIR_LSHIFTL(REGS##V,shamt,REGSTYPE));  \
     57     })
     58 
     59 RSHIFTTYPES(r,Rd,Rs,4_8,,,fECHO,,)
     60 RSHIFTTYPES(p,Rdd,Rss,8_8,,,fECHO,,)
     61 RSHIFTTYPES(r_acc,Rx,Rs,4_8,+,RxV,fECHO,,)
     62 RSHIFTTYPES(p_acc,Rxx,Rss,8_8,+,RxxV,fECHO,,)
     63 RSHIFTTYPES(r_nac,Rx,Rs,4_8,-,RxV,fECHO,,)
     64 RSHIFTTYPES(p_nac,Rxx,Rss,8_8,-,RxxV,fECHO,,)
     65 
     66 RSHIFTTYPES(r_and,Rx,Rs,4_8,&,RxV,fECHO,,)
     67 RSHIFTTYPES(r_or,Rx,Rs,4_8,|,RxV,fECHO,,)
     68 RSHIFTTYPES(p_and,Rxx,Rss,8_8,&,RxxV,fECHO,,)
     69 RSHIFTTYPES(p_or,Rxx,Rss,8_8,|,RxxV,fECHO,,)
     70 RSHIFTTYPES(p_xor,Rxx,Rss,8_8,^,RxxV,fECHO,,)
     71 
     72 
     73 #undef RSHIFTTYPES
     74 
     75 /* Register shift with saturation */
     76 #define RSATSHIFTTYPES(TAGEND,REGD,REGS,REGSTYPE) \
     77 Q6INSN(S2_asr_r_##TAGEND,#REGD "32" "=asr(" #REGS "32,Rt32):sat",ATTRIBS(), \
     78     "Arithmetic Shift Right by Register", \
     79     {  \
     80         fHIDE(size4s_t) shamt=fSXTN(7,32,RtV);\
     81         REGD##V = fBIDIR_ASHIFTR_SAT(REGS##V,shamt,REGSTYPE);  \
     82     })\
     83 \
     84 Q6INSN(S2_asl_r_##TAGEND,#REGD "32" "=asl(" #REGS "32,Rt32):sat",ATTRIBS(), \
     85     "Arithmetic Shift Left by Register", \
     86     {  \
     87         fHIDE(size4s_t) shamt=fSXTN(7,32,RtV);\
     88         REGD##V = fBIDIR_ASHIFTL_SAT(REGS##V,shamt,REGSTYPE);  \
     89     })
     90 
     91 RSATSHIFTTYPES(r_sat,Rd,Rs,4_8)
     92 
     93 
     94 
     95 
     96 
     97 #define ISHIFTTYPES(TAGEND,SIZE,REGD,REGS,REGSTYPE,ACC,ACCSRC,SAT,SATOPT,ATTRS) \
     98 Q6INSN(S2_asr_i_##TAGEND,#REGD "32" #ACC "=asr(" #REGS "32,#u" #SIZE ")" #SATOPT,ATTRIBS(ATTRS), \
     99     "Arithmetic Shift Right by Immediate", \
    100     { REGD##V = SAT(ACCSRC ACC fASHIFTR(REGS##V,uiV,REGSTYPE)); }) \
    101 \
    102 Q6INSN(S2_lsr_i_##TAGEND,#REGD "32" #ACC "=lsr(" #REGS "32,#u" #SIZE ")" #SATOPT,ATTRIBS(ATTRS), \
    103     "Logical Shift Right by Immediate", \
    104     { REGD##V = SAT(ACCSRC ACC fLSHIFTR(REGS##V,uiV,REGSTYPE)); }) \
    105 \
    106 Q6INSN(S2_asl_i_##TAGEND,#REGD "32" #ACC "=asl(" #REGS "32,#u" #SIZE ")" #SATOPT,ATTRIBS(ATTRS), \
    107     "Shift Left by Immediate", \
    108     { REGD##V = SAT(ACCSRC ACC fASHIFTL(REGS##V,uiV,REGSTYPE)); }) \
    109 Q6INSN(S6_rol_i_##TAGEND,#REGD "32" #ACC "=rol(" #REGS "32,#u" #SIZE ")" #SATOPT,ATTRIBS(ATTRS), \
    110     "Rotate Left by Immediate", \
    111     { REGD##V = SAT(ACCSRC ACC fROTL(REGS##V,uiV,REGSTYPE)); })
    112 
    113 
    114 #define ISHIFTTYPES_ONLY_ASL(TAGEND,SIZE,REGD,REGS,REGSTYPE,ACC,ACCSRC,SAT,SATOPT) \
    115 Q6INSN(S2_asl_i_##TAGEND,#REGD "32" #ACC "=asl(" #REGS "32,#u" #SIZE ")" #SATOPT,ATTRIBS(), \
    116     "", \
    117     { REGD##V = SAT(ACCSRC ACC fASHIFTL(REGS##V,uiV,REGSTYPE)); })
    118 
    119 #define ISHIFTTYPES_ONLY_ASR(TAGEND,SIZE,REGD,REGS,REGSTYPE,ACC,ACCSRC,SAT,SATOPT) \
    120 Q6INSN(S2_asr_i_##TAGEND,#REGD "32" #ACC "=asr(" #REGS "32,#u" #SIZE ")" #SATOPT,ATTRIBS(), \
    121     "", \
    122     { REGD##V = SAT(ACCSRC ACC fASHIFTR(REGS##V,uiV,REGSTYPE)); })
    123 
    124 
    125 #define ISHIFTTYPES_NOASR(TAGEND,SIZE,REGD,REGS,REGSTYPE,ACC,ACCSRC,SAT,SATOPT) \
    126 Q6INSN(S2_lsr_i_##TAGEND,#REGD "32" #ACC "=lsr(" #REGS "32,#u" #SIZE ")" #SATOPT,ATTRIBS(), \
    127     "Logical Shift Right by Register", \
    128     { REGD##V = SAT(ACCSRC ACC fLSHIFTR(REGS##V,uiV,REGSTYPE)); }) \
    129 Q6INSN(S2_asl_i_##TAGEND,#REGD "32" #ACC "=asl(" #REGS "32,#u" #SIZE ")" #SATOPT,ATTRIBS(), \
    130     "Shift Left by Register", \
    131     { REGD##V = SAT(ACCSRC ACC fASHIFTL(REGS##V,uiV,REGSTYPE)); }) \
    132 Q6INSN(S6_rol_i_##TAGEND,#REGD "32" #ACC "=rol(" #REGS "32,#u" #SIZE ")" #SATOPT,ATTRIBS(), \
    133     "Rotate Left by Immediate", \
    134     { REGD##V = SAT(ACCSRC ACC fROTL(REGS##V,uiV,REGSTYPE)); })
    135 
    136 
    137 
    138 ISHIFTTYPES(r,5,Rd,Rs,4_4,,,fECHO,,)
    139 ISHIFTTYPES(p,6,Rdd,Rss,8_8,,,fECHO,,)
    140 ISHIFTTYPES(r_acc,5,Rx,Rs,4_4,+,RxV,fECHO,,)
    141 ISHIFTTYPES(p_acc,6,Rxx,Rss,8_8,+,RxxV,fECHO,,)
    142 ISHIFTTYPES(r_nac,5,Rx,Rs,4_4,-,RxV,fECHO,,)
    143 ISHIFTTYPES(p_nac,6,Rxx,Rss,8_8,-,RxxV,fECHO,,)
    144 
    145 ISHIFTTYPES_NOASR(r_xacc,5,Rx,Rs,4_4,^, RxV,fECHO,)
    146 ISHIFTTYPES_NOASR(p_xacc,6,Rxx,Rss,8_8,^, RxxV,fECHO,)
    147 
    148 ISHIFTTYPES(r_and,5,Rx,Rs,4_4,&,RxV,fECHO,,)
    149 ISHIFTTYPES(r_or,5,Rx,Rs,4_4,|,RxV,fECHO,,)
    150 ISHIFTTYPES(p_and,6,Rxx,Rss,8_8,&,RxxV,fECHO,,)
    151 ISHIFTTYPES(p_or,6,Rxx,Rss,8_8,|,RxxV,fECHO,,)
    152 
    153 ISHIFTTYPES_ONLY_ASL(r_sat,5,Rd,Rs,4_8,,,fSAT,:sat)
    154 
    155 
    156 Q6INSN(S2_asr_i_r_rnd,"Rd32=asr(Rs32,#u5):rnd",ATTRIBS(),
    157        "Shift right with round",
    158        { RdV = fASHIFTR(((fASHIFTR(RsV,uiV,4_8))+1),1,8_8); })
    159 
    160 
    161 Q6INSN(S2_asr_i_p_rnd,"Rdd32=asr(Rss32,#u6):rnd",ATTRIBS(), "Shift right with round",
    162 { fHIDE(size8u_t tmp;)
    163   fHIDE(size8u_t rnd;)
    164   tmp = fASHIFTR(RssV,uiV,8_8);
    165   rnd = tmp & 1;
    166   RddV = fASHIFTR(tmp,1,8_8) + rnd; })
    167 
    168 
    169 Q6INSN(S4_lsli,"Rd32=lsl(#s6,Rt32)",ATTRIBS(), "Shift an immediate left by register amount",
    170 {
    171     fHIDE(size4s_t) shamt = fSXTN(7,32,RtV);
    172     RdV = fBIDIR_LSHIFTL(siV,shamt,4_8);
    173 })
    174 
    175 
    176 
    177 
    178 Q6INSN(S2_addasl_rrri,"Rd32=addasl(Rt32,Rs32,#u3)",ATTRIBS(),
    179     "Shift left by small amount and add",
    180     { RdV = RtV + fASHIFTL(RsV,uiV,4_4); })
    181 
    182 
    183 
    184 #define SHIFTOPI(TAGEND,INNEROP,INNERSEM)\
    185 Q6INSN(S4_andi_##TAGEND,"Rx32=and(#u8,"INNEROP")",,"Shift-op",{RxV=fIMMEXT(uiV)&INNERSEM;})\
    186 Q6INSN(S4_ori_##TAGEND, "Rx32=or(#u8,"INNEROP")",,"Shift-op",{RxV=fIMMEXT(uiV)|INNERSEM;})\
    187 Q6INSN(S4_addi_##TAGEND,"Rx32=add(#u8,"INNEROP")",,"Shift-op",{RxV=fIMMEXT(uiV)+INNERSEM;})\
    188 Q6INSN(S4_subi_##TAGEND,"Rx32=sub(#u8,"INNEROP")",,"Shift-op",{RxV=fIMMEXT(uiV)-INNERSEM;})
    189 
    190 
    191 SHIFTOPI(asl_ri,"asl(Rx32,#U5)",(RxV<<UiV))
    192 SHIFTOPI(lsr_ri,"lsr(Rx32,#U5)",(((unsigned int)RxV)>>UiV))
    193 
    194 
    195 /**********************************************/
    196 /* PERMUTES                                   */
    197 /**********************************************/
    198 Q6INSN(S2_valignib,"Rdd32=valignb(Rtt32,Rss32,#u3)",
    199 ATTRIBS(), "Vector align bytes",
    200 {
    201   RddV = (fLSHIFTR(RssV,uiV*8,8_8))|(fASHIFTL(RttV,((8-uiV)*8),8_8));
    202 })
    203 
    204 Q6INSN(S2_valignrb,"Rdd32=valignb(Rtt32,Rss32,Pu4)",
    205 ATTRIBS(), "Align with register",
    206 { RddV = fLSHIFTR(RssV,(PuV&0x7)*8,8_8)|(fASHIFTL(RttV,(8-(PuV&0x7))*8,8_8));})
    207 
    208 Q6INSN(S2_vspliceib,"Rdd32=vspliceb(Rss32,Rtt32,#u3)",
    209 ATTRIBS(), "Vector splice bytes",
    210 { RddV = fASHIFTL(RttV,uiV*8,8_8) | fZXTN(uiV*8,64,RssV); })
    211 
    212 Q6INSN(S2_vsplicerb,"Rdd32=vspliceb(Rss32,Rtt32,Pu4)",
    213 ATTRIBS(), "Splice with register",
    214 { RddV = fASHIFTL(RttV,(PuV&7)*8,8_8) | fZXTN((PuV&7)*8,64,RssV); })
    215 
    216 Q6INSN(S2_vsplatrh,"Rdd32=vsplath(Rs32)",
    217 ATTRIBS(), "Vector splat halfwords from register",
    218 {
    219     fHIDE(int i;)
    220     for (i=0;i<4;i++) {
    221         fSETHALF(i,RddV, fGETHALF(0,RsV));
    222     }
    223 })
    224 
    225 
    226 Q6INSN(S2_vsplatrb,"Rd32=vsplatb(Rs32)",
    227 ATTRIBS(), "Vector splat bytes from register",
    228 {
    229     fHIDE(int i;)
    230     for (i=0;i<4;i++) {
    231         fSETBYTE(i,RdV, fGETBYTE(0,RsV));
    232     }
    233 })
    234 
    235 Q6INSN(S6_vsplatrbp,"Rdd32=vsplatb(Rs32)",
    236 ATTRIBS(), "Vector splat bytes from register",
    237 {
    238     fHIDE(int i;)
    239     for (i=0;i<8;i++) {
    240         fSETBYTE(i,RddV, fGETBYTE(0,RsV));
    241     }
    242 })
    243 
    244 
    245 
    246 /**********************************************/
    247 /* Insert/Extract[u]                          */
    248 /**********************************************/
    249 
    250 Q6INSN(S2_insert,"Rx32=insert(Rs32,#u5,#U5)",
    251 ATTRIBS(), "Insert bits",
    252 {
    253     fHIDE(int) width=uiV;
    254     fHIDE(int) offset=UiV;
    255     /* clear bits in Rxx where new bits go */
    256     RxV &= ~(((fCONSTLL(1)<<width)-1)<<offset);
    257     /* OR in new bits */
    258     RxV |= ((RsV & ((fCONSTLL(1)<<width)-1)) << offset);
    259 })
    260 
    261 
    262 Q6INSN(S2_tableidxb,"Rx32=tableidxb(Rs32,#u4,#S6):raw",
    263 ATTRIBS(A_ARCHV2), "Extract and insert bits",
    264 {
    265         fHIDE(int) width=uiV;
    266         fHIDE(int) offset=SiV;
    267         fHIDE(int) field = fEXTRACTU_BIDIR(RsV,width,offset);
    268         fINSERT_BITS(RxV,width,0,field);
    269 })
    270 
    271 Q6INSN(S2_tableidxh,"Rx32=tableidxh(Rs32,#u4,#S6):raw",
    272 ATTRIBS(A_ARCHV2), "Extract and insert bits",
    273 {
    274         fHIDE(int) width=uiV;
    275         fHIDE(int) offset=SiV+1;
    276         fHIDE(int) field = fEXTRACTU_BIDIR(RsV,width,offset);
    277         fINSERT_BITS(RxV,width,1,field);
    278 })
    279 
    280 Q6INSN(S2_tableidxw,"Rx32=tableidxw(Rs32,#u4,#S6):raw",
    281 ATTRIBS(A_ARCHV2), "Extract and insert bits",
    282 {
    283         fHIDE(int) width=uiV;
    284         fHIDE(int) offset=SiV+2;
    285         fHIDE(int) field = fEXTRACTU_BIDIR(RsV,width,offset);
    286         fINSERT_BITS(RxV,width,2,field);
    287 })
    288 
    289 Q6INSN(S2_tableidxd,"Rx32=tableidxd(Rs32,#u4,#S6):raw",
    290 ATTRIBS(A_ARCHV2), "Extract and insert bits",
    291 {
    292     fHIDE(int) width=uiV;
    293     fHIDE(int) offset=SiV+3;
    294     fHIDE(int) field = fEXTRACTU_BIDIR(RsV,width,offset);
    295     fINSERT_BITS(RxV,width,3,field);
    296 })
    297 
    298 
    299 Q6INSN(A4_bitspliti,"Rdd32=bitsplit(Rs32,#u5)",
    300 ATTRIBS(), "Split a bitfield into two registers",
    301 {
    302     fSETWORD(1,RddV,(fCAST4_4u(RsV)>>uiV));
    303     fSETWORD(0,RddV,fZXTN(uiV,32,RsV));
    304 })
    305 
    306 Q6INSN(A4_bitsplit,"Rdd32=bitsplit(Rs32,Rt32)",
    307 ATTRIBS(), "Split a bitfield into two registers",
    308 {
    309     fHIDE(size4u_t) shamt = fZXTN(5,32,RtV);
    310     fSETWORD(1,RddV,(fCAST4_4u(RsV)>>shamt));
    311     fSETWORD(0,RddV,fZXTN(shamt,32,RsV));
    312 })
    313 
    314 
    315 
    316 
    317 Q6INSN(S4_extract,"Rd32=extract(Rs32,#u5,#U5)",
    318 ATTRIBS(), "Extract signed bitfield",
    319 {
    320     fHIDE(int) width=uiV;
    321     fHIDE(int) offset=UiV;
    322     RdV = fSXTN(width,32,(fCAST4_4u(RsV) >> offset));
    323 })
    324 
    325 
    326 Q6INSN(S2_extractu,"Rd32=extractu(Rs32,#u5,#U5)",
    327 ATTRIBS(), "Extract unsigned bitfield",
    328 {
    329     fHIDE(int) width=uiV;
    330     fHIDE(int) offset=UiV;
    331     RdV = fZXTN(width,32,(fCAST4_4u(RsV) >> offset));
    332 })
    333 
    334 Q6INSN(S2_insertp,"Rxx32=insert(Rss32,#u6,#U6)",
    335 ATTRIBS(), "Insert bits",
    336 {
    337     fHIDE(int) width=uiV;
    338     fHIDE(int) offset=UiV;
    339     /* clear bits in Rxx where new bits go */
    340     RxxV &= ~(((fCONSTLL(1)<<width)-1)<<offset);
    341     /* OR in new bits */
    342     RxxV |= ((RssV & ((fCONSTLL(1)<<width)-1)) << offset);
    343 })
    344 
    345 
    346 Q6INSN(S4_extractp,"Rdd32=extract(Rss32,#u6,#U6)",
    347 ATTRIBS(), "Extract signed bitfield",
    348 {
    349     fHIDE(int) width=uiV;
    350     fHIDE(int) offset=UiV;
    351     RddV = fSXTN(width,64,(fCAST8_8u(RssV) >> offset));
    352 })
    353 
    354 
    355 Q6INSN(S2_extractup,"Rdd32=extractu(Rss32,#u6,#U6)",
    356 ATTRIBS(), "Extract unsigned bitfield",
    357 {
    358     fHIDE(int) width=uiV;
    359     fHIDE(int) offset=UiV;
    360     RddV = fZXTN(width,64,(fCAST8_8u(RssV) >> offset));
    361 })
    362 
    363 
    364 
    365 
    366 Q6INSN(S2_mask,"Rd32=mask(#u5,#U5)",
    367 ATTRIBS(), "Form mask from immediate",
    368 {
    369     RdV = ((1<<uiV)-1) << UiV;
    370 })
    371 
    372 
    373 
    374 
    375 
    376 Q6INSN(S2_insert_rp,"Rx32=insert(Rs32,Rtt32)",
    377 ATTRIBS(), "Insert bits",
    378 {
    379     fHIDE(int) width=fZXTN(6,32,(fGETWORD(1,RttV)));
    380     fHIDE(int) offset=fSXTN(7,32,(fGETWORD(0,RttV)));
    381     fHIDE(size8u_t) mask = ((fCONSTLL(1)<<width)-1);
    382     if (offset < 0) {
    383         RxV = 0;
    384     } else {
    385         /* clear bits in Rxx where new bits go */
    386         RxV &= ~(mask<<offset);
    387         /* OR in new bits */
    388         RxV |= ((RsV & mask) << offset);
    389     }
    390 })
    391 
    392 
    393 Q6INSN(S4_extract_rp,"Rd32=extract(Rs32,Rtt32)",
    394 ATTRIBS(), "Extract signed bitfield",
    395 {
    396     fHIDE(int) width=fZXTN(6,32,(fGETWORD(1,RttV)));
    397     fHIDE(int) offset=fSXTN(7,32,(fGETWORD(0,RttV)));
    398     RdV = fSXTN(width,64,fBIDIR_LSHIFTR(fCAST4_8u(RsV),offset,4_8));
    399 })
    400 
    401 
    402 
    403 Q6INSN(S2_extractu_rp,"Rd32=extractu(Rs32,Rtt32)",
    404 ATTRIBS(), "Extract unsigned bitfield",
    405 {
    406     fHIDE(int) width=fZXTN(6,32,(fGETWORD(1,RttV)));
    407     fHIDE(int) offset=fSXTN(7,32,(fGETWORD(0,RttV)));
    408     RdV = fZXTN(width,64,fBIDIR_LSHIFTR(fCAST4_8u(RsV),offset,4_8));
    409 })
    410 
    411 Q6INSN(S2_insertp_rp,"Rxx32=insert(Rss32,Rtt32)",
    412 ATTRIBS(), "Insert bits",
    413 {
    414     fHIDE(int) width=fZXTN(6,32,(fGETWORD(1,RttV)));
    415     fHIDE(int) offset=fSXTN(7,32,(fGETWORD(0,RttV)));
    416     fHIDE(size8u_t) mask = ((fCONSTLL(1)<<width)-1);
    417     if (offset < 0) {
    418         RxxV = 0;
    419     } else {
    420         /* clear bits in Rxx where new bits go */
    421         RxxV &= ~(mask<<offset);
    422         /* OR in new bits */
    423         RxxV |= ((RssV & mask) << offset);
    424     }
    425 })
    426 
    427 
    428 Q6INSN(S4_extractp_rp,"Rdd32=extract(Rss32,Rtt32)",
    429 ATTRIBS(), "Extract signed bitfield",
    430 {
    431     fHIDE(int) width=fZXTN(6,32,(fGETWORD(1,RttV)));
    432     fHIDE(int) offset=fSXTN(7,32,(fGETWORD(0,RttV)));
    433     RddV = fSXTN(width,64,fBIDIR_LSHIFTR(fCAST8_8u(RssV),offset,8_8));
    434 })
    435 
    436 
    437 Q6INSN(S2_extractup_rp,"Rdd32=extractu(Rss32,Rtt32)",
    438 ATTRIBS(), "Extract unsigned bitfield",
    439 {
    440     fHIDE(int) width=fZXTN(6,32,(fGETWORD(1,RttV)));
    441     fHIDE(int) offset=fSXTN(7,32,(fGETWORD(0,RttV)));
    442     RddV = fZXTN(width,64,fBIDIR_LSHIFTR(fCAST8_8u(RssV),offset,8_8));
    443 })
    444 
    445 /**********************************************/
    446 /* tstbit/setbit/clrbit                       */
    447 /**********************************************/
    448 
    449 Q6INSN(S2_tstbit_i,"Pd4=tstbit(Rs32,#u5)",
    450 ATTRIBS(), "Test a bit",
    451 {
    452     PdV = f8BITSOF((RsV & (1<<uiV)) != 0);
    453 })
    454 
    455 Q6INSN(S4_ntstbit_i,"Pd4=!tstbit(Rs32,#u5)",
    456 ATTRIBS(), "Test a bit",
    457 {
    458     PdV = f8BITSOF((RsV & (1<<uiV)) == 0);
    459 })
    460 
    461 Q6INSN(S2_setbit_i,"Rd32=setbit(Rs32,#u5)",
    462 ATTRIBS(), "Set a bit",
    463 {
    464     RdV = (RsV | (1<<uiV));
    465 })
    466 
    467 Q6INSN(S2_togglebit_i,"Rd32=togglebit(Rs32,#u5)",
    468 ATTRIBS(), "Toggle a bit",
    469 {
    470     RdV = (RsV ^ (1<<uiV));
    471 })
    472 
    473 Q6INSN(S2_clrbit_i,"Rd32=clrbit(Rs32,#u5)",
    474 ATTRIBS(), "Clear a bit",
    475 {
    476     RdV = (RsV & (~(1<<uiV)));
    477 })
    478 
    479 
    480 
    481 /* using a register */
    482 Q6INSN(S2_tstbit_r,"Pd4=tstbit(Rs32,Rt32)",
    483 ATTRIBS(), "Test a bit",
    484 {
    485     PdV = f8BITSOF((fCAST4_8u(RsV) & fBIDIR_LSHIFTL(1,fSXTN(7,32,RtV),4_8)) != 0);
    486 })
    487 
    488 Q6INSN(S4_ntstbit_r,"Pd4=!tstbit(Rs32,Rt32)",
    489 ATTRIBS(), "Test a bit",
    490 {
    491     PdV = f8BITSOF((fCAST4_8u(RsV) & fBIDIR_LSHIFTL(1,fSXTN(7,32,RtV),4_8)) == 0);
    492 })
    493 
    494 Q6INSN(S2_setbit_r,"Rd32=setbit(Rs32,Rt32)",
    495 ATTRIBS(), "Set a bit",
    496 {
    497     RdV = (RsV | fBIDIR_LSHIFTL(1,fSXTN(7,32,RtV),4_8));
    498 })
    499 
    500 Q6INSN(S2_togglebit_r,"Rd32=togglebit(Rs32,Rt32)",
    501 ATTRIBS(), "Toggle a bit",
    502 {
    503     RdV = (RsV ^ fBIDIR_LSHIFTL(1,fSXTN(7,32,RtV),4_8));
    504 })
    505 
    506 Q6INSN(S2_clrbit_r,"Rd32=clrbit(Rs32,Rt32)",
    507 ATTRIBS(), "Clear a bit",
    508 {
    509     RdV = (RsV & (~(fBIDIR_LSHIFTL(1,fSXTN(7,32,RtV),4_8))));
    510 })
    511 
    512 
    513 /**********************************************/
    514 /* vector shifting                            */
    515 /**********************************************/
    516 
    517 /* Half Vector Immediate Shifts */
    518 
    519 Q6INSN(S2_asr_i_vh,"Rdd32=vasrh(Rss32,#u4)",ATTRIBS(),
    520     "Vector Arithmetic Shift Right by Immediate",
    521 {
    522     fHIDE(int i;)
    523     for (i=0;i<4;i++) {
    524         fSETHALF(i,RddV, (fGETHALF(i,RssV)>>uiV));
    525     }
    526 })
    527 
    528 
    529 Q6INSN(S2_lsr_i_vh,"Rdd32=vlsrh(Rss32,#u4)",ATTRIBS(),
    530     "Vector Logical Shift Right by Immediate",
    531 {
    532     fHIDE(int i;)
    533     for (i=0;i<4;i++) {
    534         fSETHALF(i,RddV, (fGETUHALF(i,RssV)>>uiV));
    535     }
    536 })
    537 
    538 Q6INSN(S2_asl_i_vh,"Rdd32=vaslh(Rss32,#u4)",ATTRIBS(),
    539     "Vector Arithmetic Shift Left by Immediate",
    540 {
    541     fHIDE(int i;)
    542     for (i=0;i<4;i++) {
    543         fSETHALF(i,RddV, (fGETHALF(i,RssV)<<uiV));
    544     }
    545 })
    546 
    547 /* Half Vector Register Shifts */
    548 
    549 Q6INSN(S2_asr_r_vh,"Rdd32=vasrh(Rss32,Rt32)",ATTRIBS(),
    550     "Vector Arithmetic Shift Right by Register",
    551 {
    552     fHIDE(int i;)
    553     for (i=0;i<4;i++) {
    554         fSETHALF(i,RddV, fBIDIR_ASHIFTR(fGETHALF(i,RssV),fSXTN(7,32,RtV),2_8));
    555     }
    556 })
    557 
    558 Q6INSN(S5_asrhub_rnd_sat,"Rd32=vasrhub(Rss32,#u4):raw",,
    559     "Vector Arithmetic Shift Right by Immediate with Round, Saturate, and Pack",
    560 {
    561     fHIDE(int i;)
    562     for (i=0;i<4;i++) {
    563         fSETBYTE(i,RdV, fSATUB( ((fGETHALF(i,RssV) >> uiV )+1)>>1  ));
    564     }
    565 })
    566 
    567 Q6INSN(S5_asrhub_sat,"Rd32=vasrhub(Rss32,#u4):sat",,
    568     "Vector Arithmetic Shift Right by Immediate with Saturate and Pack",
    569 {
    570     fHIDE(int i;)
    571     for (i=0;i<4;i++) {
    572         fSETBYTE(i,RdV, fSATUB( fGETHALF(i,RssV) >> uiV ));
    573     }
    574 })
    575 
    576 
    577 
    578 Q6INSN(S5_vasrhrnd,"Rdd32=vasrh(Rss32,#u4):raw",,
    579     "Vector Arithmetic Shift Right by Immediate with Round",
    580 {
    581     fHIDE(int i;)
    582     for (i=0;i<4;i++) {
    583         fSETHALF(i,RddV, ( ((fGETHALF(i,RssV) >> uiV)+1)>>1  ));
    584     }
    585 })
    586 
    587 
    588 Q6INSN(S2_asl_r_vh,"Rdd32=vaslh(Rss32,Rt32)",ATTRIBS(),
    589     "Vector Arithmetic Shift Left by Register",
    590 {
    591     fHIDE(int i;)
    592     for (i=0;i<4;i++) {
    593         fSETHALF(i,RddV, fBIDIR_ASHIFTL(fGETHALF(i,RssV),fSXTN(7,32,RtV),2_8));
    594     }
    595 })
    596 
    597 
    598 
    599 Q6INSN(S2_lsr_r_vh,"Rdd32=vlsrh(Rss32,Rt32)",ATTRIBS(),
    600     "Vector Logical Shift Right by Register",
    601 {
    602     fHIDE(int i;)
    603     for (i=0;i<4;i++) {
    604         fSETHALF(i,RddV, fBIDIR_LSHIFTR(fGETUHALF(i,RssV),fSXTN(7,32,RtV),2_8));
    605     }
    606 })
    607 
    608 
    609 Q6INSN(S2_lsl_r_vh,"Rdd32=vlslh(Rss32,Rt32)",ATTRIBS(),
    610     "Vector Logical Shift Left by Register",
    611 {
    612     fHIDE(int i;)
    613     for (i=0;i<4;i++) {
    614         fSETHALF(i,RddV, fBIDIR_LSHIFTL(fGETUHALF(i,RssV),fSXTN(7,32,RtV),2_8));
    615     }
    616 })
    617 
    618 
    619 
    620 
    621 /* Word Vector Immediate Shifts */
    622 
    623 Q6INSN(S2_asr_i_vw,"Rdd32=vasrw(Rss32,#u5)",ATTRIBS(),
    624     "Vector Arithmetic Shift Right by Immediate",
    625 {
    626     fHIDE(int i;)
    627     for (i=0;i<2;i++) {
    628         fSETWORD(i,RddV,(fGETWORD(i,RssV)>>uiV));
    629     }
    630 })
    631 
    632 
    633 
    634 Q6INSN(S2_asr_i_svw_trun,"Rd32=vasrw(Rss32,#u5)",ATTRIBS(A_ARCHV2),
    635     "Vector Arithmetic Shift Right by Immediate with Truncate and Pack",
    636 {
    637     fHIDE(int i;)
    638     for (i=0;i<2;i++) {
    639         fSETHALF(i,RdV,fGETHALF(0,(fGETWORD(i,RssV)>>uiV)));
    640     }
    641 })
    642 
    643 Q6INSN(S2_asr_r_svw_trun,"Rd32=vasrw(Rss32,Rt32)",ATTRIBS(A_ARCHV2),
    644     "Vector Arithmetic Shift Right truncate and Pack",
    645 {
    646     fHIDE(int i;)
    647     for (i=0;i<2;i++) {
    648         fSETHALF(i,RdV,fGETHALF(0,fBIDIR_ASHIFTR(fGETWORD(i,RssV),fSXTN(7,32,RtV),4_8)));
    649     }
    650 })
    651 
    652 
    653 Q6INSN(S2_lsr_i_vw,"Rdd32=vlsrw(Rss32,#u5)",ATTRIBS(),
    654     "Vector Logical Shift Right by Immediate",
    655 {
    656     fHIDE(int i;)
    657     for (i=0;i<2;i++) {
    658         fSETWORD(i,RddV,(fGETUWORD(i,RssV)>>uiV));
    659     }
    660 })
    661 
    662 Q6INSN(S2_asl_i_vw,"Rdd32=vaslw(Rss32,#u5)",ATTRIBS(),
    663     "Vector Arithmetic Shift Left by Immediate",
    664 {
    665     fHIDE(int i;)
    666     for (i=0;i<2;i++) {
    667         fSETWORD(i,RddV,(fGETWORD(i,RssV)<<uiV));
    668     }
    669 })
    670 
    671 /* Word Vector Register Shifts */
    672 
    673 Q6INSN(S2_asr_r_vw,"Rdd32=vasrw(Rss32,Rt32)",ATTRIBS(),
    674     "Vector Arithmetic Shift Right by Register",
    675 {
    676     fHIDE(int i;)
    677     for (i=0;i<2;i++) {
    678         fSETWORD(i,RddV, fBIDIR_ASHIFTR(fGETWORD(i,RssV),fSXTN(7,32,RtV),4_8));
    679     }
    680 })
    681 
    682 
    683 
    684 Q6INSN(S2_asl_r_vw,"Rdd32=vaslw(Rss32,Rt32)",ATTRIBS(),
    685     "Vector Arithmetic Shift Left by Register",
    686 {
    687     fHIDE(int i;)
    688     for (i=0;i<2;i++) {
    689         fSETWORD(i,RddV, fBIDIR_ASHIFTL(fGETWORD(i,RssV),fSXTN(7,32,RtV),4_8));
    690     }
    691 })
    692 
    693 
    694 Q6INSN(S2_lsr_r_vw,"Rdd32=vlsrw(Rss32,Rt32)",ATTRIBS(),
    695     "Vector Logical Shift Right by Register",
    696 {
    697     fHIDE(int i;)
    698     for (i=0;i<2;i++) {
    699         fSETWORD(i,RddV, fBIDIR_LSHIFTR(fGETUWORD(i,RssV),fSXTN(7,32,RtV),4_8));
    700     }
    701 })
    702 
    703 
    704 
    705 Q6INSN(S2_lsl_r_vw,"Rdd32=vlslw(Rss32,Rt32)",ATTRIBS(),
    706     "Vector Logical Shift Left by Register",
    707 {
    708     fHIDE(int i;)
    709     for (i=0;i<2;i++) {
    710         fSETWORD(i,RddV, fBIDIR_LSHIFTL(fGETUWORD(i,RssV),fSXTN(7,32,RtV),4_8));
    711     }
    712 })
    713 
    714 
    715 
    716 
    717 
    718 /**********************************************/
    719 /* Vector SXT/ZXT/SAT/TRUN/RNDPACK            */
    720 /**********************************************/
    721 
    722 
    723 Q6INSN(S2_vrndpackwh,"Rd32=vrndwh(Rss32)",ATTRIBS(),
    724 "Round and Pack vector of words to Halfwords",
    725 {
    726     fHIDE(int i;)
    727     for (i=0;i<2;i++) {
    728         fSETHALF(i,RdV,fGETHALF(1,(fGETWORD(i,RssV)+0x08000)));
    729     }
    730 })
    731 
    732 Q6INSN(S2_vrndpackwhs,"Rd32=vrndwh(Rss32):sat",ATTRIBS(),
    733 "Round and Pack vector of words to Halfwords",
    734 {
    735     fHIDE(int i;)
    736     for (i=0;i<2;i++) {
    737         fSETHALF(i,RdV,fGETHALF(1,fSAT(fGETWORD(i,RssV)+0x08000)));
    738     }
    739 })
    740 
    741 Q6INSN(S2_vsxtbh,"Rdd32=vsxtbh(Rs32)",ATTRIBS(A_ARCHV2),
    742 "Vector sign extend byte to half",
    743 {
    744     fHIDE(int i;)
    745     for (i=0;i<4;i++) {
    746         fSETHALF(i,RddV,fGETBYTE(i,RsV));
    747     }
    748 })
    749 
    750 Q6INSN(S2_vzxtbh,"Rdd32=vzxtbh(Rs32)",ATTRIBS(),
    751 "Vector zero extend byte to half",
    752 {
    753     fHIDE(int i;)
    754     for (i=0;i<4;i++) {
    755         fSETHALF(i,RddV,fGETUBYTE(i,RsV));
    756     }
    757 })
    758 
    759 Q6INSN(S2_vsathub,"Rd32=vsathub(Rss32)",ATTRIBS(),
    760 "Vector saturate half to unsigned byte",
    761 {
    762     fHIDE(int i;)
    763     for (i=0;i<4;i++) {
    764         fSETBYTE(i,RdV,fSATUN(8,fGETHALF(i,RssV)));
    765     }
    766 })
    767 
    768 
    769 
    770 
    771 
    772 Q6INSN(S2_svsathub,"Rd32=vsathub(Rs32)",ATTRIBS(A_ARCHV2),
    773 "Vector saturate half to unsigned byte",
    774 {
    775     fSETBYTE(0,RdV,fSATUN(8,fGETHALF(0,RsV)));
    776     fSETBYTE(1,RdV,fSATUN(8,fGETHALF(1,RsV)));
    777     fSETBYTE(2,RdV,0);
    778     fSETBYTE(3,RdV,0);
    779 })
    780 
    781 Q6INSN(S2_svsathb,"Rd32=vsathb(Rs32)",ATTRIBS(A_ARCHV2),
    782 "Vector saturate half to signed byte",
    783 {
    784     fSETBYTE(0,RdV,fSATN(8,fGETHALF(0,RsV)));
    785     fSETBYTE(1,RdV,fSATN(8,fGETHALF(1,RsV)));
    786     fSETBYTE(2,RdV,0);
    787     fSETBYTE(3,RdV,0);
    788 })
    789 
    790 
    791 Q6INSN(S2_vsathb,"Rd32=vsathb(Rss32)",ATTRIBS(A_ARCHV2),
    792 "Vector saturate half to signed byte",
    793 {
    794     fHIDE(int i;)
    795     for (i=0;i<4;i++) {
    796         fSETBYTE(i,RdV,fSATN(8,fGETHALF(i,RssV)));
    797     }
    798 })
    799 
    800 Q6INSN(S2_vtrunohb,"Rd32=vtrunohb(Rss32)",ATTRIBS(A_ARCHV2),
    801 "Vector truncate half to byte: take high",
    802 {
    803     fHIDE(int i;)
    804     for (i=0;i<4;i++) {
    805         fSETBYTE(i,RdV,fGETBYTE(i*2+1,RssV));
    806     }
    807 })
    808 
    809 Q6INSN(S2_vtrunewh,"Rdd32=vtrunewh(Rss32,Rtt32)",ATTRIBS(A_ARCHV2),
    810 "Vector truncate word to half: take low",
    811 {
    812     fSETHALF(0,RddV,fGETHALF(0,RttV));
    813     fSETHALF(1,RddV,fGETHALF(2,RttV));
    814     fSETHALF(2,RddV,fGETHALF(0,RssV));
    815     fSETHALF(3,RddV,fGETHALF(2,RssV));
    816 })
    817 
    818 Q6INSN(S2_vtrunowh,"Rdd32=vtrunowh(Rss32,Rtt32)",ATTRIBS(A_ARCHV2),
    819 "Vector truncate word to half: take high",
    820 {
    821     fSETHALF(0,RddV,fGETHALF(1,RttV));
    822     fSETHALF(1,RddV,fGETHALF(3,RttV));
    823     fSETHALF(2,RddV,fGETHALF(1,RssV));
    824     fSETHALF(3,RddV,fGETHALF(3,RssV));
    825 })
    826 
    827 
    828 Q6INSN(S2_vtrunehb,"Rd32=vtrunehb(Rss32)",ATTRIBS(),
    829 "Vector truncate half to byte: take low",
    830 {
    831     fHIDE(int i;)
    832     for (i=0;i<4;i++) {
    833         fSETBYTE(i,RdV,fGETBYTE(i*2,RssV));
    834     }
    835 })
    836 
    837 Q6INSN(S6_vtrunehb_ppp,"Rdd32=vtrunehb(Rss32,Rtt32)",ATTRIBS(),
    838 "Vector truncate half to byte: take low",
    839 {
    840     fHIDE(int i;)
    841     for (i=0;i<4;i++) {
    842         fSETBYTE(i,RddV,fGETBYTE(i*2,RttV));
    843         fSETBYTE(i+4,RddV,fGETBYTE(i*2,RssV));
    844     }
    845 })
    846 
    847 Q6INSN(S6_vtrunohb_ppp,"Rdd32=vtrunohb(Rss32,Rtt32)",ATTRIBS(),
    848 "Vector truncate half to byte: take high",
    849 {
    850     fHIDE(int i;)
    851     for (i=0;i<4;i++) {
    852         fSETBYTE(i,RddV,fGETBYTE(i*2+1,RttV));
    853         fSETBYTE(i+4,RddV,fGETBYTE(i*2+1,RssV));
    854     }
    855 })
    856 
    857 Q6INSN(S2_vsxthw,"Rdd32=vsxthw(Rs32)",ATTRIBS(),
    858 "Vector sign extend half to word",
    859 {
    860     fHIDE(int i;)
    861     for (i=0;i<2;i++) {
    862         fSETWORD(i,RddV,fGETHALF(i,RsV));
    863     }
    864 })
    865 
    866 Q6INSN(S2_vzxthw,"Rdd32=vzxthw(Rs32)",ATTRIBS(),
    867 "Vector zero extend half to word",
    868 {
    869     fHIDE(int i;)
    870     for (i=0;i<2;i++) {
    871         fSETWORD(i,RddV,fGETUHALF(i,RsV));
    872     }
    873 })
    874 
    875 
    876 Q6INSN(S2_vsatwh,"Rd32=vsatwh(Rss32)",ATTRIBS(),
    877 "Vector saturate word to signed half",
    878 {
    879     fHIDE(int i;)
    880     for (i=0;i<2;i++) {
    881         fSETHALF(i,RdV,fSATN(16,fGETWORD(i,RssV)));
    882     }
    883 })
    884 
    885 Q6INSN(S2_vsatwuh,"Rd32=vsatwuh(Rss32)",ATTRIBS(),
    886 "Vector saturate word to unsigned half",
    887 {
    888     fHIDE(int i;)
    889     for (i=0;i<2;i++) {
    890         fSETHALF(i,RdV,fSATUN(16,fGETWORD(i,RssV)));
    891     }
    892 })
    893 
    894 /* Other misc insns of this type */
    895 
    896 Q6INSN(S2_packhl,"Rdd32=packhl(Rs32,Rt32)",ATTRIBS(),
    897 "Pack high halfwords and low halfwords together",
    898 {
    899     fSETHALF(0,RddV,fGETHALF(0,RtV));
    900     fSETHALF(1,RddV,fGETHALF(0,RsV));
    901     fSETHALF(2,RddV,fGETHALF(1,RtV));
    902     fSETHALF(3,RddV,fGETHALF(1,RsV));
    903 })
    904 
    905 Q6INSN(A2_swiz,"Rd32=swiz(Rs32)",ATTRIBS(A_ARCHV2),
    906 "Endian swap the bytes of Rs",
    907 {
    908     fSETBYTE(0,RdV,fGETBYTE(3,RsV));
    909     fSETBYTE(1,RdV,fGETBYTE(2,RsV));
    910     fSETBYTE(2,RdV,fGETBYTE(1,RsV));
    911     fSETBYTE(3,RdV,fGETBYTE(0,RsV));
    912 })
    913 
    914 
    915 
    916 /* Vector Sat without Packing */
    917 Q6INSN(S2_vsathub_nopack,"Rdd32=vsathub(Rss32)",ATTRIBS(),
    918 "Vector saturate half to unsigned byte",
    919 {
    920     fHIDE(int i;)
    921     for (i=0;i<4;i++) {
    922         fSETHALF(i,RddV,fSATUN(8,fGETHALF(i,RssV)));
    923     }
    924 })
    925 
    926 Q6INSN(S2_vsathb_nopack,"Rdd32=vsathb(Rss32)",ATTRIBS(A_ARCHV2),
    927 "Vector saturate half to signed byte without pack",
    928 {
    929     fHIDE(int i;)
    930     for (i=0;i<4;i++) {
    931         fSETHALF(i,RddV,fSATN(8,fGETHALF(i,RssV)));
    932     }
    933 })
    934 
    935 Q6INSN(S2_vsatwh_nopack,"Rdd32=vsatwh(Rss32)",ATTRIBS(),
    936 "Vector saturate word to signed half",
    937 {
    938     fHIDE(int i;)
    939     for (i=0;i<2;i++) {
    940         fSETWORD(i,RddV,fSATN(16,fGETWORD(i,RssV)));
    941     }
    942 })
    943 
    944 Q6INSN(S2_vsatwuh_nopack,"Rdd32=vsatwuh(Rss32)",ATTRIBS(),
    945 "Vector saturate word to unsigned half",
    946 {
    947     fHIDE(int i;)
    948     for (i=0;i<2;i++) {
    949         fSETWORD(i,RddV,fSATUN(16,fGETWORD(i,RssV)));
    950     }
    951 })
    952 
    953 
    954 /**********************************************/
    955 /* Shuffle                                    */
    956 /**********************************************/
    957 
    958 
    959 Q6INSN(S2_shuffob,"Rdd32=shuffob(Rtt32,Rss32)",ATTRIBS(),
    960 "Shuffle high bytes together",
    961 {
    962     fHIDE(int i;)
    963     for (i=0;i<4;i++) {
    964         fSETBYTE(i*2  ,RddV,fGETBYTE(i*2+1,RssV));
    965         fSETBYTE(i*2+1,RddV,fGETBYTE(i*2+1,RttV));
    966     }
    967 })
    968 
    969 Q6INSN(S2_shuffeb,"Rdd32=shuffeb(Rss32,Rtt32)",ATTRIBS(),
    970 "Shuffle low bytes together",
    971 {
    972     fHIDE(int i;)
    973     for (i=0;i<4;i++) {
    974         fSETBYTE(i*2  ,RddV,fGETBYTE(i*2,RttV));
    975         fSETBYTE(i*2+1,RddV,fGETBYTE(i*2,RssV));
    976     }
    977 })
    978 
    979 Q6INSN(S2_shuffoh,"Rdd32=shuffoh(Rtt32,Rss32)",ATTRIBS(),
    980 "Shuffle high halves together",
    981 {
    982     fHIDE(int i;)
    983     for (i=0;i<2;i++) {
    984         fSETHALF(i*2  ,RddV,fGETHALF(i*2+1,RssV));
    985         fSETHALF(i*2+1,RddV,fGETHALF(i*2+1,RttV));
    986     }
    987 })
    988 
    989 Q6INSN(S2_shuffeh,"Rdd32=shuffeh(Rss32,Rtt32)",ATTRIBS(),
    990 "Shuffle low halves together",
    991 {
    992     fHIDE(int i;)
    993     for (i=0;i<2;i++) {
    994         fSETHALF(i*2  ,RddV,fGETHALF(i*2,RttV));
    995         fSETHALF(i*2+1,RddV,fGETHALF(i*2,RssV));
    996     }
    997 })
    998 
    999 
   1000 /**********************************************/
   1001 /* Strange bit instructions                   */
   1002 /**********************************************/
   1003 
   1004 Q6INSN(S5_popcountp,"Rd32=popcount(Rss32)",ATTRIBS(),
   1005 "Population Count", { RdV = fCOUNTONES_8(RssV); })
   1006 
   1007 Q6INSN(S4_parity,"Rd32=parity(Rs32,Rt32)",,
   1008 "Parity of Masked Value", { RdV = 1&fCOUNTONES_4(RsV & RtV); })
   1009 
   1010 Q6INSN(S2_parityp,"Rd32=parity(Rss32,Rtt32)",ATTRIBS(A_ARCHV2),
   1011 "Parity of Masked Value", { RdV = 1&fCOUNTONES_8(RssV & RttV); })
   1012 
   1013 Q6INSN(S2_lfsp,"Rdd32=lfs(Rss32,Rtt32)",ATTRIBS(A_ARCHV2),
   1014 "Parity of Masked Value", { RddV = (fCAST8u(RssV) >> 1) | (fCAST8u((1&fCOUNTONES_8(RssV & RttV)))<<63) ; })
   1015 
   1016 Q6INSN(S2_clbnorm,"Rd32=normamt(Rs32)",ATTRIBS(A_ARCHV2),
   1017 "Count leading sign bits - 1", { if (RsV == 0) { RdV = 0; } else { RdV = (fMAX(fCL1_4(RsV),fCL1_4(~RsV)))-1;} })
   1018 
   1019 Q6INSN(S4_clbaddi,"Rd32=add(clb(Rs32),#s6)",ATTRIBS(A_ARCHV2),
   1020 "Count leading sign bits then add signed number",
   1021 { RdV = (fMAX(fCL1_4(RsV),fCL1_4(~RsV)))+siV;} )
   1022 
   1023 Q6INSN(S4_clbpnorm,"Rd32=normamt(Rss32)",ATTRIBS(A_ARCHV2),
   1024 "Count leading sign bits - 1", { if (RssV == 0) { RdV = 0; }
   1025 else { RdV = (fMAX(fCL1_8(RssV),fCL1_8(~RssV)))-1;}})
   1026 
   1027 Q6INSN(S4_clbpaddi,"Rd32=add(clb(Rss32),#s6)",ATTRIBS(A_ARCHV2),
   1028 "Count leading sign bits then add signed number",
   1029 { RdV = (fMAX(fCL1_8(RssV),fCL1_8(~RssV)))+siV;})
   1030 
   1031 
   1032 
   1033 Q6INSN(S2_cabacdecbin,"Rdd32=decbin(Rss32,Rtt32)",ATTRIBS(A_ARCHV3),"CABAC decode bin",
   1034 {
   1035     fHIDE(size4u_t state;)
   1036     fHIDE(size4u_t valMPS;)
   1037     fHIDE(size4u_t bitpos;)
   1038     fHIDE(size4u_t range;)
   1039     fHIDE(size4u_t offset;)
   1040     fHIDE(size4u_t rLPS;)
   1041     fHIDE(size4u_t rMPS;)
   1042 
   1043     state =  fEXTRACTU_RANGE( fGETWORD(1,RttV) ,5,0);
   1044     valMPS = fEXTRACTU_RANGE( fGETWORD(1,RttV) ,8,8);
   1045     bitpos = fEXTRACTU_RANGE( fGETWORD(0,RttV) ,4,0);
   1046     range =  fGETWORD(0,RssV);
   1047     offset = fGETWORD(1,RssV);
   1048 
   1049     /* calculate rLPS */
   1050     range <<= bitpos;
   1051     offset <<= bitpos;
   1052     rLPS = rLPS_table_64x4[state][ (range >>29)&3];
   1053     rLPS  = rLPS << 23;   /* left aligned */
   1054 
   1055     /* calculate rMPS */
   1056     rMPS= (range&0xff800000) - rLPS;
   1057 
   1058     /* most probable region */
   1059     if (offset < rMPS) {
   1060         RddV = AC_next_state_MPS_64[state];
   1061         fINSERT_RANGE(RddV,8,8,valMPS);
   1062         fINSERT_RANGE(RddV,31,23,(rMPS>>23));
   1063         fSETWORD(1,RddV,offset);
   1064         fWRITE_P0(valMPS);
   1065 
   1066 
   1067     }
   1068     /* least probable region */
   1069     else {
   1070         RddV = AC_next_state_LPS_64[state];
   1071         fINSERT_RANGE(RddV,8,8,((!state)?(1-valMPS):(valMPS)));
   1072         fINSERT_RANGE(RddV,31,23,(rLPS>>23));
   1073         fSETWORD(1,RddV,(offset-rMPS));
   1074         fWRITE_P0((valMPS^1));
   1075     }
   1076 })
   1077 
   1078 
   1079 Q6INSN(S2_clb,"Rd32=clb(Rs32)",ATTRIBS(),
   1080 "Count leading bits", {RdV = fMAX(fCL1_4(RsV),fCL1_4(~RsV));})
   1081 
   1082 
   1083 Q6INSN(S2_cl0,"Rd32=cl0(Rs32)",ATTRIBS(),
   1084 "Count leading bits", {RdV = fCL1_4(~RsV);})
   1085 
   1086 Q6INSN(S2_cl1,"Rd32=cl1(Rs32)",ATTRIBS(),
   1087 "Count leading bits", {RdV = fCL1_4(RsV);})
   1088 
   1089 Q6INSN(S2_clbp,"Rd32=clb(Rss32)",ATTRIBS(),
   1090 "Count leading bits", {RdV = fMAX(fCL1_8(RssV),fCL1_8(~RssV));})
   1091 
   1092 Q6INSN(S2_cl0p,"Rd32=cl0(Rss32)",ATTRIBS(),
   1093 "Count leading bits", {RdV = fCL1_8(~RssV);})
   1094 
   1095 Q6INSN(S2_cl1p,"Rd32=cl1(Rss32)",ATTRIBS(),
   1096 "Count leading bits", {RdV = fCL1_8(RssV);})
   1097 
   1098 
   1099 
   1100 
   1101 Q6INSN(S2_brev, "Rd32=brev(Rs32)",   ATTRIBS(A_ARCHV2), "Bit Reverse",{RdV = fBREV_4(RsV);})
   1102 Q6INSN(S2_brevp,"Rdd32=brev(Rss32)", ATTRIBS(), "Bit Reverse",{RddV = fBREV_8(RssV);})
   1103 Q6INSN(S2_ct0,  "Rd32=ct0(Rs32)",    ATTRIBS(A_ARCHV2), "Count Trailing",{RdV = fCL1_4(~fBREV_4(RsV));})
   1104 Q6INSN(S2_ct1,  "Rd32=ct1(Rs32)",    ATTRIBS(A_ARCHV2), "Count Trailing",{RdV = fCL1_4(fBREV_4(RsV));})
   1105 Q6INSN(S2_ct0p, "Rd32=ct0(Rss32)",   ATTRIBS(), "Count Trailing",{RdV = fCL1_8(~fBREV_8(RssV));})
   1106 Q6INSN(S2_ct1p, "Rd32=ct1(Rss32)",   ATTRIBS(), "Count Trailing",{RdV = fCL1_8(fBREV_8(RssV));})
   1107 
   1108 
   1109 Q6INSN(S2_interleave,"Rdd32=interleave(Rss32)",ATTRIBS(A_ARCHV2),"Interleave bits",
   1110 {RddV = fINTERLEAVE(fGETWORD(1,RssV),fGETWORD(0,RssV));})
   1111 
   1112 Q6INSN(S2_deinterleave,"Rdd32=deinterleave(Rss32)",ATTRIBS(A_ARCHV2),"Interleave bits",
   1113 {RddV = fDEINTERLEAVE(RssV);})