diff mbox series

[RFC,v2,17/67] Hexagon arch import - macro definitions

Message ID 1582908244-304-18-git-send-email-tsimpson@quicinc.com (mailing list archive)
State New, archived
Headers show
Series Hexagon patch series | expand

Commit Message

Taylor Simpson Feb. 28, 2020, 4:43 p.m. UTC
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
diff mbox series

Patch

diff --git a/target/hexagon/imported/macros.def b/target/hexagon/imported/macros.def
new file mode 100755
index 0000000..ace0432
--- /dev/null
+++ b/target/hexagon/imported/macros.def
@@ -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)
+)