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
/>.
20 __builtin_expect((X
),1), /* BEH
*/
26 __builtin_expect((X
),0), /* BEH
*/
31 CANCEL
, /* macro name
*/
32 {if (thread
->last_pkt
) thread
->last_pkt
->slot_cancelled |
= (1<<insn
->slot
); return
;} , /* behavior
*/
37 LOAD_CANCEL
, /* macro name
*/
38 {mem_general_load_cancelled(thread
,EA
,insn
);CANCEL
;} , /* behavior
*/
43 STORE_CANCEL
, /* macro name
*/
44 {mem_general_store_cancelled(thread
,EA
,insn
);CANCEL
;} , /* behavior
*/
49 fMAX
, /* macro name
*/
50 (((A
) > (B
)) ?
(A
) : (B
)), /* behavior
*/
51 /* optional attributes
*/
55 fMIN
, /* macro name
*/
56 (((A
) < (B
)) ?
(A
) : (B
)), /* behavior
*/
57 /* optional attributes
*/
61 fABS
, /* macro name
*/
62 (((A
)<0)?
(-(A
)):(A
)), /* behavior
*/
63 /* optional attributes
*/
71 REG
= ((REG
) & ~
(((fCONSTLL(1)<<(WIDTH
))-1)<<(OFFSET
))) |
(((INVAL
) & ((fCONSTLL(1)<<(WIDTH
))-1)) << (OFFSET
));
79 (fZXTN(WIDTH
,32,(INREG
>> OFFSET
))),
85 (fZXTN(WIDTH
,32,fBIDIR_LSHIFTR((INREG
),(OFFSET
),4_8
))),
91 (fZXTN((HIBIT
-LOWBIT
+1),32,(INREG
>> LOWBIT
))),
100 int width
=HIBIT
-LOWBIT
+1;
101 /* clear bits where new bits go
*/
102 INREG
&= ~
(((fCONSTLL(1)<<width
)-1)<<offset
);
104 INREG |
= ((INVAL
& ((fCONSTLL(1)<<width
)-1)) << offset
);
112 ( (VAL) ?
0xff : 0x00),
124 predlog_read(thread
,PNUM
),
130 predlog_read(thread
,0),
136 predlog_read(thread
,1),
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
)
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
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
)
181 ({ ((VAL) < 0) ?
0 : ((1LL<<(N
))-1);}),
187 ({fSET_OVERFLOW(); ((VAL) < 0) ?
0 : ((1LL<<(N
))-1);}),
193 ({fSET_OVERFLOW(); ((VAL) < 0) ?
(-(1LL<<((N
)-1))) : ((1LL<<((N
)-1))-1);}),
199 ({((VAL) < 0) ?
(-(1LL<<((N
)-1))) : ((1LL<<((N
)-1))-1);}),
204 fZXTN
, /* macro name
*/
205 ((VAL) & ((1LL<<(N
))-1)),
210 fSXTN
, /* macro name
*/
211 ((fZXTN(N
,M
,VAL) ^
(1LL<<((N
)-1))) - (1LL<<((N
)-1))),
217 ((fSXTN(N
,64,VAL) == (VAL)) ?
(VAL) : fSATVALN(N
,VAL)),
222 ((fSXTN(N
,64,VAL) == (VAL)) ?
(VAL) : fVSATVALN(N
,VAL)),
229 size8u_t __a
= fCAST8u(A
);
230 size8u_t __b
= fCAST8u(B
);
231 size8u_t __sum
= __a
+ __b
;
232 size8u_t __xor
= __a ^ __b
;
233 const size8u_t __mask
= 0x8000000000000000ULL
;
234 if (__xor
& __mask
) {
235 /* Opposite signs
, OK
*/
237 } else
if ((__a ^ __sum
) & __mask
) {
239 if (__sum
& __mask
) {
240 /* overflowed to negative
, make max pos
*/
241 DST
=0x7FFFFFFFFFFFFFFFLL
; fSET_OVERFLOW();
243 /* overflowed to positive
, make max neg
*/
244 DST
=0x8000000000000000LL
; fSET_OVERFLOW();
247 /* signs did not mismatch
, OK
*/
256 ((fZXTN(N
,64,VAL) == (VAL)) ?
(VAL) : fVSATUVALN(N
,VAL)),
262 ((fZXTN(N
,64,VAL) == (VAL)) ?
(VAL) : fSATUVALN(N
,VAL)),
318 /*************************************/
319 /* immediate extension
*/
320 /*************************************/
336 IMM
=(IMM
& ~PCALIGN_MASK
),
340 /*************************************/
341 /* Read and Write Implicit Regs
*/
342 /*************************************/
345 fREAD_IREG
, /* read modifier register
*/
346 (fSXTN(11,64,(((VAL) & 0xf0000000)>>21) |
((VAL>>17)&0x7f) )), /* behavior
*/
351 fREAD_LR
, /* read link register
*/
352 (READ_RREG(REG_LR
)), /* behavior
*/
357 fWRITE_LR
, /* write lr
*/
358 WRITE_RREG(REG_LR
,A
), /* behavior
*/
359 (A_IMPLICIT_WRITES_LR
)
363 fWRITE_FP
, /* write sp
*/
364 WRITE_RREG(REG_FP
,A
), /* behavior
*/
365 (A_IMPLICIT_WRITES_FP
)
369 fWRITE_SP
, /* write sp
*/
370 WRITE_RREG(REG_SP
,A
), /* behavior
*/
371 (A_IMPLICIT_WRITES_SP
)
375 fREAD_SP
, /* read stack pointer
*/
376 (READ_RREG(REG_SP
)), /* behavior
*/
381 fREAD_CSREG
, /* read CS register
*/
382 (READ_RREG(REG_CSA
+N
)), /* behavior
*/
387 fREAD_LC0
, /* read loop count
*/
388 (READ_RREG(REG_LC0
)), /* behavior
*/
393 fREAD_LC1
, /* read loop count
*/
394 (READ_RREG(REG_LC1
)), /* behavior
*/
399 fREAD_SA0
, /* read start addr
*/
400 (READ_RREG(REG_SA0
)), /* behavior
*/
405 fREAD_SA1
, /* read start addr
*/
406 (READ_RREG(REG_SA1
)), /* behavior
*/
412 fREAD_FP
, /* read frame pointer
*/
413 (READ_RREG(REG_FP
)), /* behavior
*/
418 fREAD_GP
, /* read global pointer
*/
419 (insn
->extension_valid ?
0 : READ_RREG(REG_GP
)), /* behavior
*/
424 fREAD_PC
, /* read PC
*/
425 (READ_RREG(REG_PC
)), /* behavior
*/
430 fREAD_NPC
, /* read next PC
*/
431 (thread
->next_PC
& (0xfffffffe)), /* behavior
*/
436 fREAD_P0
, /* read Predicate
0 */
437 (READ_PREG(0)), /* behavior
*/
442 fREAD_P3
, /* read Predicate
3 */
443 (READ_PREG(3)), /* behavior
*/
449 if (((A
) & PCALIGN_MASK
)) {
450 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);
456 fWRITE_NPC
, /* write next PC
*/
457 if (!thread
->branch_taken
) {
458 if (A
!= thread
->next_PC
) {
459 thread
->next_pkt_guess
=thread
->last_pkt
->taken_ptr
;
462 thread
->branched
= 1; thread
->branch_taken
= 1; thread
->next_PC
= A
; \
463 thread
->branch_offset
= insn
->encoding_offset
; thread
->branch_opcode
= insn
->opcode
;
470 fWRITE_NPC(LOC
); fCOF_CALLBACK(LOC
,TYPE),
475 fJUMPR
, /* A jumpr has executed
*/
476 {fBRANCH(TARGET
,COF_TYPE_JUMPR
);},
481 fHINTJR
, /* A hintjr instruction has executed
*/
486 fCALL
, /* Do a call
*/
487 if (!thread
->branch_taken
) {fBP_RAS_CALL(A
); fWRITE_LR(fREAD_NPC()); fBRANCH(A
,COF_TYPE_CALL
);},
488 (A_COF
,A_IMPLICIT_WRITES_LR
,A_CALL
)
492 fCALLR
, /* Do a call Register
*/
493 if (!thread
->branch_taken
) {fBP_RAS_CALL(A
); fWRITE_LR(fREAD_NPC()); fBRANCH(A
,COF_TYPE_CALLR
);},
494 (A_COF
,A_IMPLICIT_WRITES_LR
,A_CALL
)
498 fWRITE_LOOP_REGS0
, /* write ln
,sa
,ea
,lc
*/
499 {WRITE_RREG(REG_LC0
,COUNT
);
500 WRITE_RREG(REG_SA0
,START
);},
501 (A_IMPLICIT_WRITES_LC0
,A_IMPLICIT_WRITES_SA0
)
505 fWRITE_LOOP_REGS1
, /* write ln
,sa
,ea
,lc
*/
506 {WRITE_RREG(REG_LC1
,COUNT
);
507 WRITE_RREG(REG_SA1
,START
);},
508 (A_IMPLICIT_WRITES_LC1
,A_IMPLICIT_WRITES_SA1
)
513 WRITE_RREG(REG_LC0
,VAL),
514 (A_IMPLICIT_WRITES_LC0
)
519 WRITE_RREG(REG_LC1
,VAL),
520 (A_IMPLICIT_WRITES_LC1
)
525 carry_from_add64(A
,B
,C
),
531 SET_USR_FIELD(USR_OVF
,1),
537 SET_USR_FIELD(USR_LPCFG
,(VAL)),
544 (GET_USR_FIELD(USR_LPCFG
)),
551 fWRITE_P0
, /* write Predicate
0 */
552 WRITE_PREG(0,VAL), /* behavior
*/
553 (A_IMPLICIT_WRITES_P0
)
557 fWRITE_P1
, /* write Predicate
0 */
558 WRITE_PREG(1,VAL), /* behavior
*/
559 (A_IMPLICIT_WRITES_P1
)
563 fWRITE_P2
, /* write Predicate
0 */
564 WRITE_PREG(2,VAL), /* behavior
*/
565 (A_IMPLICIT_WRITES_P2
)
569 fWRITE_P3
, /* write Predicate
0 */
570 WRITE_PREG(3,VAL), /* behavior
*/
571 (A_IMPLICIT_WRITES_P3
)
575 fPART1
, /* write Predicate
0 */
576 if (insn
->part1
) { WORK
; return
; }, /* behavior
*/
577 /* optional attributes
*/
581 /*************************************/
582 /* Casting
, Sign
-Zero extension
, etc
*/
583 /*************************************/
586 fCAST4u
, /* macro name
*/
587 ((size4u_t
)(A
)), /* behavior
*/
588 /* optional attributes
*/
592 fCAST4s
, /* macro name
*/
593 ((size4s_t
)(A
)), /* behavior
*/
594 /* optional attributes
*/
598 fCAST8u
, /* macro name
*/
599 ((size8u_t
)(A
)), /* behavior
*/
600 /* optional attributes
*/
604 fCAST8s
, /* macro name
*/
605 ((size8s_t
)(A
)), /* behavior
*/
606 /* optional attributes
*/
610 fCAST2_2s
, /* macro name
*/
612 /* optional attributes
*/
616 fCAST2_2u
, /* macro name
*/
618 /* optional attributes
*/
622 fCAST4_4s
, /* macro name
*/
624 /* optional attributes
*/
628 fCAST4_4u
, /* macro name
*/
630 /* optional attributes
*/
635 fCAST4_8s
, /* macro name
*/
636 ((size8s_t
)((size4s_t
)(A
))),
637 /* optional attributes
*/
641 fCAST4_8u
, /* macro name
*/
642 ((size8u_t
)((size4u_t
)(A
))),
643 /* optional attributes
*/
647 fCAST8_8s
, /* macro name
*/
649 /* optional attributes
*/
653 fCAST8_8u
, /* macro name
*/
655 /* optional attributes
*/
659 fCAST2_8s
, /* macro name
*/
660 ((size8s_t
)((size2s_t
)(A
))),
661 /* optional attributes
*/
664 fCAST2_8u
, /* macro name
*/
665 ((size8u_t
)((size2u_t
)(A
))),
666 /* optional attributes
*/
670 fZE8_16
, /* zero
-extend
8 to
16 */
671 ((size2s_t
)((size1u_t
)(A
))),
672 /* optional attributes
*/
675 fSE8_16
, /* sign
-extend
8 to
16 */
676 ((size2s_t
)((size1s_t
)(A
))),
677 /* optional attributes
*/
682 fSE16_32
, /* sign
-extend
16 to
32 */
683 ((size4s_t
)((size2s_t
)(A
))), /* behavior
*/
684 /* optional attributes
*/
688 fZE16_32
, /* zero
-extend
16 to
32 */
689 ((size4u_t
)((size2u_t
)(A
))), /* behavior
*/
690 /* optional attributes
*/
695 ( (size8s_t
)((size4s_t
)(A
)) ), /* behavior
*/
696 /* optional attributes
*/
701 ( (size8u_t
)((size4u_t
)(A
)) ), /* behavior
*/
702 /* optional attributes
*/
706 fSE8_32
, /* sign
-extend
8 to
32 */
707 ((size4s_t
)((size1s_t
)(A
))),
708 /* optional attributes
*/
712 fZE8_32
, /* zero
-extend
8 to
32 */
713 ((size4s_t
)((size1u_t
)(A
))),
714 /* optional attributes
*/
717 /*************************************/
718 /* DSP arithmetic support
*/
719 /************************************/
721 fMPY8UU
, /* multiply half integer
*/
722 (int
)(fZE8_16(A
)*fZE8_16(B
)), /* behavior
*/
726 fMPY8US
, /* multiply half integer
*/
727 (int
)(fZE8_16(A
)*fSE8_16(B
)), /* behavior
*/
731 fMPY8SU
, /* multiply half integer
*/
732 (int
)(fSE8_16(A
)*fZE8_16(B
)), /* behavior
*/
737 fMPY8SS
, /* multiply half integer
*/
738 (int
)((short
)(A
)*(short
)(B
)), /* behavior
*/
743 fMPY16SS
, /* multiply half integer
*/
744 fSE32_64(fSE16_32(A
)*fSE16_32(B
)), /* behavior
*/
749 fMPY16UU
, /* multiply unsigned half integer
*/
750 fZE32_64(fZE16_32(A
)*fZE16_32(B
)), /* behavior
*/
755 fMPY16SU
, /* multiply half integer
*/
756 fSE32_64(fSE16_32(A
)*fZE16_32(B
)), /* behavior
*/
761 fMPY16US
, /* multiply half integer
*/
767 fMPY32SS
, /* multiply half integer
*/
768 (fSE32_64(A
)*fSE32_64(B
)), /* behavior
*/
773 fMPY32UU
, /* multiply half integer
*/
774 (fZE32_64(A
)*fZE32_64(B
)), /* behavior
*/
779 fMPY32SU
, /* multiply half integer
*/
780 (fSE32_64(A
)*fZE32_64(B
)), /* behavior
*/
785 fMPY3216SS
, /* multiply mixed precision
*/
786 (fSE32_64(A
)*fSXTN(16,64,B
)), /* behavior
*/
791 fMPY3216SU
, /* multiply mixed precision
*/
792 (fSE32_64(A
)*fZXTN(16,64,B
)), /* behavior
*/
797 fROUND
, /* optional rounding
*/
799 /* optional attributes
*/
803 fCLIP
, /* optional rounding
*/
804 { size4s_t maxv
= (1<<U
)-1;
805 size4s_t minv
= -(1<<U
);
806 DST
= fMIN(maxv
,fMAX(SRC
,minv
));
808 /* optional attributes
*/
812 fCRND
, /* optional rounding
*/
813 ((((A
)&0x3)==0x3)?
((A
)+1):((A
))),
814 /* optional attributes
*/
818 fRNDN
, /* Rounding to a boundary
*/
819 ((((N
)==0)?
(A
):(((fSE32_64(A
))+(1<<((N
)-1)))))),
820 /* optional attributes
*/
824 fCRNDN
, /* Rounding to a boundary
*/
826 /* optional attributes
*/
830 fADD128
, /* Rounding to a boundary
*/
832 /* optional attributes
*/
835 fSUB128
, /* Rounding to a boundary
*/
837 /* optional attributes
*/
840 fSHIFTR128
, /* Rounding to a boundary
*/
842 /* optional attributes
*/
846 fSHIFTL128
, /* Rounding to a boundary
*/
848 /* optional attributes
*/
852 fAND128
, /* Rounding to a boundary
*/
854 /* optional attributes
*/
858 fCAST8S_16S
, /* Rounding to a boundary
*/
860 /* optional attributes
*/
863 fCAST16S_8S
, /* Rounding to a boundary
*/
865 /* optional attributes
*/
869 fEA_RI
, /* Calculate EA with Register
+ Immediate Offset
*/
870 do
{ EA
=REG
+IMM
; fDOCHKPAGECROSS(REG
,EA
); } while (0),
875 fEA_RRs
, /* Calculate EA with Register
+ Registers scaled Offset
*/
876 do
{ EA
=REG
+(REG2
<<SCALE
); fDOCHKPAGECROSS(REG
,EA
); } while (0),
881 fEA_IRs
, /* Calculate EA with Immediate
+ Registers scaled Offset
*/
882 do
{ EA
=IMM
+(REG
<<SCALE
); fDOCHKPAGECROSS(IMM
,EA
); } while (0),
887 fEA_IMM
, /* Calculate EA with Immediate
*/
893 fEA_REG
, /* Calculate EA with REGISTER
*/
899 fEA_BREVR
, /* Calculate EA with bit reversed bottom of REGISTER
*/
905 fEA_GPI
, /* Calculate EA with Global Pointer
+ Immediate
*/
906 do
{ EA
=fREAD_GP()+IMM
; fGP_DOCHKPAGECROSS(fREAD_GP(),EA
); } while (0),
911 fPM_I
, /* Post Modify Register by Immediate
*/
912 do
{ REG
= REG
+ IMM
; } while (0),
917 fPM_M
, /* Post Modify Register by M register
*/
918 do
{ REG
= REG
+ MVAL
; } while (0),
923 fPM_CIRI
, /* Post Modify Register using Circular arithmetic by Immediate
*/
924 do
{ fcirc_add(REG
,siV
,MuV
); } while (0),
929 fPM_CIRR
, /* Post Modify Register using Circular arithmetic by register
*/
930 do
{ fcirc_add(REG
,VAL,MuV
); } while (0),
937 fSCALE
, /* scale by N
*/
938 (((size8s_t
)(A
))<<N
),
939 /* optional attributes
*/
942 fVSATW
, /* saturating to
32-bits
*/
943 fVSATN(32,((long long
)A
)),
948 fSATW
, /* saturating to
32-bits
*/
949 fSATN(32,((long long
)A
)),
954 fVSAT
, /* saturating to
32-bits
*/
960 fSAT
, /* saturating to
32-bits
*/
966 fSAT_ORIG_SHL
, /* Saturating to
32-bits
, with original value
, for shift left
*/
967 ((((size4s_t
)((fSAT(A
)) ^
((size4s_t
)(ORIG_REG
)))) < 0) ?
968 fSATVALN(32,((size4s_t
)(ORIG_REG
))) :
969 ((((ORIG_REG
) > 0) && ((A
) == 0)) ?
970 fSATVALN(32,(ORIG_REG
)) :
981 fRND
, /* saturating to
32-bits
*/
988 (((SHAMT
) < 0) ?
((fCAST##
REGSTYPE(SRC
) >> ((-(SHAMT
))-1)) >>1) : (fCAST##
REGSTYPE(SRC
) << (SHAMT
))),
994 fBIDIR_SHIFTL(SRC
,SHAMT
,REGSTYPE##s
),
1000 fBIDIR_SHIFTL(SRC
,SHAMT
,REGSTYPE##u
),
1006 (((SHAMT
) < 0) ?
((fCAST##REGSTYPE##
s(SRC
) >> ((-(SHAMT
))-1)) >>1) : fSAT_ORIG_SHL(fCAST##REGSTYPE##
s(SRC
) << (SHAMT
),(SRC
))),
1013 (((SHAMT
) < 0) ?
((fCAST##
REGSTYPE(SRC
) << ((-(SHAMT
))-1)) << 1) : (fCAST##
REGSTYPE(SRC
) >> (SHAMT
))),
1019 fBIDIR_SHIFTR(SRC
,SHAMT
,REGSTYPE##s
),
1025 fBIDIR_SHIFTR(SRC
,SHAMT
,REGSTYPE##u
),
1031 (((SHAMT
) < 0) ?
fSAT_ORIG_SHL((fCAST##REGSTYPE##
s(SRC
) << ((-(SHAMT
))-1)) << 1,(SRC
)) : (fCAST##REGSTYPE##
s(SRC
) >> (SHAMT
))),
1037 (fCAST##REGSTYPE##
s(SRC
) >> (SHAMT
)),
1043 (((SHAMT
) >= 64)?
0:(fCAST##REGSTYPE##
u(SRC
) >> (SHAMT
))),
1049 (((SHAMT
)==0) ?
(SRC
) : ((fCAST##REGSTYPE##
u(SRC
) << (SHAMT
)) | \
1050 ((fCAST##REGSTYPE##
u(SRC
) >> ((sizeof(SRC
)*8)-(SHAMT
)))))),
1056 (((SHAMT
)==0) ?
(SRC
) : ((fCAST##REGSTYPE##
u(SRC
) >> (SHAMT
)) | \
1057 ((fCAST##REGSTYPE##
u(SRC
) << ((sizeof(SRC
)*8)-(SHAMT
)))))),
1063 (((SHAMT
) >= 64)?
0:(fCAST##REGSTYPE##
s(SRC
) << (SHAMT
))),
1067 /*************************************/
1068 /* Floating
-Point Support
*/
1069 /************************************/
1073 ({ union
{ float f
; size4u_t i
; } _fipun
; _fipun.i
= (A
); _fipun.f
; }), /* behavior
*/
1078 fUNFLOAT
, /* multiply half integer
*/
1079 ({ union
{ float f
; size4u_t i
; } _fipun
; _fipun.f
= (A
); isnan(_fipun.f
) ?
0xFFFFFFFFU
: _fipun.i
; }), /* behavior
*/
1091 (((A
) & 0x80000000) |
0x7f800000),
1097 (((A
) & 0x80000000) |
fUNFLOAT(1.0)),
1104 if (isnan(fFLOAT(A
))) {
1105 if ((fGETBIT(22,A
)) == 0) fRAISEFLAGS(FE_INVALID
);
1136 (fUNFLOAT(fFLOAT(A
) * fFLOAT((fSF_BIAS() + (B
)) << fSF_MANTBITS()))),
1142 (((A
) >> fSF_MANTBITS()) & 0xff),
1154 arch_sf_recip_common(&N
,&D
,&O
,&A
),
1160 arch_sf_invsqrt_common(&N
,&O
,&A
),
1166 internal_fmafx(A
,B
,C
,fSXTN(8,64,ADJ
)),
1172 internal_fmafx(A
,B
,C
,0),
1184 ((((SIGN
) & 1) << 31) |
(((EXP
) & 0xff) << fSF_MANTBITS()) |
1185 ((MANT
) & ((1<<fSF_MANTBITS())-1))),
1191 fDOUBLE
, /* multiply half integer
*/
1192 ({ union
{ double f
; size8u_t i
; } _fipun
; _fipun.i
= (A
); _fipun.f
; }), /* behavior
*/
1197 fUNDOUBLE
, /* multiply half integer
*/
1198 ({ union
{ double f
; size8u_t i
; } _fipun
; _fipun.f
= (A
); isnan(_fipun.f
) ?
0xFFFFFFFFFFFFFFFFULL
: _fipun.i
; }), /* behavior
*/
1204 0xffffffffffffffffULL
,
1210 (fpclassify(fDOUBLE(X
)) == FP_NORMAL
),
1216 (fpclassify(fDOUBLE(X
)) == FP_SUBNORMAL
),
1222 (fDF_GETEXP(X
) >= 512),
1234 (((A
) >> fDF_MANTBITS()) & 0x7ff),
1240 internal_fma(A
,B
,C
),
1246 internal_mpyhh(A
,B
,ACC
),
1252 arch_fpop_start(thread
),
1258 arch_fpop_end(thread
),
1263 fFPSETROUND_NEAREST
,
1264 fesetround(FE_TONEAREST
),
1270 fesetround(FE_TOWARDZERO
),
1276 feclearexcept(FE_ALL_EXCEPT
),
1282 ((isinf(A
) && isinf(B
)) ||
1283 (isinf(A
) && isfinite(B
) && ((B
) != 0.0)) ||
1284 (isinf(B
) && isfinite(A
) && ((A
) != 0.0))),
1290 ((((A
) == 0.0) && isfinite(B
)) ||
(((B
) == 0.0) && isfinite(A
))),
1296 arch_raise_fpflag(A
),
1303 ?
fDOUBLE(fUNDOUBLE(A
) & fUNDOUBLE(B
))
1311 ?
fDOUBLE(fUNDOUBLE(A
) |
fUNDOUBLE(B
))
1319 ?
fFLOAT(fUNFLOAT(A
) & fUNFLOAT(B
))
1327 ?
fFLOAT(fUNFLOAT(A
) |
fUNFLOAT(B
))
1332 /*************************************/
1333 /* Load
/Store support
*/
1334 /*************************************/
1337 { DST
= (size##
SIZE##SIGN##_t
)MEM_LOAD##
SIZE(thread
,EA
,insn
); },
1342 { memop##
SIZE##_##
FNTYPE(thread
,EA
,VALUE
); },
1343 (A_LOAD
,A_STORE
,A_MEMLIKE
)
1346 DEF_MACRO(fGET_FRAMEKEY
,
1347 READ_RREG(REG_FRAMEKEY
),
1351 DEF_MACRO(fFRAME_SCRAMBLE
,
1352 ((VAL) ^
(fCAST8u(fGET_FRAMEKEY()) << 32)),
1356 DEF_MACRO(fFRAME_UNSCRAMBLE
,
1357 fFRAME_SCRAMBLE(VAL),
1361 DEF_MACRO(fFRAMECHECK
,
1362 sys_check_framelimit(thread
,ADDR
,EA
),
1366 DEF_MACRO(fLOAD_LOCKED
,
1367 { DST
= (size##
SIZE##SIGN##_t
)mem_load_locked(thread
,EA
,SIZE,insn
); },
1372 { MEM_STORE##
SIZE(thread
,EA
,SRC
,insn
); },
1377 DEF_MACRO(fSTORE_LOCKED
,
1378 { PRED
= (mem_store_conditional(thread
,EA
,SRC
,SIZE,insn
) ?
0xff : 0); },
1382 /*************************************/
1383 /* Functions to help with bytes
*/
1384 /*************************************/
1387 ((size1s_t
)((SRC
>>((N
)*8))&0xff)),
1391 DEF_MACRO(fGETUBYTE
,
1392 ((size1u_t
)((SRC
>>((N
)*8))&0xff)),
1398 DST
= (DST
& ~
(0x0ffLL
<<((N
)*8))) |
(((size8u_t
)((VAL) & 0x0ffLL
)) << ((N
)*8));
1404 ((size2s_t
)((SRC
>>((N
)*16))&0xffff)),
1408 DEF_MACRO(fGETUHALF
,
1409 ((size2u_t
)((SRC
>>((N
)*16))&0xffff)),
1415 DST
= (DST
& ~
(0x0ffffLL
<<((N
)*16))) |
(((size8u_t
)((VAL) & 0x0ffff)) << ((N
)*16));
1423 ((size8s_t
)((size4s_t
)((SRC
>>((N
)*32))&0x0ffffffffLL
))),
1427 DEF_MACRO(fGETUWORD
,
1428 ((size8u_t
)((size4u_t
)((SRC
>>((N
)*32))&0x0ffffffffLL
))),
1434 DST
= (DST
& ~
(0x0ffffffffLL
<<((N
)*32))) |
(((VAL) & 0x0ffffffffLL
) << ((N
)*32));
1441 DST
= (DST
& ~
(1ULL<<(N
))) |
(((size8u_t
)(VAL))<<(N
));
1455 for (j
=LO
;j
<=HI
;j
++) {
1462 /*************************************/
1463 /* Used for parity
, etc........
*/
1464 /*************************************/
1465 DEF_MACRO(fCOUNTONES_2
,
1470 DEF_MACRO(fCOUNTONES_4
,
1475 DEF_MACRO(fCOUNTONES_8
,
1481 reverse_bits_8(VAL),
1486 reverse_bits_4(VAL),
1491 count_leading_ones_8(VAL),
1496 count_leading_ones_4(VAL),
1501 count_leading_ones_2(VAL),
1505 DEF_MACRO(fINTERLEAVE
,
1506 interleave(ODD,EVEN
),
1510 DEF_MACRO(fDEINTERLEAVE
,
1511 deinterleave(MIXED
),
1524 /* Do the things in the parens
, but don
't print the parens. */
1531 /********************************************/
1532 /* OS interface and stop/wait */
1533 /********************************************/
1536 {sys_pause(thread, insn->slot, IMM);},
1541 warn("Trap NPC=%x ",fREAD_NPC());
1542 warn("Trap exception, PCYCLE=%lld TYPE=%d NPC=%x IMM=0x%x",thread->processor_ptr->pstats[pcycles],TRAPTYPE,fREAD_NPC(),IMM);
1543 register_trap_exception(thread,fREAD_NPC(),TRAPTYPE,IMM);,
1547 DEF_MACRO(fALIGN_REG_FIELD_VALUE,
1548 ((VAL)<<reg_field_info[FIELD].offset),
1552 DEF_MACRO(fGET_REG_FIELD_MASK,
1553 (((1<<reg_field_info[FIELD].width)-1)<<reg_field_info[FIELD].offset),
1557 DEF_MACRO(fREAD_REG_FIELD,
1558 fEXTRACTU_BITS(thread->Regs[REG_##REG],
1559 reg_field_info[FIELD].width,
1560 reg_field_info[FIELD].offset),
1564 DEF_MACRO(fGET_FIELD,
1566 reg_field_info[FIELD].width,
1567 reg_field_info[FIELD].offset),
1571 DEF_MACRO(fSET_FIELD,
1573 reg_field_info[FIELD].width,
1574 reg_field_info[FIELD].offset,
1579 /********************************************/
1580 /* Cache Management */
1581 /********************************************/
1585 sys_barrier(thread, insn->slot);
1592 sys_sync(thread, insn->slot);
1599 sys_isync(thread, insn->slot);
1606 sys_dcfetch(thread, (REG), insn->slot),
1612 arch_internal_flush(thread->processor_ptr, 0, 0xffffffff);
1613 sys_icinva(thread, (REG),insn->slot);
1619 sys_l2fetch(thread, ADDR,HEIGHT,WIDTH,STRIDE,FLAGS, insn->slot),
1620 (A_MEMLIKE,A_L2FETCH)
1623 DEF_MACRO(fDCCLEANA,
1624 sys_dccleana(thread, (REG)),
1628 DEF_MACRO(fDCCLEANINVA,
1629 sys_dccleaninva(thread, (REG), insn->slot),
1630 (A_MEMLIKE,A_DCCLEANINVA)
1634 sys_dczeroa(thread, (REG)),
1638 DEF_MACRO(fCHECKFORPRIV,
1639 {sys_check_privs(thread); if (EXCEPTION_DETECTED) return; },
1643 DEF_MACRO(fCHECKFORGUEST,
1644 {sys_check_guest(thread); if (EXCEPTION_DETECTED) return; },
1648 DEF_MACRO(fBRANCH_SPECULATE_STALL,
1650 sys_speculate_branch_stall(thread, insn->slot, JUMP_COND(JUMP_PRED_SET),
1656 thread->last_pkt->pkt_has_dual_jump,
1658 (thread->fetch_access.vaddr + insn->encoding_offset*4));