1666 lines
30 KiB
Modula-2
Executable file
1666 lines
30 KiB
Modula-2
Executable file
/*
|
|
* Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
DEF_MACRO(
|
|
LIKELY, /* NAME */
|
|
__builtin_expect((X),1), /* BEH */
|
|
() /* attribs */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
UNLIKELY, /* NAME */
|
|
__builtin_expect((X),0), /* BEH */
|
|
() /* attribs */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
CANCEL, /* macro name */
|
|
{if (thread->last_pkt) thread->last_pkt->slot_cancelled |= (1<<insn->slot); return;} , /* behavior */
|
|
(A_CONDEXEC)
|
|
)
|
|
|
|
DEF_MACRO(
|
|
LOAD_CANCEL, /* macro name */
|
|
{mem_general_load_cancelled(thread,EA,insn);CANCEL;} , /* behavior */
|
|
(A_CONDEXEC)
|
|
)
|
|
|
|
DEF_MACRO(
|
|
STORE_CANCEL, /* macro name */
|
|
{mem_general_store_cancelled(thread,EA,insn);CANCEL;} , /* behavior */
|
|
(A_CONDEXEC)
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fMAX, /* macro name */
|
|
(((A) > (B)) ? (A) : (B)), /* behavior */
|
|
/* optional attributes */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fMIN, /* macro name */
|
|
(((A) < (B)) ? (A) : (B)), /* behavior */
|
|
/* optional attributes */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fABS, /* macro name */
|
|
(((A)<0)?(-(A)):(A)), /* behavior */
|
|
/* optional attributes */
|
|
)
|
|
|
|
|
|
/* Bit insert */
|
|
DEF_MACRO(
|
|
fINSERT_BITS,
|
|
{
|
|
REG = ((REG) & ~(((fCONSTLL(1)<<(WIDTH))-1)<<(OFFSET))) | (((INVAL) & ((fCONSTLL(1)<<(WIDTH))-1)) << (OFFSET));
|
|
},
|
|
/* attribs */
|
|
)
|
|
|
|
/* Bit extract */
|
|
DEF_MACRO(
|
|
fEXTRACTU_BITS,
|
|
(fZXTN(WIDTH,32,(INREG >> OFFSET))),
|
|
/* attribs */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fEXTRACTU_BIDIR,
|
|
(fZXTN(WIDTH,32,fBIDIR_LSHIFTR((INREG),(OFFSET),4_8))),
|
|
/* attribs */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fEXTRACTU_RANGE,
|
|
(fZXTN((HIBIT-LOWBIT+1),32,(INREG >> LOWBIT))),
|
|
/* attribs */
|
|
)
|
|
|
|
|
|
DEF_MACRO(
|
|
fINSERT_RANGE,
|
|
{
|
|
int offset=LOWBIT;
|
|
int width=HIBIT-LOWBIT+1;
|
|
/* clear bits where new bits go */
|
|
INREG &= ~(((fCONSTLL(1)<<width)-1)<<offset);
|
|
/* OR in new bits */
|
|
INREG |= ((INVAL & ((fCONSTLL(1)<<width)-1)) << offset);
|
|
},
|
|
/* attribs */
|
|
)
|
|
|
|
|
|
DEF_MACRO(
|
|
f8BITSOF,
|
|
( (VAL) ? 0xff : 0x00),
|
|
/* attribs */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fLSBOLD,
|
|
((VAL) & 1),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fLSBNEW,
|
|
predlog_read(thread,PNUM),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fLSBNEW0,
|
|
predlog_read(thread,0),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fLSBNEW1,
|
|
predlog_read(thread,1),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fLSBOLDNOT,
|
|
(!fLSBOLD(VAL)),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fLSBNEWNOT,
|
|
(!fLSBNEW(PNUM)),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fLSBNEW0NOT,
|
|
(!fLSBNEW0),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fLSBNEW1NOT,
|
|
(!fLSBNEW1),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fNEWREG,
|
|
({if (newvalue_missing(thread,RNUM) ||
|
|
IS_CANCELLED(insn->new_value_producer_slot)) CANCEL; reglog_read(thread,RNUM);}),
|
|
(A_DOTNEWVALUE,A_RESTRICT_SLOT0ONLY)
|
|
)
|
|
// Store new with a missing newvalue or cancelled goes out as a zero byte store in V65
|
|
// take advantage of the fact that reglog_read returns zero for not valid rnum
|
|
DEF_MACRO(
|
|
fNEWREG_ST,
|
|
({if (newvalue_missing(thread,RNUM) ||
|
|
IS_CANCELLED(insn->new_value_producer_slot)) { STORE_ZERO; RNUM = -1; }; reglog_read(thread,RNUM);}),
|
|
(A_DOTNEWVALUE,A_RESTRICT_SLOT0ONLY)
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fVSATUVALN,
|
|
({ ((VAL) < 0) ? 0 : ((1LL<<(N))-1);}),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fSATUVALN,
|
|
({fSET_OVERFLOW(); ((VAL) < 0) ? 0 : ((1LL<<(N))-1);}),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fSATVALN,
|
|
({fSET_OVERFLOW(); ((VAL) < 0) ? (-(1LL<<((N)-1))) : ((1LL<<((N)-1))-1);}),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fVSATVALN,
|
|
({((VAL) < 0) ? (-(1LL<<((N)-1))) : ((1LL<<((N)-1))-1);}),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fZXTN, /* macro name */
|
|
((VAL) & ((1LL<<(N))-1)),
|
|
/* attribs */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fSXTN, /* macro name */
|
|
((fZXTN(N,M,VAL) ^ (1LL<<((N)-1))) - (1LL<<((N)-1))),
|
|
/* attribs */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fSATN,
|
|
((fSXTN(N,64,VAL) == (VAL)) ? (VAL) : fSATVALN(N,VAL)),
|
|
()
|
|
)
|
|
DEF_MACRO(
|
|
fVSATN,
|
|
((fSXTN(N,64,VAL) == (VAL)) ? (VAL) : fVSATVALN(N,VAL)),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fADDSAT64,
|
|
{
|
|
size8u_t __a = fCAST8u(A);
|
|
size8u_t __b = fCAST8u(B);
|
|
size8u_t __sum = __a + __b;
|
|
size8u_t __xor = __a ^ __b;
|
|
const size8u_t __mask = 0x8000000000000000ULL;
|
|
if (__xor & __mask) {
|
|
/* Opposite signs, OK */
|
|
DST = __sum;
|
|
} else if ((__a ^ __sum) & __mask) {
|
|
/* Signs mismatch */
|
|
if (__sum & __mask) {
|
|
/* overflowed to negative, make max pos */
|
|
DST=0x7FFFFFFFFFFFFFFFLL; fSET_OVERFLOW();
|
|
} else {
|
|
/* overflowed to positive, make max neg */
|
|
DST=0x8000000000000000LL; fSET_OVERFLOW();
|
|
}
|
|
} else {
|
|
/* signs did not mismatch, OK */
|
|
DST = __sum;
|
|
}
|
|
},
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fVSATUN,
|
|
((fZXTN(N,64,VAL) == (VAL)) ? (VAL) : fVSATUVALN(N,VAL)),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fSATUN,
|
|
((fZXTN(N,64,VAL) == (VAL)) ? (VAL) : fSATUVALN(N,VAL)),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fSATH,
|
|
(fSATN(16,VAL)),
|
|
()
|
|
)
|
|
|
|
|
|
DEF_MACRO(
|
|
fSATUH,
|
|
(fSATUN(16,VAL)),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fVSATH,
|
|
(fVSATN(16,VAL)),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fVSATUH,
|
|
(fVSATUN(16,VAL)),
|
|
()
|
|
)
|
|
|
|
|
|
DEF_MACRO(
|
|
fSATUB,
|
|
(fSATUN(8,VAL)),
|
|
()
|
|
)
|
|
DEF_MACRO(
|
|
fSATB,
|
|
(fSATN(8,VAL)),
|
|
()
|
|
)
|
|
|
|
|
|
DEF_MACRO(
|
|
fVSATUB,
|
|
(fVSATUN(8,VAL)),
|
|
()
|
|
)
|
|
DEF_MACRO(
|
|
fVSATB,
|
|
(fVSATN(8,VAL)),
|
|
()
|
|
)
|
|
|
|
|
|
|
|
|
|
/*************************************/
|
|
/* immediate extension */
|
|
/*************************************/
|
|
|
|
DEF_MACRO(
|
|
fIMMEXT,
|
|
(IMM = IMM),
|
|
(A_EXTENDABLE)
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fMUST_IMMEXT,
|
|
fIMMEXT(IMM),
|
|
(A_EXTENDABLE)
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fPCALIGN,
|
|
IMM=(IMM & ~PCALIGN_MASK),
|
|
(A_EXTENDABLE)
|
|
)
|
|
|
|
/*************************************/
|
|
/* Read and Write Implicit Regs */
|
|
/*************************************/
|
|
|
|
DEF_MACRO(
|
|
fREAD_IREG, /* read modifier register */
|
|
(fSXTN(11,64,(((VAL) & 0xf0000000)>>21) | ((VAL>>17)&0x7f) )), /* behavior */
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fREAD_LR, /* read link register */
|
|
(READ_RREG(REG_LR)), /* behavior */
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fWRITE_LR, /* write lr */
|
|
WRITE_RREG(REG_LR,A), /* behavior */
|
|
(A_IMPLICIT_WRITES_LR)
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fWRITE_FP, /* write sp */
|
|
WRITE_RREG(REG_FP,A), /* behavior */
|
|
(A_IMPLICIT_WRITES_FP)
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fWRITE_SP, /* write sp */
|
|
WRITE_RREG(REG_SP,A), /* behavior */
|
|
(A_IMPLICIT_WRITES_SP)
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fREAD_SP, /* read stack pointer */
|
|
(READ_RREG(REG_SP)), /* behavior */
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fREAD_CSREG, /* read CS register */
|
|
(READ_RREG(REG_CSA+N)), /* behavior */
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fREAD_LC0, /* read loop count */
|
|
(READ_RREG(REG_LC0)), /* behavior */
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fREAD_LC1, /* read loop count */
|
|
(READ_RREG(REG_LC1)), /* behavior */
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fREAD_SA0, /* read start addr */
|
|
(READ_RREG(REG_SA0)), /* behavior */
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fREAD_SA1, /* read start addr */
|
|
(READ_RREG(REG_SA1)), /* behavior */
|
|
()
|
|
)
|
|
|
|
|
|
DEF_MACRO(
|
|
fREAD_FP, /* read frame pointer */
|
|
(READ_RREG(REG_FP)), /* behavior */
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fREAD_GP, /* read global pointer */
|
|
(insn->extension_valid ? 0 : READ_RREG(REG_GP)), /* behavior */
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fREAD_PC, /* read PC */
|
|
(READ_RREG(REG_PC)), /* behavior */
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fREAD_NPC, /* read next PC */
|
|
(thread->next_PC & (0xfffffffe)), /* behavior */
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fREAD_P0, /* read Predicate 0 */
|
|
(READ_PREG(0)), /* behavior */
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fREAD_P3, /* read Predicate 3 */
|
|
(READ_PREG(3)), /* behavior */
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fCHECK_PCALIGN,
|
|
if (((A) & PCALIGN_MASK)) {
|
|
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);
|
|
},
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fWRITE_NPC, /* write next PC */
|
|
if (!thread->branch_taken) {
|
|
if (A != thread->next_PC) {
|
|
thread->next_pkt_guess=thread->last_pkt->taken_ptr;
|
|
}
|
|
fCHECK_PCALIGN(A);
|
|
thread->branched = 1; thread->branch_taken = 1; thread->next_PC = A; \
|
|
thread->branch_offset = insn->encoding_offset; thread->branch_opcode = insn->opcode;
|
|
}, /* behavior */
|
|
(A_COF)
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fBRANCH,
|
|
fWRITE_NPC(LOC); fCOF_CALLBACK(LOC,TYPE),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fJUMPR, /* A jumpr has executed */
|
|
{fBRANCH(TARGET,COF_TYPE_JUMPR);},
|
|
(A_INDIRECT)
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fHINTJR, /* A hintjr instruction has executed */
|
|
{ },
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fCALL, /* Do a call */
|
|
if (!thread->branch_taken) {fBP_RAS_CALL(A); fWRITE_LR(fREAD_NPC()); fBRANCH(A,COF_TYPE_CALL);},
|
|
(A_COF,A_IMPLICIT_WRITES_LR,A_CALL)
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fCALLR, /* Do a call Register */
|
|
if (!thread->branch_taken) {fBP_RAS_CALL(A); fWRITE_LR(fREAD_NPC()); fBRANCH(A,COF_TYPE_CALLR);},
|
|
(A_COF,A_IMPLICIT_WRITES_LR,A_CALL)
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fWRITE_LOOP_REGS0, /* write ln,sa,ea,lc */
|
|
{WRITE_RREG(REG_LC0,COUNT);
|
|
WRITE_RREG(REG_SA0,START);},
|
|
(A_IMPLICIT_WRITES_LC0,A_IMPLICIT_WRITES_SA0)
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fWRITE_LOOP_REGS1, /* write ln,sa,ea,lc */
|
|
{WRITE_RREG(REG_LC1,COUNT);
|
|
WRITE_RREG(REG_SA1,START);},
|
|
(A_IMPLICIT_WRITES_LC1,A_IMPLICIT_WRITES_SA1)
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fWRITE_LC0,
|
|
WRITE_RREG(REG_LC0,VAL),
|
|
(A_IMPLICIT_WRITES_LC0)
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fWRITE_LC1,
|
|
WRITE_RREG(REG_LC1,VAL),
|
|
(A_IMPLICIT_WRITES_LC1)
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fCARRY_FROM_ADD,
|
|
carry_from_add64(A,B,C),
|
|
/* NOTHING */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fSET_OVERFLOW,
|
|
SET_USR_FIELD(USR_OVF,1),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fSET_LPCFG,
|
|
SET_USR_FIELD(USR_LPCFG,(VAL)),
|
|
()
|
|
)
|
|
|
|
|
|
DEF_MACRO(
|
|
fGET_LPCFG,
|
|
(GET_USR_FIELD(USR_LPCFG)),
|
|
()
|
|
)
|
|
|
|
|
|
|
|
DEF_MACRO(
|
|
fWRITE_P0, /* write Predicate 0 */
|
|
WRITE_PREG(0,VAL), /* behavior */
|
|
(A_IMPLICIT_WRITES_P0)
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fWRITE_P1, /* write Predicate 0 */
|
|
WRITE_PREG(1,VAL), /* behavior */
|
|
(A_IMPLICIT_WRITES_P1)
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fWRITE_P2, /* write Predicate 0 */
|
|
WRITE_PREG(2,VAL), /* behavior */
|
|
(A_IMPLICIT_WRITES_P2)
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fWRITE_P3, /* write Predicate 0 */
|
|
WRITE_PREG(3,VAL), /* behavior */
|
|
(A_IMPLICIT_WRITES_P3)
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fPART1, /* write Predicate 0 */
|
|
if (insn->part1) { WORK; return; }, /* behavior */
|
|
/* optional attributes */
|
|
)
|
|
|
|
|
|
/*************************************/
|
|
/* Casting, Sign-Zero extension, etc */
|
|
/*************************************/
|
|
|
|
DEF_MACRO(
|
|
fCAST4u, /* macro name */
|
|
((size4u_t)(A)), /* behavior */
|
|
/* optional attributes */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fCAST4s, /* macro name */
|
|
((size4s_t)(A)), /* behavior */
|
|
/* optional attributes */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fCAST8u, /* macro name */
|
|
((size8u_t)(A)), /* behavior */
|
|
/* optional attributes */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fCAST8s, /* macro name */
|
|
((size8s_t)(A)), /* behavior */
|
|
/* optional attributes */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fCAST2_2s, /* macro name */
|
|
((size2s_t)(A)),
|
|
/* optional attributes */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fCAST2_2u, /* macro name */
|
|
((size2u_t)(A)),
|
|
/* optional attributes */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fCAST4_4s, /* macro name */
|
|
((size4s_t)(A)),
|
|
/* optional attributes */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fCAST4_4u, /* macro name */
|
|
((size4u_t)(A)),
|
|
/* optional attributes */
|
|
)
|
|
|
|
|
|
DEF_MACRO(
|
|
fCAST4_8s, /* macro name */
|
|
((size8s_t)((size4s_t)(A))),
|
|
/* optional attributes */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fCAST4_8u, /* macro name */
|
|
((size8u_t)((size4u_t)(A))),
|
|
/* optional attributes */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fCAST8_8s, /* macro name */
|
|
((size8s_t)(A)),
|
|
/* optional attributes */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fCAST8_8u, /* macro name */
|
|
((size8u_t)(A)),
|
|
/* optional attributes */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fCAST2_8s, /* macro name */
|
|
((size8s_t)((size2s_t)(A))),
|
|
/* optional attributes */
|
|
)
|
|
DEF_MACRO(
|
|
fCAST2_8u, /* macro name */
|
|
((size8u_t)((size2u_t)(A))),
|
|
/* optional attributes */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fZE8_16, /* zero-extend 8 to 16 */
|
|
((size2s_t)((size1u_t)(A))),
|
|
/* optional attributes */
|
|
)
|
|
DEF_MACRO(
|
|
fSE8_16, /* sign-extend 8 to 16 */
|
|
((size2s_t)((size1s_t)(A))),
|
|
/* optional attributes */
|
|
)
|
|
|
|
|
|
DEF_MACRO(
|
|
fSE16_32, /* sign-extend 16 to 32 */
|
|
((size4s_t)((size2s_t)(A))), /* behavior */
|
|
/* optional attributes */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fZE16_32, /* zero-extend 16 to 32 */
|
|
((size4u_t)((size2u_t)(A))), /* behavior */
|
|
/* optional attributes */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fSE32_64,
|
|
( (size8s_t)((size4s_t)(A)) ), /* behavior */
|
|
/* optional attributes */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fZE32_64,
|
|
( (size8u_t)((size4u_t)(A)) ), /* behavior */
|
|
/* optional attributes */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fSE8_32, /* sign-extend 8 to 32 */
|
|
((size4s_t)((size1s_t)(A))),
|
|
/* optional attributes */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fZE8_32, /* zero-extend 8 to 32 */
|
|
((size4s_t)((size1u_t)(A))),
|
|
/* optional attributes */
|
|
)
|
|
|
|
/*************************************/
|
|
/* DSP arithmetic support */
|
|
/************************************/
|
|
DEF_MACRO(
|
|
fMPY8UU, /* multiply half integer */
|
|
(int)(fZE8_16(A)*fZE8_16(B)), /* behavior */
|
|
()
|
|
)
|
|
DEF_MACRO(
|
|
fMPY8US, /* multiply half integer */
|
|
(int)(fZE8_16(A)*fSE8_16(B)), /* behavior */
|
|
()
|
|
)
|
|
DEF_MACRO(
|
|
fMPY8SU, /* multiply half integer */
|
|
(int)(fSE8_16(A)*fZE8_16(B)), /* behavior */
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fMPY8SS, /* multiply half integer */
|
|
(int)((short)(A)*(short)(B)), /* behavior */
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fMPY16SS, /* multiply half integer */
|
|
fSE32_64(fSE16_32(A)*fSE16_32(B)), /* behavior */
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fMPY16UU, /* multiply unsigned half integer */
|
|
fZE32_64(fZE16_32(A)*fZE16_32(B)), /* behavior */
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fMPY16SU, /* multiply half integer */
|
|
fSE32_64(fSE16_32(A)*fZE16_32(B)), /* behavior */
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fMPY16US, /* multiply half integer */
|
|
fMPY16SU(B,A),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fMPY32SS, /* multiply half integer */
|
|
(fSE32_64(A)*fSE32_64(B)), /* behavior */
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fMPY32UU, /* multiply half integer */
|
|
(fZE32_64(A)*fZE32_64(B)), /* behavior */
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fMPY32SU, /* multiply half integer */
|
|
(fSE32_64(A)*fZE32_64(B)), /* behavior */
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fMPY3216SS, /* multiply mixed precision */
|
|
(fSE32_64(A)*fSXTN(16,64,B)), /* behavior */
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fMPY3216SU, /* multiply mixed precision */
|
|
(fSE32_64(A)*fZXTN(16,64,B)), /* behavior */
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fROUND, /* optional rounding */
|
|
(A+0x8000),
|
|
/* optional attributes */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fCLIP, /* optional rounding */
|
|
{ size4s_t maxv = (1<<U)-1;
|
|
size4s_t minv = -(1<<U);
|
|
DST = fMIN(maxv,fMAX(SRC,minv));
|
|
},
|
|
/* optional attributes */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fCRND, /* optional rounding */
|
|
((((A)&0x3)==0x3)?((A)+1):((A))),
|
|
/* optional attributes */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fRNDN, /* Rounding to a boundary */
|
|
((((N)==0)?(A):(((fSE32_64(A))+(1<<((N)-1)))))),
|
|
/* optional attributes */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fCRNDN, /* Rounding to a boundary */
|
|
(conv_round(A,N)),
|
|
/* optional attributes */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fADD128, /* Rounding to a boundary */
|
|
(add128(A, B)),
|
|
/* optional attributes */
|
|
)
|
|
DEF_MACRO(
|
|
fSUB128, /* Rounding to a boundary */
|
|
(sub128(A, B)),
|
|
/* optional attributes */
|
|
)
|
|
DEF_MACRO(
|
|
fSHIFTR128, /* Rounding to a boundary */
|
|
(shiftr128(A, B)),
|
|
/* optional attributes */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fSHIFTL128, /* Rounding to a boundary */
|
|
(shiftl128(A, B)),
|
|
/* optional attributes */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fAND128, /* Rounding to a boundary */
|
|
(and128(A, B)),
|
|
/* optional attributes */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fCAST8S_16S, /* Rounding to a boundary */
|
|
(cast8s_to_16s(A)),
|
|
/* optional attributes */
|
|
)
|
|
DEF_MACRO(
|
|
fCAST16S_8S, /* Rounding to a boundary */
|
|
(cast16s_to_8s(A)),
|
|
/* optional attributes */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fEA_RI, /* Calculate EA with Register + Immediate Offset */
|
|
do { EA=REG+IMM; fDOCHKPAGECROSS(REG,EA); } while (0),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fEA_RRs, /* Calculate EA with Register + Registers scaled Offset */
|
|
do { EA=REG+(REG2<<SCALE); fDOCHKPAGECROSS(REG,EA); } while (0),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fEA_IRs, /* Calculate EA with Immediate + Registers scaled Offset */
|
|
do { EA=IMM+(REG<<SCALE); fDOCHKPAGECROSS(IMM,EA); } while (0),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fEA_IMM, /* Calculate EA with Immediate */
|
|
EA=IMM,
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fEA_REG, /* Calculate EA with REGISTER */
|
|
EA=REG,
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fEA_BREVR, /* Calculate EA with bit reversed bottom of REGISTER */
|
|
EA=fbrev(REG),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fEA_GPI, /* Calculate EA with Global Poitner + Immediate */
|
|
do { EA=fREAD_GP()+IMM; fGP_DOCHKPAGECROSS(fREAD_GP(),EA); } while (0),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fPM_I, /* Post Modify Register by Immediate*/
|
|
do { REG = REG + IMM; } while (0),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fPM_M, /* Post Modify Register by M register */
|
|
do { REG = REG + MVAL; } while (0),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fPM_CIRI, /* Post Modify Register using Circular arithmetic by Immediate */
|
|
do { fcirc_add(REG,siV,MuV); } while (0),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fPM_CIRR, /* Post Modify Register using Circular arithmetic by register */
|
|
do { fcirc_add(REG,VAL,MuV); } while (0),
|
|
()
|
|
)
|
|
|
|
|
|
|
|
DEF_MACRO(
|
|
fSCALE, /* scale by N */
|
|
(((size8s_t)(A))<<N),
|
|
/* optional attributes */
|
|
)
|
|
DEF_MACRO(
|
|
fVSATW, /* saturating to 32-bits*/
|
|
fVSATN(32,((long long)A)),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fSATW, /* saturating to 32-bits*/
|
|
fSATN(32,((long long)A)),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fVSAT, /* saturating to 32-bits*/
|
|
fVSATN(32,(A)),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fSAT, /* saturating to 32-bits*/
|
|
fSATN(32,(A)),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fSAT_ORIG_SHL, /* Saturating to 32-bits, with original value, for shift left */
|
|
((((size4s_t)((fSAT(A)) ^ ((size4s_t)(ORIG_REG)))) < 0) ?
|
|
fSATVALN(32,((size4s_t)(ORIG_REG))) :
|
|
((((ORIG_REG) > 0) && ((A) == 0)) ?
|
|
fSATVALN(32,(ORIG_REG)) :
|
|
fSAT(A))),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fPASS,
|
|
A,
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fRND, /* saturating to 32-bits*/
|
|
(((A)+1)>>1),
|
|
)
|
|
|
|
|
|
DEF_MACRO(
|
|
fBIDIR_SHIFTL,
|
|
(((SHAMT) < 0) ? ((fCAST##REGSTYPE(SRC) >> ((-(SHAMT))-1)) >>1) : (fCAST##REGSTYPE(SRC) << (SHAMT))),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fBIDIR_ASHIFTL,
|
|
fBIDIR_SHIFTL(SRC,SHAMT,REGSTYPE##s),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fBIDIR_LSHIFTL,
|
|
fBIDIR_SHIFTL(SRC,SHAMT,REGSTYPE##u),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fBIDIR_ASHIFTL_SAT,
|
|
(((SHAMT) < 0) ? ((fCAST##REGSTYPE##s(SRC) >> ((-(SHAMT))-1)) >>1) : fSAT_ORIG_SHL(fCAST##REGSTYPE##s(SRC) << (SHAMT),(SRC))),
|
|
()
|
|
)
|
|
|
|
|
|
DEF_MACRO(
|
|
fBIDIR_SHIFTR,
|
|
(((SHAMT) < 0) ? ((fCAST##REGSTYPE(SRC) << ((-(SHAMT))-1)) << 1) : (fCAST##REGSTYPE(SRC) >> (SHAMT))),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fBIDIR_ASHIFTR,
|
|
fBIDIR_SHIFTR(SRC,SHAMT,REGSTYPE##s),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fBIDIR_LSHIFTR,
|
|
fBIDIR_SHIFTR(SRC,SHAMT,REGSTYPE##u),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fBIDIR_ASHIFTR_SAT,
|
|
(((SHAMT) < 0) ? fSAT_ORIG_SHL((fCAST##REGSTYPE##s(SRC) << ((-(SHAMT))-1)) << 1,(SRC)) : (fCAST##REGSTYPE##s(SRC) >> (SHAMT))),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fASHIFTR,
|
|
(fCAST##REGSTYPE##s(SRC) >> (SHAMT)),
|
|
/* */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fLSHIFTR,
|
|
(((SHAMT) >= 64)?0:(fCAST##REGSTYPE##u(SRC) >> (SHAMT))),
|
|
/* */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fROTL,
|
|
(((SHAMT)==0) ? (SRC) : ((fCAST##REGSTYPE##u(SRC) << (SHAMT)) | \
|
|
((fCAST##REGSTYPE##u(SRC) >> ((sizeof(SRC)*8)-(SHAMT)))))),
|
|
/* */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fROTR,
|
|
(((SHAMT)==0) ? (SRC) : ((fCAST##REGSTYPE##u(SRC) >> (SHAMT)) | \
|
|
((fCAST##REGSTYPE##u(SRC) << ((sizeof(SRC)*8)-(SHAMT)))))),
|
|
/* */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fASHIFTL,
|
|
(((SHAMT) >= 64)?0:(fCAST##REGSTYPE##s(SRC) << (SHAMT))),
|
|
/* */
|
|
)
|
|
|
|
/*************************************/
|
|
/* Floating-Point Support */
|
|
/************************************/
|
|
|
|
DEF_MACRO(
|
|
fFLOAT, /* name */
|
|
({ union { float f; size4u_t i; } _fipun; _fipun.i = (A); _fipun.f; }), /* behavior */
|
|
(A_FPOP)
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fUNFLOAT, /* multiply half integer */
|
|
({ union { float f; size4u_t i; } _fipun; _fipun.f = (A); isnan(_fipun.f) ? 0xFFFFFFFFU : _fipun.i; }), /* behavior */
|
|
(A_FPOP)
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fSFNANVAL,
|
|
0xffffffff,
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fSFINFVAL,
|
|
(((A) & 0x80000000) | 0x7f800000),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fSFONEVAL,
|
|
(((A) & 0x80000000) | fUNFLOAT(1.0)),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fCHECKSFNAN,
|
|
do {
|
|
if (isnan(fFLOAT(A))) {
|
|
if ((fGETBIT(22,A)) == 0) fRAISEFLAGS(FE_INVALID);
|
|
DST = fSFNANVAL();
|
|
}
|
|
} while (0),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fCHECKSFNAN3,
|
|
do {
|
|
fCHECKSFNAN(DST,A);
|
|
fCHECKSFNAN(DST,B);
|
|
fCHECKSFNAN(DST,C);
|
|
} while (0),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fSF_BIAS,
|
|
127,
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fSF_MANTBITS,
|
|
23,
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fSF_MUL_POW2,
|
|
(fUNFLOAT(fFLOAT(A) * fFLOAT((fSF_BIAS() + (B)) << fSF_MANTBITS()))),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fSF_GETEXP,
|
|
(((A) >> fSF_MANTBITS()) & 0xff),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fSF_MAXEXP,
|
|
(254),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fSF_RECIP_COMMON,
|
|
arch_sf_recip_common(&N,&D,&O,&A),
|
|
(A_FPOP)
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fSF_INVSQRT_COMMON,
|
|
arch_sf_invsqrt_common(&N,&O,&A),
|
|
(A_FPOP)
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fFMAFX,
|
|
internal_fmafx(A,B,C,fSXTN(8,64,ADJ)),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fFMAF,
|
|
internal_fmafx(A,B,C,0),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fSFMPY,
|
|
internal_mpyf(A,B),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fMAKESF,
|
|
((((SIGN) & 1) << 31) | (((EXP) & 0xff) << fSF_MANTBITS()) |
|
|
((MANT) & ((1<<fSF_MANTBITS())-1))),
|
|
()
|
|
)
|
|
|
|
|
|
DEF_MACRO(
|
|
fDOUBLE, /* multiply half integer */
|
|
({ union { double f; size8u_t i; } _fipun; _fipun.i = (A); _fipun.f; }), /* behavior */
|
|
(A_FPOP)
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fUNDOUBLE, /* multiply half integer */
|
|
({ union { double f; size8u_t i; } _fipun; _fipun.f = (A); isnan(_fipun.f) ? 0xFFFFFFFFFFFFFFFFULL : _fipun.i; }), /* behavior */
|
|
(A_FPOP)
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fDFNANVAL,
|
|
0xffffffffffffffffULL,
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fDF_ISNORMAL,
|
|
(fpclassify(fDOUBLE(X)) == FP_NORMAL),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fDF_ISDENORM,
|
|
(fpclassify(fDOUBLE(X)) == FP_SUBNORMAL),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fDF_ISBIG,
|
|
(fDF_GETEXP(X) >= 512),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fDF_MANTBITS,
|
|
52,
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fDF_GETEXP,
|
|
(((A) >> fDF_MANTBITS()) & 0x7ff),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fFMA,
|
|
internal_fma(A,B,C),
|
|
/* nothing */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fDF_MPY_HH,
|
|
internal_mpyhh(A,B,ACC),
|
|
/* nothing */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fFPOP_START,
|
|
arch_fpop_start(thread),
|
|
/* nothing */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fFPOP_END,
|
|
arch_fpop_end(thread),
|
|
/* nothing */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fFPSETROUND_NEAREST,
|
|
fesetround(FE_TONEAREST),
|
|
/* nothing */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fFPSETROUND_CHOP,
|
|
fesetround(FE_TOWARDZERO),
|
|
/* nothing */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fFPCANCELFLAGS,
|
|
feclearexcept(FE_ALL_EXCEPT),
|
|
/* nothing */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fISINFPROD,
|
|
((isinf(A) && isinf(B)) ||
|
|
(isinf(A) && isfinite(B) && ((B) != 0.0)) ||
|
|
(isinf(B) && isfinite(A) && ((A) != 0.0))),
|
|
/* nothing */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fISZEROPROD,
|
|
((((A) == 0.0) && isfinite(B)) || (((B) == 0.0) && isfinite(A))),
|
|
/* nothing */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fRAISEFLAGS,
|
|
arch_raise_fpflag(A),
|
|
/* NOTHING */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fDF_MAX,
|
|
(((A)==(B))
|
|
? fDOUBLE(fUNDOUBLE(A) & fUNDOUBLE(B))
|
|
: fmax(A,B)),
|
|
(A_FPOP)
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fDF_MIN,
|
|
(((A)==(B))
|
|
? fDOUBLE(fUNDOUBLE(A) | fUNDOUBLE(B))
|
|
: fmin(A,B)),
|
|
(A_FPOP)
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fSF_MAX,
|
|
(((A)==(B))
|
|
? fFLOAT(fUNFLOAT(A) & fUNFLOAT(B))
|
|
: fmaxf(A,B)),
|
|
(A_FPOP)
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fSF_MIN,
|
|
(((A)==(B))
|
|
? fFLOAT(fUNFLOAT(A) | fUNFLOAT(B))
|
|
: fminf(A,B)),
|
|
(A_FPOP)
|
|
)
|
|
|
|
/*************************************/
|
|
/* Load/Store support */
|
|
/*************************************/
|
|
|
|
DEF_MACRO(fLOAD,
|
|
{ DST = (size##SIZE##SIGN##_t)MEM_LOAD##SIZE(thread,EA,insn); },
|
|
(A_LOAD,A_MEMLIKE)
|
|
)
|
|
|
|
DEF_MACRO(fMEMOP,
|
|
{ memop##SIZE##_##FNTYPE(thread,EA,VALUE); },
|
|
(A_LOAD,A_STORE,A_MEMLIKE)
|
|
)
|
|
|
|
DEF_MACRO(fGET_FRAMEKEY,
|
|
READ_RREG(REG_FRAMEKEY),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fFRAME_SCRAMBLE,
|
|
((VAL) ^ (fCAST8u(fGET_FRAMEKEY()) << 32)),
|
|
/* ATTRIBS */
|
|
)
|
|
|
|
DEF_MACRO(fFRAME_UNSCRAMBLE,
|
|
fFRAME_SCRAMBLE(VAL),
|
|
/* ATTRIBS */
|
|
)
|
|
|
|
DEF_MACRO(fFRAMECHECK,
|
|
sys_check_framelimit(thread,ADDR,EA),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fLOAD_LOCKED,
|
|
{ DST = (size##SIZE##SIGN##_t)mem_load_locked(thread,EA,SIZE,insn); },
|
|
(A_LOAD,A_MEMLIKE)
|
|
)
|
|
|
|
DEF_MACRO(fSTORE,
|
|
{ MEM_STORE##SIZE(thread,EA,SRC,insn); },
|
|
(A_STORE,A_MEMLIKE)
|
|
)
|
|
|
|
|
|
DEF_MACRO(fSTORE_LOCKED,
|
|
{ PRED = (mem_store_conditional(thread,EA,SRC,SIZE,insn) ? 0xff : 0); },
|
|
(A_STORE,A_MEMLIKE)
|
|
)
|
|
|
|
/*************************************/
|
|
/* Functions to help with bytes */
|
|
/*************************************/
|
|
|
|
DEF_MACRO(fGETBYTE,
|
|
((size1s_t)((SRC>>((N)*8))&0xff)),
|
|
/* nothing */
|
|
)
|
|
|
|
DEF_MACRO(fGETUBYTE,
|
|
((size1u_t)((SRC>>((N)*8))&0xff)),
|
|
/* nothing */
|
|
)
|
|
|
|
DEF_MACRO(fSETBYTE,
|
|
{
|
|
DST = (DST & ~(0x0ffLL<<((N)*8))) | (((size8u_t)((VAL) & 0x0ffLL)) << ((N)*8));
|
|
},
|
|
/* nothing */
|
|
)
|
|
|
|
DEF_MACRO(fGETHALF,
|
|
((size2s_t)((SRC>>((N)*16))&0xffff)),
|
|
/* nothing */
|
|
)
|
|
|
|
DEF_MACRO(fGETUHALF,
|
|
((size2u_t)((SRC>>((N)*16))&0xffff)),
|
|
/* nothing */
|
|
)
|
|
|
|
DEF_MACRO(fSETHALF,
|
|
{
|
|
DST = (DST & ~(0x0ffffLL<<((N)*16))) | (((size8u_t)((VAL) & 0x0ffff)) << ((N)*16));
|
|
},
|
|
/* nothing */
|
|
)
|
|
|
|
|
|
|
|
DEF_MACRO(fGETWORD,
|
|
((size8s_t)((size4s_t)((SRC>>((N)*32))&0x0ffffffffLL))),
|
|
/* nothing */
|
|
)
|
|
|
|
DEF_MACRO(fGETUWORD,
|
|
((size8u_t)((size4u_t)((SRC>>((N)*32))&0x0ffffffffLL))),
|
|
/* nothing */
|
|
)
|
|
|
|
DEF_MACRO(fSETWORD,
|
|
{
|
|
DST = (DST & ~(0x0ffffffffLL<<((N)*32))) | (((VAL) & 0x0ffffffffLL) << ((N)*32));
|
|
},
|
|
/* nothing */
|
|
)
|
|
|
|
DEF_MACRO(fSETBIT,
|
|
{
|
|
DST = (DST & ~(1ULL<<(N))) | (((size8u_t)(VAL))<<(N));
|
|
},
|
|
/* nothing */
|
|
)
|
|
|
|
DEF_MACRO(fGETBIT,
|
|
(((SRC)>>N)&1),
|
|
/* nothing */
|
|
)
|
|
|
|
|
|
DEF_MACRO(fSETBITS,
|
|
do {
|
|
int j;
|
|
for (j=LO;j<=HI;j++) {
|
|
fSETBIT(j,DST,VAL);
|
|
}
|
|
} while (0),
|
|
/* nothing */
|
|
)
|
|
|
|
/*************************************/
|
|
/* Used for parity, etc........ */
|
|
/*************************************/
|
|
DEF_MACRO(fCOUNTONES_2,
|
|
count_ones_2(VAL),
|
|
/* nothing */
|
|
)
|
|
|
|
DEF_MACRO(fCOUNTONES_4,
|
|
count_ones_4(VAL),
|
|
/* nothing */
|
|
)
|
|
|
|
DEF_MACRO(fCOUNTONES_8,
|
|
count_ones_8(VAL),
|
|
/* nothing */
|
|
)
|
|
|
|
DEF_MACRO(fBREV_8,
|
|
reverse_bits_8(VAL),
|
|
/* nothing */
|
|
)
|
|
|
|
DEF_MACRO(fBREV_4,
|
|
reverse_bits_4(VAL),
|
|
/* nothing */
|
|
)
|
|
|
|
DEF_MACRO(fCL1_8,
|
|
count_leading_ones_8(VAL),
|
|
/* nothing */
|
|
)
|
|
|
|
DEF_MACRO(fCL1_4,
|
|
count_leading_ones_4(VAL),
|
|
/* nothing */
|
|
)
|
|
|
|
DEF_MACRO(fCL1_2,
|
|
count_leading_ones_2(VAL),
|
|
/* nothing */
|
|
)
|
|
|
|
DEF_MACRO(fINTERLEAVE,
|
|
interleave(ODD,EVEN),
|
|
/* nothing */
|
|
)
|
|
|
|
DEF_MACRO(fDEINTERLEAVE,
|
|
deinterleave(MIXED),
|
|
/* nothing */
|
|
)
|
|
|
|
DEF_MACRO(fHIDE,
|
|
A,
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fCONSTLL,
|
|
A##LL,
|
|
)
|
|
|
|
/* Do the things in the parens, but don't print the parens. */
|
|
DEF_MACRO(fECHO,
|
|
(A),
|
|
/* nothing */
|
|
)
|
|
|
|
|
|
/********************************************/
|
|
/* OS interface and stop/wait */
|
|
/********************************************/
|
|
|
|
DEF_MACRO(fPAUSE,
|
|
{sys_pause(thread, insn->slot, IMM);},
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fTRAP,
|
|
warn("Trap NPC=%x ",fREAD_NPC());
|
|
warn("Trap exception, PCYCLE=%lld TYPE=%d NPC=%x IMM=0x%x",thread->processor_ptr->pstats[pcycles],TRAPTYPE,fREAD_NPC(),IMM);
|
|
register_trap_exception(thread,fREAD_NPC(),TRAPTYPE,IMM);,
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fALIGN_REG_FIELD_VALUE,
|
|
((VAL)<<reg_field_info[FIELD].offset),
|
|
/* */
|
|
)
|
|
|
|
DEF_MACRO(fGET_REG_FIELD_MASK,
|
|
(((1<<reg_field_info[FIELD].width)-1)<<reg_field_info[FIELD].offset),
|
|
/* */
|
|
)
|
|
|
|
DEF_MACRO(fREAD_REG_FIELD,
|
|
fEXTRACTU_BITS(thread->Regs[REG_##REG],
|
|
reg_field_info[FIELD].width,
|
|
reg_field_info[FIELD].offset),
|
|
/* ATTRIBS */
|
|
)
|
|
|
|
DEF_MACRO(fGET_FIELD,
|
|
fEXTRACTU_BITS(VAL,
|
|
reg_field_info[FIELD].width,
|
|
reg_field_info[FIELD].offset),
|
|
/* ATTRIBS */
|
|
)
|
|
|
|
DEF_MACRO(fSET_FIELD,
|
|
fINSERT_BITS(VAL,
|
|
reg_field_info[FIELD].width,
|
|
reg_field_info[FIELD].offset,
|
|
(NEWVAL)),
|
|
/* ATTRIBS */
|
|
)
|
|
|
|
/********************************************/
|
|
/* Cache Management */
|
|
/********************************************/
|
|
|
|
DEF_MACRO(fBARRIER,
|
|
{
|
|
sys_barrier(thread, insn->slot);
|
|
},
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fSYNCH,
|
|
{
|
|
sys_sync(thread, insn->slot);
|
|
},
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fISYNC,
|
|
{
|
|
sys_isync(thread, insn->slot);
|
|
},
|
|
()
|
|
)
|
|
|
|
|
|
DEF_MACRO(fDCFETCH,
|
|
sys_dcfetch(thread, (REG), insn->slot),
|
|
(A_MEMLIKE)
|
|
)
|
|
|
|
DEF_MACRO(fICINVA,
|
|
{
|
|
arch_internal_flush(thread->processor_ptr, 0, 0xffffffff);
|
|
sys_icinva(thread, (REG),insn->slot);
|
|
},
|
|
(A_ICINVA)
|
|
)
|
|
|
|
DEF_MACRO(fL2FETCH,
|
|
sys_l2fetch(thread, ADDR,HEIGHT,WIDTH,STRIDE,FLAGS, insn->slot),
|
|
(A_MEMLIKE,A_L2FETCH)
|
|
)
|
|
|
|
DEF_MACRO(fDCCLEANA,
|
|
sys_dccleana(thread, (REG)),
|
|
(A_MEMLIKE)
|
|
)
|
|
|
|
DEF_MACRO(fDCCLEANINVA,
|
|
sys_dccleaninva(thread, (REG), insn->slot),
|
|
(A_MEMLIKE,A_DCCLEANINVA)
|
|
)
|
|
|
|
DEF_MACRO(fDCZEROA,
|
|
sys_dczeroa(thread, (REG)),
|
|
(A_MEMLIKE)
|
|
)
|
|
|
|
DEF_MACRO(fCHECKFORPRIV,
|
|
{sys_check_privs(thread); if (EXCEPTION_DETECTED) return; },
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fCHECKFORGUEST,
|
|
{sys_check_guest(thread); if (EXCEPTION_DETECTED) return; },
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fBRANCH_SPECULATE_STALL,
|
|
{
|
|
sys_speculate_branch_stall(thread, insn->slot, JUMP_COND(JUMP_PRED_SET),
|
|
SPEC_DIR,
|
|
DOTNEWVAL,
|
|
HINTBITNUM,
|
|
STRBITNUM,
|
|
0,
|
|
thread->last_pkt->pkt_has_dual_jump,
|
|
insn->is_2nd_jump,
|
|
(thread->fetch_access.vaddr + insn->encoding_offset*4));
|
|
},
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(IV1DEAD,
|
|
,
|
|
()
|
|
)
|