From patchwork Fri Feb 28 16:43:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Taylor Simpson X-Patchwork-Id: 11412937 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B033A924 for ; Fri, 28 Feb 2020 17:06:21 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 4B2A824697 for ; Fri, 28 Feb 2020 17:06:21 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="trMHUh6S" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4B2A824697 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=quicinc.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:50946 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j7j5g-0003yv-E0 for patchwork-qemu-devel@patchwork.kernel.org; Fri, 28 Feb 2020 12:06:20 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:57878) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j7iko-00037T-Ou for qemu-devel@nongnu.org; Fri, 28 Feb 2020 11:44:55 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1j7ikc-0005Z9-S3 for qemu-devel@nongnu.org; Fri, 28 Feb 2020 11:44:45 -0500 Received: from alexa-out-sd-01.qualcomm.com ([199.106.114.38]:13242) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1j7ikb-0005Uc-Ep for qemu-devel@nongnu.org; Fri, 28 Feb 2020 11:44:34 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1582908273; x=1614444273; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=TVQmYa127ZMM/IOizO1Ac06lhvfnyah98s5g0Gw2t9s=; b=trMHUh6SE47fQrMl5+nAntIyhDImhQCDG93uiwjGzTHtBaOat/jUwXdl 9L2hSPuUhSiEikOW0BY4dNY0U+mikYaijH4dwu6OmyZaIgJtECyZpdPTh bm72cOaNx68XAZvuecg2s/wvFkFpdk/Ml225M8fqaHchc6wI/akAmZwNE k=; Received: from unknown (HELO ironmsg-SD-alpha.qualcomm.com) ([10.53.140.30]) by alexa-out-sd-01.qualcomm.com with ESMTP; 28 Feb 2020 08:44:29 -0800 Received: from vu-tsimpson-aus.qualcomm.com (HELO vu-tsimpson1-aus.qualcomm.com) ([10.222.150.1]) by ironmsg-SD-alpha.qualcomm.com with ESMTP; 28 Feb 2020 08:44:29 -0800 Received: by vu-tsimpson1-aus.qualcomm.com (Postfix, from userid 47164) id F3DAFFCD; Fri, 28 Feb 2020 10:44:28 -0600 (CST) From: Taylor Simpson To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 17/67] Hexagon arch import - macro definitions Date: Fri, 28 Feb 2020 10:43:13 -0600 Message-Id: <1582908244-304-18-git-send-email-tsimpson@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1582908244-304-1-git-send-email-tsimpson@quicinc.com> References: <1582908244-304-1-git-send-email-tsimpson@quicinc.com> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: FreeBSD 9.x [fuzzy] X-Received-From: 199.106.114.38 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: riku.voipio@iki.fi, richard.henderson@linaro.org, laurent@vivier.eu, Taylor Simpson , philmd@redhat.com, aleksandar.m.mail@gmail.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" 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 --- target/hexagon/imported/macros.def | 3970 ++++++++++++++++++++++++++++++++++++ 1 file changed, 3970 insertions(+) create mode 100755 target/hexagon/imported/macros.def 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 . + */ + +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<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<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)<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<>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< 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)", + "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)", + "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)<0)?(fCAST##REGSTYPE##u(SRC)>>>SHAMT):(fCAST##REGSTYPE##u(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<= 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<>((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;iprocessor_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;iprocessor_ptr->arch_proc_options->thread_enable_mask>>i) & 0x1) ) { + if (SREG & (1<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;iprocessor_ptr->arch_proc_options->thread_enable_mask>>i) & 0x1)) { + result |= (((thread->processor_ptr->thread[i]->Regs[REG_IMASK]>>intbitpos)&1)<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)<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<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<debug_mode), + () +) + + +DEF_MACRO(fIN_DEBUG_MODE_WARN,(TNUM), + "", + "", + { + if (fREAD_GLOBAL_REG_FIELD(ISDBST,ISDBST_DEBUGMODE) & 1<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<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) +)