From patchwork Mon Sep 20 21:24:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Taylor Simpson X-Patchwork-Id: 12506381 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.5 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UPPERCASE_50_75,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E0C61C433EF for ; Mon, 20 Sep 2021 21:36:38 +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 82C2A60FC1 for ; Mon, 20 Sep 2021 21:36:38 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 82C2A60FC1 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=quicinc.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=nongnu.org Received: from localhost ([::1]:38872 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mSQxp-0003QB-CW for qemu-devel@archiver.kernel.org; Mon, 20 Sep 2021 17:36:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60410) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mSQmR-000214-LQ for qemu-devel@nongnu.org; Mon, 20 Sep 2021 17:24:51 -0400 Received: from alexa-out-sd-02.qualcomm.com ([199.106.114.39]:9868) by eggs.gnu.org with esmtps (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1mSQmK-00028P-FR for qemu-devel@nongnu.org; Mon, 20 Sep 2021 17:24:51 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1632173084; x=1663709084; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ZP9T+8GuL5qqDITXHHX/aZi9PUNjTg0chlMcQtxwgLU=; b=lxV96yqhe8sjU5mYijHs3e0wVqJG5sW07F5DCb8LwL9FPWxav+5OvihW YrVtPRXy/dcyOaBMWy2KGkTwPCt7VoPnwrt7l+pXn5giqDMdJV4vVbBxg fEt/b9kEX5/+hLFBNJEqgcPsavIwJ5XqxrP0flyRAA7LjFSg4cK55ENfa I=; Received: from unknown (HELO ironmsg01-sd.qualcomm.com) ([10.53.140.141]) by alexa-out-sd-02.qualcomm.com with ESMTP; 20 Sep 2021 14:24:36 -0700 X-QCInternal: smtphost Received: from vu-tsimpson-aus.qualcomm.com (HELO vu-tsimpson1-aus.qualcomm.com) ([10.222.150.1]) by ironmsg01-sd.qualcomm.com with ESMTP; 20 Sep 2021 14:24:36 -0700 Received: by vu-tsimpson1-aus.qualcomm.com (Postfix, from userid 47164) id 9E1C51410; Mon, 20 Sep 2021 16:24:35 -0500 (CDT) From: Taylor Simpson To: qemu-devel@nongnu.org Subject: [PATCH v3 05/30] Hexagon HVX (target/hexagon) macros Date: Mon, 20 Sep 2021 16:24:00 -0500 Message-Id: <1632173065-18522-6-git-send-email-tsimpson@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1632173065-18522-1-git-send-email-tsimpson@quicinc.com> References: <1632173065-18522-1-git-send-email-tsimpson@quicinc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=199.106.114.39; envelope-from=tsimpson@qualcomm.com; helo=alexa-out-sd-02.qualcomm.com X-Spam_score_int: -39 X-Spam_score: -4.0 X-Spam_bar: ---- X-Spam_report: (-4.0 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, UPPERCASE_50_75=0.008 autolearn=ham autolearn_force=no X-Spam_action: no action 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: ale@rev.ng, bcain@quicinc.com, tsimpson@quicinc.com, richard.henderson@linaro.org, f4bug@amsat.org Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" macros to interface with the generator macros referenced in instruction semantics Signed-off-by: Taylor Simpson Acked-by: Richard Henderson --- target/hexagon/macros.h | 22 +++ target/hexagon/mmvec/macros.h | 341 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 363 insertions(+) create mode 100644 target/hexagon/mmvec/macros.h diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h index 094b8da..d1d0348 100644 --- a/target/hexagon/macros.h +++ b/target/hexagon/macros.h @@ -269,6 +269,10 @@ static inline void gen_pred_cancel(TCGv pred, int slot_num) #define fNEWREG_ST(VAL) (VAL) +#define fVSATUVALN(N, VAL) \ + ({ \ + (((int)(VAL)) < 0) ? 0 : ((1LL << (N)) - 1); \ + }) #define fSATUVALN(N, VAL) \ ({ \ fSET_OVERFLOW(); \ @@ -279,10 +283,16 @@ static inline void gen_pred_cancel(TCGv pred, int slot_num) fSET_OVERFLOW(); \ ((VAL) < 0) ? (-(1LL << ((N) - 1))) : ((1LL << ((N) - 1)) - 1); \ }) +#define fVSATVALN(N, VAL) \ + ({ \ + ((VAL) < 0) ? (-(1LL << ((N) - 1))) : ((1LL << ((N) - 1)) - 1); \ + }) #define fZXTN(N, M, VAL) (((N) != 0) ? extract64((VAL), 0, (N)) : 0LL) #define fSXTN(N, M, VAL) (((N) != 0) ? sextract64((VAL), 0, (N)) : 0LL) #define fSATN(N, VAL) \ ((fSXTN(N, 64, VAL) == (VAL)) ? (VAL) : fSATVALN(N, VAL)) +#define fVSATN(N, VAL) \ + ((fSXTN(N, 64, VAL) == (VAL)) ? (VAL) : fVSATVALN(N, VAL)) #define fADDSAT64(DST, A, B) \ do { \ uint64_t __a = fCAST8u(A); \ @@ -305,12 +315,18 @@ static inline void gen_pred_cancel(TCGv pred, int slot_num) DST = __sum; \ } \ } while (0) +#define fVSATUN(N, VAL) \ + ((fZXTN(N, 64, VAL) == (VAL)) ? (VAL) : fVSATUVALN(N, VAL)) #define fSATUN(N, VAL) \ ((fZXTN(N, 64, VAL) == (VAL)) ? (VAL) : fSATUVALN(N, VAL)) #define fSATH(VAL) (fSATN(16, VAL)) #define fSATUH(VAL) (fSATUN(16, VAL)) +#define fVSATH(VAL) (fVSATN(16, VAL)) +#define fVSATUH(VAL) (fVSATUN(16, VAL)) #define fSATUB(VAL) (fSATUN(8, VAL)) #define fSATB(VAL) (fSATN(8, VAL)) +#define fVSATUB(VAL) (fVSATUN(8, VAL)) +#define fVSATB(VAL) (fVSATN(8, VAL)) #define fIMMEXT(IMM) (IMM = IMM) #define fMUST_IMMEXT(IMM) fIMMEXT(IMM) @@ -417,6 +433,8 @@ static inline TCGv gen_read_ireg(TCGv result, TCGv val, int shift) #define fCAST4s(A) ((int32_t)(A)) #define fCAST8u(A) ((uint64_t)(A)) #define fCAST8s(A) ((int64_t)(A)) +#define fCAST2_2s(A) ((int16_t)(A)) +#define fCAST2_2u(A) ((uint16_t)(A)) #define fCAST4_4s(A) ((int32_t)(A)) #define fCAST4_4u(A) ((uint32_t)(A)) #define fCAST4_8s(A) ((int64_t)((int32_t)(A))) @@ -514,7 +532,9 @@ static inline TCGv gen_read_ireg(TCGv result, TCGv val, int shift) #define fPM_M(REG, MVAL) do { REG = REG + (MVAL); } while (0) #endif #define fSCALE(N, A) (((int64_t)(A)) << N) +#define fVSATW(A) fVSATN(32, ((long long)A)) #define fSATW(A) fSATN(32, ((long long)A)) +#define fVSAT(A) fVSATN(32, (A)) #define fSAT(A) fSATN(32, (A)) #define fSAT_ORIG_SHL(A, ORIG_REG) \ ((((int32_t)((fSAT(A)) ^ ((int32_t)(ORIG_REG)))) < 0) \ @@ -651,12 +671,14 @@ static inline TCGv gen_read_ireg(TCGv result, TCGv val, int shift) fSETBIT(j, DST, VAL); \ } \ } while (0) +#define fCOUNTONES_2(VAL) ctpop16(VAL) #define fCOUNTONES_4(VAL) ctpop32(VAL) #define fCOUNTONES_8(VAL) ctpop64(VAL) #define fBREV_8(VAL) revbit64(VAL) #define fBREV_4(VAL) revbit32(VAL) #define fCL1_8(VAL) clo64(VAL) #define fCL1_4(VAL) clo32(VAL) +#define fCL1_2(VAL) (clz32(~(uint16_t)(VAL) & 0xffff) - 16) #define fINTERLEAVE(ODD, EVEN) interleave(ODD, EVEN) #define fDEINTERLEAVE(MIXED) deinterleave(MIXED) #define fHIDE(A) A diff --git a/target/hexagon/mmvec/macros.h b/target/hexagon/mmvec/macros.h new file mode 100644 index 0000000..e2d1e65 --- /dev/null +++ b/target/hexagon/mmvec/macros.h @@ -0,0 +1,341 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_MMVEC_MACROS_H +#define HEXAGON_MMVEC_MACROS_H + +#include "qemu/osdep.h" +#include "qemu/host-utils.h" +#include "arch.h" +#include "mmvec/system_ext_mmvec.h" + +#ifndef QEMU_GENERATE +#define VdV (*(MMVector *)(VdV_void)) +#define VsV (*(MMVector *)(VsV_void)) +#define VuV (*(MMVector *)(VuV_void)) +#define VvV (*(MMVector *)(VvV_void)) +#define VwV (*(MMVector *)(VwV_void)) +#define VxV (*(MMVector *)(VxV_void)) +#define VyV (*(MMVector *)(VyV_void)) + +#define VddV (*(MMVectorPair *)(VddV_void)) +#define VuuV (*(MMVectorPair *)(VuuV_void)) +#define VvvV (*(MMVectorPair *)(VvvV_void)) +#define VxxV (*(MMVectorPair *)(VxxV_void)) + +#define QeV (*(MMQReg *)(QeV_void)) +#define QdV (*(MMQReg *)(QdV_void)) +#define QsV (*(MMQReg *)(QsV_void)) +#define QtV (*(MMQReg *)(QtV_void)) +#define QuV (*(MMQReg *)(QuV_void)) +#define QvV (*(MMQReg *)(QvV_void)) +#define QxV (*(MMQReg *)(QxV_void)) +#endif + +#define LOG_VTCM_BYTE(VA, MASK, VAL, IDX) \ + do { \ + env->vtcm_log.data.ub[IDX] = (VAL); \ + if (MASK) { \ + set_bit((IDX), env->vtcm_log.mask); \ + } else { \ + clear_bit((IDX), env->vtcm_log.mask); \ + } \ + env->vtcm_log.va[IDX] = (VA); \ + } while (0) + +#define fNOTQ(VAL) \ + ({ \ + MMQReg _ret; \ + int _i_; \ + for (_i_ = 0; _i_ < fVECSIZE() / 64; _i_++) { \ + _ret.ud[_i_] = ~VAL.ud[_i_]; \ + } \ + _ret;\ + }) +#define fGETQBITS(REG, WIDTH, MASK, BITNO) \ + ((MASK) & (REG.w[(BITNO) >> 5] >> ((BITNO) & 0x1f))) +#define fGETQBIT(REG, BITNO) fGETQBITS(REG, 1, 1, BITNO) +#define fGENMASKW(QREG, IDX) \ + (((fGETQBIT(QREG, (IDX * 4 + 0)) ? 0xFF : 0x0) << 0) | \ + ((fGETQBIT(QREG, (IDX * 4 + 1)) ? 0xFF : 0x0) << 8) | \ + ((fGETQBIT(QREG, (IDX * 4 + 2)) ? 0xFF : 0x0) << 16) | \ + ((fGETQBIT(QREG, (IDX * 4 + 3)) ? 0xFF : 0x0) << 24)) +#define fGETNIBBLE(IDX, SRC) (fSXTN(4, 8, (SRC >> (4 * IDX)) & 0xF)) +#define fGETCRUMB(IDX, SRC) (fSXTN(2, 8, (SRC >> (2 * IDX)) & 0x3)) +#define fGETCRUMB_SYMMETRIC(IDX, SRC) \ + ((fGETCRUMB(IDX, SRC) >= 0 ? (2 - fGETCRUMB(IDX, SRC)) \ + : fGETCRUMB(IDX, SRC))) +#define fGENMASKH(QREG, IDX) \ + (((fGETQBIT(QREG, (IDX * 2 + 0)) ? 0xFF : 0x0) << 0) | \ + ((fGETQBIT(QREG, (IDX * 2 + 1)) ? 0xFF : 0x0) << 8)) +#define fGETMASKW(VREG, QREG, IDX) (VREG.w[IDX] & fGENMASKW((QREG), IDX)) +#define fGETMASKH(VREG, QREG, IDX) (VREG.h[IDX] & fGENMASKH((QREG), IDX)) +#define fCONDMASK8(QREG, IDX, YESVAL, NOVAL) \ + (fGETQBIT(QREG, IDX) ? (YESVAL) : (NOVAL)) +#define fCONDMASK16(QREG, IDX, YESVAL, NOVAL) \ + ((fGENMASKH(QREG, IDX) & (YESVAL)) | \ + (fGENMASKH(fNOTQ(QREG), IDX) & (NOVAL))) +#define fCONDMASK32(QREG, IDX, YESVAL, NOVAL) \ + ((fGENMASKW(QREG, IDX) & (YESVAL)) | \ + (fGENMASKW(fNOTQ(QREG), IDX) & (NOVAL))) +#define fSETQBITS(REG, WIDTH, MASK, BITNO, VAL) \ + do { \ + uint32_t __TMP = (VAL); \ + REG.w[(BITNO) >> 5] &= ~((MASK) << ((BITNO) & 0x1f)); \ + REG.w[(BITNO) >> 5] |= (((__TMP) & (MASK)) << ((BITNO) & 0x1f)); \ + } while (0) +#define fSETQBIT(REG, BITNO, VAL) fSETQBITS(REG, 1, 1, BITNO, VAL) +#define fVBYTES() (fVECSIZE()) +#define fVALIGN(ADDR, LOG2_ALIGNMENT) (ADDR = ADDR & ~(LOG2_ALIGNMENT - 1)) +#define fVLASTBYTE(ADDR, LOG2_ALIGNMENT) (ADDR = ADDR | (LOG2_ALIGNMENT - 1)) +#define fVELEM(WIDTH) ((fVECSIZE() * 8) / WIDTH) +#define fVECLOGSIZE() (7) +#define fVECSIZE() (1 << fVECLOGSIZE()) +#define fSWAPB(A, B) do { uint8_t tmp = A; A = B; B = tmp; } while (0) +#define fV_AL_CHECK(EA, MASK) \ + if ((EA) & (MASK)) { \ + warn("aligning misaligned vector. EA=%08x", (EA)); \ + } +#define fSCATTER_INIT(REGION_START, LENGTH, ELEMENT_SIZE) \ + mem_vector_scatter_init(env, slot, REGION_START, LENGTH, ELEMENT_SIZE) +#define fGATHER_INIT(REGION_START, LENGTH, ELEMENT_SIZE) \ + mem_vector_gather_init(env, REGION_START, LENGTH, ELEMENT_SIZE) +#define fSCATTER_FINISH(OP) +#define fGATHER_FINISH() +#define fLOG_SCATTER_OP(SIZE) \ + do { \ + env->vtcm_log.op = true; \ + env->vtcm_log.op_size = SIZE; \ + } while (0) +#define fVLOG_VTCM_WORD_INCREMENT(EA, OFFSET, INC, IDX, ALIGNMENT, LEN) \ + do { \ + int log_byte = 0; \ + target_ulong va = EA; \ + target_ulong va_high = EA + LEN; \ + for (int i0 = 0; i0 < 4; i0++) { \ + log_byte = (va + i0) <= va_high; \ + LOG_VTCM_BYTE(va + i0, log_byte, INC. ub[4 * IDX + i0], \ + 4 * IDX + i0); \ + } \ + } while (0) +#define fVLOG_VTCM_HALFWORD_INCREMENT(EA, OFFSET, INC, IDX, ALIGNMENT, LEN) \ + do { \ + int log_byte = 0; \ + target_ulong va = EA; \ + target_ulong va_high = EA + LEN; \ + for (int i0 = 0; i0 < 2; i0++) { \ + log_byte = (va + i0) <= va_high; \ + LOG_VTCM_BYTE(va + i0, log_byte, INC.ub[2 * IDX + i0], \ + 2 * IDX + i0); \ + } \ + } while (0) + +#define fVLOG_VTCM_HALFWORD_INCREMENT_DV(EA, OFFSET, INC, IDX, IDX2, IDX_H, \ + ALIGNMENT, LEN) \ + do { \ + int log_byte = 0; \ + target_ulong va = EA; \ + target_ulong va_high = EA + LEN; \ + for (int i0 = 0; i0 < 2; i0++) { \ + log_byte = (va + i0) <= va_high; \ + LOG_VTCM_BYTE(va + i0, log_byte, INC.ub[2 * IDX + i0], \ + 2 * IDX + i0); \ + } \ + } while (0) + +/* NOTE - Will this always be tmp_VRegs[0]; */ +#define GATHER_FUNCTION(EA, OFFSET, IDX, LEN, ELEMENT_SIZE, BANK_IDX, QVAL) \ + do { \ + int i0; \ + target_ulong va = EA; \ + target_ulong va_high = EA + LEN; \ + uintptr_t ra = GETPC(); \ + int log_bank = 0; \ + int log_byte = 0; \ + for (i0 = 0; i0 < ELEMENT_SIZE; i0++) { \ + log_byte = ((va + i0) <= va_high) && QVAL; \ + log_bank |= (log_byte << i0); \ + uint8_t B; \ + B = cpu_ldub_data_ra(env, EA + i0, ra); \ + env->tmp_VRegs[0].ub[ELEMENT_SIZE * IDX + i0] = B; \ + LOG_VTCM_BYTE(va + i0, log_byte, B, ELEMENT_SIZE * IDX + i0); \ + } \ + } while (0) +#define fVLOG_VTCM_GATHER_WORD(EA, OFFSET, IDX, LEN) \ + do { \ + GATHER_FUNCTION(EA, OFFSET, IDX, LEN, 4, IDX, 1); \ + } while (0) +#define fVLOG_VTCM_GATHER_HALFWORD(EA, OFFSET, IDX, LEN) \ + do { \ + GATHER_FUNCTION(EA, OFFSET, IDX, LEN, 2, IDX, 1); \ + } while (0) +#define fVLOG_VTCM_GATHER_HALFWORD_DV(EA, OFFSET, IDX, IDX2, IDX_H, LEN) \ + do { \ + GATHER_FUNCTION(EA, OFFSET, IDX, LEN, 2, (2 * IDX2 + IDX_H), 1); \ + } while (0) +#define fVLOG_VTCM_GATHER_WORDQ(EA, OFFSET, IDX, Q, LEN) \ + do { \ + GATHER_FUNCTION(EA, OFFSET, IDX, LEN, 4, IDX, \ + fGETQBIT(QsV, 4 * IDX + i0)); \ + } while (0) +#define fVLOG_VTCM_GATHER_HALFWORDQ(EA, OFFSET, IDX, Q, LEN) \ + do { \ + GATHER_FUNCTION(EA, OFFSET, IDX, LEN, 2, IDX, \ + fGETQBIT(QsV, 2 * IDX + i0)); \ + } while (0) +#define fVLOG_VTCM_GATHER_HALFWORDQ_DV(EA, OFFSET, IDX, IDX2, IDX_H, Q, LEN) \ + do { \ + GATHER_FUNCTION(EA, OFFSET, IDX, LEN, 2, (2 * IDX2 + IDX_H), \ + fGETQBIT(QsV, 2 * IDX + i0)); \ + } while (0) +#define SCATTER_OP_WRITE_TO_MEM(TYPE) \ + do { \ + uintptr_t ra = GETPC(); \ + for (int i = 0; i < env->vtcm_log.size; i += sizeof(TYPE)) { \ + if (test_bit(i, env->vtcm_log.mask)) { \ + TYPE dst = 0; \ + TYPE inc = 0; \ + for (int j = 0; j < sizeof(TYPE); j++) { \ + uint8_t val; \ + val = cpu_ldub_data_ra(env, env->vtcm_log.va[i + j], ra); \ + dst |= val << (8 * j); \ + inc |= env->vtcm_log.data.ub[j + i] << (8 * j); \ + clear_bit(j + i, env->vtcm_log.mask); \ + env->vtcm_log.data.ub[j + i] = 0; \ + } \ + dst += inc; \ + for (int j = 0; j < sizeof(TYPE); j++) { \ + cpu_stb_data_ra(env, env->vtcm_log.va[i + j], \ + (dst >> (8 * j)) & 0xFF, ra); \ + } \ + } \ + } \ + } while (0) +#define SCATTER_FUNCTION(EA, OFFSET, IDX, LEN, ELEM_SIZE, BANK_IDX, QVAL, IN) \ + do { \ + int i0; \ + target_ulong va = EA; \ + target_ulong va_high = EA + LEN; \ + int log_bank = 0; \ + int log_byte = 0; \ + for (i0 = 0; i0 < ELEM_SIZE; i0++) { \ + log_byte = ((va + i0) <= va_high) && QVAL; \ + log_bank |= (log_byte << i0); \ + LOG_VTCM_BYTE(va + i0, log_byte, IN.ub[ELEM_SIZE * IDX + i0], \ + ELEM_SIZE * IDX + i0); \ + } \ + } while (0) +#define fVLOG_VTCM_HALFWORD(EA, OFFSET, IN, IDX, LEN) \ + do { \ + SCATTER_FUNCTION(EA, OFFSET, IDX, LEN, 2, IDX, 1, IN); \ + } while (0) +#define fVLOG_VTCM_WORD(EA, OFFSET, IN, IDX, LEN) \ + do { \ + SCATTER_FUNCTION(EA, OFFSET, IDX, LEN, 4, IDX, 1, IN); \ + } while (0) +#define fVLOG_VTCM_HALFWORDQ(EA, OFFSET, IN, IDX, Q, LEN) \ + do { \ + SCATTER_FUNCTION(EA, OFFSET, IDX, LEN, 2, IDX, \ + fGETQBIT(QsV, 2 * IDX + i0), IN); \ + } while (0) +#define fVLOG_VTCM_WORDQ(EA, OFFSET, IN, IDX, Q, LEN) \ + do { \ + SCATTER_FUNCTION(EA, OFFSET, IDX, LEN, 4, IDX, \ + fGETQBIT(QsV, 4 * IDX + i0), IN); \ + } while (0) +#define fVLOG_VTCM_HALFWORD_DV(EA, OFFSET, IN, IDX, IDX2, IDX_H, LEN) \ + do { \ + SCATTER_FUNCTION(EA, OFFSET, IDX, LEN, 2, \ + (2 * IDX2 + IDX_H), 1, IN); \ + } while (0) +#define fVLOG_VTCM_HALFWORDQ_DV(EA, OFFSET, IN, IDX, Q, IDX2, IDX_H, LEN) \ + do { \ + SCATTER_FUNCTION(EA, OFFSET, IDX, LEN, 2, (2 * IDX2 + IDX_H), \ + fGETQBIT(QsV, 2 * IDX + i0), IN); \ + } while (0) +#define fSTORERELEASE(EA, TYPE) \ + do { \ + fV_AL_CHECK(EA, fVECSIZE() - 1); \ + } while (0) +#ifdef QEMU_GENERATE +#define fLOADMMV(EA, DST) gen_vreg_load(ctx, DST##_off, EA, true) +#endif +#ifdef QEMU_GENERATE +#define fLOADMMVU(EA, DST) gen_vreg_load(ctx, DST##_off, EA, false) +#endif +#ifdef QEMU_GENERATE +#define fSTOREMMV(EA, SRC) \ + gen_vreg_store(ctx, insn, pkt, EA, SRC##_off, insn->slot, true) +#endif +#ifdef QEMU_GENERATE +#define fSTOREMMVQ(EA, SRC, MASK) \ + gen_vreg_masked_store(ctx, EA, SRC##_off, MASK##_off, insn->slot, false) +#endif +#ifdef QEMU_GENERATE +#define fSTOREMMVNQ(EA, SRC, MASK) \ + gen_vreg_masked_store(ctx, EA, SRC##_off, MASK##_off, insn->slot, true) +#endif +#ifdef QEMU_GENERATE +#define fSTOREMMVU(EA, SRC) \ + gen_vreg_store(ctx, insn, pkt, EA, SRC##_off, insn->slot, false) +#endif +#define fVFOREACH(WIDTH, VAR) for (VAR = 0; VAR < fVELEM(WIDTH); VAR++) +#define fVARRAY_ELEMENT_ACCESS(ARRAY, TYPE, INDEX) \ + ARRAY.v[(INDEX) / (fVECSIZE() / (sizeof(ARRAY.TYPE[0])))].TYPE[(INDEX) % \ + (fVECSIZE() / (sizeof(ARRAY.TYPE[0])))] + +#define fVSATDW(U, V) fVSATW(((((long long)U) << 32) | fZXTN(32, 64, V))) +#define fVASL_SATHI(U, V) fVSATW(((U) << 1) | ((V) >> 31)) +#define fVUADDSAT(WIDTH, U, V) \ + fVSATUN(WIDTH, fZXTN(WIDTH, 2 * WIDTH, U) + fZXTN(WIDTH, 2 * WIDTH, V)) +#define fVSADDSAT(WIDTH, U, V) \ + fVSATN(WIDTH, fSXTN(WIDTH, 2 * WIDTH, U) + fSXTN(WIDTH, 2 * WIDTH, V)) +#define fVUSUBSAT(WIDTH, U, V) \ + fVSATUN(WIDTH, fZXTN(WIDTH, 2 * WIDTH, U) - fZXTN(WIDTH, 2 * WIDTH, V)) +#define fVSSUBSAT(WIDTH, U, V) \ + fVSATN(WIDTH, fSXTN(WIDTH, 2 * WIDTH, U) - fSXTN(WIDTH, 2 * WIDTH, V)) +#define fVAVGU(WIDTH, U, V) \ + ((fZXTN(WIDTH, 2 * WIDTH, U) + fZXTN(WIDTH, 2 * WIDTH, V)) >> 1) +#define fVAVGURND(WIDTH, U, V) \ + ((fZXTN(WIDTH, 2 * WIDTH, U) + fZXTN(WIDTH, 2 * WIDTH, V) + 1) >> 1) +#define fVNAVGU(WIDTH, U, V) \ + ((fZXTN(WIDTH, 2 * WIDTH, U) - fZXTN(WIDTH, 2 * WIDTH, V)) >> 1) +#define fVNAVGURNDSAT(WIDTH, U, V) \ + fVSATUN(WIDTH, ((fZXTN(WIDTH, 2 * WIDTH, U) - \ + fZXTN(WIDTH, 2 * WIDTH, V) + 1) >> 1)) +#define fVAVGS(WIDTH, U, V) \ + ((fSXTN(WIDTH, 2 * WIDTH, U) + fSXTN(WIDTH, 2 * WIDTH, V)) >> 1) +#define fVAVGSRND(WIDTH, U, V) \ + ((fSXTN(WIDTH, 2 * WIDTH, U) + fSXTN(WIDTH, 2 * WIDTH, V) + 1) >> 1) +#define fVNAVGS(WIDTH, U, V) \ + ((fSXTN(WIDTH, 2 * WIDTH, U) - fSXTN(WIDTH, 2 * WIDTH, V)) >> 1) +#define fVNAVGSRND(WIDTH, U, V) \ + ((fSXTN(WIDTH, 2 * WIDTH, U) - fSXTN(WIDTH, 2 * WIDTH, V) + 1) >> 1) +#define fVNAVGSRNDSAT(WIDTH, U, V) \ + fVSATN(WIDTH, ((fSXTN(WIDTH, 2 * WIDTH, U) - \ + fSXTN(WIDTH, 2 * WIDTH, V) + 1) >> 1)) +#define fVNOROUND(VAL, SHAMT) VAL +#define fVNOSAT(VAL) VAL +#define fVROUND(VAL, SHAMT) \ + ((VAL) + (((SHAMT) > 0) ? (1LL << ((SHAMT) - 1)) : 0)) +#define fCARRY_FROM_ADD32(A, B, C) \ + (((fZXTN(32, 64, A) + fZXTN(32, 64, B) + C) >> 32) & 1) +#define fUARCH_NOTE_PUMP_4X() +#define fUARCH_NOTE_PUMP_2X() + +#define IV1DEAD() +#endif