Hexagon (target/hexagon) circular addressing
[qemu/ar7.git] / target / hexagon / imported / macros.def
blob25f57b6f1976f0738ee107116ee4d2eed867c41e
1 /*
2 * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved.
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.
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.
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/>.
18 DEF_MACRO(
19 LIKELY, /* NAME */
20 __builtin_expect((X),1), /* BEH */
21 () /* attribs */
24 DEF_MACRO(
25 UNLIKELY, /* NAME */
26 __builtin_expect((X),0), /* BEH */
27 () /* attribs */
30 DEF_MACRO(
31 CANCEL, /* macro name */
32 {if (thread->last_pkt) thread->last_pkt->slot_cancelled |= (1<<insn->slot); return;} , /* behavior */
33 (A_CONDEXEC)
36 DEF_MACRO(
37 LOAD_CANCEL, /* macro name */
38 {mem_general_load_cancelled(thread,EA,insn);CANCEL;} , /* behavior */
39 (A_CONDEXEC)
42 DEF_MACRO(
43 STORE_CANCEL, /* macro name */
44 {mem_general_store_cancelled(thread,EA,insn);CANCEL;} , /* behavior */
45 (A_CONDEXEC)
48 DEF_MACRO(
49 fMAX, /* macro name */
50 (((A) > (B)) ? (A) : (B)), /* behavior */
51 /* optional attributes */
54 DEF_MACRO(
55 fMIN, /* macro name */
56 (((A) < (B)) ? (A) : (B)), /* behavior */
57 /* optional attributes */
60 DEF_MACRO(
61 fABS, /* macro name */
62 (((A)<0)?(-(A)):(A)), /* behavior */
63 /* optional attributes */
67 /* Bit insert */
68 DEF_MACRO(
69 fINSERT_BITS,
71 REG = ((REG) & ~(((fCONSTLL(1)<<(WIDTH))-1)<<(OFFSET))) | (((INVAL) & ((fCONSTLL(1)<<(WIDTH))-1)) << (OFFSET));
73 /* attribs */
76 /* Bit extract */
77 DEF_MACRO(
78 fEXTRACTU_BITS,
79 (fZXTN(WIDTH,32,(INREG >> OFFSET))),
80 /* attribs */
83 DEF_MACRO(
84 fEXTRACTU_BIDIR,
85 (fZXTN(WIDTH,32,fBIDIR_LSHIFTR((INREG),(OFFSET),4_8))),
86 /* attribs */
89 DEF_MACRO(
90 fEXTRACTU_RANGE,
91 (fZXTN((HIBIT-LOWBIT+1),32,(INREG >> LOWBIT))),
92 /* attribs */
95 DEF_MACRO(
96 f8BITSOF,
97 ( (VAL) ? 0xff : 0x00),
98 /* attribs */
101 DEF_MACRO(
102 fLSBOLD,
103 ((VAL) & 1),
107 DEF_MACRO(
108 fLSBNEW,
109 predlog_read(thread,PNUM),
113 DEF_MACRO(
114 fLSBNEW0,
115 predlog_read(thread,0),
119 DEF_MACRO(
120 fLSBNEW1,
121 predlog_read(thread,1),
125 DEF_MACRO(
126 fLSBOLDNOT,
127 (!fLSBOLD(VAL)),
131 DEF_MACRO(
132 fLSBNEWNOT,
133 (!fLSBNEW(PNUM)),
137 DEF_MACRO(
138 fLSBNEW0NOT,
139 (!fLSBNEW0),
143 DEF_MACRO(
144 fLSBNEW1NOT,
145 (!fLSBNEW1),
149 DEF_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)
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
157 DEF_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)
164 DEF_MACRO(
165 fSATUVALN,
166 ({fSET_OVERFLOW(); ((VAL) < 0) ? 0 : ((1LL<<(N))-1);}),
170 DEF_MACRO(
171 fSATVALN,
172 ({fSET_OVERFLOW(); ((VAL) < 0) ? (-(1LL<<((N)-1))) : ((1LL<<((N)-1))-1);}),
176 DEF_MACRO(
177 fZXTN, /* macro name */
178 ((VAL) & ((1LL<<(N))-1)),
179 /* attribs */
182 DEF_MACRO(
183 fSXTN, /* macro name */
184 ((fZXTN(N,M,VAL) ^ (1LL<<((N)-1))) - (1LL<<((N)-1))),
185 /* attribs */
188 DEF_MACRO(
189 fSATN,
190 ((fSXTN(N,64,VAL) == (VAL)) ? (VAL) : fSATVALN(N,VAL)),
194 DEF_MACRO(
195 fADDSAT64,
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();
214 } else {
215 /* signs did not mismatch, OK */
216 DST = __sum;
222 DEF_MACRO(
223 fSATUN,
224 ((fZXTN(N,64,VAL) == (VAL)) ? (VAL) : fSATUVALN(N,VAL)),
228 DEF_MACRO(
229 fSATH,
230 (fSATN(16,VAL)),
235 DEF_MACRO(
236 fSATUH,
237 (fSATUN(16,VAL)),
241 DEF_MACRO(
242 fSATUB,
243 (fSATUN(8,VAL)),
246 DEF_MACRO(
247 fSATB,
248 (fSATN(8,VAL)),
253 /*************************************/
254 /* immediate extension */
255 /*************************************/
257 DEF_MACRO(
258 fIMMEXT,
259 (IMM = IMM),
260 (A_EXTENDABLE)
263 DEF_MACRO(
264 fMUST_IMMEXT,
265 fIMMEXT(IMM),
266 (A_EXTENDABLE)
269 DEF_MACRO(
270 fPCALIGN,
271 IMM=(IMM & ~PCALIGN_MASK),
272 (A_EXTENDABLE)
275 /*************************************/
276 /* Read and Write Implicit Regs */
277 /*************************************/
279 DEF_MACRO(
280 fREAD_IREG, /* read modifier register */
281 (fSXTN(11,64,(((VAL) & 0xf0000000)>>21) | ((VAL>>17)&0x7f) )), /* behavior */
285 DEF_MACRO(
286 fREAD_LR, /* read link register */
287 (READ_RREG(REG_LR)), /* behavior */
291 DEF_MACRO(
292 fWRITE_LR, /* write lr */
293 WRITE_RREG(REG_LR,A), /* behavior */
294 (A_IMPLICIT_WRITES_LR)
297 DEF_MACRO(
298 fWRITE_FP, /* write sp */
299 WRITE_RREG(REG_FP,A), /* behavior */
300 (A_IMPLICIT_WRITES_FP)
303 DEF_MACRO(
304 fWRITE_SP, /* write sp */
305 WRITE_RREG(REG_SP,A), /* behavior */
306 (A_IMPLICIT_WRITES_SP)
309 DEF_MACRO(
310 fREAD_SP, /* read stack pointer */
311 (READ_RREG(REG_SP)), /* behavior */
315 DEF_MACRO(
316 fREAD_CSREG, /* read CS register */
317 (READ_RREG(REG_CSA+N)), /* behavior */
321 DEF_MACRO(
322 fREAD_LC0, /* read loop count */
323 (READ_RREG(REG_LC0)), /* behavior */
327 DEF_MACRO(
328 fREAD_LC1, /* read loop count */
329 (READ_RREG(REG_LC1)), /* behavior */
333 DEF_MACRO(
334 fREAD_SA0, /* read start addr */
335 (READ_RREG(REG_SA0)), /* behavior */
339 DEF_MACRO(
340 fREAD_SA1, /* read start addr */
341 (READ_RREG(REG_SA1)), /* behavior */
346 DEF_MACRO(
347 fREAD_FP, /* read frame pointer */
348 (READ_RREG(REG_FP)), /* behavior */
352 DEF_MACRO(
353 fREAD_GP, /* read global pointer */
354 (insn->extension_valid ? 0 : READ_RREG(REG_GP)), /* behavior */
358 DEF_MACRO(
359 fREAD_PC, /* read PC */
360 (READ_RREG(REG_PC)), /* behavior */
364 DEF_MACRO(
365 fREAD_NPC, /* read next PC */
366 (thread->next_PC & (0xfffffffe)), /* behavior */
370 DEF_MACRO(
371 fREAD_P0, /* read Predicate 0 */
372 (READ_PREG(0)), /* behavior */
376 DEF_MACRO(
377 fREAD_P3, /* read Predicate 3 */
378 (READ_PREG(3)), /* behavior */
382 DEF_MACRO(
383 fCHECK_PCALIGN,
384 if (((A) & PCALIGN_MASK)) {
385 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);
390 DEF_MACRO(
391 fWRITE_NPC, /* write next PC */
392 if (!thread->branch_taken) {
393 if (A != thread->next_PC) {
394 thread->next_pkt_guess=thread->last_pkt->taken_ptr;
396 fCHECK_PCALIGN(A);
397 thread->branched = 1; thread->branch_taken = 1; thread->next_PC = A; \
398 thread->branch_offset = insn->encoding_offset; thread->branch_opcode = insn->opcode;
399 }, /* behavior */
400 (A_COF)
403 DEF_MACRO(
404 fBRANCH,
405 fWRITE_NPC(LOC); fCOF_CALLBACK(LOC,TYPE),
409 DEF_MACRO(
410 fJUMPR, /* A jumpr has executed */
411 {fBRANCH(TARGET,COF_TYPE_JUMPR);},
412 (A_INDIRECT)
415 DEF_MACRO(
416 fHINTJR, /* A hintjr instruction has executed */
417 { },
420 DEF_MACRO(
421 fCALL, /* Do a call */
422 if (!thread->branch_taken) {fBP_RAS_CALL(A); fWRITE_LR(fREAD_NPC()); fBRANCH(A,COF_TYPE_CALL);},
423 (A_COF,A_IMPLICIT_WRITES_LR,A_CALL)
426 DEF_MACRO(
427 fCALLR, /* Do a call Register */
428 if (!thread->branch_taken) {fBP_RAS_CALL(A); fWRITE_LR(fREAD_NPC()); fBRANCH(A,COF_TYPE_CALLR);},
429 (A_COF,A_IMPLICIT_WRITES_LR,A_CALL)
432 DEF_MACRO(
433 fWRITE_LOOP_REGS0, /* write ln,sa,ea,lc */
434 {WRITE_RREG(REG_LC0,COUNT);
435 WRITE_RREG(REG_SA0,START);},
436 (A_IMPLICIT_WRITES_LC0,A_IMPLICIT_WRITES_SA0)
439 DEF_MACRO(
440 fWRITE_LOOP_REGS1, /* write ln,sa,ea,lc */
441 {WRITE_RREG(REG_LC1,COUNT);
442 WRITE_RREG(REG_SA1,START);},
443 (A_IMPLICIT_WRITES_LC1,A_IMPLICIT_WRITES_SA1)
446 DEF_MACRO(
447 fWRITE_LC0,
448 WRITE_RREG(REG_LC0,VAL),
449 (A_IMPLICIT_WRITES_LC0)
452 DEF_MACRO(
453 fWRITE_LC1,
454 WRITE_RREG(REG_LC1,VAL),
455 (A_IMPLICIT_WRITES_LC1)
458 DEF_MACRO(
459 fCARRY_FROM_ADD,
460 carry_from_add64(A,B,C),
461 /* NOTHING */
464 DEF_MACRO(
465 fSET_OVERFLOW,
466 SET_USR_FIELD(USR_OVF,1),
470 DEF_MACRO(
471 fSET_LPCFG,
472 SET_USR_FIELD(USR_LPCFG,(VAL)),
477 DEF_MACRO(
478 fGET_LPCFG,
479 (GET_USR_FIELD(USR_LPCFG)),
485 DEF_MACRO(
486 fWRITE_P0, /* write Predicate 0 */
487 WRITE_PREG(0,VAL), /* behavior */
488 (A_IMPLICIT_WRITES_P0)
491 DEF_MACRO(
492 fWRITE_P1, /* write Predicate 0 */
493 WRITE_PREG(1,VAL), /* behavior */
494 (A_IMPLICIT_WRITES_P1)
497 DEF_MACRO(
498 fWRITE_P2, /* write Predicate 0 */
499 WRITE_PREG(2,VAL), /* behavior */
500 (A_IMPLICIT_WRITES_P2)
503 DEF_MACRO(
504 fWRITE_P3, /* write Predicate 0 */
505 WRITE_PREG(3,VAL), /* behavior */
506 (A_IMPLICIT_WRITES_P3)
509 DEF_MACRO(
510 fPART1, /* write Predicate 0 */
511 if (insn->part1) { WORK; return; }, /* behavior */
512 /* optional attributes */
516 /*************************************/
517 /* Casting, Sign-Zero extension, etc */
518 /*************************************/
520 DEF_MACRO(
521 fCAST4u, /* macro name */
522 ((size4u_t)(A)), /* behavior */
523 /* optional attributes */
526 DEF_MACRO(
527 fCAST4s, /* macro name */
528 ((size4s_t)(A)), /* behavior */
529 /* optional attributes */
532 DEF_MACRO(
533 fCAST8u, /* macro name */
534 ((size8u_t)(A)), /* behavior */
535 /* optional attributes */
538 DEF_MACRO(
539 fCAST8s, /* macro name */
540 ((size8s_t)(A)), /* behavior */
541 /* optional attributes */
544 DEF_MACRO(
545 fCAST4_4s, /* macro name */
546 ((size4s_t)(A)),
547 /* optional attributes */
550 DEF_MACRO(
551 fCAST4_4u, /* macro name */
552 ((size4u_t)(A)),
553 /* optional attributes */
557 DEF_MACRO(
558 fCAST4_8s, /* macro name */
559 ((size8s_t)((size4s_t)(A))),
560 /* optional attributes */
563 DEF_MACRO(
564 fCAST4_8u, /* macro name */
565 ((size8u_t)((size4u_t)(A))),
566 /* optional attributes */
569 DEF_MACRO(
570 fCAST8_8s, /* macro name */
571 ((size8s_t)(A)),
572 /* optional attributes */
575 DEF_MACRO(
576 fCAST8_8u, /* macro name */
577 ((size8u_t)(A)),
578 /* optional attributes */
581 DEF_MACRO(
582 fCAST2_8s, /* macro name */
583 ((size8s_t)((size2s_t)(A))),
584 /* optional attributes */
586 DEF_MACRO(
587 fCAST2_8u, /* macro name */
588 ((size8u_t)((size2u_t)(A))),
589 /* optional attributes */
592 DEF_MACRO(
593 fZE8_16, /* zero-extend 8 to 16 */
594 ((size2s_t)((size1u_t)(A))),
595 /* optional attributes */
597 DEF_MACRO(
598 fSE8_16, /* sign-extend 8 to 16 */
599 ((size2s_t)((size1s_t)(A))),
600 /* optional attributes */
604 DEF_MACRO(
605 fSE16_32, /* sign-extend 16 to 32 */
606 ((size4s_t)((size2s_t)(A))), /* behavior */
607 /* optional attributes */
610 DEF_MACRO(
611 fZE16_32, /* zero-extend 16 to 32 */
612 ((size4u_t)((size2u_t)(A))), /* behavior */
613 /* optional attributes */
616 DEF_MACRO(
617 fSE32_64,
618 ( (size8s_t)((size4s_t)(A)) ), /* behavior */
619 /* optional attributes */
622 DEF_MACRO(
623 fZE32_64,
624 ( (size8u_t)((size4u_t)(A)) ), /* behavior */
625 /* optional attributes */
628 DEF_MACRO(
629 fSE8_32, /* sign-extend 8 to 32 */
630 ((size4s_t)((size1s_t)(A))),
631 /* optional attributes */
634 DEF_MACRO(
635 fZE8_32, /* zero-extend 8 to 32 */
636 ((size4s_t)((size1u_t)(A))),
637 /* optional attributes */
640 /*************************************/
641 /* DSP arithmetic support */
642 /************************************/
643 DEF_MACRO(
644 fMPY8UU, /* multiply half integer */
645 (int)(fZE8_16(A)*fZE8_16(B)), /* behavior */
648 DEF_MACRO(
649 fMPY8US, /* multiply half integer */
650 (int)(fZE8_16(A)*fSE8_16(B)), /* behavior */
653 DEF_MACRO(
654 fMPY8SU, /* multiply half integer */
655 (int)(fSE8_16(A)*fZE8_16(B)), /* behavior */
659 DEF_MACRO(
660 fMPY8SS, /* multiply half integer */
661 (int)((short)(A)*(short)(B)), /* behavior */
665 DEF_MACRO(
666 fMPY16SS, /* multiply half integer */
667 fSE32_64(fSE16_32(A)*fSE16_32(B)), /* behavior */
671 DEF_MACRO(
672 fMPY16UU, /* multiply unsigned half integer */
673 fZE32_64(fZE16_32(A)*fZE16_32(B)), /* behavior */
677 DEF_MACRO(
678 fMPY16SU, /* multiply half integer */
679 fSE32_64(fSE16_32(A)*fZE16_32(B)), /* behavior */
683 DEF_MACRO(
684 fMPY16US, /* multiply half integer */
685 fMPY16SU(B,A),
689 DEF_MACRO(
690 fMPY32SS, /* multiply half integer */
691 (fSE32_64(A)*fSE32_64(B)), /* behavior */
695 DEF_MACRO(
696 fMPY32UU, /* multiply half integer */
697 (fZE32_64(A)*fZE32_64(B)), /* behavior */
701 DEF_MACRO(
702 fMPY32SU, /* multiply half integer */
703 (fSE32_64(A)*fZE32_64(B)), /* behavior */
707 DEF_MACRO(
708 fMPY3216SS, /* multiply mixed precision */
709 (fSE32_64(A)*fSXTN(16,64,B)), /* behavior */
713 DEF_MACRO(
714 fMPY3216SU, /* multiply mixed precision */
715 (fSE32_64(A)*fZXTN(16,64,B)), /* behavior */
719 DEF_MACRO(
720 fROUND, /* optional rounding */
721 (A+0x8000),
722 /* optional attributes */
725 DEF_MACRO(
726 fCLIP, /* optional rounding */
727 { size4s_t maxv = (1<<U)-1;
728 size4s_t minv = -(1<<U);
729 DST = fMIN(maxv,fMAX(SRC,minv));
731 /* optional attributes */
734 DEF_MACRO(
735 fCRND, /* optional rounding */
736 ((((A)&0x3)==0x3)?((A)+1):((A))),
737 /* optional attributes */
740 DEF_MACRO(
741 fRNDN, /* Rounding to a boundary */
742 ((((N)==0)?(A):(((fSE32_64(A))+(1<<((N)-1)))))),
743 /* optional attributes */
746 DEF_MACRO(
747 fCRNDN, /* Rounding to a boundary */
748 (conv_round(A,N)),
749 /* optional attributes */
752 DEF_MACRO(
753 fADD128, /* Rounding to a boundary */
754 (add128(A, B)),
755 /* optional attributes */
757 DEF_MACRO(
758 fSUB128, /* Rounding to a boundary */
759 (sub128(A, B)),
760 /* optional attributes */
762 DEF_MACRO(
763 fSHIFTR128, /* Rounding to a boundary */
764 (shiftr128(A, B)),
765 /* optional attributes */
768 DEF_MACRO(
769 fSHIFTL128, /* Rounding to a boundary */
770 (shiftl128(A, B)),
771 /* optional attributes */
774 DEF_MACRO(
775 fAND128, /* Rounding to a boundary */
776 (and128(A, B)),
777 /* optional attributes */
780 DEF_MACRO(
781 fCAST8S_16S, /* Rounding to a boundary */
782 (cast8s_to_16s(A)),
783 /* optional attributes */
785 DEF_MACRO(
786 fCAST16S_8S, /* Rounding to a boundary */
787 (cast16s_to_8s(A)),
788 /* optional attributes */
791 DEF_MACRO(
792 fEA_RI, /* Calculate EA with Register + Immediate Offset */
793 do { EA=REG+IMM; fDOCHKPAGECROSS(REG,EA); } while (0),
797 DEF_MACRO(
798 fEA_RRs, /* Calculate EA with Register + Registers scaled Offset */
799 do { EA=REG+(REG2<<SCALE); fDOCHKPAGECROSS(REG,EA); } while (0),
803 DEF_MACRO(
804 fEA_IRs, /* Calculate EA with Immediate + Registers scaled Offset */
805 do { EA=IMM+(REG<<SCALE); fDOCHKPAGECROSS(IMM,EA); } while (0),
809 DEF_MACRO(
810 fEA_IMM, /* Calculate EA with Immediate */
811 EA=IMM,
815 DEF_MACRO(
816 fEA_REG, /* Calculate EA with REGISTER */
817 EA=REG,
821 DEF_MACRO(
822 fEA_GPI, /* Calculate EA with Global Poitner + Immediate */
823 do { EA=fREAD_GP()+IMM; fGP_DOCHKPAGECROSS(fREAD_GP(),EA); } while (0),
827 DEF_MACRO(
828 fPM_I, /* Post Modify Register by Immediate*/
829 do { REG = REG + IMM; } while (0),
833 DEF_MACRO(
834 fPM_M, /* Post Modify Register by M register */
835 do { REG = REG + MVAL; } while (0),
839 DEF_MACRO(
840 fPM_CIRI, /* Post Modify Register using Circular arithmetic by Immediate */
841 do { fcirc_add(REG,siV,MuV); } while (0),
845 DEF_MACRO(
846 fPM_CIRR, /* Post Modify Register using Circular arithmetic by register */
847 do { fcirc_add(REG,VAL,MuV); } while (0),
853 DEF_MACRO(
854 fSCALE, /* scale by N */
855 (((size8s_t)(A))<<N),
856 /* optional attributes */
859 DEF_MACRO(
860 fSATW, /* saturating to 32-bits*/
861 fSATN(32,((long long)A)),
865 DEF_MACRO(
866 fSAT, /* saturating to 32-bits*/
867 fSATN(32,(A)),
871 DEF_MACRO(
872 fSAT_ORIG_SHL, /* Saturating to 32-bits, with original value, for shift left */
873 ((((size4s_t)((fSAT(A)) ^ ((size4s_t)(ORIG_REG)))) < 0) ?
874 fSATVALN(32,((size4s_t)(ORIG_REG))) :
875 ((((ORIG_REG) > 0) && ((A) == 0)) ?
876 fSATVALN(32,(ORIG_REG)) :
877 fSAT(A))),
881 DEF_MACRO(
882 fPASS,
886 DEF_MACRO(
887 fRND, /* saturating to 32-bits*/
888 (((A)+1)>>1),
892 DEF_MACRO(
893 fBIDIR_SHIFTL,
894 (((SHAMT) < 0) ? ((fCAST##REGSTYPE(SRC) >> ((-(SHAMT))-1)) >>1) : (fCAST##REGSTYPE(SRC) << (SHAMT))),
898 DEF_MACRO(
899 fBIDIR_ASHIFTL,
900 fBIDIR_SHIFTL(SRC,SHAMT,REGSTYPE##s),
904 DEF_MACRO(
905 fBIDIR_LSHIFTL,
906 fBIDIR_SHIFTL(SRC,SHAMT,REGSTYPE##u),
910 DEF_MACRO(
911 fBIDIR_ASHIFTL_SAT,
912 (((SHAMT) < 0) ? ((fCAST##REGSTYPE##s(SRC) >> ((-(SHAMT))-1)) >>1) : fSAT_ORIG_SHL(fCAST##REGSTYPE##s(SRC) << (SHAMT),(SRC))),
917 DEF_MACRO(
918 fBIDIR_SHIFTR,
919 (((SHAMT) < 0) ? ((fCAST##REGSTYPE(SRC) << ((-(SHAMT))-1)) << 1) : (fCAST##REGSTYPE(SRC) >> (SHAMT))),
923 DEF_MACRO(
924 fBIDIR_ASHIFTR,
925 fBIDIR_SHIFTR(SRC,SHAMT,REGSTYPE##s),
929 DEF_MACRO(
930 fBIDIR_LSHIFTR,
931 fBIDIR_SHIFTR(SRC,SHAMT,REGSTYPE##u),
935 DEF_MACRO(
936 fBIDIR_ASHIFTR_SAT,
937 (((SHAMT) < 0) ? fSAT_ORIG_SHL((fCAST##REGSTYPE##s(SRC) << ((-(SHAMT))-1)) << 1,(SRC)) : (fCAST##REGSTYPE##s(SRC) >> (SHAMT))),
941 DEF_MACRO(
942 fASHIFTR,
943 (fCAST##REGSTYPE##s(SRC) >> (SHAMT)),
944 /* */
947 DEF_MACRO(
948 fLSHIFTR,
949 (((SHAMT) >= 64)?0:(fCAST##REGSTYPE##u(SRC) >> (SHAMT))),
950 /* */
953 DEF_MACRO(
954 fROTL,
955 (((SHAMT)==0) ? (SRC) : ((fCAST##REGSTYPE##u(SRC) << (SHAMT)) | \
956 ((fCAST##REGSTYPE##u(SRC) >> ((sizeof(SRC)*8)-(SHAMT)))))),
957 /* */
960 DEF_MACRO(
961 fROTR,
962 (((SHAMT)==0) ? (SRC) : ((fCAST##REGSTYPE##u(SRC) >> (SHAMT)) | \
963 ((fCAST##REGSTYPE##u(SRC) << ((sizeof(SRC)*8)-(SHAMT)))))),
964 /* */
967 DEF_MACRO(
968 fASHIFTL,
969 (((SHAMT) >= 64)?0:(fCAST##REGSTYPE##s(SRC) << (SHAMT))),
970 /* */
973 /*************************************/
974 /* Floating-Point Support */
975 /************************************/
977 DEF_MACRO(
978 fFLOAT, /* name */
979 ({ union { float f; size4u_t i; } _fipun; _fipun.i = (A); _fipun.f; }), /* behavior */
980 (A_FPOP)
983 DEF_MACRO(
984 fUNFLOAT, /* multiply half integer */
985 ({ union { float f; size4u_t i; } _fipun; _fipun.f = (A); isnan(_fipun.f) ? 0xFFFFFFFFU : _fipun.i; }), /* behavior */
986 (A_FPOP)
989 DEF_MACRO(
990 fSFNANVAL,
991 0xffffffff,
995 DEF_MACRO(
996 fSFINFVAL,
997 (((A) & 0x80000000) | 0x7f800000),
1001 DEF_MACRO(
1002 fSFONEVAL,
1003 (((A) & 0x80000000) | fUNFLOAT(1.0)),
1007 DEF_MACRO(
1008 fCHECKSFNAN,
1009 do {
1010 if (isnan(fFLOAT(A))) {
1011 if ((fGETBIT(22,A)) == 0) fRAISEFLAGS(FE_INVALID);
1012 DST = fSFNANVAL();
1014 } while (0),
1018 DEF_MACRO(
1019 fCHECKSFNAN3,
1020 do {
1021 fCHECKSFNAN(DST,A);
1022 fCHECKSFNAN(DST,B);
1023 fCHECKSFNAN(DST,C);
1024 } while (0),
1028 DEF_MACRO(
1029 fSF_BIAS,
1030 127,
1034 DEF_MACRO(
1035 fSF_MANTBITS,
1040 DEF_MACRO(
1041 fSF_MUL_POW2,
1042 (fUNFLOAT(fFLOAT(A) * fFLOAT((fSF_BIAS() + (B)) << fSF_MANTBITS()))),
1046 DEF_MACRO(
1047 fSF_GETEXP,
1048 (((A) >> fSF_MANTBITS()) & 0xff),
1052 DEF_MACRO(
1053 fSF_MAXEXP,
1054 (254),
1058 DEF_MACRO(
1059 fSF_RECIP_COMMON,
1060 arch_sf_recip_common(&N,&D,&O,&A),
1061 (A_FPOP)
1064 DEF_MACRO(
1065 fSF_INVSQRT_COMMON,
1066 arch_sf_invsqrt_common(&N,&O,&A),
1067 (A_FPOP)
1070 DEF_MACRO(
1071 fFMAFX,
1072 internal_fmafx(A,B,C,fSXTN(8,64,ADJ)),
1076 DEF_MACRO(
1077 fFMAF,
1078 internal_fmafx(A,B,C,0),
1082 DEF_MACRO(
1083 fSFMPY,
1084 internal_mpyf(A,B),
1088 DEF_MACRO(
1089 fMAKESF,
1090 ((((SIGN) & 1) << 31) | (((EXP) & 0xff) << fSF_MANTBITS()) |
1091 ((MANT) & ((1<<fSF_MANTBITS())-1))),
1096 DEF_MACRO(
1097 fDOUBLE, /* multiply half integer */
1098 ({ union { double f; size8u_t i; } _fipun; _fipun.i = (A); _fipun.f; }), /* behavior */
1099 (A_FPOP)
1102 DEF_MACRO(
1103 fUNDOUBLE, /* multiply half integer */
1104 ({ union { double f; size8u_t i; } _fipun; _fipun.f = (A); isnan(_fipun.f) ? 0xFFFFFFFFFFFFFFFFULL : _fipun.i; }), /* behavior */
1105 (A_FPOP)
1108 DEF_MACRO(
1109 fDFNANVAL,
1110 0xffffffffffffffffULL,
1114 DEF_MACRO(
1115 fDF_ISNORMAL,
1116 (fpclassify(fDOUBLE(X)) == FP_NORMAL),
1120 DEF_MACRO(
1121 fDF_ISDENORM,
1122 (fpclassify(fDOUBLE(X)) == FP_SUBNORMAL),
1126 DEF_MACRO(
1127 fDF_ISBIG,
1128 (fDF_GETEXP(X) >= 512),
1132 DEF_MACRO(
1133 fDF_MANTBITS,
1138 DEF_MACRO(
1139 fDF_GETEXP,
1140 (((A) >> fDF_MANTBITS()) & 0x7ff),
1144 DEF_MACRO(
1145 fFMA,
1146 internal_fma(A,B,C),
1147 /* nothing */
1150 DEF_MACRO(
1151 fDF_MPY_HH,
1152 internal_mpyhh(A,B,ACC),
1153 /* nothing */
1156 DEF_MACRO(
1157 fFPOP_START,
1158 arch_fpop_start(thread),
1159 /* nothing */
1162 DEF_MACRO(
1163 fFPOP_END,
1164 arch_fpop_end(thread),
1165 /* nothing */
1168 DEF_MACRO(
1169 fFPSETROUND_NEAREST,
1170 fesetround(FE_TONEAREST),
1171 /* nothing */
1174 DEF_MACRO(
1175 fFPSETROUND_CHOP,
1176 fesetround(FE_TOWARDZERO),
1177 /* nothing */
1180 DEF_MACRO(
1181 fFPCANCELFLAGS,
1182 feclearexcept(FE_ALL_EXCEPT),
1183 /* nothing */
1186 DEF_MACRO(
1187 fISINFPROD,
1188 ((isinf(A) && isinf(B)) ||
1189 (isinf(A) && isfinite(B) && ((B) != 0.0)) ||
1190 (isinf(B) && isfinite(A) && ((A) != 0.0))),
1191 /* nothing */
1194 DEF_MACRO(
1195 fISZEROPROD,
1196 ((((A) == 0.0) && isfinite(B)) || (((B) == 0.0) && isfinite(A))),
1197 /* nothing */
1200 DEF_MACRO(
1201 fRAISEFLAGS,
1202 arch_raise_fpflag(A),
1203 /* NOTHING */
1206 DEF_MACRO(
1207 fDF_MAX,
1208 (((A)==(B))
1209 ? fDOUBLE(fUNDOUBLE(A) & fUNDOUBLE(B))
1210 : fmax(A,B)),
1211 (A_FPOP)
1214 DEF_MACRO(
1215 fDF_MIN,
1216 (((A)==(B))
1217 ? fDOUBLE(fUNDOUBLE(A) | fUNDOUBLE(B))
1218 : fmin(A,B)),
1219 (A_FPOP)
1222 DEF_MACRO(
1223 fSF_MAX,
1224 (((A)==(B))
1225 ? fFLOAT(fUNFLOAT(A) & fUNFLOAT(B))
1226 : fmaxf(A,B)),
1227 (A_FPOP)
1230 DEF_MACRO(
1231 fSF_MIN,
1232 (((A)==(B))
1233 ? fFLOAT(fUNFLOAT(A) | fUNFLOAT(B))
1234 : fminf(A,B)),
1235 (A_FPOP)
1238 /*************************************/
1239 /* Load/Store support */
1240 /*************************************/
1242 DEF_MACRO(fLOAD,
1243 { DST = (size##SIZE##SIGN##_t)MEM_LOAD##SIZE(thread,EA,insn); },
1244 (A_LOAD,A_MEMLIKE)
1247 DEF_MACRO(fMEMOP,
1248 { memop##SIZE##_##FNTYPE(thread,EA,VALUE); },
1249 (A_LOAD,A_STORE,A_MEMLIKE)
1252 DEF_MACRO(fGET_FRAMEKEY,
1253 READ_RREG(REG_FRAMEKEY),
1257 DEF_MACRO(fFRAME_SCRAMBLE,
1258 ((VAL) ^ (fCAST8u(fGET_FRAMEKEY()) << 32)),
1259 /* ATTRIBS */
1262 DEF_MACRO(fFRAME_UNSCRAMBLE,
1263 fFRAME_SCRAMBLE(VAL),
1264 /* ATTRIBS */
1267 DEF_MACRO(fFRAMECHECK,
1268 sys_check_framelimit(thread,ADDR,EA),
1272 DEF_MACRO(fLOAD_LOCKED,
1273 { DST = (size##SIZE##SIGN##_t)mem_load_locked(thread,EA,SIZE,insn); },
1274 (A_LOAD,A_MEMLIKE)
1277 DEF_MACRO(fSTORE,
1278 { MEM_STORE##SIZE(thread,EA,SRC,insn); },
1279 (A_STORE,A_MEMLIKE)
1283 DEF_MACRO(fSTORE_LOCKED,
1284 { PRED = (mem_store_conditional(thread,EA,SRC,SIZE,insn) ? 0xff : 0); },
1285 (A_STORE,A_MEMLIKE)
1288 /*************************************/
1289 /* Functions to help with bytes */
1290 /*************************************/
1292 DEF_MACRO(fGETBYTE,
1293 ((size1s_t)((SRC>>((N)*8))&0xff)),
1294 /* nothing */
1297 DEF_MACRO(fGETUBYTE,
1298 ((size1u_t)((SRC>>((N)*8))&0xff)),
1299 /* nothing */
1302 DEF_MACRO(fSETBYTE,
1304 DST = (DST & ~(0x0ffLL<<((N)*8))) | (((size8u_t)((VAL) & 0x0ffLL)) << ((N)*8));
1306 /* nothing */
1309 DEF_MACRO(fGETHALF,
1310 ((size2s_t)((SRC>>((N)*16))&0xffff)),
1311 /* nothing */
1314 DEF_MACRO(fGETUHALF,
1315 ((size2u_t)((SRC>>((N)*16))&0xffff)),
1316 /* nothing */
1319 DEF_MACRO(fSETHALF,
1321 DST = (DST & ~(0x0ffffLL<<((N)*16))) | (((size8u_t)((VAL) & 0x0ffff)) << ((N)*16));
1323 /* nothing */
1328 DEF_MACRO(fGETWORD,
1329 ((size8s_t)((size4s_t)((SRC>>((N)*32))&0x0ffffffffLL))),
1330 /* nothing */
1333 DEF_MACRO(fGETUWORD,
1334 ((size8u_t)((size4u_t)((SRC>>((N)*32))&0x0ffffffffLL))),
1335 /* nothing */
1338 DEF_MACRO(fSETWORD,
1340 DST = (DST & ~(0x0ffffffffLL<<((N)*32))) | (((VAL) & 0x0ffffffffLL) << ((N)*32));
1342 /* nothing */
1345 DEF_MACRO(fSETBIT,
1347 DST = (DST & ~(1ULL<<(N))) | (((size8u_t)(VAL))<<(N));
1349 /* nothing */
1352 DEF_MACRO(fGETBIT,
1353 (((SRC)>>N)&1),
1354 /* nothing */
1358 DEF_MACRO(fSETBITS,
1359 do {
1360 int j;
1361 for (j=LO;j<=HI;j++) {
1362 fSETBIT(j,DST,VAL);
1364 } while (0),
1365 /* nothing */
1368 /*************************************/
1369 /* Used for parity, etc........ */
1370 /*************************************/
1371 DEF_MACRO(fCOUNTONES_4,
1372 count_ones_4(VAL),
1373 /* nothing */
1376 DEF_MACRO(fCOUNTONES_8,
1377 count_ones_8(VAL),
1378 /* nothing */
1381 DEF_MACRO(fBREV_8,
1382 reverse_bits_8(VAL),
1383 /* nothing */
1386 DEF_MACRO(fBREV_4,
1387 reverse_bits_4(VAL),
1388 /* nothing */
1391 DEF_MACRO(fCL1_8,
1392 count_leading_ones_8(VAL),
1393 /* nothing */
1396 DEF_MACRO(fCL1_4,
1397 count_leading_ones_4(VAL),
1398 /* nothing */
1401 DEF_MACRO(fINTERLEAVE,
1402 interleave(ODD,EVEN),
1403 /* nothing */
1406 DEF_MACRO(fDEINTERLEAVE,
1407 deinterleave(MIXED),
1408 /* nothing */
1411 DEF_MACRO(fHIDE,
1416 DEF_MACRO(fCONSTLL,
1417 A##LL,
1420 /* Do the things in the parens, but don't print the parens. */
1421 DEF_MACRO(fECHO,
1422 (A),
1423 /* nothing */
1427 /********************************************/
1428 /* OS interface and stop/wait */
1429 /********************************************/
1431 DEF_MACRO(fPAUSE,
1432 {sys_pause(thread, insn->slot, IMM);},
1436 DEF_MACRO(fTRAP,
1437 warn("Trap NPC=%x ",fREAD_NPC());
1438 warn("Trap exception, PCYCLE=%lld TYPE=%d NPC=%x IMM=0x%x",thread->processor_ptr->pstats[pcycles],TRAPTYPE,fREAD_NPC(),IMM);
1439 register_trap_exception(thread,fREAD_NPC(),TRAPTYPE,IMM);,
1443 DEF_MACRO(fALIGN_REG_FIELD_VALUE,
1444 ((VAL)<<reg_field_info[FIELD].offset),
1445 /* */
1448 DEF_MACRO(fGET_REG_FIELD_MASK,
1449 (((1<<reg_field_info[FIELD].width)-1)<<reg_field_info[FIELD].offset),
1450 /* */
1453 DEF_MACRO(fREAD_REG_FIELD,
1454 fEXTRACTU_BITS(thread->Regs[REG_##REG],
1455 reg_field_info[FIELD].width,
1456 reg_field_info[FIELD].offset),
1457 /* ATTRIBS */
1460 DEF_MACRO(fGET_FIELD,
1461 fEXTRACTU_BITS(VAL,
1462 reg_field_info[FIELD].width,
1463 reg_field_info[FIELD].offset),
1464 /* ATTRIBS */
1467 DEF_MACRO(fSET_FIELD,
1468 fINSERT_BITS(VAL,
1469 reg_field_info[FIELD].width,
1470 reg_field_info[FIELD].offset,
1471 (NEWVAL)),
1472 /* ATTRIBS */
1475 /********************************************/
1476 /* Cache Management */
1477 /********************************************/
1479 DEF_MACRO(fBARRIER,
1481 sys_barrier(thread, insn->slot);
1486 DEF_MACRO(fSYNCH,
1488 sys_sync(thread, insn->slot);
1493 DEF_MACRO(fISYNC,
1495 sys_isync(thread, insn->slot);
1501 DEF_MACRO(fDCFETCH,
1502 sys_dcfetch(thread, (REG), insn->slot),
1503 (A_MEMLIKE)
1506 DEF_MACRO(fICINVA,
1508 arch_internal_flush(thread->processor_ptr, 0, 0xffffffff);
1509 sys_icinva(thread, (REG),insn->slot);
1511 (A_ICINVA)
1514 DEF_MACRO(fL2FETCH,
1515 sys_l2fetch(thread, ADDR,HEIGHT,WIDTH,STRIDE,FLAGS, insn->slot),
1516 (A_MEMLIKE,A_L2FETCH)
1519 DEF_MACRO(fDCCLEANA,
1520 sys_dccleana(thread, (REG)),
1521 (A_MEMLIKE)
1524 DEF_MACRO(fDCCLEANINVA,
1525 sys_dccleaninva(thread, (REG), insn->slot),
1526 (A_MEMLIKE,A_DCCLEANINVA)
1529 DEF_MACRO(fDCZEROA,
1530 sys_dczeroa(thread, (REG)),
1531 (A_MEMLIKE)
1534 DEF_MACRO(fCHECKFORPRIV,
1535 {sys_check_privs(thread); if (EXCEPTION_DETECTED) return; },
1539 DEF_MACRO(fCHECKFORGUEST,
1540 {sys_check_guest(thread); if (EXCEPTION_DETECTED) return; },
1544 DEF_MACRO(fBRANCH_SPECULATE_STALL,
1546 sys_speculate_branch_stall(thread, insn->slot, JUMP_COND(JUMP_PRED_SET),
1547 SPEC_DIR,
1548 DOTNEWVAL,
1549 HINTBITNUM,
1550 STRBITNUM,
1552 thread->last_pkt->pkt_has_dual_jump,
1553 insn->is_2nd_jump,
1554 (thread->fetch_access.vaddr + insn->encoding_offset*4));