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
18DEF_MACRO(
19    LIKELY,    /* NAME */
20    __builtin_expect((X),1), /* BEH */
21    ()    /* attribs */
22)
23
24DEF_MACRO(
25    UNLIKELY,    /* NAME */
26    __builtin_expect((X),0), /* BEH */
27    ()    /* attribs */
28)
29
30DEF_MACRO(
31    CANCEL, /* macro name */
32    {if (thread->last_pkt) thread->last_pkt->slot_cancelled |= (1<<insn->slot); return;} , /* behavior */
33    (A_CONDEXEC)
34)
35
36DEF_MACRO(
37    LOAD_CANCEL, /* macro name */
38    {mem_general_load_cancelled(thread,EA,insn);CANCEL;} , /* behavior */
39    (A_CONDEXEC)
40)
41
42DEF_MACRO(
43    STORE_CANCEL, /* macro name */
44    {mem_general_store_cancelled(thread,EA,insn);CANCEL;} , /* behavior */
45    (A_CONDEXEC)
46)
47
48DEF_MACRO(
49    fMAX, /* macro name */
50    (((A) > (B)) ? (A) : (B)), /* behavior */
51    /* optional attributes */
52)
53
54DEF_MACRO(
55    fMIN, /* macro name */
56    (((A) < (B)) ? (A) : (B)), /* behavior */
57    /* optional attributes */
58)
59
60DEF_MACRO(
61    fABS, /* macro name */
62    (((A)<0)?(-(A)):(A)), /* behavior */
63    /* optional attributes */
64)
65
66
67/* Bit insert */
68DEF_MACRO(
69    fINSERT_BITS,
70        {
71            REG = ((REG) & ~(((fCONSTLL(1)<<(WIDTH))-1)<<(OFFSET))) | (((INVAL) & ((fCONSTLL(1)<<(WIDTH))-1)) << (OFFSET));
72        },
73    /* attribs */
74)
75
76/* Bit extract */
77DEF_MACRO(
78    fEXTRACTU_BITS,
79    (fZXTN(WIDTH,32,(INREG >> OFFSET))),
80    /* attribs */
81)
82
83DEF_MACRO(
84    fEXTRACTU_BIDIR,
85    (fZXTN(WIDTH,32,fBIDIR_LSHIFTR((INREG),(OFFSET),4_8))),
86    /* attribs */
87)
88
89DEF_MACRO(
90    fEXTRACTU_RANGE,
91    (fZXTN((HIBIT-LOWBIT+1),32,(INREG >> LOWBIT))),
92    /* attribs */
93)
94
95
96DEF_MACRO(
97    fINSERT_RANGE,
98        {
99            int offset=LOWBIT;
100            int width=HIBIT-LOWBIT+1;
101            /* clear bits where new bits go */
102            INREG &= ~(((fCONSTLL(1)<<width)-1)<<offset);
103            /* OR in new bits */
104            INREG |= ((INVAL & ((fCONSTLL(1)<<width)-1)) << offset);
105        },
106    /* attribs */
107)
108
109
110DEF_MACRO(
111    f8BITSOF,
112    ( (VAL) ? 0xff : 0x00),
113    /* attribs */
114)
115
116DEF_MACRO(
117    fLSBOLD,
118    ((VAL) & 1),
119    ()
120)
121
122DEF_MACRO(
123    fLSBNEW,
124    predlog_read(thread,PNUM),
125    ()
126)
127
128DEF_MACRO(
129    fLSBNEW0,
130    predlog_read(thread,0),
131    ()
132)
133
134DEF_MACRO(
135    fLSBNEW1,
136    predlog_read(thread,1),
137    ()
138)
139
140DEF_MACRO(
141    fLSBOLDNOT,
142    (!fLSBOLD(VAL)),
143    ()
144)
145
146DEF_MACRO(
147    fLSBNEWNOT,
148    (!fLSBNEW(PNUM)),
149    ()
150)
151
152DEF_MACRO(
153    fLSBNEW0NOT,
154    (!fLSBNEW0),
155    ()
156)
157
158DEF_MACRO(
159    fLSBNEW1NOT,
160    (!fLSBNEW1),
161    ()
162)
163
164DEF_MACRO(
165    fNEWREG,
166    ({if (newvalue_missing(thread,RNUM) ||
167      IS_CANCELLED(insn->new_value_producer_slot)) CANCEL; reglog_read(thread,RNUM);}),
168    (A_DOTNEWVALUE,A_RESTRICT_SLOT0ONLY)
169)
170// Store new with a missing newvalue or cancelled goes out as a zero byte store in V65
171// take advantage of the fact that reglog_read returns zero for not valid rnum
172DEF_MACRO(
173    fNEWREG_ST,
174    ({if (newvalue_missing(thread,RNUM) ||
175      IS_CANCELLED(insn->new_value_producer_slot)) { STORE_ZERO; RNUM = -1; }; reglog_read(thread,RNUM);}),
176    (A_DOTNEWVALUE,A_RESTRICT_SLOT0ONLY)
177)
178
179DEF_MACRO(
180    fSATUVALN,
181    ({fSET_OVERFLOW(); ((VAL) < 0) ? 0 : ((1LL<<(N))-1);}),
182    ()
183)
184
185DEF_MACRO(
186    fSATVALN,
187    ({fSET_OVERFLOW(); ((VAL) < 0) ? (-(1LL<<((N)-1))) : ((1LL<<((N)-1))-1);}),
188    ()
189)
190
191DEF_MACRO(
192    fZXTN, /* macro name */
193    ((VAL) & ((1LL<<(N))-1)),
194    /* attribs */
195)
196
197DEF_MACRO(
198    fSXTN, /* macro name */
199    ((fZXTN(N,M,VAL) ^ (1LL<<((N)-1))) - (1LL<<((N)-1))),
200    /* attribs */
201)
202
203DEF_MACRO(
204    fSATN,
205    ((fSXTN(N,64,VAL) == (VAL)) ? (VAL) : fSATVALN(N,VAL)),
206    ()
207)
208
209DEF_MACRO(
210    fADDSAT64,
211    {
212        size8u_t __a = fCAST8u(A);
213        size8u_t __b = fCAST8u(B);
214        size8u_t __sum = __a + __b;
215        size8u_t __xor = __a ^ __b;
216        const size8u_t __mask = 0x8000000000000000ULL;
217        if (__xor & __mask) {
218            /* Opposite signs, OK */
219            DST = __sum;
220        } else if ((__a ^ __sum) & __mask) {
221            /* Signs mismatch */
222            if (__sum & __mask) {
223                /* overflowed to negative, make max pos */
224                DST=0x7FFFFFFFFFFFFFFFLL; fSET_OVERFLOW();
225            } else {
226                /* overflowed to positive, make max neg */
227                DST=0x8000000000000000LL; fSET_OVERFLOW();
228            }
229        } else {
230            /* signs did not mismatch, OK */
231            DST = __sum;
232        }
233    },
234    ()
235)
236
237DEF_MACRO(
238    fSATUN,
239    ((fZXTN(N,64,VAL) == (VAL)) ? (VAL) : fSATUVALN(N,VAL)),
240    ()
241)
242
243DEF_MACRO(
244    fSATH,
245    (fSATN(16,VAL)),
246    ()
247)
248
249
250DEF_MACRO(
251    fSATUH,
252    (fSATUN(16,VAL)),
253    ()
254)
255
256DEF_MACRO(
257    fSATUB,
258    (fSATUN(8,VAL)),
259    ()
260)
261DEF_MACRO(
262    fSATB,
263    (fSATN(8,VAL)),
264    ()
265)
266
267
268/*************************************/
269/* immediate extension               */
270/*************************************/
271
272DEF_MACRO(
273    fIMMEXT,
274    (IMM = IMM),
275    (A_EXTENDABLE)
276)
277
278DEF_MACRO(
279    fMUST_IMMEXT,
280    fIMMEXT(IMM),
281    (A_EXTENDABLE)
282)
283
284DEF_MACRO(
285    fPCALIGN,
286    IMM=(IMM & ~PCALIGN_MASK),
287    (A_EXTENDABLE)
288)
289
290/*************************************/
291/* Read and Write Implicit Regs      */
292/*************************************/
293
294DEF_MACRO(
295    fREAD_IREG, /* read modifier register */
296    (fSXTN(11,64,(((VAL) & 0xf0000000)>>21) | ((VAL>>17)&0x7f) )),          /* behavior */
297    ()
298)
299
300DEF_MACRO(
301    fREAD_LR, /* read link register */
302    (READ_RREG(REG_LR)),          /* behavior */
303    ()
304)
305
306DEF_MACRO(
307    fWRITE_LR, /* write lr */
308    WRITE_RREG(REG_LR,A),          /* behavior */
309    (A_IMPLICIT_WRITES_LR)
310)
311
312DEF_MACRO(
313    fWRITE_FP, /* write sp */
314    WRITE_RREG(REG_FP,A),          /* behavior */
315    (A_IMPLICIT_WRITES_FP)
316)
317
318DEF_MACRO(
319    fWRITE_SP, /* write sp */
320    WRITE_RREG(REG_SP,A),          /* behavior */
321    (A_IMPLICIT_WRITES_SP)
322)
323
324DEF_MACRO(
325    fREAD_SP, /* read stack pointer */
326    (READ_RREG(REG_SP)),          /* behavior */
327    ()
328)
329
330DEF_MACRO(
331    fREAD_CSREG, /* read  CS register */
332    (READ_RREG(REG_CSA+N)),          /* behavior */
333    ()
334)
335
336DEF_MACRO(
337    fREAD_LC0, /* read loop count */
338    (READ_RREG(REG_LC0)),          /* behavior */
339    ()
340)
341
342DEF_MACRO(
343    fREAD_LC1, /* read loop count */
344    (READ_RREG(REG_LC1)),          /* behavior */
345    ()
346)
347
348DEF_MACRO(
349    fREAD_SA0, /* read start addr */
350    (READ_RREG(REG_SA0)),          /* behavior */
351    ()
352)
353
354DEF_MACRO(
355    fREAD_SA1, /* read start addr */
356    (READ_RREG(REG_SA1)),          /* behavior */
357    ()
358)
359
360
361DEF_MACRO(
362    fREAD_FP, /* read frame pointer */
363    (READ_RREG(REG_FP)),          /* behavior */
364    ()
365)
366
367DEF_MACRO(
368    fREAD_GP, /* read global pointer */
369    (insn->extension_valid ? 0 : READ_RREG(REG_GP)),          /* behavior */
370    ()
371)
372
373DEF_MACRO(
374    fREAD_PC, /* read PC */
375    (READ_RREG(REG_PC)),          /* behavior */
376    ()
377)
378
379DEF_MACRO(
380    fREAD_NPC, /* read next PC */
381    (thread->next_PC & (0xfffffffe)),          /* behavior */
382    ()
383)
384
385DEF_MACRO(
386    fREAD_P0, /* read Predicate 0 */
387    (READ_PREG(0)),          /* behavior */
388    ()
389)
390
391DEF_MACRO(
392    fREAD_P3, /* read Predicate 3 */
393    (READ_PREG(3)),          /* behavior */
394    ()
395)
396
397DEF_MACRO(
398    fCHECK_PCALIGN,
399    if (((A) & PCALIGN_MASK)) {
400        register_error_exception(thread,PRECISE_CAUSE_PC_NOT_ALIGNED,thread->Regs[REG_BADVA0],thread->Regs[REG_BADVA1],GET_SSR_FIELD(SSR_BVS),GET_SSR_FIELD(SSR_V0),GET_SSR_FIELD(SSR_V1),0);
401    },
402    ()
403)
404
405DEF_MACRO(
406    fWRITE_NPC, /* write next PC */
407    if (!thread->branch_taken) {
408        if (A != thread->next_PC) {
409            thread->next_pkt_guess=thread->last_pkt->taken_ptr;
410        }
411        fCHECK_PCALIGN(A);
412        thread->branched = 1; thread->branch_taken = 1; thread->next_PC = A; \
413        thread->branch_offset = insn->encoding_offset; thread->branch_opcode = insn->opcode;
414    },          /* behavior */
415    (A_COF)
416)
417
418DEF_MACRO(
419    fBRANCH,
420    fWRITE_NPC(LOC); fCOF_CALLBACK(LOC,TYPE),
421    ()
422)
423
424DEF_MACRO(
425    fJUMPR,    /* A jumpr has executed */
426    {fBRANCH(TARGET,COF_TYPE_JUMPR);},
427    (A_INDIRECT)
428)
429
430DEF_MACRO(
431    fHINTJR,    /* A hintjr instruction has executed */
432    { },
433)
434
435DEF_MACRO(
436    fCALL,    /* Do a call */
437    if (!thread->branch_taken) {fBP_RAS_CALL(A); fWRITE_LR(fREAD_NPC()); fBRANCH(A,COF_TYPE_CALL);},
438    (A_COF,A_IMPLICIT_WRITES_LR,A_CALL)
439)
440
441DEF_MACRO(
442    fCALLR,    /* Do a call Register */
443    if (!thread->branch_taken) {fBP_RAS_CALL(A); fWRITE_LR(fREAD_NPC()); fBRANCH(A,COF_TYPE_CALLR);},
444    (A_COF,A_IMPLICIT_WRITES_LR,A_CALL)
445)
446
447DEF_MACRO(
448    fWRITE_LOOP_REGS0, /* write ln,sa,ea,lc */
449    {WRITE_RREG(REG_LC0,COUNT);
450     WRITE_RREG(REG_SA0,START);},
451    (A_IMPLICIT_WRITES_LC0,A_IMPLICIT_WRITES_SA0)
452)
453
454DEF_MACRO(
455    fWRITE_LOOP_REGS1, /* write ln,sa,ea,lc */
456    {WRITE_RREG(REG_LC1,COUNT);
457     WRITE_RREG(REG_SA1,START);},
458    (A_IMPLICIT_WRITES_LC1,A_IMPLICIT_WRITES_SA1)
459)
460
461DEF_MACRO(
462    fWRITE_LC0,
463    WRITE_RREG(REG_LC0,VAL),
464    (A_IMPLICIT_WRITES_LC0)
465)
466
467DEF_MACRO(
468    fWRITE_LC1,
469    WRITE_RREG(REG_LC1,VAL),
470    (A_IMPLICIT_WRITES_LC1)
471)
472
473DEF_MACRO(
474    fCARRY_FROM_ADD,
475    carry_from_add64(A,B,C),
476    /* NOTHING */
477)
478
479DEF_MACRO(
480    fSET_OVERFLOW,
481    SET_USR_FIELD(USR_OVF,1),
482    ()
483)
484
485DEF_MACRO(
486    fSET_LPCFG,
487    SET_USR_FIELD(USR_LPCFG,(VAL)),
488    ()
489)
490
491
492DEF_MACRO(
493    fGET_LPCFG,
494    (GET_USR_FIELD(USR_LPCFG)),
495    ()
496)
497
498
499
500DEF_MACRO(
501    fWRITE_P0, /* write Predicate 0 */
502    WRITE_PREG(0,VAL),          /* behavior */
503    (A_IMPLICIT_WRITES_P0)
504)
505
506DEF_MACRO(
507    fWRITE_P1, /* write Predicate 0 */
508    WRITE_PREG(1,VAL),          /* behavior */
509    (A_IMPLICIT_WRITES_P1)
510)
511
512DEF_MACRO(
513    fWRITE_P2, /* write Predicate 0 */
514    WRITE_PREG(2,VAL),          /* behavior */
515    (A_IMPLICIT_WRITES_P2)
516)
517
518DEF_MACRO(
519    fWRITE_P3, /* write Predicate 0 */
520    WRITE_PREG(3,VAL),     /* behavior */
521    (A_IMPLICIT_WRITES_P3)
522)
523
524DEF_MACRO(
525    fPART1, /* write Predicate 0 */
526    if (insn->part1) { WORK; return; },          /* behavior */
527    /* optional attributes */
528)
529
530
531/*************************************/
532/* Casting, Sign-Zero extension, etc */
533/*************************************/
534
535DEF_MACRO(
536    fCAST4u, /* macro name */
537    ((size4u_t)(A)),          /* behavior */
538    /* optional attributes */
539)
540
541DEF_MACRO(
542    fCAST4s, /* macro name */
543    ((size4s_t)(A)),          /* behavior */
544    /* optional attributes */
545)
546
547DEF_MACRO(
548    fCAST8u, /* macro name */
549    ((size8u_t)(A)),          /* behavior */
550    /* optional attributes */
551)
552
553DEF_MACRO(
554    fCAST8s, /* macro name */
555    ((size8s_t)(A)),          /* behavior */
556    /* optional attributes */
557)
558
559DEF_MACRO(
560    fCAST4_4s, /* macro name */
561    ((size4s_t)(A)),
562    /* optional attributes */
563)
564
565DEF_MACRO(
566    fCAST4_4u, /* macro name */
567    ((size4u_t)(A)),
568    /* optional attributes */
569)
570
571
572DEF_MACRO(
573    fCAST4_8s, /* macro name */
574    ((size8s_t)((size4s_t)(A))),
575    /* optional attributes */
576)
577
578DEF_MACRO(
579    fCAST4_8u, /* macro name */
580    ((size8u_t)((size4u_t)(A))),
581    /* optional attributes */
582)
583
584DEF_MACRO(
585    fCAST8_8s, /* macro name */
586    ((size8s_t)(A)),
587    /* optional attributes */
588)
589
590DEF_MACRO(
591    fCAST8_8u, /* macro name */
592    ((size8u_t)(A)),
593    /* optional attributes */
594)
595
596DEF_MACRO(
597    fCAST2_8s, /* macro name */
598    ((size8s_t)((size2s_t)(A))),
599    /* optional attributes */
600)
601DEF_MACRO(
602    fCAST2_8u, /* macro name */
603    ((size8u_t)((size2u_t)(A))),
604    /* optional attributes */
605)
606
607DEF_MACRO(
608    fZE8_16, /* zero-extend 8 to 16 */
609    ((size2s_t)((size1u_t)(A))),
610    /* optional attributes */
611)
612DEF_MACRO(
613    fSE8_16, /* sign-extend 8 to 16 */
614    ((size2s_t)((size1s_t)(A))),
615    /* optional attributes */
616)
617
618
619DEF_MACRO(
620    fSE16_32, /* sign-extend 16 to 32 */
621    ((size4s_t)((size2s_t)(A))),          /* behavior */
622    /* optional attributes */
623)
624
625DEF_MACRO(
626    fZE16_32, /* zero-extend 16 to 32 */
627    ((size4u_t)((size2u_t)(A))),          /* behavior */
628    /* optional attributes */
629)
630
631DEF_MACRO(
632    fSE32_64,
633    ( (size8s_t)((size4s_t)(A)) ),          /* behavior */
634    /* optional attributes */
635)
636
637DEF_MACRO(
638    fZE32_64,
639    ( (size8u_t)((size4u_t)(A)) ),          /* behavior */
640    /* optional attributes */
641)
642
643DEF_MACRO(
644    fSE8_32, /* sign-extend 8 to 32 */
645    ((size4s_t)((size1s_t)(A))),
646    /* optional attributes */
647)
648
649DEF_MACRO(
650    fZE8_32, /* zero-extend 8 to 32 */
651    ((size4s_t)((size1u_t)(A))),
652    /* optional attributes */
653)
654
655/*************************************/
656/* DSP arithmetic support            */
657/************************************/
658DEF_MACRO(
659    fMPY8UU, /* multiply half integer */
660    (int)(fZE8_16(A)*fZE8_16(B)),     /* behavior */
661    ()
662)
663DEF_MACRO(
664    fMPY8US, /* multiply half integer */
665    (int)(fZE8_16(A)*fSE8_16(B)),     /* behavior */
666    ()
667)
668DEF_MACRO(
669    fMPY8SU, /* multiply half integer */
670    (int)(fSE8_16(A)*fZE8_16(B)),     /* behavior */
671    ()
672)
673
674DEF_MACRO(
675    fMPY8SS, /* multiply half integer */
676    (int)((short)(A)*(short)(B)),     /* behavior */
677    ()
678)
679
680DEF_MACRO(
681    fMPY16SS, /* multiply half integer */
682    fSE32_64(fSE16_32(A)*fSE16_32(B)),     /* behavior */
683    ()
684)
685
686DEF_MACRO(
687    fMPY16UU, /* multiply unsigned half integer */
688    fZE32_64(fZE16_32(A)*fZE16_32(B)),     /* behavior */
689    ()
690)
691
692DEF_MACRO(
693    fMPY16SU, /* multiply half integer */
694    fSE32_64(fSE16_32(A)*fZE16_32(B)),     /* behavior */
695    ()
696)
697
698DEF_MACRO(
699    fMPY16US, /* multiply half integer */
700    fMPY16SU(B,A),
701    ()
702)
703
704DEF_MACRO(
705    fMPY32SS, /* multiply half integer */
706    (fSE32_64(A)*fSE32_64(B)),     /* behavior */
707    ()
708)
709
710DEF_MACRO(
711    fMPY32UU, /* multiply half integer */
712    (fZE32_64(A)*fZE32_64(B)),     /* behavior */
713    ()
714)
715
716DEF_MACRO(
717    fMPY32SU, /* multiply half integer */
718    (fSE32_64(A)*fZE32_64(B)),     /* behavior */
719    ()
720)
721
722DEF_MACRO(
723    fMPY3216SS, /* multiply mixed precision */
724    (fSE32_64(A)*fSXTN(16,64,B)),     /* behavior */
725    ()
726)
727
728DEF_MACRO(
729    fMPY3216SU, /* multiply mixed precision */
730    (fSE32_64(A)*fZXTN(16,64,B)),     /* behavior */
731    ()
732)
733
734DEF_MACRO(
735    fROUND, /* optional rounding */
736    (A+0x8000),
737    /* optional attributes */
738)
739
740DEF_MACRO(
741    fCLIP, /* optional rounding */
742    { size4s_t maxv = (1<<U)-1;
743      size4s_t minv = -(1<<U);
744      DST = fMIN(maxv,fMAX(SRC,minv));
745    },
746    /* optional attributes */
747)
748
749DEF_MACRO(
750    fCRND, /* optional rounding */
751    ((((A)&0x3)==0x3)?((A)+1):((A))),
752    /* optional attributes */
753)
754
755DEF_MACRO(
756    fRNDN, /* Rounding to a boundary */
757    ((((N)==0)?(A):(((fSE32_64(A))+(1<<((N)-1)))))),
758    /* optional attributes */
759)
760
761DEF_MACRO(
762    fCRNDN, /* Rounding to a boundary */
763    (conv_round(A,N)),
764    /* optional attributes */
765)
766
767DEF_MACRO(
768    fADD128, /* Rounding to a boundary */
769    (add128(A, B)),
770    /* optional attributes */
771)
772DEF_MACRO(
773    fSUB128, /* Rounding to a boundary */
774    (sub128(A, B)),
775    /* optional attributes */
776)
777DEF_MACRO(
778    fSHIFTR128, /* Rounding to a boundary */
779    (shiftr128(A, B)),
780    /* optional attributes */
781)
782
783DEF_MACRO(
784    fSHIFTL128, /* Rounding to a boundary */
785    (shiftl128(A, B)),
786    /* optional attributes */
787)
788
789DEF_MACRO(
790    fAND128, /* Rounding to a boundary */
791    (and128(A, B)),
792    /* optional attributes */
793)
794
795DEF_MACRO(
796    fCAST8S_16S, /* Rounding to a boundary */
797    (cast8s_to_16s(A)),
798    /* optional attributes */
799)
800DEF_MACRO(
801    fCAST16S_8S, /* Rounding to a boundary */
802    (cast16s_to_8s(A)),
803    /* optional attributes */
804)
805
806DEF_MACRO(
807    fEA_RI, /* Calculate EA with Register + Immediate Offset */
808    do { EA=REG+IMM; fDOCHKPAGECROSS(REG,EA); } while (0),
809    ()
810)
811
812DEF_MACRO(
813    fEA_RRs, /* Calculate EA with Register + Registers scaled Offset */
814    do { EA=REG+(REG2<<SCALE); fDOCHKPAGECROSS(REG,EA); } while (0),
815    ()
816)
817
818DEF_MACRO(
819    fEA_IRs, /* Calculate EA with Immediate + Registers scaled Offset */
820    do { EA=IMM+(REG<<SCALE); fDOCHKPAGECROSS(IMM,EA); } while (0),
821    ()
822)
823
824DEF_MACRO(
825    fEA_IMM, /* Calculate EA with Immediate */
826    EA=IMM,
827    ()
828)
829
830DEF_MACRO(
831    fEA_REG, /* Calculate EA with REGISTER */
832    EA=REG,
833    ()
834)
835
836DEF_MACRO(
837    fEA_BREVR, /* Calculate EA with bit reversed bottom of REGISTER */
838    EA=fbrev(REG),
839    ()
840)
841
842DEF_MACRO(
843    fEA_GPI, /* Calculate EA with Global Poitner + Immediate */
844    do { EA=fREAD_GP()+IMM; fGP_DOCHKPAGECROSS(fREAD_GP(),EA); } while (0),
845    ()
846)
847
848DEF_MACRO(
849    fPM_I, /* Post Modify Register by Immediate*/
850    do { REG = REG + IMM; } while (0),
851    ()
852)
853
854DEF_MACRO(
855    fPM_M, /* Post Modify Register by M register */
856    do { REG = REG + MVAL; } while (0),
857    ()
858)
859
860DEF_MACRO(
861    fPM_CIRI, /* Post Modify Register using Circular arithmetic by Immediate */
862    do { fcirc_add(REG,siV,MuV); } while (0),
863    ()
864)
865
866DEF_MACRO(
867    fPM_CIRR, /* Post Modify Register using Circular arithmetic by register */
868    do { fcirc_add(REG,VAL,MuV); } while (0),
869    ()
870)
871
872
873
874DEF_MACRO(
875    fSCALE, /* scale by N */
876    (((size8s_t)(A))<<N),
877    /* optional attributes */
878)
879
880DEF_MACRO(
881    fSATW, /* saturating to 32-bits*/
882    fSATN(32,((long long)A)),
883    ()
884)
885
886DEF_MACRO(
887    fSAT, /* saturating to 32-bits*/
888    fSATN(32,(A)),
889    ()
890)
891
892DEF_MACRO(
893    fSAT_ORIG_SHL, /* Saturating to 32-bits, with original value, for shift left */
894    ((((size4s_t)((fSAT(A)) ^ ((size4s_t)(ORIG_REG)))) < 0) ?
895        fSATVALN(32,((size4s_t)(ORIG_REG))) :
896        ((((ORIG_REG) > 0) && ((A) == 0)) ?
897            fSATVALN(32,(ORIG_REG)) :
898            fSAT(A))),
899    ()
900)
901
902DEF_MACRO(
903    fPASS,
904    A,
905)
906
907DEF_MACRO(
908    fRND, /* saturating to 32-bits*/
909    (((A)+1)>>1),
910)
911
912
913DEF_MACRO(
914    fBIDIR_SHIFTL,
915    (((SHAMT) < 0) ? ((fCAST##REGSTYPE(SRC) >> ((-(SHAMT))-1)) >>1) : (fCAST##REGSTYPE(SRC) << (SHAMT))),
916    ()
917)
918
919DEF_MACRO(
920    fBIDIR_ASHIFTL,
921    fBIDIR_SHIFTL(SRC,SHAMT,REGSTYPE##s),
922    ()
923)
924
925DEF_MACRO(
926    fBIDIR_LSHIFTL,
927    fBIDIR_SHIFTL(SRC,SHAMT,REGSTYPE##u),
928    ()
929)
930
931DEF_MACRO(
932    fBIDIR_ASHIFTL_SAT,
933    (((SHAMT) < 0) ? ((fCAST##REGSTYPE##s(SRC) >> ((-(SHAMT))-1)) >>1) : fSAT_ORIG_SHL(fCAST##REGSTYPE##s(SRC) << (SHAMT),(SRC))),
934    ()
935)
936
937
938DEF_MACRO(
939    fBIDIR_SHIFTR,
940    (((SHAMT) < 0) ? ((fCAST##REGSTYPE(SRC) << ((-(SHAMT))-1)) << 1) : (fCAST##REGSTYPE(SRC) >> (SHAMT))),
941    ()
942)
943
944DEF_MACRO(
945    fBIDIR_ASHIFTR,
946    fBIDIR_SHIFTR(SRC,SHAMT,REGSTYPE##s),
947    ()
948)
949
950DEF_MACRO(
951    fBIDIR_LSHIFTR,
952    fBIDIR_SHIFTR(SRC,SHAMT,REGSTYPE##u),
953    ()
954)
955
956DEF_MACRO(
957    fBIDIR_ASHIFTR_SAT,
958    (((SHAMT) < 0) ? fSAT_ORIG_SHL((fCAST##REGSTYPE##s(SRC) << ((-(SHAMT))-1)) << 1,(SRC)) : (fCAST##REGSTYPE##s(SRC) >> (SHAMT))),
959    ()
960)
961
962DEF_MACRO(
963    fASHIFTR,
964    (fCAST##REGSTYPE##s(SRC) >> (SHAMT)),
965    /* */
966)
967
968DEF_MACRO(
969    fLSHIFTR,
970    (((SHAMT) >= 64)?0:(fCAST##REGSTYPE##u(SRC) >> (SHAMT))),
971    /* */
972)
973
974DEF_MACRO(
975    fROTL,
976    (((SHAMT)==0) ? (SRC) : ((fCAST##REGSTYPE##u(SRC) << (SHAMT)) | \
977        ((fCAST##REGSTYPE##u(SRC) >> ((sizeof(SRC)*8)-(SHAMT)))))),
978    /* */
979)
980
981DEF_MACRO(
982    fROTR,
983    (((SHAMT)==0) ? (SRC) : ((fCAST##REGSTYPE##u(SRC) >> (SHAMT)) | \
984        ((fCAST##REGSTYPE##u(SRC) << ((sizeof(SRC)*8)-(SHAMT)))))),
985    /* */
986)
987
988DEF_MACRO(
989    fASHIFTL,
990    (((SHAMT) >= 64)?0:(fCAST##REGSTYPE##s(SRC) << (SHAMT))),
991    /* */
992)
993
994/*************************************/
995/* Floating-Point Support            */
996/************************************/
997
998DEF_MACRO(
999    fFLOAT, /* name */
1000    ({ union { float f; size4u_t i; } _fipun; _fipun.i = (A); _fipun.f; }),     /* behavior */
1001    (A_FPOP)
1002)
1003
1004DEF_MACRO(
1005    fUNFLOAT, /* multiply half integer */
1006    ({ union { float f; size4u_t i; } _fipun; _fipun.f = (A); isnan(_fipun.f) ? 0xFFFFFFFFU : _fipun.i; }),     /* behavior */
1007    (A_FPOP)
1008)
1009
1010DEF_MACRO(
1011    fSFNANVAL,
1012    0xffffffff,
1013    ()
1014)
1015
1016DEF_MACRO(
1017    fSFINFVAL,
1018    (((A) & 0x80000000) | 0x7f800000),
1019    ()
1020)
1021
1022DEF_MACRO(
1023    fSFONEVAL,
1024    (((A) & 0x80000000) | fUNFLOAT(1.0)),
1025    ()
1026)
1027
1028DEF_MACRO(
1029    fCHECKSFNAN,
1030    do {
1031        if (isnan(fFLOAT(A))) {
1032            if ((fGETBIT(22,A)) == 0) fRAISEFLAGS(FE_INVALID);
1033            DST = fSFNANVAL();
1034        }
1035    } while (0),
1036    ()
1037)
1038
1039DEF_MACRO(
1040    fCHECKSFNAN3,
1041    do {
1042        fCHECKSFNAN(DST,A);
1043        fCHECKSFNAN(DST,B);
1044        fCHECKSFNAN(DST,C);
1045    } while (0),
1046    ()
1047)
1048
1049DEF_MACRO(
1050    fSF_BIAS,
1051    127,
1052    ()
1053)
1054
1055DEF_MACRO(
1056    fSF_MANTBITS,
1057    23,
1058    ()
1059)
1060
1061DEF_MACRO(
1062    fSF_MUL_POW2,
1063    (fUNFLOAT(fFLOAT(A) * fFLOAT((fSF_BIAS() + (B)) << fSF_MANTBITS()))),
1064    ()
1065)
1066
1067DEF_MACRO(
1068    fSF_GETEXP,
1069    (((A) >> fSF_MANTBITS()) & 0xff),
1070    ()
1071)
1072
1073DEF_MACRO(
1074    fSF_MAXEXP,
1075    (254),
1076    ()
1077)
1078
1079DEF_MACRO(
1080    fSF_RECIP_COMMON,
1081    arch_sf_recip_common(&N,&D,&O,&A),
1082    (A_FPOP)
1083)
1084
1085DEF_MACRO(
1086    fSF_INVSQRT_COMMON,
1087    arch_sf_invsqrt_common(&N,&O,&A),
1088    (A_FPOP)
1089)
1090
1091DEF_MACRO(
1092    fFMAFX,
1093    internal_fmafx(A,B,C,fSXTN(8,64,ADJ)),
1094    ()
1095)
1096
1097DEF_MACRO(
1098    fFMAF,
1099    internal_fmafx(A,B,C,0),
1100    ()
1101)
1102
1103DEF_MACRO(
1104    fSFMPY,
1105    internal_mpyf(A,B),
1106    ()
1107)
1108
1109DEF_MACRO(
1110    fMAKESF,
1111    ((((SIGN) & 1) << 31) | (((EXP) & 0xff) << fSF_MANTBITS()) |
1112        ((MANT) & ((1<<fSF_MANTBITS())-1))),
1113    ()
1114)
1115
1116
1117DEF_MACRO(
1118    fDOUBLE, /* multiply half integer */
1119    ({ union { double f; size8u_t i; } _fipun; _fipun.i = (A); _fipun.f; }),     /* behavior */
1120    (A_FPOP)
1121)
1122
1123DEF_MACRO(
1124    fUNDOUBLE, /* multiply half integer */
1125    ({ union { double f; size8u_t i; } _fipun; _fipun.f = (A); isnan(_fipun.f) ? 0xFFFFFFFFFFFFFFFFULL : _fipun.i; }),     /* behavior */
1126    (A_FPOP)
1127)
1128
1129DEF_MACRO(
1130    fDFNANVAL,
1131    0xffffffffffffffffULL,
1132    ()
1133)
1134
1135DEF_MACRO(
1136    fDF_ISNORMAL,
1137    (fpclassify(fDOUBLE(X)) == FP_NORMAL),
1138    ()
1139)
1140
1141DEF_MACRO(
1142    fDF_ISDENORM,
1143    (fpclassify(fDOUBLE(X)) == FP_SUBNORMAL),
1144    ()
1145)
1146
1147DEF_MACRO(
1148    fDF_ISBIG,
1149    (fDF_GETEXP(X) >= 512),
1150    ()
1151)
1152
1153DEF_MACRO(
1154    fDF_MANTBITS,
1155    52,
1156    ()
1157)
1158
1159DEF_MACRO(
1160    fDF_GETEXP,
1161    (((A) >> fDF_MANTBITS()) & 0x7ff),
1162    ()
1163)
1164
1165DEF_MACRO(
1166    fFMA,
1167    internal_fma(A,B,C),
1168    /* nothing */
1169)
1170
1171DEF_MACRO(
1172    fDF_MPY_HH,
1173    internal_mpyhh(A,B,ACC),
1174    /* nothing */
1175)
1176
1177DEF_MACRO(
1178    fFPOP_START,
1179    arch_fpop_start(thread),
1180    /* nothing */
1181)
1182
1183DEF_MACRO(
1184    fFPOP_END,
1185    arch_fpop_end(thread),
1186    /* nothing */
1187)
1188
1189DEF_MACRO(
1190    fFPSETROUND_NEAREST,
1191    fesetround(FE_TONEAREST),
1192    /* nothing */
1193)
1194
1195DEF_MACRO(
1196    fFPSETROUND_CHOP,
1197    fesetround(FE_TOWARDZERO),
1198    /* nothing */
1199)
1200
1201DEF_MACRO(
1202    fFPCANCELFLAGS,
1203    feclearexcept(FE_ALL_EXCEPT),
1204    /* nothing */
1205)
1206
1207DEF_MACRO(
1208    fISINFPROD,
1209    ((isinf(A) && isinf(B)) ||
1210     (isinf(A) && isfinite(B) && ((B) != 0.0)) ||
1211     (isinf(B) && isfinite(A) && ((A) != 0.0))),
1212    /* nothing */
1213)
1214
1215DEF_MACRO(
1216    fISZEROPROD,
1217    ((((A) == 0.0) && isfinite(B)) || (((B) == 0.0) && isfinite(A))),
1218    /* nothing */
1219)
1220
1221DEF_MACRO(
1222    fRAISEFLAGS,
1223    arch_raise_fpflag(A),
1224    /* NOTHING */
1225)
1226
1227DEF_MACRO(
1228    fDF_MAX,
1229    (((A)==(B))
1230    ? fDOUBLE(fUNDOUBLE(A) & fUNDOUBLE(B))
1231    : fmax(A,B)),
1232    (A_FPOP)
1233)
1234
1235DEF_MACRO(
1236    fDF_MIN,
1237    (((A)==(B))
1238    ? fDOUBLE(fUNDOUBLE(A) | fUNDOUBLE(B))
1239    : fmin(A,B)),
1240    (A_FPOP)
1241)
1242
1243DEF_MACRO(
1244    fSF_MAX,
1245    (((A)==(B))
1246    ? fFLOAT(fUNFLOAT(A) & fUNFLOAT(B))
1247    : fmaxf(A,B)),
1248    (A_FPOP)
1249)
1250
1251DEF_MACRO(
1252    fSF_MIN,
1253    (((A)==(B))
1254    ? fFLOAT(fUNFLOAT(A) | fUNFLOAT(B))
1255    : fminf(A,B)),
1256    (A_FPOP)
1257)
1258
1259/*************************************/
1260/* Load/Store support                */
1261/*************************************/
1262
1263DEF_MACRO(fLOAD,
1264    { DST = (size##SIZE##SIGN##_t)MEM_LOAD##SIZE(thread,EA,insn); },
1265    (A_LOAD,A_MEMLIKE)
1266)
1267
1268DEF_MACRO(fMEMOP,
1269    { memop##SIZE##_##FNTYPE(thread,EA,VALUE); },
1270    (A_LOAD,A_STORE,A_MEMLIKE)
1271)
1272
1273DEF_MACRO(fGET_FRAMEKEY,
1274    READ_RREG(REG_FRAMEKEY),
1275    ()
1276)
1277
1278DEF_MACRO(fFRAME_SCRAMBLE,
1279    ((VAL) ^ (fCAST8u(fGET_FRAMEKEY()) << 32)),
1280    /* ATTRIBS */
1281)
1282
1283DEF_MACRO(fFRAME_UNSCRAMBLE,
1284    fFRAME_SCRAMBLE(VAL),
1285    /* ATTRIBS */
1286)
1287
1288DEF_MACRO(fFRAMECHECK,
1289    sys_check_framelimit(thread,ADDR,EA),
1290    ()
1291)
1292
1293DEF_MACRO(fLOAD_LOCKED,
1294    {     DST = (size##SIZE##SIGN##_t)mem_load_locked(thread,EA,SIZE,insn); },
1295    (A_LOAD,A_MEMLIKE)
1296)
1297
1298DEF_MACRO(fSTORE,
1299    { MEM_STORE##SIZE(thread,EA,SRC,insn); },
1300    (A_STORE,A_MEMLIKE)
1301)
1302
1303
1304DEF_MACRO(fSTORE_LOCKED,
1305    { PRED = (mem_store_conditional(thread,EA,SRC,SIZE,insn) ? 0xff : 0); },
1306    (A_STORE,A_MEMLIKE)
1307)
1308
1309/*************************************/
1310/* Functions to help with bytes      */
1311/*************************************/
1312
1313DEF_MACRO(fGETBYTE,
1314    ((size1s_t)((SRC>>((N)*8))&0xff)),
1315    /* nothing */
1316)
1317
1318DEF_MACRO(fGETUBYTE,
1319    ((size1u_t)((SRC>>((N)*8))&0xff)),
1320    /* nothing */
1321)
1322
1323DEF_MACRO(fSETBYTE,
1324    {
1325        DST = (DST & ~(0x0ffLL<<((N)*8))) | (((size8u_t)((VAL) & 0x0ffLL)) << ((N)*8));
1326    },
1327    /* nothing */
1328)
1329
1330DEF_MACRO(fGETHALF,
1331    ((size2s_t)((SRC>>((N)*16))&0xffff)),
1332    /* nothing */
1333)
1334
1335DEF_MACRO(fGETUHALF,
1336    ((size2u_t)((SRC>>((N)*16))&0xffff)),
1337    /* nothing */
1338)
1339
1340DEF_MACRO(fSETHALF,
1341    {
1342        DST = (DST & ~(0x0ffffLL<<((N)*16))) | (((size8u_t)((VAL) & 0x0ffff)) << ((N)*16));
1343    },
1344    /* nothing */
1345)
1346
1347
1348
1349DEF_MACRO(fGETWORD,
1350    ((size8s_t)((size4s_t)((SRC>>((N)*32))&0x0ffffffffLL))),
1351    /* nothing */
1352)
1353
1354DEF_MACRO(fGETUWORD,
1355    ((size8u_t)((size4u_t)((SRC>>((N)*32))&0x0ffffffffLL))),
1356    /* nothing */
1357)
1358
1359DEF_MACRO(fSETWORD,
1360    {
1361        DST = (DST & ~(0x0ffffffffLL<<((N)*32))) | (((VAL) & 0x0ffffffffLL) << ((N)*32));
1362    },
1363    /* nothing */
1364)
1365
1366DEF_MACRO(fSETBIT,
1367    {
1368        DST = (DST & ~(1ULL<<(N))) | (((size8u_t)(VAL))<<(N));
1369    },
1370    /* nothing */
1371)
1372
1373DEF_MACRO(fGETBIT,
1374    (((SRC)>>N)&1),
1375    /* nothing */
1376)
1377
1378
1379DEF_MACRO(fSETBITS,
1380    do {
1381        int j;
1382        for (j=LO;j<=HI;j++) {
1383          fSETBIT(j,DST,VAL);
1384        }
1385    } while (0),
1386    /* nothing */
1387)
1388
1389/*************************************/
1390/* Used for parity, etc........      */
1391/*************************************/
1392DEF_MACRO(fCOUNTONES_4,
1393    count_ones_4(VAL),
1394    /* nothing */
1395)
1396
1397DEF_MACRO(fCOUNTONES_8,
1398    count_ones_8(VAL),
1399    /* nothing */
1400)
1401
1402DEF_MACRO(fBREV_8,
1403    reverse_bits_8(VAL),
1404    /* nothing */
1405)
1406
1407DEF_MACRO(fBREV_4,
1408    reverse_bits_4(VAL),
1409    /* nothing */
1410)
1411
1412DEF_MACRO(fCL1_8,
1413    count_leading_ones_8(VAL),
1414    /* nothing */
1415)
1416
1417DEF_MACRO(fCL1_4,
1418    count_leading_ones_4(VAL),
1419    /* nothing */
1420)
1421
1422DEF_MACRO(fINTERLEAVE,
1423    interleave(ODD,EVEN),
1424    /* nothing */
1425)
1426
1427DEF_MACRO(fDEINTERLEAVE,
1428    deinterleave(MIXED),
1429    /* nothing */
1430)
1431
1432DEF_MACRO(fHIDE,
1433    A,
1434    ()
1435)
1436
1437DEF_MACRO(fCONSTLL,
1438    A##LL,
1439)
1440
1441/* Do the things in the parens, but don't print the parens. */
1442DEF_MACRO(fECHO,
1443    (A),
1444    /* nothing */
1445)
1446
1447
1448/********************************************/
1449/* OS interface and stop/wait               */
1450/********************************************/
1451
1452DEF_MACRO(fPAUSE,
1453    {sys_pause(thread, insn->slot, IMM);},
1454    ()
1455)
1456
1457DEF_MACRO(fTRAP,
1458    warn("Trap NPC=%x ",fREAD_NPC());
1459    warn("Trap exception, PCYCLE=%lld TYPE=%d NPC=%x IMM=0x%x",thread->processor_ptr->pstats[pcycles],TRAPTYPE,fREAD_NPC(),IMM);
1460    register_trap_exception(thread,fREAD_NPC(),TRAPTYPE,IMM);,
1461    ()
1462)
1463
1464DEF_MACRO(fALIGN_REG_FIELD_VALUE,
1465    ((VAL)<<reg_field_info[FIELD].offset),
1466    /* */
1467)
1468
1469DEF_MACRO(fGET_REG_FIELD_MASK,
1470    (((1<<reg_field_info[FIELD].width)-1)<<reg_field_info[FIELD].offset),
1471    /* */
1472)
1473
1474DEF_MACRO(fREAD_REG_FIELD,
1475    fEXTRACTU_BITS(thread->Regs[REG_##REG],
1476        reg_field_info[FIELD].width,
1477        reg_field_info[FIELD].offset),
1478    /* ATTRIBS */
1479)
1480
1481DEF_MACRO(fGET_FIELD,
1482    fEXTRACTU_BITS(VAL,
1483        reg_field_info[FIELD].width,
1484        reg_field_info[FIELD].offset),
1485    /* ATTRIBS */
1486)
1487
1488DEF_MACRO(fSET_FIELD,
1489    fINSERT_BITS(VAL,
1490        reg_field_info[FIELD].width,
1491        reg_field_info[FIELD].offset,
1492        (NEWVAL)),
1493    /* ATTRIBS */
1494)
1495
1496/********************************************/
1497/* Cache Management                         */
1498/********************************************/
1499
1500DEF_MACRO(fBARRIER,
1501    {
1502        sys_barrier(thread, insn->slot);
1503    },
1504    ()
1505)
1506
1507DEF_MACRO(fSYNCH,
1508    {
1509        sys_sync(thread, insn->slot);
1510    },
1511    ()
1512)
1513
1514DEF_MACRO(fISYNC,
1515    {
1516        sys_isync(thread, insn->slot);
1517    },
1518    ()
1519)
1520
1521
1522DEF_MACRO(fDCFETCH,
1523    sys_dcfetch(thread, (REG), insn->slot),
1524    (A_MEMLIKE)
1525)
1526
1527DEF_MACRO(fICINVA,
1528    {
1529        arch_internal_flush(thread->processor_ptr, 0, 0xffffffff);
1530        sys_icinva(thread, (REG),insn->slot);
1531    },
1532    (A_ICINVA)
1533)
1534
1535DEF_MACRO(fL2FETCH,
1536    sys_l2fetch(thread, ADDR,HEIGHT,WIDTH,STRIDE,FLAGS, insn->slot),
1537    (A_MEMLIKE,A_L2FETCH)
1538)
1539
1540DEF_MACRO(fDCCLEANA,
1541    sys_dccleana(thread, (REG)),
1542    (A_MEMLIKE)
1543)
1544
1545DEF_MACRO(fDCCLEANINVA,
1546    sys_dccleaninva(thread, (REG), insn->slot),
1547    (A_MEMLIKE,A_DCCLEANINVA)
1548)
1549
1550DEF_MACRO(fDCZEROA,
1551    sys_dczeroa(thread, (REG)),
1552    (A_MEMLIKE)
1553)
1554
1555DEF_MACRO(fCHECKFORPRIV,
1556    {sys_check_privs(thread); if (EXCEPTION_DETECTED) return; },
1557    ()
1558)
1559
1560DEF_MACRO(fCHECKFORGUEST,
1561    {sys_check_guest(thread); if (EXCEPTION_DETECTED) return; },
1562    ()
1563)
1564
1565DEF_MACRO(fBRANCH_SPECULATE_STALL,
1566    {
1567        sys_speculate_branch_stall(thread, insn->slot, JUMP_COND(JUMP_PRED_SET),
1568            SPEC_DIR,
1569            DOTNEWVAL,
1570            HINTBITNUM,
1571            STRBITNUM,
1572            0,
1573            thread->last_pkt->pkt_has_dual_jump,
1574            insn->is_2nd_jump,
1575            (thread->fetch_access.vaddr + insn->encoding_offset*4));
1576    },
1577    ()
1578)
1579