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