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
))),
97 ( (VAL) ?
0xff : 0x00),
109 predlog_read(thread
,PNUM
),
115 predlog_read(thread
,0),
121 predlog_read(thread
,1),
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
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
)
166 ({fSET_OVERFLOW(); ((VAL) < 0) ?
0 : ((1LL<<(N
))-1);}),
172 ({fSET_OVERFLOW(); ((VAL) < 0) ?
(-(1LL<<((N
)-1))) : ((1LL<<((N
)-1))-1);}),
177 fZXTN
, /* macro name
*/
178 ((VAL) & ((1LL<<(N
))-1)),
183 fSXTN
, /* macro name
*/
184 ((fZXTN(N
,M
,VAL) ^
(1LL<<((N
)-1))) - (1LL<<((N
)-1))),
190 ((fSXTN(N
,64,VAL) == (VAL)) ?
(VAL) : fSATVALN(N
,VAL)),
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
*/
205 } else
if ((__a ^ __sum
) & __mask
) {
207 if (__sum
& __mask
) {
208 /* overflowed to negative
, make max pos
*/
209 DST
=0x7FFFFFFFFFFFFFFFLL
; fSET_OVERFLOW();
211 /* overflowed to positive
, make max neg
*/
212 DST
=0x8000000000000000LL
; fSET_OVERFLOW();
215 /* signs did not mismatch
, OK
*/
224 ((fZXTN(N
,64,VAL) == (VAL)) ?
(VAL) : fSATUVALN(N
,VAL)),
253 /*************************************/
254 /* immediate extension
*/
255 /*************************************/
271 IMM
=(IMM
& ~PCALIGN_MASK
),
275 /*************************************/
276 /* Read and Write Implicit Regs
*/
277 /*************************************/
280 fREAD_IREG
, /* read modifier register
*/
281 (fSXTN(11,64,(((VAL) & 0xf0000000)>>21) |
((VAL>>17)&0x7f) )), /* behavior
*/
286 fREAD_LR
, /* read link register
*/
287 (READ_RREG(REG_LR
)), /* behavior
*/
292 fWRITE_LR
, /* write lr
*/
293 WRITE_RREG(REG_LR
,A
), /* behavior
*/
294 (A_IMPLICIT_WRITES_LR
)
298 fWRITE_FP
, /* write sp
*/
299 WRITE_RREG(REG_FP
,A
), /* behavior
*/
300 (A_IMPLICIT_WRITES_FP
)
304 fWRITE_SP
, /* write sp
*/
305 WRITE_RREG(REG_SP
,A
), /* behavior
*/
306 (A_IMPLICIT_WRITES_SP
)
310 fREAD_SP
, /* read stack pointer
*/
311 (READ_RREG(REG_SP
)), /* behavior
*/
316 fREAD_CSREG
, /* read CS register
*/
317 (READ_RREG(REG_CSA
+N
)), /* behavior
*/
322 fREAD_LC0
, /* read loop count
*/
323 (READ_RREG(REG_LC0
)), /* behavior
*/
328 fREAD_LC1
, /* read loop count
*/
329 (READ_RREG(REG_LC1
)), /* behavior
*/
334 fREAD_SA0
, /* read start addr
*/
335 (READ_RREG(REG_SA0
)), /* behavior
*/
340 fREAD_SA1
, /* read start addr
*/
341 (READ_RREG(REG_SA1
)), /* behavior
*/
347 fREAD_FP
, /* read frame pointer
*/
348 (READ_RREG(REG_FP
)), /* behavior
*/
353 fREAD_GP
, /* read global pointer
*/
354 (insn
->extension_valid ?
0 : READ_RREG(REG_GP
)), /* behavior
*/
359 fREAD_PC
, /* read PC
*/
360 (READ_RREG(REG_PC
)), /* behavior
*/
365 fREAD_NPC
, /* read next PC
*/
366 (thread
->next_PC
& (0xfffffffe)), /* behavior
*/
371 fREAD_P0
, /* read Predicate
0 */
372 (READ_PREG(0)), /* behavior
*/
377 fREAD_P3
, /* read Predicate
3 */
378 (READ_PREG(3)), /* behavior
*/
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);
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
;
397 thread
->branched
= 1; thread
->branch_taken
= 1; thread
->next_PC
= A
; \
398 thread
->branch_offset
= insn
->encoding_offset
; thread
->branch_opcode
= insn
->opcode
;
405 fWRITE_NPC(LOC
); fCOF_CALLBACK(LOC
,TYPE),
410 fJUMPR
, /* A jumpr has executed
*/
411 {fBRANCH(TARGET
,COF_TYPE_JUMPR
);},
416 fHINTJR
, /* A hintjr instruction has executed
*/
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
)
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
)
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
)
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
)
448 WRITE_RREG(REG_LC0
,VAL),
449 (A_IMPLICIT_WRITES_LC0
)
454 WRITE_RREG(REG_LC1
,VAL),
455 (A_IMPLICIT_WRITES_LC1
)
460 carry_from_add64(A
,B
,C
),
466 SET_USR_FIELD(USR_OVF
,1),
472 SET_USR_FIELD(USR_LPCFG
,(VAL)),
479 (GET_USR_FIELD(USR_LPCFG
)),
486 fWRITE_P0
, /* write Predicate
0 */
487 WRITE_PREG(0,VAL), /* behavior
*/
488 (A_IMPLICIT_WRITES_P0
)
492 fWRITE_P1
, /* write Predicate
0 */
493 WRITE_PREG(1,VAL), /* behavior
*/
494 (A_IMPLICIT_WRITES_P1
)
498 fWRITE_P2
, /* write Predicate
0 */
499 WRITE_PREG(2,VAL), /* behavior
*/
500 (A_IMPLICIT_WRITES_P2
)
504 fWRITE_P3
, /* write Predicate
0 */
505 WRITE_PREG(3,VAL), /* behavior
*/
506 (A_IMPLICIT_WRITES_P3
)
510 fPART1
, /* write Predicate
0 */
511 if (insn
->part1
) { WORK
; return
; }, /* behavior
*/
512 /* optional attributes
*/
516 /*************************************/
517 /* Casting
, Sign
-Zero extension
, etc
*/
518 /*************************************/
521 fCAST4u
, /* macro name
*/
522 ((size4u_t
)(A
)), /* behavior
*/
523 /* optional attributes
*/
527 fCAST4s
, /* macro name
*/
528 ((size4s_t
)(A
)), /* behavior
*/
529 /* optional attributes
*/
533 fCAST8u
, /* macro name
*/
534 ((size8u_t
)(A
)), /* behavior
*/
535 /* optional attributes
*/
539 fCAST8s
, /* macro name
*/
540 ((size8s_t
)(A
)), /* behavior
*/
541 /* optional attributes
*/
545 fCAST4_4s
, /* macro name
*/
547 /* optional attributes
*/
551 fCAST4_4u
, /* macro name
*/
553 /* optional attributes
*/
558 fCAST4_8s
, /* macro name
*/
559 ((size8s_t
)((size4s_t
)(A
))),
560 /* optional attributes
*/
564 fCAST4_8u
, /* macro name
*/
565 ((size8u_t
)((size4u_t
)(A
))),
566 /* optional attributes
*/
570 fCAST8_8s
, /* macro name
*/
572 /* optional attributes
*/
576 fCAST8_8u
, /* macro name
*/
578 /* optional attributes
*/
582 fCAST2_8s
, /* macro name
*/
583 ((size8s_t
)((size2s_t
)(A
))),
584 /* optional attributes
*/
587 fCAST2_8u
, /* macro name
*/
588 ((size8u_t
)((size2u_t
)(A
))),
589 /* optional attributes
*/
593 fZE8_16
, /* zero
-extend
8 to
16 */
594 ((size2s_t
)((size1u_t
)(A
))),
595 /* optional attributes
*/
598 fSE8_16
, /* sign
-extend
8 to
16 */
599 ((size2s_t
)((size1s_t
)(A
))),
600 /* optional attributes
*/
605 fSE16_32
, /* sign
-extend
16 to
32 */
606 ((size4s_t
)((size2s_t
)(A
))), /* behavior
*/
607 /* optional attributes
*/
611 fZE16_32
, /* zero
-extend
16 to
32 */
612 ((size4u_t
)((size2u_t
)(A
))), /* behavior
*/
613 /* optional attributes
*/
618 ( (size8s_t
)((size4s_t
)(A
)) ), /* behavior
*/
619 /* optional attributes
*/
624 ( (size8u_t
)((size4u_t
)(A
)) ), /* behavior
*/
625 /* optional attributes
*/
629 fSE8_32
, /* sign
-extend
8 to
32 */
630 ((size4s_t
)((size1s_t
)(A
))),
631 /* optional attributes
*/
635 fZE8_32
, /* zero
-extend
8 to
32 */
636 ((size4s_t
)((size1u_t
)(A
))),
637 /* optional attributes
*/
640 /*************************************/
641 /* DSP arithmetic support
*/
642 /************************************/
644 fMPY8UU
, /* multiply half integer
*/
645 (int
)(fZE8_16(A
)*fZE8_16(B
)), /* behavior
*/
649 fMPY8US
, /* multiply half integer
*/
650 (int
)(fZE8_16(A
)*fSE8_16(B
)), /* behavior
*/
654 fMPY8SU
, /* multiply half integer
*/
655 (int
)(fSE8_16(A
)*fZE8_16(B
)), /* behavior
*/
660 fMPY8SS
, /* multiply half integer
*/
661 (int
)((short
)(A
)*(short
)(B
)), /* behavior
*/
666 fMPY16SS
, /* multiply half integer
*/
667 fSE32_64(fSE16_32(A
)*fSE16_32(B
)), /* behavior
*/
672 fMPY16UU
, /* multiply unsigned half integer
*/
673 fZE32_64(fZE16_32(A
)*fZE16_32(B
)), /* behavior
*/
678 fMPY16SU
, /* multiply half integer
*/
679 fSE32_64(fSE16_32(A
)*fZE16_32(B
)), /* behavior
*/
684 fMPY16US
, /* multiply half integer
*/
690 fMPY32SS
, /* multiply half integer
*/
691 (fSE32_64(A
)*fSE32_64(B
)), /* behavior
*/
696 fMPY32UU
, /* multiply half integer
*/
697 (fZE32_64(A
)*fZE32_64(B
)), /* behavior
*/
702 fMPY32SU
, /* multiply half integer
*/
703 (fSE32_64(A
)*fZE32_64(B
)), /* behavior
*/
708 fMPY3216SS
, /* multiply mixed precision
*/
709 (fSE32_64(A
)*fSXTN(16,64,B
)), /* behavior
*/
714 fMPY3216SU
, /* multiply mixed precision
*/
715 (fSE32_64(A
)*fZXTN(16,64,B
)), /* behavior
*/
720 fROUND
, /* optional rounding
*/
722 /* optional attributes
*/
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
*/
735 fCRND
, /* optional rounding
*/
736 ((((A
)&0x3)==0x3)?
((A
)+1):((A
))),
737 /* optional attributes
*/
741 fRNDN
, /* Rounding to a boundary
*/
742 ((((N
)==0)?
(A
):(((fSE32_64(A
))+(1<<((N
)-1)))))),
743 /* optional attributes
*/
747 fCRNDN
, /* Rounding to a boundary
*/
749 /* optional attributes
*/
753 fADD128
, /* Rounding to a boundary
*/
755 /* optional attributes
*/
758 fSUB128
, /* Rounding to a boundary
*/
760 /* optional attributes
*/
763 fSHIFTR128
, /* Rounding to a boundary
*/
765 /* optional attributes
*/
769 fSHIFTL128
, /* Rounding to a boundary
*/
771 /* optional attributes
*/
775 fAND128
, /* Rounding to a boundary
*/
777 /* optional attributes
*/
781 fCAST8S_16S
, /* Rounding to a boundary
*/
783 /* optional attributes
*/
786 fCAST16S_8S
, /* Rounding to a boundary
*/
788 /* optional attributes
*/
792 fEA_RI
, /* Calculate EA with Register
+ Immediate Offset
*/
793 do
{ EA
=REG
+IMM
; fDOCHKPAGECROSS(REG
,EA
); } while (0),
798 fEA_RRs
, /* Calculate EA with Register
+ Registers scaled Offset
*/
799 do
{ EA
=REG
+(REG2
<<SCALE
); fDOCHKPAGECROSS(REG
,EA
); } while (0),
804 fEA_IRs
, /* Calculate EA with Immediate
+ Registers scaled Offset
*/
805 do
{ EA
=IMM
+(REG
<<SCALE
); fDOCHKPAGECROSS(IMM
,EA
); } while (0),
810 fEA_IMM
, /* Calculate EA with Immediate
*/
816 fEA_REG
, /* Calculate EA with REGISTER
*/
822 fEA_GPI
, /* Calculate EA with Global Poitner
+ Immediate
*/
823 do
{ EA
=fREAD_GP()+IMM
; fGP_DOCHKPAGECROSS(fREAD_GP(),EA
); } while (0),
828 fPM_I
, /* Post Modify Register by Immediate
*/
829 do
{ REG
= REG
+ IMM
; } while (0),
834 fPM_M
, /* Post Modify Register by M register
*/
835 do
{ REG
= REG
+ MVAL
; } while (0),
840 fPM_CIRI
, /* Post Modify Register using Circular arithmetic by Immediate
*/
841 do
{ fcirc_add(REG
,siV
,MuV
); } while (0),
846 fPM_CIRR
, /* Post Modify Register using Circular arithmetic by register
*/
847 do
{ fcirc_add(REG
,VAL,MuV
); } while (0),
854 fSCALE
, /* scale by N
*/
855 (((size8s_t
)(A
))<<N
),
856 /* optional attributes
*/
860 fSATW
, /* saturating to
32-bits
*/
861 fSATN(32,((long long
)A
)),
866 fSAT
, /* saturating to
32-bits
*/
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
)) :
887 fRND
, /* saturating to
32-bits
*/
894 (((SHAMT
) < 0) ?
((fCAST##
REGSTYPE(SRC
) >> ((-(SHAMT
))-1)) >>1) : (fCAST##
REGSTYPE(SRC
) << (SHAMT
))),
900 fBIDIR_SHIFTL(SRC
,SHAMT
,REGSTYPE##s
),
906 fBIDIR_SHIFTL(SRC
,SHAMT
,REGSTYPE##u
),
912 (((SHAMT
) < 0) ?
((fCAST##REGSTYPE##
s(SRC
) >> ((-(SHAMT
))-1)) >>1) : fSAT_ORIG_SHL(fCAST##REGSTYPE##
s(SRC
) << (SHAMT
),(SRC
))),
919 (((SHAMT
) < 0) ?
((fCAST##
REGSTYPE(SRC
) << ((-(SHAMT
))-1)) << 1) : (fCAST##
REGSTYPE(SRC
) >> (SHAMT
))),
925 fBIDIR_SHIFTR(SRC
,SHAMT
,REGSTYPE##s
),
931 fBIDIR_SHIFTR(SRC
,SHAMT
,REGSTYPE##u
),
937 (((SHAMT
) < 0) ?
fSAT_ORIG_SHL((fCAST##REGSTYPE##
s(SRC
) << ((-(SHAMT
))-1)) << 1,(SRC
)) : (fCAST##REGSTYPE##
s(SRC
) >> (SHAMT
))),
943 (fCAST##REGSTYPE##
s(SRC
) >> (SHAMT
)),
949 (((SHAMT
) >= 64)?
0:(fCAST##REGSTYPE##
u(SRC
) >> (SHAMT
))),
955 (((SHAMT
)==0) ?
(SRC
) : ((fCAST##REGSTYPE##
u(SRC
) << (SHAMT
)) | \
956 ((fCAST##REGSTYPE##
u(SRC
) >> ((sizeof(SRC
)*8)-(SHAMT
)))))),
962 (((SHAMT
)==0) ?
(SRC
) : ((fCAST##REGSTYPE##
u(SRC
) >> (SHAMT
)) | \
963 ((fCAST##REGSTYPE##
u(SRC
) << ((sizeof(SRC
)*8)-(SHAMT
)))))),
969 (((SHAMT
) >= 64)?
0:(fCAST##REGSTYPE##
s(SRC
) << (SHAMT
))),
973 /*************************************/
974 /* Floating
-Point Support
*/
975 /************************************/
979 ({ union
{ float f
; size4u_t i
; } _fipun
; _fipun.i
= (A
); _fipun.f
; }), /* behavior
*/
984 fUNFLOAT
, /* multiply half integer
*/
985 ({ union
{ float f
; size4u_t i
; } _fipun
; _fipun.f
= (A
); isnan(_fipun.f
) ?
0xFFFFFFFFU
: _fipun.i
; }), /* behavior
*/
997 (((A
) & 0x80000000) |
0x7f800000),
1003 (((A
) & 0x80000000) |
fUNFLOAT(1.0)),
1010 if (isnan(fFLOAT(A
))) {
1011 if ((fGETBIT(22,A
)) == 0) fRAISEFLAGS(FE_INVALID
);
1042 (fUNFLOAT(fFLOAT(A
) * fFLOAT((fSF_BIAS() + (B
)) << fSF_MANTBITS()))),
1048 (((A
) >> fSF_MANTBITS()) & 0xff),
1060 arch_sf_recip_common(&N
,&D
,&O
,&A
),
1066 arch_sf_invsqrt_common(&N
,&O
,&A
),
1072 internal_fmafx(A
,B
,C
,fSXTN(8,64,ADJ
)),
1078 internal_fmafx(A
,B
,C
,0),
1090 ((((SIGN
) & 1) << 31) |
(((EXP
) & 0xff) << fSF_MANTBITS()) |
1091 ((MANT
) & ((1<<fSF_MANTBITS())-1))),
1097 fDOUBLE
, /* multiply half integer
*/
1098 ({ union
{ double f
; size8u_t i
; } _fipun
; _fipun.i
= (A
); _fipun.f
; }), /* behavior
*/
1103 fUNDOUBLE
, /* multiply half integer
*/
1104 ({ union
{ double f
; size8u_t i
; } _fipun
; _fipun.f
= (A
); isnan(_fipun.f
) ?
0xFFFFFFFFFFFFFFFFULL
: _fipun.i
; }), /* behavior
*/
1110 0xffffffffffffffffULL
,
1116 (fpclassify(fDOUBLE(X
)) == FP_NORMAL
),
1122 (fpclassify(fDOUBLE(X
)) == FP_SUBNORMAL
),
1128 (fDF_GETEXP(X
) >= 512),
1140 (((A
) >> fDF_MANTBITS()) & 0x7ff),
1146 internal_fma(A
,B
,C
),
1152 internal_mpyhh(A
,B
,ACC
),
1158 arch_fpop_start(thread
),
1164 arch_fpop_end(thread
),
1169 fFPSETROUND_NEAREST
,
1170 fesetround(FE_TONEAREST
),
1176 fesetround(FE_TOWARDZERO
),
1182 feclearexcept(FE_ALL_EXCEPT
),
1188 ((isinf(A
) && isinf(B
)) ||
1189 (isinf(A
) && isfinite(B
) && ((B
) != 0.0)) ||
1190 (isinf(B
) && isfinite(A
) && ((A
) != 0.0))),
1196 ((((A
) == 0.0) && isfinite(B
)) ||
(((B
) == 0.0) && isfinite(A
))),
1202 arch_raise_fpflag(A
),
1209 ?
fDOUBLE(fUNDOUBLE(A
) & fUNDOUBLE(B
))
1217 ?
fDOUBLE(fUNDOUBLE(A
) |
fUNDOUBLE(B
))
1225 ?
fFLOAT(fUNFLOAT(A
) & fUNFLOAT(B
))
1233 ?
fFLOAT(fUNFLOAT(A
) |
fUNFLOAT(B
))
1238 /*************************************/
1239 /* Load
/Store support
*/
1240 /*************************************/
1243 { DST
= (size##
SIZE##SIGN##_t
)MEM_LOAD##
SIZE(thread
,EA
,insn
); },
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)),
1262 DEF_MACRO(fFRAME_UNSCRAMBLE
,
1263 fFRAME_SCRAMBLE(VAL),
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
); },
1278 { MEM_STORE##
SIZE(thread
,EA
,SRC
,insn
); },
1283 DEF_MACRO(fSTORE_LOCKED
,
1284 { PRED
= (mem_store_conditional(thread
,EA
,SRC
,SIZE,insn
) ?
0xff : 0); },
1288 /*************************************/
1289 /* Functions to help with bytes
*/
1290 /*************************************/
1293 ((size1s_t
)((SRC
>>((N
)*8))&0xff)),
1297 DEF_MACRO(fGETUBYTE
,
1298 ((size1u_t
)((SRC
>>((N
)*8))&0xff)),
1304 DST
= (DST
& ~
(0x0ffLL
<<((N
)*8))) |
(((size8u_t
)((VAL) & 0x0ffLL
)) << ((N
)*8));
1310 ((size2s_t
)((SRC
>>((N
)*16))&0xffff)),
1314 DEF_MACRO(fGETUHALF
,
1315 ((size2u_t
)((SRC
>>((N
)*16))&0xffff)),
1321 DST
= (DST
& ~
(0x0ffffLL
<<((N
)*16))) |
(((size8u_t
)((VAL) & 0x0ffff)) << ((N
)*16));
1329 ((size8s_t
)((size4s_t
)((SRC
>>((N
)*32))&0x0ffffffffLL
))),
1333 DEF_MACRO(fGETUWORD
,
1334 ((size8u_t
)((size4u_t
)((SRC
>>((N
)*32))&0x0ffffffffLL
))),
1340 DST
= (DST
& ~
(0x0ffffffffLL
<<((N
)*32))) |
(((VAL) & 0x0ffffffffLL
) << ((N
)*32));
1347 DST
= (DST
& ~
(1ULL<<(N
))) |
(((size8u_t
)(VAL))<<(N
));
1361 for (j
=LO
;j
<=HI
;j
++) {
1368 /*************************************/
1369 /* Used for parity
, etc........
*/
1370 /*************************************/
1371 DEF_MACRO(fCOUNTONES_4
,
1376 DEF_MACRO(fCOUNTONES_8
,
1382 reverse_bits_8(VAL),
1387 reverse_bits_4(VAL),
1392 count_leading_ones_8(VAL),
1397 count_leading_ones_4(VAL),
1401 DEF_MACRO(fINTERLEAVE
,
1402 interleave(ODD,EVEN
),
1406 DEF_MACRO(fDEINTERLEAVE
,
1407 deinterleave(MIXED
),
1420 /* Do the things in the parens
, but don
't print the parens. */
1427 /********************************************/
1428 /* OS interface and stop/wait */
1429 /********************************************/
1432 {sys_pause(thread, insn->slot, IMM);},
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),
1448 DEF_MACRO(fGET_REG_FIELD_MASK,
1449 (((1<<reg_field_info[FIELD].width)-1)<<reg_field_info[FIELD].offset),
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),
1460 DEF_MACRO(fGET_FIELD,
1462 reg_field_info[FIELD].width,
1463 reg_field_info[FIELD].offset),
1467 DEF_MACRO(fSET_FIELD,
1469 reg_field_info[FIELD].width,
1470 reg_field_info[FIELD].offset,
1475 /********************************************/
1476 /* Cache Management */
1477 /********************************************/
1481 sys_barrier(thread, insn->slot);
1488 sys_sync(thread, insn->slot);
1495 sys_isync(thread, insn->slot);
1502 sys_dcfetch(thread, (REG), insn->slot),
1508 arch_internal_flush(thread->processor_ptr, 0, 0xffffffff);
1509 sys_icinva(thread, (REG),insn->slot);
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)),
1524 DEF_MACRO(fDCCLEANINVA,
1525 sys_dccleaninva(thread, (REG), insn->slot),
1526 (A_MEMLIKE,A_DCCLEANINVA)
1530 sys_dczeroa(thread, (REG)),
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),
1552 thread->last_pkt->pkt_has_dual_jump,
1554 (thread->fetch_access.vaddr + insn->encoding_offset*4));