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) \
31Q6INSN(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\
38Q6INSN(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\
45Q6INSN(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\
52Q6INSN(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
59RSHIFTTYPES(r,Rd,Rs,4_8,,,fECHO,,)
60RSHIFTTYPES(p,Rdd,Rss,8_8,,,fECHO,,)
61RSHIFTTYPES(r_acc,Rx,Rs,4_8,+,RxV,fECHO,,)
62RSHIFTTYPES(p_acc,Rxx,Rss,8_8,+,RxxV,fECHO,,)
63RSHIFTTYPES(r_nac,Rx,Rs,4_8,-,RxV,fECHO,,)
64RSHIFTTYPES(p_nac,Rxx,Rss,8_8,-,RxxV,fECHO,,)
65
66RSHIFTTYPES(r_and,Rx,Rs,4_8,&,RxV,fECHO,,)
67RSHIFTTYPES(r_or,Rx,Rs,4_8,|,RxV,fECHO,,)
68RSHIFTTYPES(p_and,Rxx,Rss,8_8,&,RxxV,fECHO,,)
69RSHIFTTYPES(p_or,Rxx,Rss,8_8,|,RxxV,fECHO,,)
70RSHIFTTYPES(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) \
77Q6INSN(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\
84Q6INSN(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
91RSATSHIFTTYPES(r_sat,Rd,Rs,4_8)
92
93
94
95
96
97#define ISHIFTTYPES(TAGEND,SIZE,REGD,REGS,REGSTYPE,ACC,ACCSRC,SAT,SATOPT,ATTRS) \
98Q6INSN(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\
102Q6INSN(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\
106Q6INSN(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)); }) \
109Q6INSN(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) \
115Q6INSN(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) \
120Q6INSN(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) \
126Q6INSN(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)); }) \
129Q6INSN(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)); }) \
132Q6INSN(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
138ISHIFTTYPES(r,5,Rd,Rs,4_4,,,fECHO,,)
139ISHIFTTYPES(p,6,Rdd,Rss,8_8,,,fECHO,,)
140ISHIFTTYPES(r_acc,5,Rx,Rs,4_4,+,RxV,fECHO,,)
141ISHIFTTYPES(p_acc,6,Rxx,Rss,8_8,+,RxxV,fECHO,,)
142ISHIFTTYPES(r_nac,5,Rx,Rs,4_4,-,RxV,fECHO,,)
143ISHIFTTYPES(p_nac,6,Rxx,Rss,8_8,-,RxxV,fECHO,,)
144
145ISHIFTTYPES_NOASR(r_xacc,5,Rx,Rs,4_4,^, RxV,fECHO,)
146ISHIFTTYPES_NOASR(p_xacc,6,Rxx,Rss,8_8,^, RxxV,fECHO,)
147
148ISHIFTTYPES(r_and,5,Rx,Rs,4_4,&,RxV,fECHO,,)
149ISHIFTTYPES(r_or,5,Rx,Rs,4_4,|,RxV,fECHO,,)
150ISHIFTTYPES(p_and,6,Rxx,Rss,8_8,&,RxxV,fECHO,,)
151ISHIFTTYPES(p_or,6,Rxx,Rss,8_8,|,RxxV,fECHO,,)
152
153ISHIFTTYPES_ONLY_ASL(r_sat,5,Rd,Rs,4_8,,,fSAT,:sat)
154
155
156Q6INSN(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
161Q6INSN(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
169Q6INSN(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
178Q6INSN(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)\
185Q6INSN(S4_andi_##TAGEND,"Rx32=and(#u8,"INNEROP")",,"Shift-op",{RxV=fIMMEXT(uiV)&INNERSEM;})\
186Q6INSN(S4_ori_##TAGEND, "Rx32=or(#u8,"INNEROP")",,"Shift-op",{RxV=fIMMEXT(uiV)|INNERSEM;})\
187Q6INSN(S4_addi_##TAGEND,"Rx32=add(#u8,"INNEROP")",,"Shift-op",{RxV=fIMMEXT(uiV)+INNERSEM;})\
188Q6INSN(S4_subi_##TAGEND,"Rx32=sub(#u8,"INNEROP")",,"Shift-op",{RxV=fIMMEXT(uiV)-INNERSEM;})
189
190
191SHIFTOPI(asl_ri,"asl(Rx32,#U5)",(RxV<<UiV))
192SHIFTOPI(lsr_ri,"lsr(Rx32,#U5)",(((unsigned int)RxV)>>UiV))
193
194
195/**********************************************/
196/* PERMUTES                                   */
197/**********************************************/
198Q6INSN(S2_valignib,"Rdd32=valignb(Rtt32,Rss32,#u3)",
199ATTRIBS(), "Vector align bytes",
200{
201  RddV = (fLSHIFTR(RssV,uiV*8,8_8))|(fASHIFTL(RttV,((8-uiV)*8),8_8));
202})
203
204Q6INSN(S2_valignrb,"Rdd32=valignb(Rtt32,Rss32,Pu4)",
205ATTRIBS(), "Align with register",
206{ RddV = fLSHIFTR(RssV,(PuV&0x7)*8,8_8)|(fASHIFTL(RttV,(8-(PuV&0x7))*8,8_8));})
207
208Q6INSN(S2_vspliceib,"Rdd32=vspliceb(Rss32,Rtt32,#u3)",
209ATTRIBS(), "Vector splice bytes",
210{ RddV = fASHIFTL(RttV,uiV*8,8_8) | fZXTN(uiV*8,64,RssV); })
211
212Q6INSN(S2_vsplicerb,"Rdd32=vspliceb(Rss32,Rtt32,Pu4)",
213ATTRIBS(), "Splice with register",
214{ RddV = fASHIFTL(RttV,(PuV&7)*8,8_8) | fZXTN((PuV&7)*8,64,RssV); })
215
216Q6INSN(S2_vsplatrh,"Rdd32=vsplath(Rs32)",
217ATTRIBS(), "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
226Q6INSN(S2_vsplatrb,"Rd32=vsplatb(Rs32)",
227ATTRIBS(), "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
235Q6INSN(S6_vsplatrbp,"Rdd32=vsplatb(Rs32)",
236ATTRIBS(), "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
250Q6INSN(S2_insert,"Rx32=insert(Rs32,#u5,#U5)",
251ATTRIBS(), "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
262Q6INSN(S2_tableidxb,"Rx32=tableidxb(Rs32,#u4,#S6):raw",
263ATTRIBS(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
271Q6INSN(S2_tableidxh,"Rx32=tableidxh(Rs32,#u4,#S6):raw",
272ATTRIBS(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
280Q6INSN(S2_tableidxw,"Rx32=tableidxw(Rs32,#u4,#S6):raw",
281ATTRIBS(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
289Q6INSN(S2_tableidxd,"Rx32=tableidxd(Rs32,#u4,#S6):raw",
290ATTRIBS(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
299Q6INSN(A4_bitspliti,"Rdd32=bitsplit(Rs32,#u5)",
300ATTRIBS(), "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
306Q6INSN(A4_bitsplit,"Rdd32=bitsplit(Rs32,Rt32)",
307ATTRIBS(), "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
317Q6INSN(S4_extract,"Rd32=extract(Rs32,#u5,#U5)",
318ATTRIBS(), "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
326Q6INSN(S2_extractu,"Rd32=extractu(Rs32,#u5,#U5)",
327ATTRIBS(), "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
334Q6INSN(S2_insertp,"Rxx32=insert(Rss32,#u6,#U6)",
335ATTRIBS(), "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
346Q6INSN(S4_extractp,"Rdd32=extract(Rss32,#u6,#U6)",
347ATTRIBS(), "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
355Q6INSN(S2_extractup,"Rdd32=extractu(Rss32,#u6,#U6)",
356ATTRIBS(), "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
366Q6INSN(S2_mask,"Rd32=mask(#u5,#U5)",
367ATTRIBS(), "Form mask from immediate",
368{
369    RdV = ((1<<uiV)-1) << UiV;
370})
371
372
373
374
375
376Q6INSN(S2_insert_rp,"Rx32=insert(Rs32,Rtt32)",
377ATTRIBS(), "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
393Q6INSN(S4_extract_rp,"Rd32=extract(Rs32,Rtt32)",
394ATTRIBS(), "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
403Q6INSN(S2_extractu_rp,"Rd32=extractu(Rs32,Rtt32)",
404ATTRIBS(), "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
411Q6INSN(S2_insertp_rp,"Rxx32=insert(Rss32,Rtt32)",
412ATTRIBS(), "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
428Q6INSN(S4_extractp_rp,"Rdd32=extract(Rss32,Rtt32)",
429ATTRIBS(), "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
437Q6INSN(S2_extractup_rp,"Rdd32=extractu(Rss32,Rtt32)",
438ATTRIBS(), "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
449Q6INSN(S2_tstbit_i,"Pd4=tstbit(Rs32,#u5)",
450ATTRIBS(), "Test a bit",
451{
452    PdV = f8BITSOF((RsV & (1<<uiV)) != 0);
453})
454
455Q6INSN(S4_ntstbit_i,"Pd4=!tstbit(Rs32,#u5)",
456ATTRIBS(), "Test a bit",
457{
458    PdV = f8BITSOF((RsV & (1<<uiV)) == 0);
459})
460
461Q6INSN(S2_setbit_i,"Rd32=setbit(Rs32,#u5)",
462ATTRIBS(), "Set a bit",
463{
464    RdV = (RsV | (1<<uiV));
465})
466
467Q6INSN(S2_togglebit_i,"Rd32=togglebit(Rs32,#u5)",
468ATTRIBS(), "Toggle a bit",
469{
470    RdV = (RsV ^ (1<<uiV));
471})
472
473Q6INSN(S2_clrbit_i,"Rd32=clrbit(Rs32,#u5)",
474ATTRIBS(), "Clear a bit",
475{
476    RdV = (RsV & (~(1<<uiV)));
477})
478
479
480
481/* using a register */
482Q6INSN(S2_tstbit_r,"Pd4=tstbit(Rs32,Rt32)",
483ATTRIBS(), "Test a bit",
484{
485    PdV = f8BITSOF((fCAST4_8u(RsV) & fBIDIR_LSHIFTL(1,fSXTN(7,32,RtV),4_8)) != 0);
486})
487
488Q6INSN(S4_ntstbit_r,"Pd4=!tstbit(Rs32,Rt32)",
489ATTRIBS(), "Test a bit",
490{
491    PdV = f8BITSOF((fCAST4_8u(RsV) & fBIDIR_LSHIFTL(1,fSXTN(7,32,RtV),4_8)) == 0);
492})
493
494Q6INSN(S2_setbit_r,"Rd32=setbit(Rs32,Rt32)",
495ATTRIBS(), "Set a bit",
496{
497    RdV = (RsV | fBIDIR_LSHIFTL(1,fSXTN(7,32,RtV),4_8));
498})
499
500Q6INSN(S2_togglebit_r,"Rd32=togglebit(Rs32,Rt32)",
501ATTRIBS(), "Toggle a bit",
502{
503    RdV = (RsV ^ fBIDIR_LSHIFTL(1,fSXTN(7,32,RtV),4_8));
504})
505
506Q6INSN(S2_clrbit_r,"Rd32=clrbit(Rs32,Rt32)",
507ATTRIBS(), "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
519Q6INSN(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
529Q6INSN(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
538Q6INSN(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
549Q6INSN(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
558Q6INSN(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
567Q6INSN(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
578Q6INSN(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
588Q6INSN(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
599Q6INSN(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
609Q6INSN(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
623Q6INSN(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
634Q6INSN(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
643Q6INSN(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
653Q6INSN(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
662Q6INSN(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
673Q6INSN(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
684Q6INSN(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
694Q6INSN(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
705Q6INSN(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
723Q6INSN(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
732Q6INSN(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
741Q6INSN(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
750Q6INSN(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
759Q6INSN(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
772Q6INSN(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
781Q6INSN(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
791Q6INSN(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
800Q6INSN(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
809Q6INSN(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
818Q6INSN(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
828Q6INSN(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
837Q6INSN(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
847Q6INSN(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
857Q6INSN(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
866Q6INSN(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
876Q6INSN(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
885Q6INSN(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
896Q6INSN(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
905Q6INSN(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 */
917Q6INSN(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
926Q6INSN(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
935Q6INSN(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
944Q6INSN(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
959Q6INSN(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
969Q6INSN(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
979Q6INSN(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
989Q6INSN(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
1004Q6INSN(S5_popcountp,"Rd32=popcount(Rss32)",ATTRIBS(),
1005"Population Count", { RdV = fCOUNTONES_8(RssV); })
1006
1007Q6INSN(S4_parity,"Rd32=parity(Rs32,Rt32)",,
1008"Parity of Masked Value", { RdV = 1&fCOUNTONES_4(RsV & RtV); })
1009
1010Q6INSN(S2_parityp,"Rd32=parity(Rss32,Rtt32)",ATTRIBS(A_ARCHV2),
1011"Parity of Masked Value", { RdV = 1&fCOUNTONES_8(RssV & RttV); })
1012
1013Q6INSN(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
1016Q6INSN(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
1019Q6INSN(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
1023Q6INSN(S4_clbpnorm,"Rd32=normamt(Rss32)",ATTRIBS(A_ARCHV2),
1024"Count leading sign bits - 1", { if (RssV == 0) { RdV = 0; }
1025else { RdV = (fMAX(fCL1_8(RssV),fCL1_8(~RssV)))-1;}})
1026
1027Q6INSN(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
1033Q6INSN(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
1079Q6INSN(S2_clb,"Rd32=clb(Rs32)",ATTRIBS(),
1080"Count leading bits", {RdV = fMAX(fCL1_4(RsV),fCL1_4(~RsV));})
1081
1082
1083Q6INSN(S2_cl0,"Rd32=cl0(Rs32)",ATTRIBS(),
1084"Count leading bits", {RdV = fCL1_4(~RsV);})
1085
1086Q6INSN(S2_cl1,"Rd32=cl1(Rs32)",ATTRIBS(),
1087"Count leading bits", {RdV = fCL1_4(RsV);})
1088
1089Q6INSN(S2_clbp,"Rd32=clb(Rss32)",ATTRIBS(),
1090"Count leading bits", {RdV = fMAX(fCL1_8(RssV),fCL1_8(~RssV));})
1091
1092Q6INSN(S2_cl0p,"Rd32=cl0(Rss32)",ATTRIBS(),
1093"Count leading bits", {RdV = fCL1_8(~RssV);})
1094
1095Q6INSN(S2_cl1p,"Rd32=cl1(Rss32)",ATTRIBS(),
1096"Count leading bits", {RdV = fCL1_8(RssV);})
1097
1098
1099
1100
1101Q6INSN(S2_brev, "Rd32=brev(Rs32)",   ATTRIBS(A_ARCHV2), "Bit Reverse",{RdV = fBREV_4(RsV);})
1102Q6INSN(S2_brevp,"Rdd32=brev(Rss32)", ATTRIBS(), "Bit Reverse",{RddV = fBREV_8(RssV);})
1103Q6INSN(S2_ct0,  "Rd32=ct0(Rs32)",    ATTRIBS(A_ARCHV2), "Count Trailing",{RdV = fCL1_4(~fBREV_4(RsV));})
1104Q6INSN(S2_ct1,  "Rd32=ct1(Rs32)",    ATTRIBS(A_ARCHV2), "Count Trailing",{RdV = fCL1_4(fBREV_4(RsV));})
1105Q6INSN(S2_ct0p, "Rd32=ct0(Rss32)",   ATTRIBS(), "Count Trailing",{RdV = fCL1_8(~fBREV_8(RssV));})
1106Q6INSN(S2_ct1p, "Rd32=ct1(Rss32)",   ATTRIBS(), "Count Trailing",{RdV = fCL1_8(fBREV_8(RssV));})
1107
1108
1109Q6INSN(S2_interleave,"Rdd32=interleave(Rss32)",ATTRIBS(A_ARCHV2),"Interleave bits",
1110{RddV = fINTERLEAVE(fGETWORD(1,RssV),fGETWORD(0,RssV));})
1111
1112Q6INSN(S2_deinterleave,"Rdd32=deinterleave(Rss32)",ATTRIBS(A_ARCHV2),"Interleave bits",
1113{RddV = fDEINTERLEAVE(RssV);})
1114