new file mode 100755
@@ -0,0 +1,3970 @@
+/*
+ * Copyright(c) 2019-2020 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 */
+ (X), /* PARAMS */
+ "X", /* sdescr */
+ "X", /* ldescr */
+ __builtin_expect((X),1), /* BEH */
+ () /* attribs */
+)
+
+DEF_MACRO(
+ UNLIKELY, /* NAME */
+ (X), /* PARAMS */
+ "X", /* sdescr */
+ "X", /* ldescr */
+ __builtin_expect((X),0), /* BEH */
+ () /* attribs */
+)
+
+DEF_MACRO(
+ CANCEL, /* macro name */
+ , /* parameters */
+ "NOP", /* short description */
+ "NOP this instruction", /* long description */
+ {if (thread->last_pkt) thread->last_pkt->slot_cancelled |= (1<<insn->slot); return;} , /* behavior */
+ (A_CONDEXEC)
+)
+
+DEF_MACRO(
+ STORE_ZERO, /* macro name */
+ , /* parameters */
+ "Zero Store", /* short description */
+ "NOP this instruction", /* long description */
+ {if (thread->last_pkt) thread->last_pkt->slot_zero_byte_store |= (1<<insn->slot); } , /* behavior */
+ (A_CONDEXEC)
+)
+
+DEF_MACRO(
+ LOAD_CANCEL, /* macro name */
+ (EA), /* parameters */
+ "NOP", /* short description */
+ "NOP this instruction", /* long description */
+ {mem_general_load_cancelled(thread,EA,insn);CANCEL;} , /* behavior */
+ (A_CONDEXEC)
+)
+
+DEF_MACRO(
+ STORE_CANCEL, /* macro name */
+ (EA), /* parameters */
+ "NOP", /* short description */
+ "NOP this instruction", /* long description */
+ {mem_general_store_cancelled(thread,EA,insn);CANCEL;} , /* behavior */
+ (A_CONDEXEC)
+)
+
+DEF_MACRO(
+ IS_CANCELLED, /* macro name */
+ (SLOT), /* parameters */
+ "", /* short description */
+ "", /* long description */
+ ((thread->last_pkt->slot_cancelled >> SLOT)&1) , /* behavior */
+ /* attrib */
+)
+
+DEF_MACRO(
+ fMAX, /* macro name */
+ (A,B), /* parameters */
+ "max(A,B)", /* short description */
+ "the larger of A and B", /* long description */
+ (((A) > (B)) ? (A) : (B)), /* behavior */
+ /* optional attributes */
+)
+
+DEF_MACRO(
+ fMIN, /* macro name */
+ (A,B), /* parameters */
+ "min(A,B)", /* short description */
+ "the smaller of A and B", /* long description */
+ (((A) < (B)) ? (A) : (B)), /* behavior */
+ /* optional attributes */
+)
+
+DEF_MACRO(
+ fABS, /* macro name */
+ (A), /* parameters */
+ "ABS(A)", /* short description */
+ "if A is less than zero then A=-A", /* long description */
+ (((A)<0)?(-(A)):(A)), /* behavior */
+ /* optional attributes */
+)
+
+
+/* Bit insert */
+DEF_MACRO(
+ fINSERT_BITS,(REG,WIDTH,OFFSET,INVAL),
+ "REG[(WIDTH-1+OFFSET):OFFSET]=INVAL",
+ "REG[(WIDTH-1+OFFSET):OFFSET]=INVAL",
+ {
+ REG = ((REG) & ~(((fCONSTLL(1)<<(WIDTH))-1)<<(OFFSET))) | (((INVAL) & ((fCONSTLL(1)<<(WIDTH))-1)) << (OFFSET));
+ },
+ /* attribs */
+)
+
+/* Bit extract */
+DEF_MACRO(
+ fEXTRACTU_BITS,(INREG,WIDTH,OFFSET),
+ "INREG[(WIDTH+OFFSET-1):OFFSET]",
+ "INREG[(WIDTH+OFFSET-1):OFFSET]",
+ (fZXTN(WIDTH,32,(INREG >> OFFSET))),
+ /* attribs */
+)
+
+DEF_MACRO(
+ fEXTRACTU_BIDIR,(INREG,WIDTH,OFFSET),
+ "INREG[(WIDTH+OFFSET-1):OFFSET]",
+ "INREG[(WIDTH+OFFSET-1):OFFSET]",
+ (fZXTN(WIDTH,32,fBIDIR_LSHIFTR((INREG),(OFFSET),4_8))),
+ /* attribs */
+)
+
+DEF_MACRO(
+ fEXTRACTU_RANGE,(INREG,HIBIT,LOWBIT),
+ "INREG[HIBIT:LOWBIT]",
+ "INREG[HIBIT:LOWBIT]",
+ (fZXTN((HIBIT-LOWBIT+1),32,(INREG >> LOWBIT))),
+ /* attribs */
+)
+
+
+DEF_MACRO(
+ fINSERT_RANGE,(INREG,HIBIT,LOWBIT,INVAL),
+ "INREG[HIBIT:LOWBIT]=INVAL",
+ "INREG[HIBIT:LOWBIT]=INVAL",
+ {
+ 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),
+ "VAL ? 0xff : 0x00",
+ "VAL ? 0xff : 0x00",
+ ( (VAL) ? 0xff : 0x00),
+ /* attribs */
+)
+
+DEF_MACRO(
+ fLSBOLD,(VAL),
+ "VAL[0]",
+ "Least significant bit of VAL",
+ ((VAL) & 1),
+ (A_DOTOLD)
+)
+
+DEF_MACRO(
+ fLSBNEW,(PNUM),
+ "PNUM.new[0]",
+ "Least significant bit of new PNUM",
+ predlog_read(thread,PNUM),
+ (A_DOTNEW)
+)
+
+DEF_MACRO(
+ fLSBNEW0,,
+ "P0.new[0]",
+ "Least significant bit of new P0",
+ predlog_read(thread,0),
+ (A_DOTNEW,A_IMPLICIT_READS_P0)
+)
+
+DEF_MACRO(
+ fLSBNEW1,,
+ "P1.new[0]",
+ "Least significant bit of new P1",
+ predlog_read(thread,1),
+ (A_DOTNEW,A_IMPLICIT_READS_P1)
+)
+
+DEF_MACRO(
+ fLSBOLDNOT,(VAL),
+ "!VAL[0]",
+ "!Least significant bit of VAL",
+ (!fLSBOLD(VAL)),
+ (A_DOTOLD,A_INVPRED)
+)
+
+DEF_MACRO(
+ fLSBNEWNOT,(PNUM),
+ "!PNUM.new[0]",
+ "!Least significant bit of new PNUM",
+ (!fLSBNEW(PNUM)),
+ (A_DOTNEW,A_INVPRED)
+)
+
+DEF_MACRO(
+ fLSBNEW0NOT,,
+ "!P0.new[0]",
+ "!Least significant bit of new P0",
+ (!fLSBNEW0),
+ (A_DOTNEW,A_INVPRED,A_IMPLICIT_READS_P0)
+)
+
+DEF_MACRO(
+ fLSBNEW1NOT,,
+ "P1.new[0]",
+ "Least significant bit of new P1",
+ (!fLSBNEW1),
+ (A_DOTNEW,A_INVPRED,A_IMPLICIT_READS_P1)
+)
+
+DEF_MACRO(
+ fNEWREG,(RNUM),
+ "RNUM.new",
+ "Register value produced in this packet",
+ ({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,(RNUM),
+ "RNUM.new",
+ "Register value produced in this packet for store",
+ ({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(
+ fMEMZNEW,(RNUM),
+ "RNUM.new == 0",
+ "Newly loaded value is zero",
+ (RNUM == 0),
+ /* attribs */
+)
+
+DEF_MACRO(
+ fMEMNZNEW,(RNUM),
+ "RNUM.new != 0",
+ "Newly loaded value is non-zero",
+ (RNUM != 0),
+ /* attribs */
+)
+
+DEF_MACRO(
+ fVSATUVALN,(N,VAL),
+ "N-Bit Unsigned Saturation Value for sign of VAL",
+ "N-Bit Unsigned Saturation Value for sign of VAL",
+ ({ ((VAL) < 0) ? 0 : ((1LL<<(N))-1);}),
+ (A_USATURATE)
+)
+
+DEF_MACRO(
+ fSATUVALN,(N,VAL),
+ "N-Bit Unsigned Saturation Value for sign of VAL",
+ "N-Bit Unsigned Saturation Value for sign of VAL",
+ ({fSET_OVERFLOW(); ((VAL) < 0) ? 0 : ((1LL<<(N))-1);}),
+ (A_USATURATE)
+)
+
+DEF_MACRO(
+ fSATVALN,(N,VAL),
+ "N-Bit Saturation Value for sign of VAL",
+ "N-Bit Saturation Value for sign of VAL",
+ ({fSET_OVERFLOW(); ((VAL) < 0) ? (-(1LL<<((N)-1))) : ((1LL<<((N)-1))-1);}),
+ (A_SATURATE)
+)
+
+DEF_MACRO(
+ fVSATVALN,(N,VAL),
+ "N-Bit Saturation Value for sign of VAL",
+ "N-Bit Saturation Value for sign of VAL",
+ ({((VAL) < 0) ? (-(1LL<<((N)-1))) : ((1LL<<((N)-1))-1);}),
+ (A_SATURATE)
+)
+
+DEF_MACRO(
+ fZXTN, /* macro name */
+ (N,M,VAL),
+ "zxt_{N->M}(VAL)", /* short descr */
+ "Zero extend N bits from VAL",
+ ((VAL) & ((1LL<<(N))-1)),
+ /* attribs */
+)
+
+DEF_MACRO(
+ fSXTN, /* macro name */
+ (N,M,VAL),
+ "sxt_{N->M}(VAL)", /* short descr */
+ "Sign extend N bits from VAL",
+ ((fZXTN(N,M,VAL) ^ (1LL<<((N)-1))) - (1LL<<((N)-1))),
+ /* attribs */
+)
+
+DEF_MACRO(
+ fSATN,
+ (N,VAL),
+ "sat_##N(VAL)", /* short descr */
+ "Saturate VAL to N bits",
+ ((fSXTN(N,64,VAL) == (VAL)) ? (VAL) : fSATVALN(N,VAL)),
+ (A_SATURATE)
+)
+DEF_MACRO(
+ fVSATN,
+ (N,VAL),
+ "sat_##N(VAL)", /* short descr */
+ "Saturate VAL to N bits",
+ ((fSXTN(N,64,VAL) == (VAL)) ? (VAL) : fVSATVALN(N,VAL)),
+ (A_SATURATE)
+)
+
+DEF_MACRO(
+ fADDSAT64,
+ (DST,A,B),
+ "DST=sat64(A+B)", /* short descr */
+ "DST=sat64(A+B)",
+ {
+ 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;
+ }
+ },
+ (A_SATURATE)
+)
+
+DEF_MACRO(
+ fVSATUN,
+ (N,VAL),
+ "usat_##N(VAL)", /* short descr */
+ "Saturate VAL to N bits",
+ ((fZXTN(N,64,VAL) == (VAL)) ? (VAL) : fVSATUVALN(N,VAL)),
+ (A_USATURATE)
+)
+
+DEF_MACRO(
+ fSATUN,
+ (N,VAL),
+ "usat_##N(VAL)", /* short descr */
+ "Saturate VAL to N bits",
+ ((fZXTN(N,64,VAL) == (VAL)) ? (VAL) : fSATUVALN(N,VAL)),
+ (A_USATURATE)
+)
+
+DEF_MACRO(
+ fSATH,
+ (VAL),
+ "sat_16(VAL)", /* short descr */
+ "Saturate VAL to a signed half",
+ (fSATN(16,VAL)),
+ (A_SATURATE)
+)
+
+
+DEF_MACRO(
+ fSATUH,
+ (VAL),
+ "usat_16(VAL)", /* short descr */
+ "Saturate VAL to an unsigned half",
+ (fSATUN(16,VAL)),
+ (A_USATURATE)
+)
+
+DEF_MACRO(
+ fVSATH,
+ (VAL),
+ "sat_16(VAL)", /* short descr */
+ "Saturate VAL to a signed half",
+ (fVSATN(16,VAL)),
+ (A_SATURATE)
+)
+
+DEF_MACRO(
+ fVSATUH,
+ (VAL),
+ "usat_16(VAL)", /* short descr */
+ "Saturate VAL to a signed half",
+ (fVSATUN(16,VAL)),
+ (A_USATURATE)
+)
+
+
+DEF_MACRO(
+ fSATUB,
+ (VAL),
+ "usat_8(VAL)", /* short descr */
+ "Saturate VAL to an unsigned byte",
+ (fSATUN(8,VAL)),
+ (A_USATURATE)
+)
+DEF_MACRO(
+ fSATB,
+ (VAL),
+ "sat_8(VAL)", /* short descr */
+ "Saturate VAL to a signed byte",
+ (fSATN(8,VAL)),
+ (A_SATURATE)
+)
+
+
+DEF_MACRO(
+ fVSATUB,
+ (VAL),
+ "usat_8(VAL)", /* short descr */
+ "Saturate VAL to a unsigned byte",
+ (fVSATUN(8,VAL)),
+ (A_USATURATE)
+)
+DEF_MACRO(
+ fVSATB,
+ (VAL),
+ "sat_8(VAL)", /* short descr */
+ "Saturate VAL to a signed byte",
+ (fVSATN(8,VAL)),
+ (A_SATURATE)
+)
+
+
+
+
+/*************************************/
+/* immediate extension */
+/*************************************/
+
+DEF_MACRO(
+ fIMMEXT,
+ (IMM),
+ "apply_extension(IMM)",
+ "Apply extension to IMM",
+ (IMM = IMM /* (insn->extension_valid?(fGET_EXTENSION | fZXTN(6,32,(IMM))):(IMM)) */ ),
+ (A_EXTENDABLE)
+)
+
+DEF_MACRO(
+ fMUST_IMMEXT,
+ (IMM),
+ "apply_extension(IMM)",
+ "Apply extension to IMM",
+ fIMMEXT(IMM),
+ (A_EXTENDABLE,A_MUST_EXTEND)
+)
+
+DEF_MACRO(
+ fPCALIGN,
+ (IMM),
+ "IMM=IMM & ~PCALIGN_MASK",
+ "",
+ IMM=(IMM & ~PCALIGN_MASK),
+ (A_EXTENDABLE)
+)
+
+DEF_MACRO(
+ fGET_EXTENSION,
+ ,
+ "extension",
+ "extension",
+ insn->extension,
+ /* attrs */
+)
+
+/*************************************/
+/* Read and Write Implicit Regs */
+/*************************************/
+
+DEF_MACRO(
+ fREAD_IREG, /* read link register */
+ (VAL), /* parameters */
+ "I", /* short description */
+ "I", /* long description */
+ (fSXTN(11,64,(((VAL) & 0xf0000000)>>21) | ((VAL>>17)&0x7f) )), /* behavior */
+ ()
+)
+
+
+DEF_MACRO(
+ fREAD_R0, /* read r0 */
+ (), /* parameters */
+ "R0", /* short description */
+ "R0", /* long description */
+ (READ_RREG(0)), /* behavior */
+ (A_IMPLICIT_READS_R00)
+)
+
+DEF_MACRO(
+ fREAD_LR, /* read link register */
+ (), /* parameters */
+ "LR", /* short description */
+ "LR", /* long description */
+ (READ_RREG(REG_LR)), /* behavior */
+ (A_IMPLICIT_READS_LR)
+)
+
+DEF_MACRO(
+ fREAD_SSR, /* read link register */
+ (), /* parameters */
+ "SSR", /* short description */
+ "SSR", /* long description */
+ (READ_RREG(REG_SSR)), /* behavior */
+ ()
+)
+
+DEF_MACRO(
+ fWRITE_R0, /* write r0 */
+ (A), /* parameters */
+ "R0=A", /* short description */
+ "R0=A", /* long description */
+ WRITE_RREG(0,A), /* behavior */
+ (A_IMPLICIT_WRITES_R00)
+)
+
+DEF_MACRO(
+ fWRITE_LR, /* write lr */
+ (A), /* parameters */
+ "LR=A", /* short description */
+ "LR=A", /* long description */
+ WRITE_RREG(REG_LR,A), /* behavior */
+ (A_IMPLICIT_WRITES_LR)
+)
+
+DEF_MACRO(
+ fWRITE_FP, /* write sp */
+ (A), /* parameters */
+ "FP=A", /* short description */
+ "FP=A", /* long description */
+ WRITE_RREG(REG_FP,A), /* behavior */
+ (A_IMPLICIT_WRITES_FP)
+)
+
+DEF_MACRO(
+ fWRITE_SP, /* write sp */
+ (A), /* parameters */
+ "SP=A", /* short description */
+ "SP=A", /* long description */
+ WRITE_RREG(REG_SP,A), /* behavior */
+ (A_IMPLICIT_WRITES_SP)
+)
+
+DEF_MACRO(
+ fWRITE_GOSP, /* write gosp */
+ (A), /* parameters */
+ "GOSP=A", /* short description */
+ "GOSP=A", /* long description */
+ WRITE_RREG(REG_GOSP,A), /* behavior */
+ (A_IMPLICIT_WRITES_GOSP)
+)
+
+DEF_MACRO(
+ fWRITE_GP, /* write gp */
+ (A), /* parameters */
+ "GP=A", /* short description */
+ "GP=A", /* long description */
+ WRITE_RREG(REG_GP,A), /* behavior */
+ (A_IMPLICIT_WRITES_GP)
+)
+
+DEF_MACRO(
+ fREAD_SP, /* read stack pointer */
+ (), /* parameters */
+ "SP", /* short description */
+ "SP", /* long description */
+ (READ_RREG(REG_SP)), /* behavior */
+ (A_IMPLICIT_READS_SP)
+)
+
+DEF_MACRO(
+ fREAD_GOSP, /* read guest other stack pointer */
+ (), /* parameters */
+ "GOSP", /* short description */
+ "GOSP", /* long description */
+ (READ_RREG(REG_GOSP)), /* behavior */
+ (A_IMPLICIT_READS_GOSP)
+)
+
+DEF_MACRO(
+ fREAD_GELR, /* read guest other stack pointer */
+ (), /* parameters */
+ "GELR", /* short description */
+ "GELR", /* long description */
+ (READ_RREG(REG_GELR)), /* behavior */
+ (A_IMPLICIT_READS_GELR)
+)
+
+DEF_MACRO(
+ fREAD_GEVB, /* read guest other stack pointer */
+ (), /* parameters */
+ "GEVB", /* short description */
+ "GEVB", /* long description */
+ (READ_RREG(REG_GEVB)), /* behavior */
+ (A_IMPLICIT_READS_GEVB)
+)
+
+DEF_MACRO(
+ fREAD_CSREG, /* read stack pointer */
+ (N), /* parameters */
+ "CS N", /* short description */
+ "CS N", /* long description */
+ (READ_RREG(REG_CSA+N)), /* behavior */
+ (A_IMPLICIT_READS_CS)
+)
+
+DEF_MACRO(
+ fREAD_LC0, /* read loop count */
+ , /* parameters */
+ "LC0", /* short description */
+ "LC0", /* long description */
+ (READ_RREG(REG_LC0)), /* behavior */
+ (A_IMPLICIT_READS_LC0)
+)
+
+DEF_MACRO(
+ fREAD_LC1, /* read loop count */
+ , /* parameters */
+ "LC1", /* short description */
+ "LC1", /* long description */
+ (READ_RREG(REG_LC1)), /* behavior */
+ (A_IMPLICIT_READS_LC1)
+)
+
+DEF_MACRO(
+ fREAD_SA0, /* read start addr */
+ , /* parameters */
+ "SA0", /* short description */
+ "SA0", /* long description */
+ (READ_RREG(REG_SA0)), /* behavior */
+ (A_IMPLICIT_READS_SA0)
+)
+
+DEF_MACRO(
+ fREAD_SA1, /* read start addr */
+ , /* parameters */
+ "SA1", /* short description */
+ "SA1", /* long description */
+ (READ_RREG(REG_SA1)), /* behavior */
+ (A_IMPLICIT_READS_SA1)
+)
+
+
+DEF_MACRO(
+ fREAD_FP, /* read stack pointer */
+ (), /* parameters */
+ "FP", /* short description */
+ "FP", /* long description */
+ (READ_RREG(REG_FP)), /* behavior */
+ (A_IMPLICIT_READS_FP)
+)
+
+DEF_MACRO(
+ fREAD_GP, /* read global pointer */
+ (), /* parameters */
+ "(Constant_extended ? (0) : GP)", /* short description */
+ "(Constant_extended ? (0) : GP)", /* long description */
+ (insn->extension_valid ? 0 : READ_RREG(REG_GP)), /* behavior */
+ (A_IMPLICIT_READS_GP)
+)
+
+DEF_MACRO(
+ fREAD_PC, /* read PC */
+ (), /* parameters */
+ "PC", /* short description */
+ "PC", /* long description */
+ (READ_RREG(REG_PC)), /* behavior */
+ (A_IMPLICIT_READS_PC)
+)
+
+DEF_MACRO(
+ fREAD_NPC, /* read PC */
+ (), /* parameters */
+ "NPC", /* short description */
+ "NPC", /* long description */
+ (thread->next_PC & (0xfffffffe)), /* behavior */
+ ()
+)
+
+DEF_MACRO(
+ fREAD_P0, /* read Predicate 0 */
+ (), /* parameters */
+ "P0", /* short description */
+ "P0", /* long description */
+ (READ_PREG(0)), /* behavior */
+ (A_IMPLICIT_READS_P0)
+)
+
+DEF_MACRO(
+ fREAD_P3, /* read Predicate 0 */
+ (), /* parameters */
+ "P3", /* short description */
+ "P3", /* long description */
+ (READ_PREG(3)), /* behavior */
+ (A_IMPLICIT_READS_P3)
+)
+
+DEF_MACRO(
+ fNOATTRIB_READ_P3, /* read Predicate 0 */
+ (), /* parameters */
+ "P3", /* short description */
+ "P3", /* long description */
+ (READ_PREG(3)), /* behavior */
+ ()
+)
+
+DEF_MACRO(
+ fINVALID,(),
+ "Invalid instruction!",
+ "Invalid instruction!",
+ (register_error_exception(thread,PRECISE_CAUSE_INVALID_PACKET,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(
+ fCHECK_PCALIGN, (A),
+ "",
+ "",
+ /* EJP: if exception already detected, do not trigger pc unaligned exception since we will be rewinding PC anyway. */
+ /* Maybe this will screw up prioritization logic... but probably it is ok? Otherwise we can ditch out of dealloc_return early if EXCEPTION_DETECTED */
+ 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(
+ fCUREXT,(),
+ "",
+ "",
+ GET_SSR_FIELD(SSR_XA),
+ ()
+)
+
+DEF_MACRO(
+ fCUREXT_WRAP,(EXT_NO),
+ "",
+ "",
+ {
+ EXT_NO = fCUREXT();
+ if (thread->processor_ptr->arch_proc_options->ext_contexts)
+ EXT_NO &= (thread->processor_ptr->arch_proc_options->ext_contexts-1);
+ else
+ EXT_NO = 0;
+ EXT_NO = thread->processor_ptr->features->QDSP6_CP_PRESENT ? (EXT_NO & 0x3) : (EXT_NO+4);
+ },
+ ()
+)
+
+DEF_MACRO(
+ fWRITE_NPC, /* write next PC */
+ (A), /* parameters */
+ "PC=A", /* short description */
+ "PC=A", /* long description */
+ 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_IMPLICIT_WRITES_PC,A_COF)
+)
+
+
+DEF_MACRO(
+ fLOOPSTATS,
+ (A),
+ "",
+ "",
+ /* INC_TSTAT(tloopends);
+ INC_TSTATN(tloopend_same_line,(thread->Regs[REG_PC] & -32) == ((A) & -32));
+ INC_TSTATN(tloopend_samepc,(thread->Regs[REG_PC]) == (A));*/ ,
+ ()
+)
+
+
+DEF_MACRO(
+ fCOF_CALLBACK,
+ (LOC,TYPE),
+ "",
+ "",
+ {
+ thread->cof_log_to_va = (LOC);
+ thread->cof_log_coftype = (TYPE);
+ thread->cof_log_valid = 1;
+ },
+ ()
+)
+
+DEF_MACRO(
+ fBRANCH,
+ (LOC,TYPE),
+ "PC=LOC",
+ "PC=LOC",
+ fWRITE_NPC(LOC); fCOF_CALLBACK(LOC,TYPE),
+ ()
+)
+
+DEF_MACRO(
+ fTIME_JUMPR,
+ (REGNO,TARGET,TYPE),
+ "",
+ "",
+ { sys_branch_return(thread, insn->slot, TARGET, REGNO); },
+ (A_INDIRECT)
+)
+
+
+DEF_MACRO(
+ fJUMPR, /* A jumpr has executed */
+ (REGNO,TARGET,TYPE),
+ "PC=TARGET",
+ "PC=TARGET",
+ { fTIME_JUMPR(REGNO,TARGET,TYPE); fBRANCH(TARGET,COF_TYPE_JUMPR);},
+ (A_INDIRECT)
+)
+
+DEF_MACRO(
+ fHINTJR, /* A hintjr instruction has executed */
+ (TARGET),
+ "",
+ "",
+ { },
+)
+
+DEF_MACRO(
+ fBP_RAS_CALL,
+ (A),
+ "",
+ "",
+ { sys_branch_call(thread, insn->slot, A, fREAD_NPC()); },
+)
+
+DEF_MACRO(
+ fCALL, /* Do a call */
+ (A),
+ "fWRITE_LR(fREAD_NPC()); fWRITE_NPC(A);",
+ "fWRITE_LR(fREAD_NPC()); fWRITE_NPC(A);",
+ if (!thread->branch_taken) {fBP_RAS_CALL(A); fWRITE_LR(fREAD_NPC()); fBRANCH(A,COF_TYPE_CALL);},
+ (A_IMPLICIT_WRITES_PC,A_COF,A_IMPLICIT_WRITES_LR,A_CALL)
+)
+
+DEF_MACRO(
+ fCALLR, /* Do a call Register */
+ (A),
+ "fWRITE_LR(fREAD_NPC()); fWRITE_NPC(A);",
+ "fWRITE_LR(fREAD_NPC()); fWRITE_NPC(A);",
+ if (!thread->branch_taken) {fBP_RAS_CALL(A); fWRITE_LR(fREAD_NPC()); fBRANCH(A,COF_TYPE_CALLR);},
+ (A_IMPLICIT_WRITES_PC,A_COF,A_IMPLICIT_WRITES_LR,A_CALL)
+)
+
+DEF_MACRO(
+ fWRITE_LOOP_REGS0, /* write ln,sa,ea,lc */
+ (START,COUNT), /* parameters */
+ "SA0=START; LC0=COUNT", /* short description */
+ "SA0=START; LC0=COUNT", /* short description */
+ {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 */
+ (START,COUNT), /* parameters */
+ "SA1=START; LC1=COUNT", /* short description */
+ "SA1=START; LC1=COUNT", /* short description */
+ {WRITE_RREG(REG_LC1,COUNT);
+ WRITE_RREG(REG_SA1,START);},
+ (A_IMPLICIT_WRITES_LC1,A_IMPLICIT_WRITES_SA1)
+)
+
+DEF_MACRO(
+ fWRITE_LC0,
+ (VAL), /* parameters */
+ "LC0=VAL", /* short description */
+ "LC0=VAL",
+ WRITE_RREG(REG_LC0,VAL),
+ (A_IMPLICIT_WRITES_LC0)
+)
+
+DEF_MACRO(
+ fWRITE_LC1,
+ (VAL), /* parameters */
+ "LC1=VAL", /* short description */
+ "LC1=VAL",
+ WRITE_RREG(REG_LC1,VAL),
+ (A_IMPLICIT_WRITES_LC1)
+)
+
+DEF_MACRO(
+ fCARRY_FROM_ADD,
+ (A,B,C),
+ "carry_from_add(A,B,C)",
+ "carry_from_add(A,B,C)",
+ carry_from_add64(A,B,C),
+ /* NOTHING */
+)
+
+DEF_MACRO(
+ fSETCV_ADD,
+ (A,B,CARRY),
+ "SR[CV]=FLAGS(A+B)",
+ "SR[CV]=FLAGS(A+B)",
+ do {
+ SET_USR_FIELD(USR_C,gen_carry_add((A),(B),((A)+(B))));
+ SET_USR_FIELD(USR_V,gen_overflow_add((A),(B),((A)+(B))));
+ } while (0),
+ (A_IMPLICIT_WRITES_CVBITS,A_NOTE_CVFLAGS,A_RESTRICT_NOSRMOVE)
+)
+DEF_MACRO(
+ fSETCV_SUB,
+ (A,B,CARRY),
+ "SR[CV]=FLAGS(A-B)",
+ "SR[CV]=FLAGS(A-B)",
+ do {
+ SET_USR_FIELD(USR_C,gen_carry_add((A),(B),((A)-(B))));
+ SET_USR_FIELD(USR_V,gen_overflow_add((A),(B),((A)-(B))));
+ } while (0),
+ (A_IMPLICIT_WRITES_CVBITS,A_NOTE_CVFLAGS,A_RESTRICT_NOSRMOVE)
+)
+
+DEF_MACRO(
+ fSET_OVERFLOW,
+ (),
+ "USR.OVF=1",
+ "USR.OVF=1",
+ SET_USR_FIELD(USR_OVF,1),
+ (A_IMPLICIT_WRITES_SRBIT,A_NOTE_SR_OVF_WHEN_SATURATING,A_RESTRICT_NOSRMOVE)
+)
+
+DEF_MACRO(
+ fSET_LPCFG,
+ (VAL), /* parameters */
+ "USR.LPCFG=VAL",
+ "USR.LPCFG=VAL",
+ SET_USR_FIELD(USR_LPCFG,(VAL)),
+ (A_IMPLICIT_WRITES_LPCFG,A_RESTRICT_NOSRMOVE)
+)
+
+
+DEF_MACRO(
+ fGET_LPCFG,
+ , /* parameters */
+ "USR.LPCFG",
+ "USR.LPCFG",
+ (GET_USR_FIELD(USR_LPCFG)),
+ ()
+)
+
+
+
+DEF_MACRO(
+ fWRITE_P0, /* write Predicate 0 */
+ (VAL), /* parameters */
+ "P0=VAL", /* short description */
+ "P0=VAL", /* long description */
+ WRITE_PREG(0,VAL), /* behavior */
+ (A_IMPLICIT_WRITES_P0)
+)
+
+DEF_MACRO(
+ fWRITE_P1, /* write Predicate 0 */
+ (VAL), /* parameters */
+ "P1=VAL", /* short description */
+ "P1=VAL", /* long description */
+ WRITE_PREG(1,VAL), /* behavior */
+ (A_IMPLICIT_WRITES_P1)
+)
+
+DEF_MACRO(
+ fWRITE_P2, /* write Predicate 0 */
+ (VAL), /* parameters */
+ "P2=VAL", /* short description */
+ "P2=VAL", /* long description */
+ WRITE_PREG(2,VAL), /* behavior */
+ (A_IMPLICIT_WRITES_P2)
+)
+
+DEF_MACRO(
+ fWRITE_P3, /* write Predicate 0 */
+ (VAL), /* parameters */
+ "P3=VAL", /* short description */
+ "P3=VAL", /* long description */
+ WRITE_PREG(3,VAL), /* behavior */
+ (A_IMPLICIT_WRITES_P3)
+)
+
+DEF_MACRO(
+ fWRITE_P3_LATE, /* write Predicate 0 */
+ (VAL), /* parameters */
+ "P3=VAL", /* short description */
+ "P3=VAL", /* long description */
+ {WRITE_PREG(3,VAL); fHIDE(MARK_LATE_PRED_WRITE(3))} , /* behavior */
+ (A_IMPLICIT_WRITES_P3,A_RESTRICT_LATEPRED)
+)
+
+
+DEF_MACRO(
+ fPART1, /* write Predicate 0 */
+ (WORK), /* parameters */
+ "WORK", /* short description */
+ "WORK", /* long description */
+ if (insn->part1) { WORK; return; }, /* behavior */
+ /* optional attributes */
+)
+
+
+/*************************************/
+/* Casting, Sign-Zero extension, etc */
+/*************************************/
+
+DEF_MACRO(
+ fCAST4u, /* macro name */
+ (A), /* parameters */
+ "A.uw[0]", /* short description */
+ "unsigned 32-bit A", /* long description */
+ ((size4u_t)(A)), /* behavior */
+ /* optional attributes */
+)
+
+DEF_MACRO(
+ fCAST4s, /* macro name */
+ (A), /* parameters */
+ "A.s32", /* short description */
+ "signed 32-bit A", /* long description */
+ ((size4s_t)(A)), /* behavior */
+ /* optional attributes */
+)
+
+DEF_MACRO(
+ fCAST8u, /* macro name */
+ (A), /* parameters */
+ "A.u64", /* short description */
+ "unsigned 64-bit A", /* long description */
+ ((size8u_t)(A)), /* behavior */
+ /* optional attributes */
+)
+
+DEF_MACRO(
+ fCAST8s, /* macro name */
+ (A), /* parameters */
+ "A.s64", /* short description */
+ "signed 64-bit A", /* long description */
+ ((size8s_t)(A)), /* behavior */
+ /* optional attributes */
+)
+
+DEF_MACRO(
+ fCAST2_2s, /* macro name */
+ (A), /* params */
+ "A",
+ "signed 16-bit A",
+ ((size2s_t)(A)),
+ /* optional attributes */
+)
+
+DEF_MACRO(
+ fCAST2_2u, /* macro name */
+ (A), /* params */
+ "A",
+ "unsigned 16-bit A",
+ ((size2u_t)(A)),
+ /* optional attributes */
+)
+
+DEF_MACRO(
+ fCAST4_4s, /* macro name */
+ (A), /* params */
+ "A",
+ "signed 32-bit A",
+ ((size4s_t)(A)),
+ /* optional attributes */
+)
+
+DEF_MACRO(
+ fCAST4_4u, /* macro name */
+ (A), /* params */
+ "A",
+ "unsigned 32-bit A",
+ ((size4u_t)(A)),
+ /* optional attributes */
+)
+
+
+DEF_MACRO(
+ fCAST4_8s, /* macro name */
+ (A), /* params */
+ "fSXTN(32,64,A)",
+ "32-bit A sign-extended to signed 64-bit",
+ ((size8s_t)((size4s_t)(A))),
+ /* optional attributes */
+)
+
+DEF_MACRO(
+ fCAST4_8u, /* macro name */
+ (A), /* params */
+ "fZXTN(32,64,A)",
+ "32-bit A zero-extended to unsigned 64-bit",
+ ((size8u_t)((size4u_t)(A))),
+ /* optional attributes */
+)
+
+DEF_MACRO(
+ fCAST8_8s, /* macro name */
+ (A), /* params */
+ "A",
+ "signed 64-bit A",
+ ((size8s_t)(A)),
+ /* optional attributes */
+)
+
+DEF_MACRO(
+ fCAST8_8u, /* macro name */
+ (A), /* params */
+ "A",
+ "unsigned 64-bit A",
+ ((size8u_t)(A)),
+ /* optional attributes */
+)
+
+DEF_MACRO(
+ fCAST2_8s, /* macro name */
+ (A), /* params */
+ "fSXTN(16,64,A)",
+ "16-bit A sign-extended to signed 64-bit",
+ ((size8s_t)((size2s_t)(A))),
+ /* optional attributes */
+)
+
+DEF_MACRO(
+ fCAST2_8u, /* macro name */
+ (A), /* params */
+ "fZXTN(16,64,A)",
+ "16-bit A zero-extended to unsigned 64-bit",
+ ((size8u_t)((size2u_t)(A))),
+ /* optional attributes */
+)
+
+DEF_MACRO(
+ fZE8_16, /* zero-extend 8 to 16 */
+ (A),
+ "A",
+ "Unsigned low 8 bits of A",
+ ((size2s_t)((size1u_t)(A))),
+ /* optional attributes */
+)
+DEF_MACRO(
+ fSE8_16, /* sign-extend 8 to 16 */
+ (A),
+ "A",
+ "Signed low 8 bits of A",
+ ((size2s_t)((size1s_t)(A))),
+ /* optional attributes */
+)
+
+
+DEF_MACRO(
+ fSE16_32, /* sign-extend 16 to 32 */
+ (A), /* parameters */
+ "A", /* short description */
+ "signed low 16-bits of A", /* long description */
+ ((size4s_t)((size2s_t)(A))), /* behavior */
+ /* optional attributes */
+)
+
+DEF_MACRO(
+ fZE16_32, /* zero-extend 16 to 32 */
+ (A), /* parameters */
+ "A", /* short description */
+ "signed low 16-bits of A", /* long description */
+ ((size4u_t)((size2u_t)(A))), /* behavior */
+ /* optional attributes */
+)
+
+DEF_MACRO(
+ fSE32_64,
+ (A), /* parameters */
+ "A", /* short description */
+ "A", /* long description */
+ ( (size8s_t)((size4s_t)(A)) ), /* behavior */
+ /* optional attributes */
+)
+
+DEF_MACRO(
+ fZE32_64,
+ (A), /* parameters */
+ "A", /* short description */
+ "zero-extend A from 32 to 64", /* long description */
+ ( (size8u_t)((size4u_t)(A)) ), /* behavior */
+ /* optional attributes */
+)
+
+DEF_MACRO(
+ fSE8_32, /* sign-extend 8 to 32 */
+ (A),
+ "A",
+ "Signed low 8 bits of A",
+ ((size4s_t)((size1s_t)(A))),
+ /* optional attributes */
+)
+
+DEF_MACRO(
+ fZE8_32, /* zero-extend 8 to 32 */
+ (A),
+ "A",
+ "Unsigned low 8 bits of A",
+ ((size4s_t)((size1u_t)(A))),
+ /* optional attributes */
+)
+
+/*************************************/
+/* DSP arithmetic support */
+/************************************/
+DEF_MACRO(
+ fMPY8UU, /* multiply half integer */
+ (A,B), /* parameters */
+ "(A * B)", /* short description */
+ "unsigned 8-bit multiply of A by B", /* long description */
+ (int)(fZE8_16(A)*fZE8_16(B)), /* behavior */
+ (A_MPY)
+)
+DEF_MACRO(
+ fMPY8US, /* multiply half integer */
+ (A,B), /* parameters */
+ "(A * B)", /* short description */
+ "unsigned 8-bit multiply of A by signed B", /* long description */
+ (int)(fZE8_16(A)*fSE8_16(B)), /* behavior */
+ (A_MPY)
+)
+DEF_MACRO(
+ fMPY8SU, /* multiply half integer */
+ (A,B), /* parameters */
+ "(A * B)", /* short description */
+ "signed 8-bit multiply of A by unsigned B", /* long description */
+ (int)(fSE8_16(A)*fZE8_16(B)), /* behavior */
+ (A_MPY)
+)
+
+DEF_MACRO(
+ fMPY8SS, /* multiply half integer */
+ (A,B), /* parameters */
+ "(A * B)", /* short description */
+ "signed 8-bit multiply of A by B", /* long description */
+ (int)((short)(A)*(short)(B)), /* behavior */
+ (A_MPY)
+)
+
+DEF_MACRO(
+ fMPY16SS, /* multiply half integer */
+ (A,B), /* parameters */
+ "(A * B)", /* short description */
+ "signed 16-bit multiply of A by B", /* long description */
+ fSE32_64(fSE16_32(A)*fSE16_32(B)), /* behavior */
+ (A_MPY)
+)
+
+DEF_MACRO(
+ fMPY16UU, /* multiply unsigned half integer */
+ (A,B), /* parameters */
+ "(A * B)", /* short description */
+ "multiply unsigned A by unsigned B", /* long description */
+ fZE32_64(fZE16_32(A)*fZE16_32(B)), /* behavior */
+ (A_MPY)
+)
+
+DEF_MACRO(
+ fMPY16SU, /* multiply half integer */
+ (A,B), /* parameters */
+ "(A * B)", /* short description */
+ "signed 16-bit A times unsigned 16-bit B", /* long description */
+ fSE32_64(fSE16_32(A)*fZE16_32(B)), /* behavior */
+ (A_MPY)
+)
+
+DEF_MACRO(
+ fMPY16US, /* multiply half integer */
+ (A,B), /* parameters */
+ "(A * B)", /* short description */
+ "unsigned 16-bit A times signed 16-bit B", /* long description */
+ fMPY16SU(B,A),
+ (A_MPY)
+)
+
+DEF_MACRO(
+ fMPY32SS, /* multiply half integer */
+ (A,B), /* parameters */
+ "(A * B)", /* short description */
+ "signed 32-bit multiply of A by B", /* long description */
+ (fSE32_64(A)*fSE32_64(B)), /* behavior */
+ (A_MPY)
+)
+
+DEF_MACRO(
+ fMPY32UU, /* multiply half integer */
+ (A,B), /* parameters */
+ "(A * B)", /* short description */
+ "unsigned 32-bit multiply of A by B", /* long description */
+ (fZE32_64(A)*fZE32_64(B)), /* behavior */
+ (A_MPY)
+)
+
+DEF_MACRO(
+ fMPY32SU, /* multiply half integer */
+ (A,B), /* parameters */
+ "(A * B)", /* short description */
+ "32-bit multiply of signed A by unsigned B", /* long description */
+ (fSE32_64(A)*fZE32_64(B)), /* behavior */
+ (A_MPY)
+)
+
+DEF_MACRO(
+ fMPY3216SS, /* multiply mixed precision */
+ (A,B), /* parameters */
+ "(A * B)", /* short description */
+ "signed 16-bit multiply of A by B", /* long description */
+ (fSE32_64(A)*fSXTN(16,64,B)), /* behavior */
+ (A_MPY)
+)
+
+DEF_MACRO(
+ fMPY3216SU, /* multiply mixed precision */
+ (A,B), /* parameters */
+ "(A * B)", /* short description */
+ "signed 16-bit multiply of A by unsigned B", /* long description */
+ (fSE32_64(A)*fZXTN(16,64,B)), /* behavior */
+ (A_MPY)
+)
+
+DEF_MACRO(
+ fROUND, /* optional rounding */
+ (A), /* parameters */
+ "round(A)", /* short description */
+ "round(A)", /* long description */
+ (A+0x8000),
+ /* optional attributes */
+)
+
+DEF_MACRO(
+ fCLIP, /* optional rounding */
+ (DST,SRC,U), /* parameters */
+ "DST=MIN((1<<U)-1,MAX(SRC,-(1<<U)))", /* short description */
+ "DST=IN((1<<U)-1,MAX(SRC,-(1<<U)))", /* long description */
+ { 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), /* parameters */
+ "convround(A)", /* short description */
+ "convround(A)", /* long description */
+ ((((A)&0x3)==0x3)?((A)+1):((A))),
+ /* optional attributes */
+)
+
+DEF_MACRO(
+ fRNDN, /* Rounding to a boundary */
+ (A,N), /* parameters */
+ "(N==0)?(A):round(A,2**(N-1))", /* short description */
+ "(N==0)?(A):round(A,2**(N-1))", /* long description */
+ ((((N)==0)?(A):(((fSE32_64(A))+(1<<((N)-1)))))),
+ /* optional attributes */
+)
+
+DEF_MACRO(
+ fCRNDN, /* Rounding to a boundary */
+ (A,N), /* parameters */
+ "(N==0)?A:convround(A,2**(N-1))>>N", /* short description */
+ "(N==0)?A:convround(A,2**(N-1))>>N", /* long description */
+ (conv_round(A,N)),
+ /* optional attributes */
+)
+
+DEF_MACRO(
+ fCRNDN64, /* Rounding to a boundary */
+ (A,N), /* parameters */
+ "(N==0)?A:convround(A,2**(N-1))>>N", /* short description */
+ "(N==0)?A:convround(A,2**(N-1))>>N", /* long description */
+ (conv_round64(A,N)),
+ /* optional attributes */
+)
+DEF_MACRO(
+ fADD128, /* Rounding to a boundary */
+ (A,B), /* parameters */
+ "A+B", /* short description */
+ "", /* long description */
+ (add128(A, B)),
+ /* optional attributes */
+)
+DEF_MACRO(
+ fSUB128, /* Rounding to a boundary */
+ (A,B), /* parameters */
+ "A-B", /* short description */
+ "", /* long description */
+ (sub128(A, B)),
+ /* optional attributes */
+)
+DEF_MACRO(
+ fSHIFTR128, /* Rounding to a boundary */
+ (A,B), /* parameters */
+ "(size8s_t) (A >> B)", /* short description */
+ "", /* long description */
+ (shiftr128(A, B)),
+ /* optional attributes */
+)
+
+DEF_MACRO(
+ fSHIFTL128, /* Rounding to a boundary */
+ (A,B), /* parameters */
+ "(A << B)", /* short description */
+ "", /* long description */
+ (shiftl128(A, B)),
+ /* optional attributes */
+)
+
+DEF_MACRO(
+ fAND128, /* Rounding to a boundary */
+ (A,B), /* parameters */
+ "(A & B)", /* short description */
+ "", /* long description */
+ (and128(A, B)),
+ /* optional attributes */
+)
+
+DEF_MACRO(
+ fCAST8S_16S, /* Rounding to a boundary */
+ (A), /* parameters */
+ "sxt_{64->128}(A)", /* short description */
+ "", /* long description */
+ (cast8s_to_16s(A)),
+ /* optional attributes */
+)
+DEF_MACRO(
+ fCAST16S_8S, /* Rounding to a boundary */
+ (A), /* parameters */
+ "sxt_{128->64}(A)", /* short description */
+ "", /* long description */
+ (cast16s_to_8s(A)),
+ /* optional attributes */
+)
+DEF_MACRO(
+ fCAST16S_4S, /* Rounding to a boundary */
+ (A), /* parameters */
+ "sxt_{128->32}(A)", /* short description */
+ "", /* long description */
+ (cast16s_to_4s(A)),
+ /* optional attributes */
+)
+
+
+
+DEF_MACRO(
+ fEA_RI, /* Calculate EA with Register + Immediate Offset */
+ (REG,IMM),
+ "EA=REG+IMM", /* short descr */
+ "EA=REG+IMM", /* long descr */
+ do { EA=REG+IMM; fDOCHKPAGECROSS(REG,EA); } while (0),
+ (A_EA_REG_PLUS_IMM)
+)
+
+DEF_MACRO(
+ fEA_RRs, /* Calculate EA with Register + Registers scaled Offset */
+ (REG,REG2,SCALE),
+ "EA=REG+(REG2<<SCALE)", /* short descr */
+ "EA=REG+(REG2<<SCALE)", /* long descr */
+ do { EA=REG+(REG2<<SCALE); fDOCHKPAGECROSS(REG,EA); } while (0),
+ (A_EA_REG_PLUS_REGSCALED)
+)
+
+DEF_MACRO(
+ fEA_IRs, /* Calculate EA with Immediate + Registers scaled Offset */
+ (IMM,REG,SCALE),
+ "EA=IMM+(REG<<SCALE)", /* short descr */
+ "EA=IMM+(REG<<SCALE)", /* long descr */
+ do { EA=IMM+(REG<<SCALE); fDOCHKPAGECROSS(IMM,EA); } while (0),
+ (A_EA_IMM_PLUS_REGSCALED)
+)
+
+DEF_MACRO(
+ fEA_IMM, /* Calculate EA with Immediate */
+ (IMM),
+ "EA=IMM", /* short descr */
+ "EA=IMM", /* long descr */
+ EA=IMM,
+ (A_EA_IMM_ONLY)
+)
+
+DEF_MACRO(
+ fEA_REG, /* Calculate EA with REGISTER */
+ (REG),
+ "EA=REG", /* short descr */
+ "EA=REG", /* long descr */
+ EA=REG,
+ (A_EA_REG_ONLY)
+)
+
+DEF_MACRO(
+ fEA_BREVR, /* Calculate EA with bit reversed bottom of REGISTER */
+ (REG),
+ "EA=fbrev(REG)", /* short descr */
+ "EA=fbrev(REG)", /* long descr */
+ EA=fbrev(REG),
+ (A_EA_BREV_REG)
+)
+
+DEF_MACRO(
+ fEA_GPI, /* Calculate EA with Global Poitner + Immediate */
+ (IMM),
+ "EA=fREAD_GP()+IMM", /* short descr */
+ "EA=fREAD_GP()+IMM", /* long descr */
+ do { EA=fREAD_GP()+IMM; fGP_DOCHKPAGECROSS(fREAD_GP(),EA); } while (0),
+ (A_EA_GP_IMM)
+)
+
+DEF_MACRO(
+ fPM_I, /* Post Modify Register by Immediate*/
+ (REG,IMM),
+ "REG=REG+IMM", /* short descr */
+ "REG=REG+IMM", /* long descr */
+ do { REG = REG + IMM; fTIMING_AIA(EA,REG); } while (0),
+ (A_PM_I)
+)
+
+DEF_MACRO(
+ fPM_M, /* Post Modify Register by M register */
+ (REG,MVAL),
+ "REG=REG+MVAL", /* short descr */
+ "REG=REG+MVAL", /* long descr */
+ do { REG = REG + MVAL; fTIMING_AIA(EA,REG); } while (0),
+ (A_PM_M)
+)
+
+DEF_MACRO(
+ fPM_CIRI, /* Post Modify Register using Circular arithmetic by Immediate */
+ (REG,IMM,MVAL),
+ "REG=fcirc_add(REG,IMM,MVAL)", /* short descr */
+ "REG=fcirc_add(REG,IMM,MVAL)", /* long descr */
+ do { fcirc_add(REG,siV,MuV); fTIMING_AIA(EA,REG); } while (0),
+ (A_PM_CIRI)
+)
+
+DEF_MACRO(
+ fPM_CIRR, /* Post Modify Register using Circular arithmetic by register */
+ (REG,VAL,MVAL),
+ "REG=fcirc_add(REG,VAL,MVAL)", /* short descr */
+ "REG=fcirc_add(REG,VAL,MVAL)", /* long descr */
+ do { fcirc_add(REG,VAL,MuV); fTIMING_AIA(EA,REG); } while (0),
+ (A_PM_CIRR)
+)
+
+
+
+DEF_MACRO(
+ fMODCIRCU, /* modulo power of 2, positive output */
+ (N,P), /* parameters */
+ "N modulo 2^P", /* short description */
+ "N modulo 2^P ", /* long description */
+ ((N) & ((1<<(P))-1)),
+ /* optional attributes */
+)
+
+DEF_MACRO(
+ fSCALE, /* scale by N */
+ (N,A), /* parameters */
+ "A<<N", /* short description */
+ "A<<N", /* long description */
+ (((size8s_t)(A))<<N),
+ /* optional attributes */
+)
+DEF_MACRO(
+ fVSATW, /* saturating to 32-bits*/
+ (A), /* parameters */
+ "sat_32(A)", /* short description */
+ "saturate A to 32-bits", /* long description */
+ fVSATN(32,((long long)A)),
+ (A_SATURATE)
+)
+
+DEF_MACRO(
+ fSATW, /* saturating to 32-bits*/
+ (A), /* parameters */
+ "sat_32(A)", /* short description */
+ "saturate A to 32-bits", /* long description */
+ fSATN(32,((long long)A)),
+ (A_SATURATE)
+)
+
+DEF_MACRO(
+ fVSAT, /* saturating to 32-bits*/
+ (A), /* parameters */
+ "sat_32(A)", /* short description */
+ "saturate A to 32-bits", /* long description */
+ fVSATN(32,(A)),
+ (A_SATURATE)
+)
+
+DEF_MACRO(
+ fSAT, /* saturating to 32-bits*/
+ (A), /* parameters */
+ "sat_32(A)", /* short description */
+ "saturate A to 32-bits", /* long description */
+ fSATN(32,(A)),
+ (A_SATURATE)
+)
+
+DEF_MACRO(
+ fSAT_ORIG_SHL, /* Saturating to 32-bits, with original value, for shift left */
+ (A,ORIG_REG), /* parameters */
+ "sat_32(A)", /* short description */
+ "saturate A to 32-bits for left shift", /* long description */
+ ((((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))),
+ (A_SATURATE)
+)
+
+DEF_MACRO(
+ fPASS,
+ (A),
+ "A", /* short description */
+ "", /* long description */
+ A,
+)
+
+DEF_MACRO(
+ fRND, /* saturating to 32-bits*/
+ (A), /* parameters */
+ "((A)+1)>>1", /* short description */
+ "round(A)", /* long description */
+ (((A)+1)>>1),
+)
+
+
+DEF_MACRO(
+ fBIDIR_SHIFTL,
+ (SRC,SHAMT,REGSTYPE),
+ "bidir_shiftl(SRC,SHAMT)",
+ "bidir_shiftl(SRC,SHAMT)",
+ (((SHAMT) < 0) ? ((fCAST##REGSTYPE(SRC) >> ((-(SHAMT))-1)) >>1) : (fCAST##REGSTYPE(SRC) << (SHAMT))),
+ (A_BIDIRSHIFTL)
+)
+
+DEF_MACRO(
+ fBIDIR_ASHIFTL,
+ (SRC,SHAMT,REGSTYPE),
+ "(SHAMT>0)?(fCAST##REGSTYPE##s(SRC)<<SHAMT):(fCAST##REGSTYPE##s(SRC)>>SHAMT)",
+ "bidir_asl(fCAST##REGSTYPE##s(SRC),SHAMT)",
+ fBIDIR_SHIFTL(SRC,SHAMT,REGSTYPE##s),
+ (A_BIDIRSHIFTL)
+)
+
+DEF_MACRO(
+ fBIDIR_LSHIFTL,
+ (SRC,SHAMT,REGSTYPE),
+ "(SHAMT>0)?(fCAST##REGSTYPE##u(SRC)<<SHAMT):(fCAST##REGSTYPE##u(SRC)>>>SHAMT)",
+ "bidir_lsl(fCAST##REGSTYPE##u(SRC),SHAMT)",
+ fBIDIR_SHIFTL(SRC,SHAMT,REGSTYPE##u),
+ (A_BIDIRSHIFTL)
+)
+
+DEF_MACRO(
+ fBIDIR_ASHIFTL_SAT,
+ (SRC,SHAMT,REGSTYPE),
+ "bidir_shiftl(SRC,SHAMT)",
+ "bidir_shiftl(SRC,SHAMT)",
+ (((SHAMT) < 0) ? ((fCAST##REGSTYPE##s(SRC) >> ((-(SHAMT))-1)) >>1) : fSAT_ORIG_SHL(fCAST##REGSTYPE##s(SRC) << (SHAMT),(SRC))),
+ (A_BIDIRSHIFTL)
+)
+
+
+DEF_MACRO(
+ fBIDIR_SHIFTR,
+ (SRC,SHAMT,REGSTYPE),
+ "bidir_shiftr(SRC,SHAMT)",
+ "bidir_shiftr(SRC,SHAMT)",
+ (((SHAMT) < 0) ? ((fCAST##REGSTYPE(SRC) << ((-(SHAMT))-1)) << 1) : (fCAST##REGSTYPE(SRC) >> (SHAMT))),
+ (A_BIDIRSHIFTR)
+)
+
+DEF_MACRO(
+ fBIDIR_ASHIFTR,
+ (SRC,SHAMT,REGSTYPE),
+ "(SHAMT>0)?(fCAST##REGSTYPE##s(SRC)>>SHAMT):(fCAST##REGSTYPE##s(SRC)<<SHAMT)",
+ "bidir_asr(fCAST##REGSTYPE##s(SRC),SHAMT)",
+ fBIDIR_SHIFTR(SRC,SHAMT,REGSTYPE##s),
+ (A_BIDIRSHIFTR)
+)
+
+DEF_MACRO(
+ fBIDIR_LSHIFTR,
+ (SRC,SHAMT,REGSTYPE),
+ "(SHAMT>0)?(fCAST##REGSTYPE##u(SRC)>>>SHAMT):(fCAST##REGSTYPE##u(SRC)<<SHAMT)",
+ "bidir_lsr(fCAST##REGSTYPE##u(SRC),SHAMT)",
+ fBIDIR_SHIFTR(SRC,SHAMT,REGSTYPE##u),
+ (A_BIDIRSHIFTR)
+)
+
+DEF_MACRO(
+ fBIDIR_ASHIFTR_SAT,
+ (SRC,SHAMT,REGSTYPE),
+ "bidir_shiftr(SRC,SHAMT)",
+ "bidir_shiftr(SRC,SHAMT)",
+ (((SHAMT) < 0) ? fSAT_ORIG_SHL((fCAST##REGSTYPE##s(SRC) << ((-(SHAMT))-1)) << 1,(SRC)) : (fCAST##REGSTYPE##s(SRC) >> (SHAMT))),
+ (A_BIDIRSHIFTR)
+)
+
+DEF_MACRO(
+ fASHIFTR,
+ (SRC,SHAMT,REGSTYPE),
+ "SRC >> SHAMT",
+ "asr(SRC,SHAMT)",
+ (fCAST##REGSTYPE##s(SRC) >> (SHAMT)),
+ /* */
+)
+
+DEF_MACRO(
+ fLSHIFTR,
+ (SRC,SHAMT,REGSTYPE),
+ "SRC >>> SHAMT",
+ "lsr(SRC,SHAMT)",
+ (((SHAMT) >= 64)?0:(fCAST##REGSTYPE##u(SRC) >> (SHAMT))),
+ /* */
+)
+
+DEF_MACRO(
+ fROTL,
+ (SRC,SHAMT,REGSTYPE),
+ "SRC <<_{R} SHAMT",
+ "rol(SRC,SHAMT)",
+ (((SHAMT)==0) ? (SRC) : ((fCAST##REGSTYPE##u(SRC) << (SHAMT)) | \
+ ((fCAST##REGSTYPE##u(SRC) >> ((sizeof(SRC)*8)-(SHAMT)))))),
+ /* */
+)
+
+DEF_MACRO(
+ fROTR,
+ (SRC,SHAMT,REGSTYPE),
+ "SRC >>_{R} SHAMT",
+ "ror(SRC,SHAMT)",
+ (((SHAMT)==0) ? (SRC) : ((fCAST##REGSTYPE##u(SRC) >> (SHAMT)) | \
+ ((fCAST##REGSTYPE##u(SRC) << ((sizeof(SRC)*8)-(SHAMT)))))),
+ /* */
+)
+
+DEF_MACRO(
+ fASHIFTL,
+ (SRC,SHAMT,REGSTYPE),
+ "fCAST##REGSTYPE##s(SRC) << SHAMT",
+ "asl(SRC,SHAMT)",
+ (((SHAMT) >= 64)?0:(fCAST##REGSTYPE##s(SRC) << (SHAMT))),
+ /* */
+)
+
+/*************************************/
+/* Floating-Point Support */
+/************************************/
+
+DEF_MACRO(
+ fFLOAT, /* name */
+ (A), /* parameters */
+ "A", /* short description */
+ "A", /* long description */
+ ({ union { float f; size4u_t i; } _fipun; _fipun.i = (A); _fipun.f; }), /* behavior */
+ (A_FPOP,A_FPSINGLE,A_IMPLICIT_WRITES_FPFLAGS,A_IMPLICIT_READS_FPRND)
+)
+
+DEF_MACRO(
+ fUNFLOAT, /* multiply half integer */
+ (A), /* parameters */
+ "A", /* short description */
+ "A", /* long description */
+ ({ union { float f; size4u_t i; } _fipun; _fipun.f = (A); isnan(_fipun.f) ? 0xFFFFFFFFU : _fipun.i; }), /* behavior */
+ (A_FPOP,A_FPSINGLE,A_IMPLICIT_WRITES_FPFLAGS,A_IMPLICIT_READS_FPRND)
+)
+
+DEF_MACRO(
+ fSFNANVAL,(),
+ "NaN",
+ "NaN",
+ 0xffffffff,
+ ()
+)
+
+DEF_MACRO(
+ fSFINFVAL,(A),
+ "sign(A) * Inf",
+ "sign(A) * Inf",
+ (((A) & 0x80000000) | 0x7f800000),
+ ()
+)
+
+DEF_MACRO(
+ fSFONEVAL,(A),
+ "sign(A) * 1.0",
+ "sign(A) * 1.0",
+ (((A) & 0x80000000) | fUNFLOAT(1.0)),
+ ()
+)
+
+DEF_MACRO(
+ fCHECKSFNAN,(DST,A),
+ "if (isnan(A)) DST = NaN;",
+ "if (isnan(A)) DST = NaN;",
+ do {
+ if (isnan(fFLOAT(A))) {
+ if ((fGETBIT(22,A)) == 0) fRAISEFLAGS(FE_INVALID);
+ DST = fSFNANVAL();
+ }
+ } while (0),
+ ()
+)
+
+DEF_MACRO(
+ fCHECKSFNAN3,(DST,A,B,C),
+ "if (isnan(A) || isnan(B) || isnan(C)) DST = NaN;",
+ "if (isnan(A) || isnan(B) || isnan(C)) DST = NaN;",
+ do {
+ fCHECKSFNAN(DST,A);
+ fCHECKSFNAN(DST,B);
+ fCHECKSFNAN(DST,C);
+ } while (0),
+ ()
+)
+
+DEF_MACRO(
+ fSF_BIAS,(),
+ "127",
+ "single precision bias",
+ 127,
+ ()
+)
+
+DEF_MACRO(
+ fSF_MANTBITS,(),
+ "23",
+ "single mantissa bits",
+ 23,
+ ()
+)
+
+DEF_MACRO(
+ fSF_RECIP_LOOKUP,(IDX),
+ "recip_lut[IDX]",
+ "Single Precision reciprocal Estimate",
+ arch_recip_lookup(IDX),
+ ()
+)
+
+DEF_MACRO(
+ fSF_INVSQRT_LOOKUP,(IDX),
+ "invsqrt_lut[IDX]",
+ "Single Precision reciprocal Estimate",
+ arch_invsqrt_lookup(IDX),
+ ()
+)
+
+DEF_MACRO(
+ fSF_MUL_POW2,(A,B),
+ "A * 2**B",
+ "A * 2**B",
+ (fUNFLOAT(fFLOAT(A) * fFLOAT((fSF_BIAS() + (B)) << fSF_MANTBITS()))),
+ ()
+)
+
+DEF_MACRO(
+ fSF_GETEXP,(A),
+ "exponent(A)",
+ "exponent(A)",
+ (((A) >> fSF_MANTBITS()) & 0xff),
+ ()
+)
+
+DEF_MACRO(
+ fSF_MAXEXP,(),
+ "254",
+ "SF maximum exponent",
+ (254),
+ ()
+)
+
+DEF_MACRO(
+ fSF_RECIP_COMMON,(N,D,O,A),
+ "(N,D,O,A)=recip_common(N,D)",
+ "(N,D,O,A)=recip_common(N,D)",
+ arch_sf_recip_common(&N,&D,&O,&A),
+ (A_FPOP,A_IMPLICIT_WRITES_FPFLAGS)
+)
+
+DEF_MACRO(
+ fSF_INVSQRT_COMMON,(N,O,A),
+ "(N,O,A)=invsqrt_common(N)",
+ "(N,O,A)=invsqrt_common(N)",
+ arch_sf_invsqrt_common(&N,&O,&A),
+ (A_FPOP,A_IMPLICIT_WRITES_FPFLAGS)
+)
+
+DEF_MACRO(
+ fFMAFX,(A,B,C,ADJ),
+ "fmaf(A,B,C) * 2**(ADJ)",
+ "Fused Multiply Add w/ Scaling: (A*B+C)*2**ADJ",
+ internal_fmafx(A,B,C,fSXTN(8,64,ADJ)),
+ (A_MPY)
+)
+
+DEF_MACRO(
+ fFMAF,(A,B,C),
+ "fmaf(A,B,C)",
+ "Fused Multiply Add: (A*B+C)",
+ internal_fmafx(A,B,C,0),
+ (A_MPY)
+)
+
+DEF_MACRO(
+ fSFMPY,(A,B),
+ "A*B",
+ "Multiply: A*B",
+ internal_mpyf(A,B),
+ (A_MPY)
+)
+
+DEF_MACRO(
+ fMAKESF,(SIGN,EXP,MANT),
+ "-1**SIGN * 1.MANT * 2**(EXP-BIAS)",
+ "-1**SIGN * 1.MANT * 2**(EXP-BIAS)",
+ ((((SIGN) & 1) << 31) | (((EXP) & 0xff) << fSF_MANTBITS()) |
+ ((MANT) & ((1<<fSF_MANTBITS())-1))),
+ ()
+)
+
+
+DEF_MACRO(
+ fDOUBLE, /* multiply half integer */
+ (A), /* parameters */
+ "A", /* short description */
+ "A", /* long description */
+ ({ union { double f; size8u_t i; } _fipun; _fipun.i = (A); _fipun.f; }), /* behavior */
+ (A_FPOP,A_FPDOUBLE,A_IMPLICIT_WRITES_FPFLAGS,A_IMPLICIT_READS_FPRND)
+)
+
+DEF_MACRO(
+ fUNDOUBLE, /* multiply half integer */
+ (A), /* parameters */
+ "A", /* short description */
+ "A", /* long description */
+ ({ union { double f; size8u_t i; } _fipun; _fipun.f = (A); isnan(_fipun.f) ? 0xFFFFFFFFFFFFFFFFULL : _fipun.i; }), /* behavior */
+ (A_FPOP,A_FPDOUBLE,A_IMPLICIT_WRITES_FPFLAGS,A_IMPLICIT_READS_FPRND)
+)
+
+DEF_MACRO(
+ fDFNANVAL,(),
+ "NaN",
+ "NaN",
+ 0xffffffffffffffffULL,
+ ()
+)
+
+DEF_MACRO(
+ fDFINFVAL,(A),
+ "sign(A) * Inf",
+ "sign(A) * Inf",
+ (((A) & 0x8000000000000000ULL) | 0x7ff0000000000000ULL),
+ ()
+)
+
+DEF_MACRO(
+ fDFONEVAL,(A),
+ "sign(A) * 1.0",
+ "sign(A) * 1.0",
+ (((A) & 0x8000000000000000ULL) | fUNDOUBLE(1.0)),
+ ()
+)
+
+DEF_MACRO(
+ fCHECKDFNAN,(DST,A),
+ "if (isnan(A)) DST = NaN;",
+ "if (isnan(A)) DST = NaN;",
+ do {
+ if (isnan(fDOUBLE(A))) {
+ if ((fGETBIT(51,A)) == 0) fRAISEFLAGS(FE_INVALID);
+ DST = fDFNANVAL();
+ }
+ } while (0),
+ ()
+)
+
+DEF_MACRO(
+ fCHECKDFNAN3,(DST,A,B,C),
+ "if (isnan(A) || isnan(B) || isnan(C)) DST = NaN;",
+ "if (isnan(A) || isnan(B) || isnan(C)) DST = NaN;",
+ do {
+ fCHECKDFNAN(DST,A);
+ fCHECKDFNAN(DST,B);
+ fCHECKDFNAN(DST,C);
+ } while (0),
+ ()
+)
+
+DEF_MACRO(
+ fDF_BIAS,(),
+ "1023",
+ "double precision bias",
+ 1023,
+ ()
+)
+
+DEF_MACRO(
+ fDF_ISNORMAL,(X),
+ "is_normal(X)",
+ "is X normal?",
+ (fpclassify(fDOUBLE(X)) == FP_NORMAL),
+ ()
+)
+
+DEF_MACRO(
+ fDF_ISDENORM,(X),
+ "is_denormal(X)",
+ "is X denormal?",
+ (fpclassify(fDOUBLE(X)) == FP_SUBNORMAL),
+ ()
+)
+
+DEF_MACRO(
+ fDF_ISBIG,(X),
+ "(df_exponent(X) >= 512)",
+ "is X sufficiently large for mpyfix (exp >= 512)?",
+ (fDF_GETEXP(X) >= 512),
+ ()
+)
+
+DEF_MACRO(
+ fDF_MANTBITS,(),
+ "52",
+ "single mantissa bits",
+ 52,
+ ()
+)
+
+DEF_MACRO(
+ fDF_RECIP_LOOKUP,(IDX),
+ "recip_lut[IDX]",
+ "Single Precision reciprocal Estimate",
+ (size8u_t)(arch_recip_lookup(IDX)),
+ ()
+)
+
+DEF_MACRO(
+ fDF_INVSQRT_LOOKUP,(IDX),
+ "invsqrt_lut[IDX]",
+ "Single Precision reciprocal square root Estimate",
+ (size8u_t)(arch_invsqrt_lookup(IDX)),
+ ()
+)
+
+DEF_MACRO(
+ fDF_MUL_POW2,(A,B),
+ "A * 2**B",
+ "A * 2**B",
+ (fUNDOUBLE(fDOUBLE(A) * fDOUBLE((0ULL + fDF_BIAS() + (B)) << fDF_MANTBITS()))),
+ ()
+)
+
+DEF_MACRO(
+ fDF_GETEXP,(A),
+ "exponent(A)",
+ "exponent(A)",
+ (((A) >> fDF_MANTBITS()) & 0x7ff),
+ ()
+)
+
+DEF_MACRO(
+ fDF_MAXEXP,(),
+ "2046",
+ "SF maximum exponent",
+ (2046),
+ ()
+)
+
+DEF_MACRO(
+ fDF_RECIP_COMMON,(N,D,O,A),
+ "(N,D,O,A)=recip_common(N,D)",
+ "(N,D,O,A)=recip_common(N,D)",
+ arch_df_recip_common(&N,&D,&O,&A),
+ (A_FPOP)
+)
+
+DEF_MACRO(
+ fDF_INVSQRT_COMMON,(N,O,A),
+ "(N,O,A)=invsqrt_common(N)",
+ "(N,O,A)=invsqrt_common(N)",
+ arch_df_invsqrt_common(&N,&O,&A),
+ (A_FPOP)
+)
+
+DEF_MACRO(
+ fFMA, (A,B,C),
+ "fma(A,B,C)",
+ "Fused Multiply Add: A*B+C",
+ internal_fma(A,B,C),
+ /* nothing */
+)
+
+DEF_MACRO(
+ fDFMPY, (A,B),
+ "A*B",
+ "Multiply: A*B",
+ internal_mpy(A,B),
+ /* nothing */
+)
+
+DEF_MACRO(
+ fDF_MPY_HH, (A,B,ACC),
+ "A*B with partial product ACC",
+ "Multiply: A*B with partial product ACC",
+ internal_mpyhh(A,B,ACC),
+ /* nothing */
+)
+
+DEF_MACRO(
+ fFMAX, (A,B,C,ADJ),
+ "fma(A,B,C)*2**(2*ADJ)",
+ "Fused Multiply Add: (A*B+C)*2**(2*ADJ)",
+ internal_fmax(A,B,C,fSXTN(8,64,ADJ)*2),
+ /* nothing */
+)
+
+DEF_MACRO(
+ fMAKEDF,(SIGN,EXP,MANT),
+ "-1**SIGN * 1.MANT * 2**(EXP-BIAS)",
+ "-1**SIGN * 1.MANT * 2**(EXP-BIAS)",
+ ((((SIGN) & 1ULL) << 63) | (((EXP) & 0x7ffULL) << fDF_MANTBITS()) |
+ ((MANT) & ((1ULL<<fDF_MANTBITS())-1))),
+ ()
+)
+
+DEF_MACRO(
+ fFPOP_START,
+ (),
+ "fpop_start",
+ "Begin floating point operation",
+ arch_fpop_start(thread),
+ /* nothing */
+)
+
+DEF_MACRO(
+ fFPOP_END,
+ (),
+ "fpop_end",
+ "End floating point operation",
+ arch_fpop_end(thread),
+ /* nothing */
+)
+
+DEF_MACRO(
+ fFPSETROUND_NEAREST,
+ (),
+ "round_to_nearest()",
+ "Set rounding mode to Nearest",
+ fesetround(FE_TONEAREST),
+ /* nothing */
+)
+
+DEF_MACRO(
+ fFPSETROUND_CHOP,
+ (),
+ "round_to_zero()",
+ "Set rounding mode to Chop",
+ fesetround(FE_TOWARDZERO),
+ /* nothing */
+)
+
+DEF_MACRO(
+ fFPCANCELFLAGS,
+ (),
+ "cancel_flags()",
+ "Do not update Floating Point Flags",
+ feclearexcept(FE_ALL_EXCEPT),
+ /* nothing */
+)
+
+DEF_MACRO(
+ fISINFPROD,
+ (A,B),
+ "isinf(A*B)",
+ "True if the product of A and B is truly infinite",
+ ((isinf(A) && isinf(B)) ||
+ (isinf(A) && isfinite(B) && ((B) != 0.0)) ||
+ (isinf(B) && isfinite(A) && ((A) != 0.0))),
+ /* nothing */
+)
+
+DEF_MACRO(
+ fISZEROPROD,
+ (A,B),
+ "is_true_zero(A*B)",
+ "True if the product of A and B is truly zero",
+ ((((A) == 0.0) && isfinite(B)) || (((B) == 0.0) && isfinite(A))),
+ /* nothing */
+)
+
+DEF_MACRO(
+ fRAISEFLAGS,
+ (A),
+ "fpflags |= A",
+ "Raise Floating Point Flags",
+ arch_raise_fpflag(A),
+ /* NOTHING */
+)
+
+DEF_MACRO(
+ fDF_MAX,
+ (A,B),
+ "fmax(A,B)",
+ "Floating Point Maximum",
+ (((A)==(B))
+ ? fDOUBLE(fUNDOUBLE(A) & fUNDOUBLE(B))
+ : fmax(A,B)),
+ (A_FPOP)
+)
+
+DEF_MACRO(
+ fDF_MIN,
+ (A,B),
+ "fmin(A,B)",
+ "Floating Point Maximum",
+ (((A)==(B))
+ ? fDOUBLE(fUNDOUBLE(A) | fUNDOUBLE(B))
+ : fmin(A,B)),
+ (A_FPOP)
+)
+
+DEF_MACRO(
+ fSF_MAX,
+ (A,B),
+ "fmaxf(A,B)",
+ "Floating Point Maximum",
+ (((A)==(B))
+ ? fFLOAT(fUNFLOAT(A) & fUNFLOAT(B))
+ : fmaxf(A,B)),
+ (A_FPOP)
+)
+
+DEF_MACRO(
+ fSF_MIN,
+ (A,B),
+ "fmin(A,B)",
+ "Floating Point Maximum",
+ (((A)==(B))
+ ? fFLOAT(fUNFLOAT(A) | fUNFLOAT(B))
+ : fminf(A,B)),
+ (A_FPOP)
+)
+
+/*************************************/
+/* Load/Store support */
+/*************************************/
+
+DEF_MACRO(fMMU,(ADDR),
+ "ADDR",
+ "ADDR",
+ /* mmu xlate */ ADDR,
+ (A_EXCEPTION_TLB,A_EXCEPTION_ACCESS)
+)
+
+DEF_MACRO(fcirc_add,(REG,INCR,IMMED),
+ "REG=circ_add(REG,INCR,IMMED)",
+ "REG=circ_add(REG,INCR,IMMED)",
+ (REG=fcircadd(thread, REG,INCR,IMMED, fREAD_CSREG(MuN))),
+ (A_CIRCADDR,A_IMPLICIT_READS_CS)
+)
+
+DEF_MACRO(fbrev,(REG),
+ "REG.h[1] | brev(REG.h[0])",
+ "REG.h[1] | brev(REG.h[0])",
+ (fbrevaddr(REG)),
+ (A_BREVADDR)
+)
+
+
+DEF_MACRO(fLOAD,(NUM,SIZE,SIGN,EA,DST),
+ "DST = *EA",
+ "Get SIZE bytes from memory at EA and save in DST.",
+ { DST = (size##SIZE##SIGN##_t)MEM_LOAD##SIZE(thread,EA,insn); },
+ (A_LOAD,A_MEMLIKE,A_RESTRICT_SINGLE_MEM_FIRST)
+)
+
+DEF_MACRO(fMEMOP,(NUM,SIZE,SIGN,EA,FNTYPE,VALUE),
+ "DST = *EA",
+ "Get SIZE bytes from memory at EA and save in DST.",
+ { memop##SIZE##_##FNTYPE(thread,EA,VALUE); },
+ (A_LOAD,A_STORE,A_MEMLIKE,A_RESTRICT_SINGLE_MEM_FIRST)
+)
+
+DEF_MACRO(fGET_FRAMEKEY,(),
+ "FRAMEKEY",
+ "FRAMEKEY",
+ READ_RREG(REG_FRAMEKEY),
+ (A_IMPLICIT_READS_FRAMEKEY)
+)
+
+DEF_MACRO(fFRAME_SCRAMBLE,(VAL),
+ "frame_scramble(VAL)",
+ "frame_scramble(VAL)",
+ ((VAL) ^ (fCAST8u(fGET_FRAMEKEY()) << 32)),
+ /* ATTRIBS */
+)
+
+DEF_MACRO(fFRAME_UNSCRAMBLE,(VAL),
+ "frame_unscramble(VAL)",
+ "frame_unscramble(VAL)",
+ fFRAME_SCRAMBLE(VAL),
+ /* ATTRIBS */
+)
+
+DEF_MACRO(fFRAMECHECK,(ADDR,EA),
+ "frame_check_limit(ADDR)",
+ "frame_check_limit(ADDR)",
+ sys_check_framelimit(thread,ADDR,EA),
+ (A_IMPLICIT_READS_FRAMELIMIT)
+)
+
+DEF_MACRO(fLOAD_LOCKED,(NUM,SIZE,SIGN,EA,DST),
+ "DST = *EA; ",
+ "Get SIZE bytes from memory at EA and save in DST.",
+ { DST = (size##SIZE##SIGN##_t)mem_load_locked(thread,EA,SIZE,insn);
+ },
+ (A_LOAD,A_MEMLIKE,A_RESTRICT_SINGLE_MEM_FIRST)
+)
+
+DEF_MACRO(fLOAD_PHYS,(NUM,SIZE,SIGN,SRC1,SRC2,DST),
+ "DST = *((SRC1&0x7ff) | (SRC2<<11))",
+ "Load from physical address",
+ { DST = (size##SIZE##SIGN##_t)mem_load_phys(thread,SRC1,SRC2,insn);
+ },
+ (A_LOAD,A_MEMLIKE,A_RESTRICT_SINGLE_MEM_FIRST)
+)
+
+
+DEF_MACRO(fSTORE,(NUM,SIZE,EA,SRC),
+ "*EA = SRC",
+ "Store SIZE bytes from SRC into memory at EA",
+ { MEM_STORE##SIZE(thread,EA,SRC,insn); },
+ (A_STORE,A_MEMLIKE,A_RESTRICT_SINGLE_MEM_FIRST)
+)
+
+
+DEF_MACRO(fSTORE_LOCKED,(NUM,SIZE,EA,SRC,PRED),
+ "if (lock_valid) { *EA = SRC; PRED = 0xff; lock_valid = 0; } else { PRED = 0; }",
+ "if the lock is valid, Store SIZE bytes from SRC into memory at EA, and invalidate the lock. PRED is set to all 1s if the write actually took place.",
+ { PRED = (mem_store_conditional(thread,EA,SRC,SIZE,insn) ? 0xff : 0); },
+ (A_STORE,A_MEMLIKE,A_RESTRICT_SINGLE_MEM_FIRST)
+)
+
+DEF_MACRO(fVTCM_MEMCPY,(DST,SRC,SIZE),
+ "for (i = 0; i <= SIZE; i++) { *(DST + i) = *(SRC + i); }",
+ "Copy SIZE+1 bytes from memory at SRC to memory at DST",
+ mem_vtcm_memcpy(thread, insn, DST, SRC, SIZE);,
+ /* ATTRIBS */
+)
+
+
+/*************************************/
+/* Permute Handler */
+/*************************************/
+
+DEF_MACRO(fPERMUTEH,(SRC0,SRC1,CTRL),
+ "permute(SRC0,SRC1,CTRL)",
+ "Permute SRC0 and SRC1 according to CTRL",
+ fpermuteh((SRC0),(SRC1),CTRL),
+ (A_PERM)
+)
+
+DEF_MACRO(fPERMUTEB,(SRC0,SRC1,CTRL),
+ "permute(SRC0,SRC1,CTRL)",
+ "Permute SRC0 and SRC1 according to CTRL",
+ fpermuteb((SRC0),(SRC1),CTRL),
+ (A_PERM)
+)
+
+/*************************************/
+/* Functions to help with bytes */
+/*************************************/
+
+DEF_MACRO(fGETBYTE,(N,SRC),
+ "SRC.b[N]",
+ "Byte N from SRC",
+ ((size1s_t)((SRC>>((N)*8))&0xff)),
+ /* nothing */
+)
+
+DEF_MACRO(fGETUBYTE,(N,SRC),
+ "SRC.ub[N]",
+ "Byte N from SRC",
+ ((size1u_t)((SRC>>((N)*8))&0xff)),
+ /* nothing */
+)
+
+DEF_MACRO(fSETBYTE,(N,DST,VAL),
+ "DST.b[N]=VAL",
+ "Byte N from DST = VAL",
+ {
+ DST = (DST & ~(0x0ffLL<<((N)*8))) | (((size8u_t)((VAL) & 0x0ffLL)) << ((N)*8));
+ },
+ /* nothing */
+)
+
+DEF_MACRO(fGETHALF,(N,SRC),
+ "SRC.h[N]",
+ "Halfword N from SRC",
+ ((size2s_t)((SRC>>((N)*16))&0xffff)),
+ /* nothing */
+)
+
+DEF_MACRO(fGETUHALF,(N,SRC),
+ "SRC.uh[N]",
+ "Halfword N from SRC",
+ ((size2u_t)((SRC>>((N)*16))&0xffff)),
+ /* nothing */
+)
+
+DEF_MACRO(fSETHALF,(N,DST,VAL),
+ "DST.h[N]=VAL",
+ "Halfword N from DST = VAL",
+ {
+ DST = (DST & ~(0x0ffffLL<<((N)*16))) | (((size8u_t)((VAL) & 0x0ffff)) << ((N)*16));
+ },
+ /* nothing */
+)
+
+
+
+DEF_MACRO(fGETWORD,(N,SRC),
+ "SRC.w[N]",
+ "Word N from SRC",
+ ((size8s_t)((size4s_t)((SRC>>((N)*32))&0x0ffffffffLL))),
+ /* nothing */
+)
+
+DEF_MACRO(fGETUWORD,(N,SRC),
+ "SRC.uw[N]",
+ "Word N from SRC",
+ ((size8u_t)((size4u_t)((SRC>>((N)*32))&0x0ffffffffLL))),
+ /* nothing */
+)
+
+DEF_MACRO(fSETWORD,(N,DST,VAL),
+ "DST.w[N]=VAL",
+ "Word N from DST = VAL",
+ {
+ DST = (DST & ~(0x0ffffffffLL<<((N)*32))) | (((VAL) & 0x0ffffffffLL) << ((N)*32));
+ },
+ /* nothing */
+)
+
+DEF_MACRO(fACC,(),
+ "",
+ "",
+ ,
+ (A_ACC)
+)
+
+DEF_MACRO(fEXTENSION_AUDIO,(A),
+ "A",
+ "A",
+ A,
+ (A_EXTENSION_AUDIO,A_NOTE_EXTENSION_AUDIO)
+)
+
+DEF_MACRO(fSETBIT,(N,DST,VAL),
+ "DST.N = VAL",
+ "Set bit N in DST to VAL",
+ {
+ DST = (DST & ~(1ULL<<(N))) | (((size8u_t)(VAL))<<(N));
+ },
+ /* nothing */
+)
+
+DEF_MACRO(fGETBIT,(N,SRC),
+ "SRC.N",
+ "Get bit N from SRC",
+ (((SRC)>>N)&1),
+ /* nothing */
+)
+
+
+DEF_MACRO(fSETBITS,(HI,LO,DST,VAL),
+ "DST[HI:LO] = VAL",
+ "Set bits from HI to LO in DST to VAL",
+ do {
+ int j;
+ for (j=LO;j<=HI;j++) {
+ fSETBIT(j,DST,VAL);
+ }
+ } while (0),
+ /* nothing */
+)
+
+DEF_MACRO(fUNDEFINED,(),
+ "UNDEFINED",
+ "UNDEFINED",
+ warn("[UNDEFINED]: architecturally undefined"),
+ /* NOTHING */
+)
+
+/*************************************/
+/* Used for parity, etc........ */
+/*************************************/
+DEF_MACRO(fCOUNTONES_2,(VAL),
+ "count_ones(VAL)",
+ "Count the number of bits set in VAL",
+ count_ones_2(VAL),
+ /* nothing */
+)
+
+DEF_MACRO(fCOUNTONES_4,(VAL),
+ "count_ones(VAL)",
+ "Count the number of bits set in VAL",
+ count_ones_4(VAL),
+ /* nothing */
+)
+
+DEF_MACRO(fCOUNTONES_8,(VAL),
+ "count_ones(VAL)",
+ "Count the number of bits set in VAL",
+ count_ones_8(VAL),
+ /* nothing */
+)
+
+DEF_MACRO(fBREV_8,(VAL),
+ "reverse_bits(VAL)",
+ "Count the number of bits set in VAL",
+ reverse_bits_8(VAL),
+ /* nothing */
+)
+
+DEF_MACRO(fBREV_4,(VAL),
+ "reverse_bits(VAL)",
+ "Count the number of bits set in VAL",
+ reverse_bits_4(VAL),
+ /* nothing */
+)
+
+DEF_MACRO(fBREV_2,(VAL),
+ "reverse_bits(VAL)",
+ "Count the number of bits set in VAL",
+ reverse_bits_2(VAL),
+ /* nothing */
+)
+
+DEF_MACRO(fBREV_1,(VAL),
+ "reverse_bits(VAL)",
+ "Count the number of bits set in VAL",
+ reverse_bits_1(VAL),
+ /* nothing */
+)
+
+DEF_MACRO(fCL1_8,(VAL),
+ "count_leading_ones(VAL)",
+ "Count the number of bits set in VAL",
+ count_leading_ones_8(VAL),
+ /* nothing */
+)
+
+DEF_MACRO(fCL1_4,(VAL),
+ "count_leading_ones(VAL)",
+ "Count the number of bits set in VAL",
+ count_leading_ones_4(VAL),
+ /* nothing */
+)
+
+DEF_MACRO(fCL1_2,(VAL),
+ "count_leading_ones(VAL)",
+ "Count the number of bits set in VAL",
+ count_leading_ones_2(VAL),
+ /* nothing */
+)
+
+DEF_MACRO(fCL1_1,(VAL),
+ "count_leading_ones(VAL)",
+ "Count the number of bits set in VAL",
+ count_leading_ones_1(VAL),
+ /* nothing */
+)
+
+DEF_MACRO(fINTERLEAVE,(ODD,EVEN),
+ "interleave(ODD,EVEN)",
+ "Interleave odd bits from ODD with even bits from EVEN",
+ interleave(ODD,EVEN),
+ /* nothing */
+)
+
+DEF_MACRO(fDEINTERLEAVE,(MIXED),
+ "deinterleave(ODD,EVEN)",
+ "Deinterleave odd bits into high half even bits to low half",
+ deinterleave(MIXED),
+ /* nothing */
+)
+
+DEF_MACRO(fNORM16,(VAL),
+ "get norm of 16bit value(VAL)",
+ "the number of leading sign bits in VAL",
+ ((VAL == 0) ? (31) : (fMAX(fCL1_2( VAL),fCL1_2(~VAL))-1)),
+ /* nothing */
+)
+
+
+
+DEF_MACRO(fHIDE,(A),
+ "",
+ "",
+ A,
+ ()
+)
+
+DEF_MACRO(fASM_MAP,(A,B),
+ "Assembler mapped to: B",
+ "Assembler mapped to: B",
+ fatal("ASM_MAP instruction " A "->" B " executed.");,
+ ()
+)
+
+DEF_MACRO(fCOND_ASM_MAP,(A,C,X,Y),
+ "if (C) {Assembler mapped to: X;} else {Assembler mapped to: Y;}@",
+ "if (C) {Assembler mapped to: Y;} else {Assembler mapped to: Y;}@",
+ fatal("ASM_MAP instruction " A "->" X "/" Y " executed.");,
+ ()
+)
+
+DEF_MACRO(fCONSTLL,(A),
+ "A",
+ "A",
+ A##LL,
+)
+
+DEF_MACRO(fCONSTULL,(A),
+ "A",
+ "A",
+ A##ULL,
+)
+
+/* Do the things in the parens, but don't print the parens. */
+DEF_MACRO(fECHO,(A),
+ "A",
+ "A",
+ (A),
+ /* nothing */
+)
+
+
+/********************************************/
+/* OS interface and stop/wait */
+/********************************************/
+
+DEF_MACRO(RUNNABLE_THREADS_MAX,,
+ "THREADS_MAX",
+ "THREADS_MAX",
+ (thread->processor_ptr->runnable_threads_max),
+ ()
+)
+
+DEF_MACRO(THREAD_IS_ON,(PROC,TNUM),
+ "THREAD IS ENABLE",
+ "Thread is enabled in the revid",
+ ((PROC->arch_proc_options->thread_enable_mask>>TNUM) & 0x1),
+ ()
+)
+
+DEF_MACRO(THREAD_EN_MASK,(PROC),
+ "THREAD IS ENABLE MASK",
+ "Thread is enabled in the revid",
+ ((PROC->arch_proc_options->thread_enable_mask)),
+ ()
+)
+
+
+
+DEF_MACRO(READ_IMASK,(TH),
+ "IMASK[TH]",
+ "IMASK[TH]",
+ (((TH) >= (thread->processor_ptr->runnable_threads_max)) ? 0 : (thread->processor_ptr->thread[TH]->Regs[REG_IMASK])),
+ (A_IMPLICIT_READS_IMASK_ANYTHREAD)
+)
+DEF_MACRO(WRITE_IMASK,(TH,VAL),
+ "IMASK[TH]=VAL",
+ "IMASK[TH]=VAL",
+ if ((TH) < (thread->processor_ptr->runnable_threads_max)) { thread->processor_ptr->thread[TH]->Regs[REG_IMASK]=(VAL & reg_mutability[REG_IMASK] ); },
+ (A_IMPLICIT_WRITES_IMASK_ANYTHREAD)
+)
+
+
+DEF_MACRO(WRITE_PRIO,(TH,VAL),
+ "TID[TH].PRIO=VAL",
+ "TID[TH].PRIO=VAL",
+ {
+ if ((TH) < (thread->processor_ptr->runnable_threads_max)) {
+ size4u_t tid_reg = thread->processor_ptr->thread[TH]->Regs[REG_TID];
+ fINSERT_BITS(tid_reg, reg_field_info[STID_PRIO].width, reg_field_info[STID_PRIO].offset, VAL);
+ LOG_OTHER_THREAD_REG_WRITE(thread,REG_TID,tid_reg,TH);
+ }
+ },
+ (A_IMPLICIT_WRITES_STID_PRIO_ANYTHREAD)
+)
+
+
+DEF_MACRO(DO_IASSIGNW,(REG),
+ "IASSIGNW(REG)",
+ "IASSIGNW(REG)",
+ {
+ int i;
+ int intbitpos = ((REG>>16)&0xF);
+ for (i=0;i<RUNNABLE_THREADS_MAX;i++) {
+ if(( (thread->processor_ptr->arch_proc_options->thread_enable_mask>>i) & 0x1)) {
+ fINSERT_BITS(thread->processor_ptr->thread[i]->Regs[REG_IMASK],1, intbitpos, (REG>>i) & 1);
+ }
+ }
+ },
+ (A_IMPLICIT_WRITES_IMASK_ANYTHREAD)
+)
+
+
+
+
+DEF_MACRO(fDO_NMI,(SREG),
+ "Raise NMI on threads",
+ "Raise NMI on threads",
+ {
+ int i;
+ for (i=0;i<RUNNABLE_THREADS_MAX;i++) {
+ if( ( (thread->processor_ptr->arch_proc_options->thread_enable_mask>>i) & 0x1) ) {
+ if (SREG & (1<<i)) {
+ register_nmi_interrupt(thread->processor_ptr->thread[i]);
+ }
+ }
+ }
+ },
+)
+
+DEF_MACRO(fDO_TRACE,(SREG),
+ "Send value to ETM trace",
+ "Send value to ETM trace",
+ {
+ fHIDE(CALLBACK(thread->processor_ptr->options->trace_callback,
+ thread->system_ptr,thread->processor_ptr,
+ thread->threadId,SREG);)
+ },
+)
+
+DEF_MACRO(DO_IASSIGNR,(SREG,DREG),
+ "DREG=IASSIGNR(SREG)",
+ "DREG=IASSIGNR(SREG)",
+ {
+ int i;
+ int result=0;
+ int intbitpos = ((SREG>>16)&0xF);
+ for (i=0;i<RUNNABLE_THREADS_MAX;i++) {
+ if(( (thread->processor_ptr->arch_proc_options->thread_enable_mask>>i) & 0x1)) {
+ result |= (((thread->processor_ptr->thread[i]->Regs[REG_IMASK]>>intbitpos)&1)<<i);
+ }
+ }
+ DREG=result;
+ },
+ (A_IMPLICIT_READS_IMASK_ANYTHREAD)
+)
+
+#ifdef NEW_INTERRUPTS
+
+DEF_MACRO(DO_SWI,(REG),
+ "IPEND |= REG",
+ "IPEND |= REG",
+ {fHIDE(CALLBACK(thread->processor_ptr->options->swi_callback,
+ thread->system_ptr,thread->processor_ptr,
+ thread->threadId,REG));
+ fLOG_GLOBAL_REG_FIELD(IPENDAD,IPENDAD_IPEND,fREAD_GLOBAL_REG_FIELD(IPENDAD,IPENDAD_IPEND)|(REG));
+ },
+ (A_EXCEPTION_SWI,A_IMPLICIT_READS_IPENDAD_IPEND,A_IMPLICIT_WRITES_IPENDAD_IPEND)
+)
+
+DEF_MACRO(DO_CSWI,(REG),
+ "IPEND &= ~REG",
+ "IPEND &= ~REG",
+ fLOG_GLOBAL_REG_FIELD(IPENDAD,IPENDAD_IPEND,fREAD_GLOBAL_REG_FIELD(IPENDAD,IPENDAD_IPEND) & ~(REG));,
+ (A_IMPLICIT_READS_IPENDAD_IPEND,A_IMPLICIT_WRITES_IPENDAD_IPEND)
+)
+
+DEF_MACRO(DO_CIAD,(VAL),
+ "IAD &= ~VAL",
+ "IAD &= ~VAL",
+ sys_ciad(thread,VAL);
+ fLOG_GLOBAL_REG_FIELD(IPENDAD,IPENDAD_IAD,fREAD_GLOBAL_REG_FIELD(IPENDAD,IPENDAD_IAD) & ~(VAL));,
+ (A_EXCEPTION_SWI,A_IMPLICIT_READS_IPENDAD_IAD,A_IMPLICIT_WRITES_IPENDAD_IAD)
+)
+
+DEF_MACRO(DO_SIAD,(VAL),
+ "IAD |= VAL",
+ "IAD |= VAL",
+ sys_siad(thread,VAL);
+ fLOG_GLOBAL_REG_FIELD(IPENDAD,IPENDAD_IAD,fREAD_GLOBAL_REG_FIELD(IPENDAD,IPENDAD_IAD) | (VAL));,
+ (A_EXCEPTION_SWI,A_IMPLICIT_READS_IPENDAD_IAD,A_IMPLICIT_WRITES_IPENDAD_IAD)
+)
+
+#else
+
+DEF_MACRO(DO_SWI,(REG),
+ "IPEND |= REG",
+ "IPEND |= REG",
+ {fHIDE(CALLBACK(thread->processor_ptr->options->swi_callback,
+ thread->system_ptr,thread->processor_ptr,
+ thread->threadId,REG));
+ LOG_GLOBAL_REG_WRITE(REG_IPEND,(GLOBAL_REG_READ(REG_IPEND) | (REG & GLOBAL_REG_READ(REG_IEL))));
+ },
+ (A_EXCEPTION_SWI)
+)
+
+DEF_MACRO(DO_CSWI,(REG),
+ "IPEND &= ~REG",
+ "IPEND &= ~REG",
+ LOG_GLOBAL_REG_WRITE(REG_IPEND,GLOBAL_REG_READ(REG_IPEND) & ~((REG) & GLOBAL_REG_READ(REG_IEL)));,
+ ()
+)
+
+DEF_MACRO(DO_CIAD,(VAL),
+ "IAD &= ~VAL",
+ "IAD &= ~VAL",
+ sys_ciad(thread,VAL); LOG_GLOBAL_REG_WRITE(REG_IAD,GLOBAL_REG_READ(REG_IAD) & ~(VAL));,
+ (A_EXCEPTION_SWI)
+)
+
+DEF_MACRO(DO_SIAD,(VAL),
+ "IAD |= VAL",
+ "IAD |= VAL",
+ sys_siad(thread,VAL); LOG_GLOBAL_REG_WRITE(REG_IAD,GLOBAL_REG_READ(REG_IAD) | (VAL));,
+ (A_EXCEPTION_SWI)
+)
+
+
+#endif
+
+DEF_MACRO(fBREAK,(),
+ "Enter Debug mode",
+ "Enter Debug mode",
+ {isdb_brkpt_insn(thread->processor_ptr,thread->threadId);},
+ ()
+)
+
+DEF_MACRO(fGP_DOCHKPAGECROSS,(BASE,SUM),
+ "",
+ "",
+ if (!(insn->extension_valid)) {
+ fDOCHKPAGECROSS(BASE,SUM);
+ },
+ (A_EA_PAGECROSS)
+)
+
+DEF_MACRO(fDOCHKPAGECROSS,(BASE,SUM),
+ "",
+ "",
+ if (thread->bq_on) {
+ thread->mem_access[insn->slot].check_page_crosses = 1;
+ thread->mem_access[insn->slot].page_cross_base = BASE;
+ thread->mem_access[insn->slot].page_cross_sum = SUM;
+ },
+ (A_EA_PAGECROSS)
+)
+
+DEF_MACRO(fTIMING_AIA,(OLDVA,NEWVA),
+ "",
+ "",
+ if(thread->bq_on){
+ thread->mem_access[insn->slot].post_updated = 1;
+ thread->mem_access[insn->slot].post_updated_va = NEWVA;
+ insn->is_aia = 1;
+ },
+ (A_PM_ANY)
+)
+
+
+DEF_MACRO(fPAUSE,(IMM),
+ "Pause for IMM cycles",
+ "Pause for IMM cycles",
+ {sys_pause(thread, insn->slot, IMM);},
+ ()
+)
+
+
+#if 1
+/* The way it should be */
+DEF_MACRO(fTRAP,(TRAPTYPE,IMM),
+ "SSR.CAUSE = IMM; TRAP # TRAPTYPE",
+ "SSR.CAUSE = IMM; TRAP # TRAPTYPE",
+ 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);,
+ (A_EXCEPTION_SWI)
+)
+#else
+DEF_MACRO(fTRAP,(TRAPTYPE,IMM),
+ "SSR.CAUSE = IMM; TRAP # TRAPTYPE",
+ "SSR.CAUSE = IMM; TRAP # TRAPTYPE",
+ if ((TRAPTYPE == 0) && (IMM == 0) &&
+ (!thread->sandbox_execution) &&
+ (!thread->processor_ptr->options->disable_angelswi)) {
+ sim_handle_trap(thread->system_ptr,thread->processor_ptr,thread->threadId,0);
+ /*thread->status |= EXEC_STATUS_SWI;*/
+ } else if ((TRAPTYPE == 0) && (IMM == 0xdb) &&
+ (!thread->sandbox_execution) &&
+ (!thread->processor_ptr->options->disable_angelswi)) {
+ sim_handle_debug(thread->system_ptr,thread->processor_ptr,thread->threadId,0xdb);
+ } else {
+ warn("Trap exception, TYPE=%d NPC=%x IMM=0x%x",TRAPTYPE,fREAD_NPC(),IMM);
+ register_trap_exception(thread,fREAD_NPC(),TRAPTYPE,IMM);
+ },
+ (A_EXCEPTION_SWI)
+)
+#endif
+
+DEF_MACRO(fINTERNAL_CLEAR_SAMEPAGE,
+ (),
+ "",
+ "",
+ /* force re-xlate at next fetch, refresh of in_user_mode, etc */
+ /* Permissions change too... */
+ sys_utlb_invalidate(thread->processor_ptr,thread),
+ /* NOTHING */
+)
+
+DEF_MACRO(fCLEAR_RTE_EX,(),
+ "SSR.SSR_EX = 0",
+ "SSR.SSR_EX = 0",
+ {
+ fLOG_REG_FIELD(SSR,SSR_EX,0);
+ fINTERNAL_CLEAR_SAMEPAGE();
+ },
+ ()
+)
+
+DEF_MACRO(fTLB_LOCK_AVAILABLE,(),
+ "SYSCFG.TLBLOCK == 0",
+ "SYSCFG.TLBLOCK == 0",
+ (fREAD_GLOBAL_REG_FIELD(SYSCONF,SYSCFG_TLBLOCK) == 0),
+ ()
+)
+
+DEF_MACRO(fK0_LOCK_AVAILABLE,(),
+ "SYSCFG.K0LOCK == 0",
+ "SYSCFG.K0LOCK == 0",
+ (fREAD_GLOBAL_REG_FIELD(SYSCONF,SYSCFG_K0LOCK) == 0),
+ ()
+)
+
+DEF_MACRO(fSET_TLB_LOCK,(),
+ "if (can_aquire_tlb_lock) {SYSCFG.TLBLOCK = 1;} else {sleep_until_available;}",
+ "if (can_aquire_tlb_lock) {SYSCFG.TLBLOCK = 1;} else {sleep_until_available;}",
+ {
+ if (fTLB_LOCK_AVAILABLE()) {
+ fLOG_GLOBAL_REG_FIELD(SYSCONF,SYSCFG_TLBLOCK,1);
+ } else {
+ sys_waiting_for_tlb_lock(thread);
+ }
+ },
+ (A_IMPLICIT_READS_SYSCFG_TLBLOCK,A_IMPLICIT_WRITES_SYSCFG_TLBLOCK)
+)
+
+DEF_MACRO(fSET_K0_LOCK,(),
+ "if (can_aquire_k0_lock) {SYSCFG.K0LOCK = 1;} else {sleep_until_available;}",
+ "if (can_aquire_k0_lock) {SYSCFG.K0LOCK = 1;} else {sleep_until_available;}",
+ {
+ if (fK0_LOCK_AVAILABLE() && sys_k0lock_queue_ready(thread)) {
+ warn("k0lock: T%d: PC=0x%x: PCycle=%lld",thread->threadId,thread->Regs[REG_PC],thread->processor_ptr->pstats[pcycles]);
+ fLOG_GLOBAL_REG_FIELD(SYSCONF,SYSCFG_K0LOCK,1);
+ } else {
+ warn("k0lock_waiting: T%d: PC=0x%x: PCycle=%lld",thread->threadId,thread->Regs[REG_PC],thread->processor_ptr->pstats[pcycles]);
+ sys_waiting_for_k0_lock(thread);
+ }
+ },
+ (A_IMPLICIT_READS_SYSCFG_K0LOCK,A_IMPLICIT_WRITES_SYSCFG_K0LOCK)
+)
+
+DEF_MACRO(fCLEAR_TLB_LOCK,(),
+ "SYSCFG.TLBLOCK = 0",
+ "SYSCFG.TLBLOCK = 0",
+ {
+ int i;
+ fLOG_GLOBAL_REG_FIELD(SYSCONF,SYSCFG_TLBLOCK,0);
+ for (i = 0; i < RUNNABLE_THREADS_MAX; i++) {
+ if(( (thread->processor_ptr->arch_proc_options->thread_enable_mask>>i) & 0x1)) {
+ thread->processor_ptr->thread[i]->cu_tlb_lock_waiting = 0;
+ }
+ }
+ },
+ (A_IMPLICIT_READS_SYSCFG_TLBLOCK,A_IMPLICIT_WRITES_SYSCFG_TLBLOCK)
+)
+
+DEF_MACRO(fCLEAR_K0_LOCK,(),
+ "SYSCFG.K0LOCK = 0",
+ "SYSCFG.K0LOCK = 0",
+ do {
+ warn("k0unlock: T%d: PC=0x%x: Pcycle=%lld",thread->threadId,thread->Regs[REG_PC], thread->processor_ptr->pstats[pcycles]);
+ sys_initiate_clear_k0_lock(thread);
+ } while (0),
+ (A_IMPLICIT_READS_SYSCFG_K0LOCK,A_IMPLICIT_WRITES_SYSCFG_K0LOCK)
+)
+
+DEF_MACRO(fWRITE_REG_FIELD,(REG,FIELD,VAL),
+ "REG.FIELD = VAL",
+ "REG.FIELD = VAL",
+ fINSERT_BITS(thread->Regs[REG_##REG],
+ reg_field_info[FIELD].width,
+ reg_field_info[FIELD].offset,VAL),
+)
+
+DEF_MACRO(fALIGN_REG_FIELD_VALUE,(FIELD,VAL),
+ "VAL << FIELD.OFFSET",
+ "VAL << FIELD.OFFSET",
+ ((VAL)<<reg_field_info[FIELD].offset),
+ /* */
+)
+
+DEF_MACRO(fGET_REG_FIELD_MASK,(FIELD),
+ "VAL << FIELD.OFFSET",
+ "VAL << FIELD.OFFSET",
+ (((1<<reg_field_info[FIELD].width)-1)<<reg_field_info[FIELD].offset),
+ /* */
+)
+
+DEF_MACRO(fLOG_REG_FIELD,(REG,FIELD,VAL),
+ "REG.FIELD = VAL",
+ "REG.FIELD = VAL",
+ LOG_MASKED_REG_WRITE(thread,REG_##REG,
+ fALIGN_REG_FIELD_VALUE(FIELD,VAL),
+ fGET_REG_FIELD_MASK(FIELD)),
+ ()
+)
+
+DEF_MACRO(fWRITE_GLOBAL_REG_FIELD,(REG,FIELD,VAL),
+ "REG.FIELD = VAL",
+ "REG.FIELD = VAL",
+ fINSERT_BITS(thread->processor_ptr->global_regs[REG_##REG],
+ reg_field_info[FIELD].width,
+ reg_field_info[FIELD].offset,VAL),
+)
+
+DEF_MACRO(fLOG_GLOBAL_REG_FIELD,(REG,FIELD,VAL),
+ "REG.FIELD = VAL",
+ "REG.FIELD = VAL",
+ LOG_MASKED_GLOBAL_REG_WRITE(REG_##REG,
+ fALIGN_REG_FIELD_VALUE(FIELD,VAL),
+ fGET_REG_FIELD_MASK(FIELD)),
+ ()
+)
+
+DEF_MACRO(fREAD_REG_FIELD,(REG,FIELD),
+ "REG.FIELD",
+ "REG.FIELD",
+ fEXTRACTU_BITS(thread->Regs[REG_##REG],
+ reg_field_info[FIELD].width,
+ reg_field_info[FIELD].offset),
+ /* ATTRIBS */
+)
+
+DEF_MACRO(fREAD_GLOBAL_REG_FIELD,(REG,FIELD),
+ "REG.FIELD",
+ "REG.FIELD",
+ fEXTRACTU_BITS(thread->processor_ptr->global_regs[REG_##REG],
+ reg_field_info[FIELD].width,
+ reg_field_info[FIELD].offset),
+ /* ATTRIBS */
+)
+
+DEF_MACRO(fGET_FIELD,(VAL,FIELD),
+ "VAL.FIELD",
+ "VAL.FIELD",
+ fEXTRACTU_BITS(VAL,
+ reg_field_info[FIELD].width,
+ reg_field_info[FIELD].offset),
+ /* ATTRIBS */
+)
+
+DEF_MACRO(fSET_FIELD,(VAL,FIELD,NEWVAL),
+ "VAL.FIELD",
+ "VAL.FIELD",
+ fINSERT_BITS(VAL,
+ reg_field_info[FIELD].width,
+ reg_field_info[FIELD].offset,
+ (NEWVAL)),
+ /* ATTRIBS */
+)
+
+DEF_MACRO(fSET_RUN_MODE_NOW,(TNUM),
+ "modectl[TNUM] = 1",
+ "modectl[TNUM] = 1",
+ {thread->processor_ptr->global_regs[REG_MODECTL] |= (1<<TNUM);
+ thread->last_commit_cycle = thread->processor_ptr->pcycle_counter;
+ sys_recalc_num_running_threads(thread->processor_ptr);},
+)
+
+DEF_MACRO(fIN_DEBUG_MODE,(TNUM),
+ "in_debug_mode",
+ "in_debug_mode",
+ (thread->debug_mode || (fREAD_GLOBAL_REG_FIELD(ISDBST,ISDBST_DEBUGMODE) & 1<<TNUM)),
+ ()
+)
+DEF_MACRO(fIN_DEBUG_MODE_NO_ISDB,(TNUM),
+ "in_debug_mode",
+ "in_debug_mode",
+ (thread->debug_mode),
+ ()
+)
+
+
+DEF_MACRO(fIN_DEBUG_MODE_WARN,(TNUM),
+ "",
+ "",
+ {
+ if (fREAD_GLOBAL_REG_FIELD(ISDBST,ISDBST_DEBUGMODE) & 1<<TNUM)
+ warn("In ISDB debug mode, but TB told me to step normally");
+ },
+ ()
+)
+
+DEF_MACRO(fCLEAR_RUN_MODE,(TNUM),
+ "modectl[TNUM] = 0",
+ "modectl[TNUM] = 0",
+ {fLOG_GLOBAL_REG_FIELD(MODECTL,MODECTL_E,
+ fREAD_GLOBAL_REG_FIELD(MODECTL,MODECTL_E) & ~(1<<(TNUM)))},
+ /* NOTHING */
+)
+
+DEF_MACRO(fCLEAR_RUN_MODE_NOW,(TNUM),
+ "modectl[TNUM] = 0",
+ "modectl[TNUM] = 0",
+ do {
+ fWRITE_GLOBAL_REG_FIELD(MODECTL,MODECTL_E,
+ fREAD_GLOBAL_REG_FIELD(MODECTL,MODECTL_E) & ~(1<<(TNUM)));
+ sys_recalc_num_running_threads(thread->processor_ptr);
+ } while (0),
+ /* NOTHING */
+)
+
+DEF_MACRO(fGET_RUN_MODE,(TNUM),
+ "modectl[TNUM]",
+ "modectl[TNUM]",
+ ((thread->processor_ptr->global_regs[REG_MODECTL]>>TNUM)&0x1),
+)
+
+DEF_MACRO(fSET_WAIT_MODE,(TNUM),
+ "modectl[(TNUM+16)] = 1",
+ "modectl[(TNUM+16)] = 1",
+ {fLOG_GLOBAL_REG_FIELD(MODECTL,MODECTL_W,
+ fREAD_GLOBAL_REG_FIELD(MODECTL,MODECTL_W) | 1<<(TNUM))},
+ /* NOTHING */
+)
+
+DEF_MACRO(fCLEAR_WAIT_MODE,(TNUM),
+ "modectl[(TNUM+16)] = 0",
+ "modectl[(TNUM+16)] = 0",
+ {thread->processor_ptr->global_regs[REG_MODECTL] &= ~(1<<(TNUM+16));
+ thread->last_commit_cycle = thread->processor_ptr->pcycle_counter;
+ sys_recalc_num_running_threads(thread->processor_ptr);},
+)
+
+DEF_MACRO(fGET_WAIT_MODE,(TNUM),
+ "modectl[(TNUM+16)]",
+ "modectl[(TNUM+16)]",
+ ((thread->processor_ptr->global_regs[REG_MODECTL]>>(TNUM+16))&0x1),
+)
+
+
+DEF_MACRO(fRESET_THREAD,(T,NUM),
+ "reset_thread(NUM)",
+ "reset_thread(NUM)",
+ register_reset_interrupt(T,NUM),
+)
+
+DEF_MACRO(fREAD_CURRENT_EVB,(),
+ "EVB",
+ "EVB",
+ (GLOBAL_REG_READ(REG_EVB)),
+ /* nothing */
+)
+
+DEF_MACRO(fREAD_ELR,(),
+ "ELR",
+ "ELR",
+ READ_RREG(REG_ELR),
+ (A_IMPLICIT_READS_ELR)
+)
+
+DEF_MACRO(fPOW2_HELP_ROUNDUP,(VAL),
+ "helper for pow2_roundup",
+ "helper for pow2_roundup",
+ ((VAL) | ((VAL) >> 1) | ((VAL) >> 2) | ((VAL) >> 4) | ((VAL) >> 8) | ((VAL) >> 16)),
+ ()
+)
+
+DEF_MACRO(fPOW2_ROUNDUP,(VAL),
+ "pow2_roundup(VAL)",
+ "pow2_roundup(VAL)",
+ fPOW2_HELP_ROUNDUP((VAL)-1)+1,
+ ()
+)
+
+DEF_MACRO(fTLB_IDXMASK,(INDEX),
+ "INDEX % TLBSIZE",
+ "INDEX % TLBSIZE",
+ ((INDEX) & (fPOW2_ROUNDUP(fCAST4u(thread->processor_ptr->arch_proc_options->jtlb_size)) - 1)),
+ ()
+)
+
+DEF_MACRO(fTLB_NONPOW2WRAP,(INDEX),
+ "INDEX % TLBSIZE",
+ "INDEX % TLBSIZE",
+ (((INDEX) >= thread->processor_ptr->arch_proc_options->jtlb_size) ? ((INDEX) - thread->processor_ptr->arch_proc_options->jtlb_size) : (INDEX)),
+ /* ATTRIBS */
+)
+
+DEF_MACRO(fTLBW,(INDEX,VALUE),
+ "TLB[INDEX] = VALUE",
+ "TLB[INDEX] = VALUE",
+ do {size4u_t __myidx = fTLB_NONPOW2WRAP(fTLB_IDXMASK(INDEX));
+ TLB_REG_WRITE(__myidx,VALUE);
+ fHIDE(CALLBACK(thread->processor_ptr->options->tlbw_callback,thread->system_ptr,thread->processor_ptr,thread->threadId,__myidx);)
+ fHIDE(sys_tlb_write(thread,__myidx,VALUE);)} while (0),
+ /* ATTRIBS */
+)
+
+DEF_MACRO(fTLB_ENTRY_OVERLAP,(VALUE),
+ "CHECK_TLB_OVERLAP(VALUE)",
+ "CHECK_TLB_OVERLAP(VALUE)",
+ fHIDE( (sys_check_overlap(thread,VALUE)!=-2) ),
+ /* ATTRIBS */
+)
+
+DEF_MACRO(fTLB_ENTRY_OVERLAP_IDX,(VALUE),
+ "GET_OVERLAPPING_IDX(VALUE)",
+ "GET_OVERLAPPING_IDX(VALUE)",
+ fHIDE(sys_check_overlap(thread,VALUE)),
+ /* ATTRIBS */
+)
+
+
+DEF_MACRO(fTLBR,(INDEX),
+ "TLB[INDEX]",
+ "TLB[INDEX]",
+ TLB_REG_READ(fTLB_NONPOW2WRAP(fTLB_IDXMASK(INDEX))),
+ /* ATTRIBS */
+)
+
+DEF_MACRO(fTLBP,(TLBHI),
+ "search_TLB(TLBHI)",
+ "search_TLB(TLBHI)",
+ tlb_lookup(thread,((TLBHI)>>12),((TLBHI)<<12),1),
+ /* attribs */
+)
+
+
+
+DEF_MACRO(READ_SGP0,(),
+ "SGP0",
+ "SGP0",
+ READ_RREG(REG_SGP),
+ (A_IMPLICIT_READS_SGP0)
+)
+
+DEF_MACRO(READ_SGP1,(),
+ "SGP1",
+ "SGP1",
+ READ_RREG(REG_SGP+1),
+ (A_IMPLICIT_READS_SGP1)
+)
+
+DEF_MACRO(READ_SGP10,(),
+ "SGP",
+ "SGP",
+ READ_RREG_PAIR(REG_SGP),
+ (A_IMPLICIT_READS_SGP0,A_IMPLICIT_READS_SGP1)
+)
+
+DEF_MACRO(READ_UGP,(),
+ "UGP",
+ "UGP",
+ READ_RREG(REG_UGP),
+)
+
+DEF_MACRO(WRITE_SGP0,(VAL),
+ "SGP0 = VAL",
+ "SGP0 = VAL",
+ WRITE_RREG(REG_SGP,VAL),
+ (A_IMPLICIT_WRITES_SGP0)
+)
+
+DEF_MACRO(WRITE_SGP1,(VAL),
+ "SGP1 = VAL",
+ "SGP1 = VAL",
+ WRITE_RREG(REG_SGP+1,VAL),
+ (A_IMPLICIT_WRITES_SGP1)
+)
+
+DEF_MACRO(WRITE_SGP10,(VAL),
+ "SGP = VAL",
+ "SGP = VAL",
+ WRITE_RREG_PAIR(REG_SGP,VAL),
+ (A_IMPLICIT_WRITES_SGP0,A_IMPLICIT_WRITES_SGP1)
+)
+
+DEF_MACRO(WRITE_UGP,(VAL),
+ "UGP = VAL",
+ "UGP = VAL",
+ WRITE_RREG(REG_UGP,VAL),
+)
+
+DEF_MACRO(fSTART,(REG),
+ "start(REG)",
+ "start(REG)",
+ fLOG_GLOBAL_REG_FIELD(MODECTL,MODECTL_E, fREAD_GLOBAL_REG_FIELD(MODECTL,MODECTL_E) | (((REG & ((1<<RUNNABLE_THREADS_MAX)-1))) & THREAD_EN_MASK(thread->processor_ptr))),
+ ()
+)
+
+DEF_MACRO(fRESUME,(REG),
+ "resume(REG)",
+ "resume(REG)",
+ fLOG_GLOBAL_REG_FIELD(MODECTL,MODECTL_W,
+ fREAD_GLOBAL_REG_FIELD(MODECTL,MODECTL_W) & (~(REG))),
+ ()
+)
+
+DEF_MACRO(fGET_TNUM,(),
+ "TNUM",
+ "TNUM",
+ thread->threadId,
+ ()
+)
+
+/********************************************/
+/* Cache Management */
+/********************************************/
+
+DEF_MACRO(fBARRIER,(),
+ "memory_barrier",
+ "memory_barrier",
+ {
+ sys_barrier(thread, insn->slot);
+ },
+ ()
+)
+
+DEF_MACRO(fSYNCH,(),
+ "memory_synch",
+ "memory_synch",
+ {
+ sys_sync(thread, insn->slot);
+ },
+ ()
+)
+
+DEF_MACRO(fISYNC,(),
+ "instruction_sync",
+ "instruction_sync",
+ {
+ sys_isync(thread, insn->slot);
+ },
+ ()
+)
+
+
+DEF_MACRO(fICFETCH,(REG),
+ "icache_fetch(REG)",
+ "icache_fetch(REG)",
+ /* Unimplemented for now in uarch... cache_nru_icache_fetch(thread->processor_ptr, thread->threadId, (REG)) */,
+ ()
+)
+
+DEF_MACRO(fDCFETCH,(REG),
+ "dcache_fetch(REG)",
+ "dcache_fetch(REG)",
+ sys_dcfetch(thread, (REG), insn->slot),
+ (A_MEMLIKE,A_RESTRICT_SINGLE_MEM_FIRST)
+)
+
+DEF_MACRO(fICINVIDX,(REG),
+ "icache_inv_idx(REG)",
+ "icache_inv_idx(REG)",
+ {
+ arch_internal_flush(thread->processor_ptr,0,0xffffffff);
+ }
+ ,
+ ()
+)
+
+DEF_MACRO(fICINVA,(REG),
+ "icache_inv_addr(REG)",
+ "icache_inv_addr(REG)",
+ {
+ arch_internal_flush(thread->processor_ptr, 0, 0xffffffff);
+ sys_icinva(thread, (REG),insn->slot);
+ },
+ (A_ICINVA)
+)
+
+DEF_MACRO(fICKILL,(),
+ "icache_inv_all()",
+ "icache_inv_all()",
+ arch_internal_flush(thread->processor_ptr, 0, 0xffffffff);
+ cache_kill_icache(thread->processor_ptr); ,
+ ()
+)
+
+DEF_MACRO(fDCKILL,(),
+ "dcache_inv_all()",
+ "dcache_inv_all()",
+ cache_kill_dcache(thread->processor_ptr); ,
+ ()
+)
+
+DEF_MACRO(fL2KILL,(),
+ "l2cache_inv_all()",
+ "l2cache_inv_all()",
+ cache_kill_l2cache(thread->processor_ptr); ,
+ (A_IMPLICIT_READS_SYSCFG_GCA,A_IMPLICIT_WRITES_SYSCFG_GCA)
+)
+
+DEF_MACRO(fL2UNLOCK,(),
+ "l2cache_global_unlock()",
+ "l2cache_global_unlock()",
+ sys_l2gunlock(thread),
+ (A_IMPLICIT_READS_SYSCFG_GCA,A_IMPLICIT_WRITES_SYSCFG_GCA)
+)
+
+DEF_MACRO(fL2CLEAN,(),
+ "l2cache_global_clean()",
+ "l2cache_global_clean()",
+ sys_l2gclean(thread),
+ (A_IMPLICIT_READS_SYSCFG_GCA,A_IMPLICIT_WRITES_SYSCFG_GCA)
+)
+
+DEF_MACRO(fL2CLEANINV,(),
+ "l2cache_global_clean_inv()",
+ "l2cache_global_clean_inv()",
+ sys_l2gcleaninv(thread),
+ (A_IMPLICIT_READS_SYSCFG_GCA,A_IMPLICIT_WRITES_SYSCFG_GCA)
+)
+
+DEF_MACRO(fL2CLEANPA,(REG),
+ "l2cache_global_clean_range(REG)",
+ "l2cache_global_clean_range(REG)",
+ sys_l2gclean_pa(thread,REG),
+ (A_IMPLICIT_READS_SYSCFG_GCA,A_IMPLICIT_WRITES_SYSCFG_GCA)
+)
+
+DEF_MACRO(fL2CLEANINVPA,(REG),
+ "l2cache_global_clean_inv_range(REG)",
+ "l2cache_global_clean_inv_range(REG)",
+ sys_l2gcleaninv_pa(thread,REG),
+ (A_IMPLICIT_READS_SYSCFG_GCA,A_IMPLICIT_WRITES_SYSCFG_GCA)
+)
+
+
+DEF_MACRO(fL2CLEANINVIDX,(REG),
+ "l2cache_clean_invalidate_idx(REG)",
+ "l2cache_clean_invalidate_idx(REG)",
+ sys_l2cleaninvidx(thread, (REG)),
+ (A_MEMLIKE,A_RESTRICT_SINGLE_MEM_FIRST)
+)
+
+DEF_MACRO(fL2CLEANIDX,(REG),
+ "l2cache_clean_idx(REG)",
+ "l2cache_clean_idx(REG)",
+ sys_l2cleanidx(thread, (REG)),
+ (A_MEMLIKE,A_RESTRICT_SINGLE_MEM_FIRST)
+)
+
+DEF_MACRO(fL2INVIDX,(REG),
+ "l2cache_inv_idx(REG)",
+ "l2cache_inv_idx(REG)",
+ sys_l2invidx(thread, (REG)),
+ (A_MEMLIKE,A_RESTRICT_SINGLE_MEM_FIRST)
+)
+
+DEF_MACRO(fDCTAGR,(INDEX,DST,DSTREGNO),
+ "dcache_tag_read(INDEX)",
+ "dcache_tag_read(INDEX)",
+ ({DST=sys_dctagr(thread, INDEX, insn->slot,DSTREGNO);})/* FIXME */,
+ ()
+)
+
+DEF_MACRO(fDCTAGW,(INDEX,PART2),
+ "dcache_tag_write(INDEX,PART2)",
+ "dcache_tag_write(INDEX,PART2)",
+ (sys_dctagw(thread, INDEX, PART2, insn->slot)),
+ ()
+)
+DEF_MACRO(fICTAGR,(INDEX,DST,REGNO),
+ "icache_tag_read(INDEX)",
+ "icache_tag_read(INDEX)",
+ ({DST=sys_ictagr(thread, INDEX, insn->slot,REGNO);}),
+ ()
+)
+
+DEF_MACRO(fICDATAR,(INDEX, DST),
+ "icache_data_read(INDEX)",
+ "icache_data_read(INDEX)",
+ ({DST=sys_icdatar(thread, INDEX, insn->slot);}),
+ ()
+)
+
+DEF_MACRO(fICTAGW,(INDEX,PART2),
+ "icache_tag_write(INDEX,PART2)",
+ "icache_tag_write(INDEX,PART2)",
+ (sys_ictagw(thread, INDEX, PART2, insn->slot)),
+ ()
+)
+DEF_MACRO(fICDATAW,(INDEX,DATA),
+ "icache_data_write(INDEX,DATA)",
+ "icache_data_write(INDEX,DATA)",
+ ({ fHIDE(); }),
+ ()
+)
+
+DEF_MACRO(fL2FETCH,(ADDR,HEIGHT,WIDTH,STRIDE,FLAGS),
+ "l2fetch(ADDR,INFO)",
+ "l2fetch(ADDR,INFO)",
+ sys_l2fetch(thread, ADDR,HEIGHT,WIDTH,STRIDE,FLAGS, insn->slot),
+ (A_MEMLIKE,A_RESTRICT_SINGLE_MEM_FIRST,A_L2FETCH)
+)
+
+DEF_MACRO(fL2TAGR,(INDEX, DST, DSTREG),
+ "l2cache_tag_read(INDEX)",
+ "l2cache_tag_read(INDEX)",
+ ({DST=sys_l2tagr(thread, INDEX, insn->slot, DSTREG);}),
+ ()
+)
+
+DEF_MACRO(fL2LOCKA,(VA,DST,PREGDST),
+ "DST=l2locka(VA)",
+ "DST=l2locka(VA)",
+ do {DST=sys_l2locka(thread, VA, insn->slot, PREGDST); } while (0),
+ ()
+)
+
+DEF_MACRO(fL2UNLOCKA,(VA),
+ "l2unlocka(VA)",
+ "l2unlocka(VA)",
+ sys_l2unlocka(thread, VA, insn->slot),
+ ()
+)
+
+DEF_MACRO(fL2TAGW,(INDEX,PART2),
+ "l2cache_tag_write(INDEX,PART2)",
+ "l2cache_tag_write(INDEX,PART2)",
+ ({sys_l2tagw(thread, INDEX, PART2, insn->slot);}),
+ ()
+)
+
+DEF_MACRO(fDCCLEANIDX,(REG),
+ "dcache_clean_idx(REG)",
+ "dcache_clean_idx(REG)",
+ sys_dccleanidx(thread, (REG)),
+ (A_MEMLIKE,A_RESTRICT_SINGLE_MEM_FIRST)
+)
+
+DEF_MACRO(fDCCLEANA,(REG),
+ "dcache_clean_addr(REG)",
+ "dcache_clean_addr(REG)",
+ sys_dccleana(thread, (REG)),
+ (A_MEMLIKE,A_RESTRICT_SINGLE_MEM_FIRST)
+)
+
+DEF_MACRO(fDCCLEANINVIDX,(REG),
+ "dcache_cleaninv_idx(REG)",
+ "dcache_cleaninv_idx(REG)",
+ sys_dccleaninvidx(thread, (REG)),
+ (A_MEMLIKE,A_RESTRICT_SINGLE_MEM_FIRST)
+)
+
+DEF_MACRO(fDCCLEANINVA,(REG),
+ "dcache_cleaninv_addr(REG)",
+ "dcache_cleaninv_addr(REG)",
+ sys_dccleaninva(thread, (REG), insn->slot),
+ (A_MEMLIKE,A_RESTRICT_SINGLE_MEM_FIRST,A_DCCLEANINVA)
+)
+
+DEF_MACRO(fDCZEROA,(REG),
+ "dcache_zero_addr(REG)",
+ "dcache_zero_addr(REG)",
+ sys_dczeroa(thread, (REG)),
+ (A_MEMLIKE,A_RESTRICT_SINGLE_MEM_FIRST)
+)
+
+DEF_MACRO(fDCINVIDX,(REG),
+ "dcache_inv_idx(REG)",
+ "dcache_inv_idx(REG)",
+ sys_dcinvidx(thread, (REG)),
+ (A_MEMLIKE,A_RESTRICT_SINGLE_MEM_FIRST)
+)
+
+DEF_MACRO(fDCINVA,(REG),
+ "dcache_inv_addr(REG)",
+ "dcache_inv_addr(REG)",
+ sys_dcinva(thread, (REG)),
+ (A_MEMLIKE,A_RESTRICT_SINGLE_MEM_FIRST)
+)
+
+
+DEF_MACRO(fCHECKFORPRIV,(),
+ "priv_check();",
+ "priv_check();",
+ {sys_check_privs(thread); if (EXCEPTION_DETECTED) return; },
+ ()
+)
+
+DEF_MACRO(fCHECKFORGUEST,(),
+ "priv_check();",
+ "priv_check();",
+ {sys_check_guest(thread); if (EXCEPTION_DETECTED) return; },
+ ()
+)
+
+DEF_MACRO(fILLEGAL,(),
+ "illegal()",
+ "illegal()",
+ do {sys_illegal(thread); if (EXCEPTION_DETECTED) return; } while (0),
+ ()
+)
+
+#ifdef NEW_INTERRUPTS
+
+DEF_MACRO(fTAKEN_INTERRUPT_EDGECLEAR,(proc,intnum),
+ "clear_ipend(intnum)",
+ "If the interrupt is edge triggered, clear the interrupt from IPEND due to being taken",
+ { fWRITE_GLOBAL_REG_FIELD(IPENDAD,IPENDAD_IPEND,
+ fREAD_GLOBAL_REG_FIELD(IPENDAD,IPENDAD_IPEND) & ~(INT_NUMTOMASK(intnum))); },
+ ()
+)
+
+DEF_MACRO(fSET_IAD,(thread,intnum),
+ "set_iad(intnum)",
+ "Set IAD bit corresponding to intnum",
+ { sys_siad(thread,INT_NUMTOMASK(intnum));
+ fWRITE_GLOBAL_REG_FIELD(IPENDAD,IPENDAD_IAD,
+ fREAD_GLOBAL_REG_FIELD(IPENDAD,IPENDAD_IAD) | INT_NUMTOMASK(intnum)); },
+ ()
+)
+#else
+
+DEF_MACRO(fTAKEN_INTERRUPT_EDGECLEAR,(proc,intnum),
+ "clear_ipend(intnum)",
+ "If the interrupt is edge triggered, clear the interrupt from IPEND due to being taken",
+ { proc->global_regs[REG_IPEND] &= ~(INT_NUMTOMASK(intnum) & proc->global_regs[REG_IEL]); },
+ ()
+)
+
+DEF_MACRO(fSET_IAD,(thread,intnum),
+ "set_iad(intnum)",
+ "Set IAD bit corresponding to intnum",
+ { sys_siad(thread,INT_NUMTOMASK(intnum)); thread->processor_ptr->global_regs[REG_IAD] |= INT_NUMTOMASK(intnum); },
+ ()
+)
+
+#endif
+
+DEF_MACRO(fBRANCH_SPECULATED_RIGHT,(JC,SD,DOTNEWVAL),
+ "branch_speculated_right(JC,SD,DOTNEWVAL)",
+ "branch_speculated_right(JC,SD,DOTNEWVAL)",
+ (((JC) ^ (SD) ^ (DOTNEWVAL&1)) & 0x1),
+ ()
+)
+
+
+
+DEF_MACRO(fBRANCH_SPECULATE_STALL,(DOTNEWVAL, JUMP_COND, SPEC_DIR, HINTBITNUM, STRBITNUM),
+ "",
+ "Check the .new predicate and stall if wrongly speculated.",
+ {
+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));
+ },
+ (A_BIMODAL_BRANCH)
+)
+
+
+DEF_MACRO(CACHE_MODIFY, (A, B),
+ "cache_modify()",
+ "Assigns B to A if not sandbox execution",
+ A=B
+ ,
+ ()
+)
+
+DEF_MACRO(SIM_BUSACCESS, (A,B,C,D,E,F,G,H,I),
+ "sim_busaccess_macro()",
+ "Sim bus access qualified with cache modify",
+ ({
+ sim_busaccess_t p = B->busaccess;
+ if (!p) p = sim_busaccess;
+ p(A,B,C,D,E,F,G,H,I);
+ })
+ ,
+ ()
+)
+
+DEF_MACRO(SIM_BUSACCESS_ACK, (A,B,C,D,E,F,G,H,I),
+ "sim_busaccess_macro()",
+ "Sim bus access with a return value and qualified with cache modify",
+ /* EJP: implicit "status" is probably bad. */
+ do {
+ sim_busaccess_t p = B->busaccess;
+ if (!p) p = sim_busaccess;
+ status = p(A,B,C,D,E,F,G,H,I);
+ } while (0)
+ ,
+ ()
+)
+
+DEF_MACRO(SET_PMU_EVENT_STATE, (_THREAD_, _PMU_EVENT_NUM_),
+ "set_pmu_state()",
+ "Sets the bit for an event in the PMU array in the thread",
+ (_THREAD_->processor_ptr->pmu_event_state[_PMU_EVENT_NUM_] = 1)
+ ,
+ ()
+)
+
+DEF_MACRO(CLEAR_PMU_EVENT_STATE, (_THREAD_, _PMU_EVENT_NUM_),
+ "clear_pmu_state()",
+ "Clears the bit for an event in the PMU array in the thread",
+ (_THREAD_->processor_ptr->pmu_event_state[_PMU_EVENT_NUM_] = 0)
+ ,
+ ()
+)
+
+DEF_MACRO(fNOP_EXECUTED,
+ ,
+ "do nothing",
+ "some magic triggers for cache drive",
+ { sys_nop_executed(thread); },
+ ()
+)
+
+DEF_MACRO(fSETMREG,
+ (IDX, VAL),
+ "fSETMREG(IDX,VAL)", /* short desc */
+ "SET MREG Vector IDX", /* long desc */
+ (thread->Mregs[IDX] = (VAL)),
+ ()
+)
+
+DEF_MACRO(fGETMREG,
+ (IDX),
+ "fGETMREG(IDX)", /* short desc */
+ "GET MREG Vector IDX", /* long desc */
+ (thread->Mregs[IDX]),
+ ()
+)
+
+
+
+
+
+
+
+
+DEF_MACRO(fXORBITS,(SUM,VAR,VEC),
+ "SUM = xor bitsin(VEC)",
+ "XOR all bits together in a 32bit register",
+ {
+ for (SUM=0,VAR=0;VAR<32;VAR++) {
+ SUM ^= VEC & 1;
+ VEC = VEC >> 1;
+ }
+ },
+)
+
+DEF_MACRO(fTIMING,(A),
+ "",
+ "",
+ if (UNLIKELY(thread->timing_on)) {
+ A;
+ },
+ ()
+)
+
+DEF_MACRO(IV1DEAD,(),
+ "",
+ "",
+ ,
+ () /*A_NOTE_NOISTARIV1*/
+)
+
+DEF_MACRO(FAKE,(),
+ "",
+ "",
+ ,
+ (A_FAKEINSN)
+)
+
+DEF_MACRO(fIN_MONITOR_MODE,(),
+ "in_monitor_mode()",
+ "in_monitor_mode()",
+ sys_in_monitor_mode(thread),
+ (A_IMPLICIT_READS_SSR)
+)
+
+DEF_MACRO(fIN_USER_MODE,(),
+ "in_user_mode()",
+ "in_user_mode()",
+ sys_in_user_mode(thread),
+ (A_IMPLICIT_READS_SSR)
+)
+
+DEF_MACRO(fIN_GUEST_MODE,(),
+ "in_guest_mode()",
+ "in_guest_mode()",
+ sys_in_guest_mode(thread),
+ (A_IMPLICIT_READS_SSR)
+)
+
+DEF_MACRO(fGRE_ENABLED,(),
+ "CCR.GRE",
+ "CCR.GRE",
+ fREAD_REG_FIELD(CCR,CCR_GRE),
+ (A_IMPLICIT_READS_CCR)
+)
+
+DEF_MACRO(fGTE_ENABLED,(),
+ "CCR.GRE",
+ "CCR.GRE",
+ fREAD_REG_FIELD(CCR,CCR_GRE),
+ (A_IMPLICIT_READS_CCR)
+)
+
+DEF_MACRO(fTRAP1_VIRTINSN,(IMM),
+ "can_handle_trap1_virtinsn(IMM)",
+ "can_handle_trap1_virtinsn(IMM)",
+ ((fIN_GUEST_MODE())
+ && (fGRE_ENABLED())
+ && ( ((IMM) == 1)
+ || ((IMM) == 3)
+ || ((IMM) == 4)
+ || ((IMM) == 6))),
+ ()
+)
+
+DEF_MACRO(fTRAP0_TO_GUEST,(),
+ "can_handle_trap0_to_guest(IMM)",
+ "can_handle_trap0_to_guest(IMM)",
+ ((!fIN_MONITOR_MODE())
+ && (fGTE_ENABLED())),
+ ()
+)
+
+DEF_MACRO(fVIRTINSN_RTE,(IMM,REG),
+ "VMRTE",
+ "VMRTE",
+ do {
+ thread->trap1_info = TRAP1_VIRTINSN_RTE;
+ fLOG_REG_FIELD(SSR,SSR_SS,fREAD_REG_FIELD(GSR,GSR_SS));
+ fLOG_REG_FIELD(CCR,CCR_GIE,fREAD_REG_FIELD(GSR,GSR_IE));
+ fLOG_REG_FIELD(SSR,SSR_GM,!fREAD_REG_FIELD(GSR,GSR_UM));
+ fBRANCH((fREAD_GELR() & -4),COF_TYPE_RTE);
+ fINTERNAL_CLEAR_SAMEPAGE();
+ } while (0),
+ (A_IMPLICIT_READS_GSR,A_IMPLICIT_WRITES_PC,A_IMPLICIT_WRITES_CCR,A_IMPLICIT_WRITES_SSR)
+)
+
+DEF_MACRO(fVIRTINSN_SETIE,(IMM,REG),
+ "VMSETIE",
+ "VMSETIE",
+ do { fLOG_REG_FIELD(CCR,CCR_GIE,(REG) & 1);
+ REG = fREAD_REG_FIELD(CCR,CCR_GIE);
+ thread->trap1_info = TRAP1_VIRTINSN_SETIE;
+ } while (0),
+ (A_IMPLICIT_READS_CCR,A_IMPLICIT_WRITES_CCR)
+)
+
+DEF_MACRO(fVIRTINSN_GETIE,(IMM,REG),
+ "VMGETIE",
+ "VMGETIE",
+ { thread->trap1_info = TRAP1_VIRTINSN_GETIE;
+ REG = fREAD_REG_FIELD(CCR,CCR_GIE);
+ },
+
+ (A_IMPLICIT_READS_CCR)
+)
+
+DEF_MACRO(fVIRTINSN_SPSWAP,(IMM,REG),
+ "VMSPSWAP",
+ "VMSPSWAP",
+ do { if (fREAD_REG_FIELD(GSR,GSR_UM)) {
+ size4u_t TEMP = REG;
+ REG = fREAD_GOSP();
+ fWRITE_GOSP(TEMP);
+ thread->trap1_info = TRAP1_VIRTINSN_SPSWAP;
+ } } while (0),
+ (A_IMPLICIT_READS_GSR,A_IMPLICIT_READS_GOSP,A_IMPLICIT_WRITES_GOSP)
+)
+
+DEF_MACRO(fGUESTTRAP,(TRAPTYPE,IMM),
+ "GSR.CAUSE = IMM; TRAP # TRAPTYPE",
+ "GSR.CAUSE = IMM; TRAP # TRAPTYPE",
+ do {
+ if (TRAPTYPE == 0) {
+ CALLBACK(thread->processor_ptr->options->trap0_callback,
+ thread->system_ptr, thread->processor_ptr,
+ thread->threadId, IMM);
+ }
+ WRITE_RREG(REG_GELR,fREAD_NPC());
+ fLOG_REG_FIELD(GSR,GSR_UM,!fREAD_REG_FIELD(SSR,SSR_GM));
+ fLOG_REG_FIELD(GSR,GSR_SS,fREAD_REG_FIELD(SSR,SSR_SS));
+ fLOG_REG_FIELD(GSR,GSR_IE,fREAD_REG_FIELD(CCR,CCR_GIE));
+ fLOG_REG_FIELD(GSR,GSR_CAUSE,IMM);
+ fLOG_REG_FIELD(SSR,SSR_GM,1);
+ fLOG_REG_FIELD(SSR,SSR_SS,0);
+ fLOG_REG_FIELD(CCR,CCR_GIE,0);
+ fBRANCH(fREAD_GEVB() + ((EXCEPT_TYPE_TRAP##TRAPTYPE)<<2),COF_TYPE_TRAP);
+ } while (0),
+ ()
+)
+
+DEF_MACRO(fPREDUSE_TIMING,(),
+ "PREDUSE_TIMING",
+ "PREDUSE_TIMING",
+ ,
+ (A_PREDUSE_BSB)
+)
Imported from the Hexagon architecture library imported/macros.def Scalar core macro definitions The macro definition files specify instruction attributes that are applied to each instruction that reverences the macro. Signed-off-by: Taylor Simpson <tsimpson@quicinc.com> --- target/hexagon/imported/macros.def | 3970 ++++++++++++++++++++++++++++++++++++ 1 file changed, 3970 insertions(+) create mode 100755 target/hexagon/imported/macros.def