164458f48STaylor Simpson /* 2f128c0feSTaylor Simpson * Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved. 364458f48STaylor Simpson * 464458f48STaylor Simpson * This program is free software; you can redistribute it and/or modify 564458f48STaylor Simpson * it under the terms of the GNU General Public License as published by 664458f48STaylor Simpson * the Free Software Foundation; either version 2 of the License, or 764458f48STaylor Simpson * (at your option) any later version. 864458f48STaylor Simpson * 964458f48STaylor Simpson * This program is distributed in the hope that it will be useful, 1064458f48STaylor Simpson * but WITHOUT ANY WARRANTY; without even the implied warranty of 1164458f48STaylor Simpson * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1264458f48STaylor Simpson * GNU General Public License for more details. 1364458f48STaylor Simpson * 1464458f48STaylor Simpson * You should have received a copy of the GNU General Public License 1564458f48STaylor Simpson * along with this program; if not, see <http://www.gnu.org/licenses/>. 1664458f48STaylor Simpson */ 1764458f48STaylor Simpson 1864458f48STaylor Simpson #ifndef HEXAGON_MMVEC_MACROS_H 1964458f48STaylor Simpson #define HEXAGON_MMVEC_MACROS_H 2064458f48STaylor Simpson 2164458f48STaylor Simpson #include "qemu/host-utils.h" 2264458f48STaylor Simpson #include "arch.h" 2364458f48STaylor Simpson #include "mmvec/system_ext_mmvec.h" 2464458f48STaylor Simpson 2564458f48STaylor Simpson #ifndef QEMU_GENERATE 2664458f48STaylor Simpson #define VdV (*(MMVector *)(VdV_void)) 2764458f48STaylor Simpson #define VsV (*(MMVector *)(VsV_void)) 2864458f48STaylor Simpson #define VuV (*(MMVector *)(VuV_void)) 2964458f48STaylor Simpson #define VvV (*(MMVector *)(VvV_void)) 3064458f48STaylor Simpson #define VwV (*(MMVector *)(VwV_void)) 3164458f48STaylor Simpson #define VxV (*(MMVector *)(VxV_void)) 3264458f48STaylor Simpson #define VyV (*(MMVector *)(VyV_void)) 3364458f48STaylor Simpson 3464458f48STaylor Simpson #define VddV (*(MMVectorPair *)(VddV_void)) 3564458f48STaylor Simpson #define VuuV (*(MMVectorPair *)(VuuV_void)) 3664458f48STaylor Simpson #define VvvV (*(MMVectorPair *)(VvvV_void)) 3764458f48STaylor Simpson #define VxxV (*(MMVectorPair *)(VxxV_void)) 3864458f48STaylor Simpson 3964458f48STaylor Simpson #define QeV (*(MMQReg *)(QeV_void)) 4064458f48STaylor Simpson #define QdV (*(MMQReg *)(QdV_void)) 4164458f48STaylor Simpson #define QsV (*(MMQReg *)(QsV_void)) 4264458f48STaylor Simpson #define QtV (*(MMQReg *)(QtV_void)) 4364458f48STaylor Simpson #define QuV (*(MMQReg *)(QuV_void)) 4464458f48STaylor Simpson #define QvV (*(MMQReg *)(QvV_void)) 4564458f48STaylor Simpson #define QxV (*(MMQReg *)(QxV_void)) 4664458f48STaylor Simpson #endif 4764458f48STaylor Simpson 4864458f48STaylor Simpson #define LOG_VTCM_BYTE(VA, MASK, VAL, IDX) \ 4964458f48STaylor Simpson do { \ 5064458f48STaylor Simpson env->vtcm_log.data.ub[IDX] = (VAL); \ 5164458f48STaylor Simpson if (MASK) { \ 5264458f48STaylor Simpson set_bit((IDX), env->vtcm_log.mask); \ 5364458f48STaylor Simpson } else { \ 5464458f48STaylor Simpson clear_bit((IDX), env->vtcm_log.mask); \ 5564458f48STaylor Simpson } \ 5664458f48STaylor Simpson env->vtcm_log.va[IDX] = (VA); \ 5764458f48STaylor Simpson } while (0) 5864458f48STaylor Simpson 5964458f48STaylor Simpson #define fNOTQ(VAL) \ 6064458f48STaylor Simpson ({ \ 6164458f48STaylor Simpson MMQReg _ret; \ 6264458f48STaylor Simpson int _i_; \ 6364458f48STaylor Simpson for (_i_ = 0; _i_ < fVECSIZE() / 64; _i_++) { \ 6464458f48STaylor Simpson _ret.ud[_i_] = ~VAL.ud[_i_]; \ 6564458f48STaylor Simpson } \ 6664458f48STaylor Simpson _ret;\ 6764458f48STaylor Simpson }) 6864458f48STaylor Simpson #define fGETQBITS(REG, WIDTH, MASK, BITNO) \ 6964458f48STaylor Simpson ((MASK) & (REG.w[(BITNO) >> 5] >> ((BITNO) & 0x1f))) 7064458f48STaylor Simpson #define fGETQBIT(REG, BITNO) fGETQBITS(REG, 1, 1, BITNO) 7164458f48STaylor Simpson #define fGENMASKW(QREG, IDX) \ 7264458f48STaylor Simpson (((fGETQBIT(QREG, (IDX * 4 + 0)) ? 0xFF : 0x0) << 0) | \ 7364458f48STaylor Simpson ((fGETQBIT(QREG, (IDX * 4 + 1)) ? 0xFF : 0x0) << 8) | \ 7464458f48STaylor Simpson ((fGETQBIT(QREG, (IDX * 4 + 2)) ? 0xFF : 0x0) << 16) | \ 7564458f48STaylor Simpson ((fGETQBIT(QREG, (IDX * 4 + 3)) ? 0xFF : 0x0) << 24)) 7664458f48STaylor Simpson #define fGETNIBBLE(IDX, SRC) (fSXTN(4, 8, (SRC >> (4 * IDX)) & 0xF)) 7764458f48STaylor Simpson #define fGETCRUMB(IDX, SRC) (fSXTN(2, 8, (SRC >> (2 * IDX)) & 0x3)) 7864458f48STaylor Simpson #define fGETCRUMB_SYMMETRIC(IDX, SRC) \ 7964458f48STaylor Simpson ((fGETCRUMB(IDX, SRC) >= 0 ? (2 - fGETCRUMB(IDX, SRC)) \ 8064458f48STaylor Simpson : fGETCRUMB(IDX, SRC))) 8164458f48STaylor Simpson #define fGENMASKH(QREG, IDX) \ 8264458f48STaylor Simpson (((fGETQBIT(QREG, (IDX * 2 + 0)) ? 0xFF : 0x0) << 0) | \ 8364458f48STaylor Simpson ((fGETQBIT(QREG, (IDX * 2 + 1)) ? 0xFF : 0x0) << 8)) 8464458f48STaylor Simpson #define fGETMASKW(VREG, QREG, IDX) (VREG.w[IDX] & fGENMASKW((QREG), IDX)) 8564458f48STaylor Simpson #define fGETMASKH(VREG, QREG, IDX) (VREG.h[IDX] & fGENMASKH((QREG), IDX)) 8664458f48STaylor Simpson #define fCONDMASK8(QREG, IDX, YESVAL, NOVAL) \ 8764458f48STaylor Simpson (fGETQBIT(QREG, IDX) ? (YESVAL) : (NOVAL)) 8864458f48STaylor Simpson #define fCONDMASK16(QREG, IDX, YESVAL, NOVAL) \ 8964458f48STaylor Simpson ((fGENMASKH(QREG, IDX) & (YESVAL)) | \ 9064458f48STaylor Simpson (fGENMASKH(fNOTQ(QREG), IDX) & (NOVAL))) 9164458f48STaylor Simpson #define fCONDMASK32(QREG, IDX, YESVAL, NOVAL) \ 9264458f48STaylor Simpson ((fGENMASKW(QREG, IDX) & (YESVAL)) | \ 9364458f48STaylor Simpson (fGENMASKW(fNOTQ(QREG), IDX) & (NOVAL))) 9464458f48STaylor Simpson #define fSETQBITS(REG, WIDTH, MASK, BITNO, VAL) \ 9564458f48STaylor Simpson do { \ 9664458f48STaylor Simpson uint32_t __TMP = (VAL); \ 9764458f48STaylor Simpson REG.w[(BITNO) >> 5] &= ~((MASK) << ((BITNO) & 0x1f)); \ 9864458f48STaylor Simpson REG.w[(BITNO) >> 5] |= (((__TMP) & (MASK)) << ((BITNO) & 0x1f)); \ 9964458f48STaylor Simpson } while (0) 10064458f48STaylor Simpson #define fSETQBIT(REG, BITNO, VAL) fSETQBITS(REG, 1, 1, BITNO, VAL) 10164458f48STaylor Simpson #define fVBYTES() (fVECSIZE()) 10264458f48STaylor Simpson #define fVALIGN(ADDR, LOG2_ALIGNMENT) (ADDR = ADDR & ~(LOG2_ALIGNMENT - 1)) 10364458f48STaylor Simpson #define fVLASTBYTE(ADDR, LOG2_ALIGNMENT) (ADDR = ADDR | (LOG2_ALIGNMENT - 1)) 10464458f48STaylor Simpson #define fVELEM(WIDTH) ((fVECSIZE() * 8) / WIDTH) 10564458f48STaylor Simpson #define fVECLOGSIZE() (7) 10664458f48STaylor Simpson #define fVECSIZE() (1 << fVECLOGSIZE()) 10764458f48STaylor Simpson #define fSWAPB(A, B) do { uint8_t tmp = A; A = B; B = tmp; } while (0) 10864458f48STaylor Simpson #define fV_AL_CHECK(EA, MASK) \ 10964458f48STaylor Simpson if ((EA) & (MASK)) { \ 11064458f48STaylor Simpson warn("aligning misaligned vector. EA=%08x", (EA)); \ 11164458f48STaylor Simpson } 11264458f48STaylor Simpson #define fSCATTER_INIT(REGION_START, LENGTH, ELEMENT_SIZE) \ 11364458f48STaylor Simpson mem_vector_scatter_init(env) 11464458f48STaylor Simpson #define fGATHER_INIT(REGION_START, LENGTH, ELEMENT_SIZE) \ 11564458f48STaylor Simpson mem_vector_gather_init(env) 11664458f48STaylor Simpson #define fSCATTER_FINISH(OP) 11764458f48STaylor Simpson #define fGATHER_FINISH() 11864458f48STaylor Simpson #define fLOG_SCATTER_OP(SIZE) \ 11964458f48STaylor Simpson do { \ 12064458f48STaylor Simpson env->vtcm_log.op = true; \ 12164458f48STaylor Simpson env->vtcm_log.op_size = SIZE; \ 12264458f48STaylor Simpson } while (0) 12364458f48STaylor Simpson #define fVLOG_VTCM_WORD_INCREMENT(EA, OFFSET, INC, IDX, ALIGNMENT, LEN) \ 12464458f48STaylor Simpson do { \ 12564458f48STaylor Simpson int log_byte = 0; \ 12664458f48STaylor Simpson target_ulong va = EA; \ 12764458f48STaylor Simpson target_ulong va_high = EA + LEN; \ 12864458f48STaylor Simpson for (int i0 = 0; i0 < 4; i0++) { \ 12964458f48STaylor Simpson log_byte = (va + i0) <= va_high; \ 13064458f48STaylor Simpson LOG_VTCM_BYTE(va + i0, log_byte, INC. ub[4 * IDX + i0], \ 13164458f48STaylor Simpson 4 * IDX + i0); \ 13264458f48STaylor Simpson } \ 13364458f48STaylor Simpson } while (0) 13464458f48STaylor Simpson #define fVLOG_VTCM_HALFWORD_INCREMENT(EA, OFFSET, INC, IDX, ALIGNMENT, LEN) \ 13564458f48STaylor Simpson do { \ 13664458f48STaylor Simpson int log_byte = 0; \ 13764458f48STaylor Simpson target_ulong va = EA; \ 13864458f48STaylor Simpson target_ulong va_high = EA + LEN; \ 13964458f48STaylor Simpson for (int i0 = 0; i0 < 2; i0++) { \ 14064458f48STaylor Simpson log_byte = (va + i0) <= va_high; \ 14164458f48STaylor Simpson LOG_VTCM_BYTE(va + i0, log_byte, INC.ub[2 * IDX + i0], \ 14264458f48STaylor Simpson 2 * IDX + i0); \ 14364458f48STaylor Simpson } \ 14464458f48STaylor Simpson } while (0) 14564458f48STaylor Simpson 14664458f48STaylor Simpson #define fVLOG_VTCM_HALFWORD_INCREMENT_DV(EA, OFFSET, INC, IDX, IDX2, IDX_H, \ 14764458f48STaylor Simpson ALIGNMENT, LEN) \ 14864458f48STaylor Simpson do { \ 14964458f48STaylor Simpson int log_byte = 0; \ 15064458f48STaylor Simpson target_ulong va = EA; \ 15164458f48STaylor Simpson target_ulong va_high = EA + LEN; \ 15264458f48STaylor Simpson for (int i0 = 0; i0 < 2; i0++) { \ 15364458f48STaylor Simpson log_byte = (va + i0) <= va_high; \ 15464458f48STaylor Simpson LOG_VTCM_BYTE(va + i0, log_byte, INC.ub[2 * IDX + i0], \ 15564458f48STaylor Simpson 2 * IDX + i0); \ 15664458f48STaylor Simpson } \ 15764458f48STaylor Simpson } while (0) 15864458f48STaylor Simpson 15964458f48STaylor Simpson /* NOTE - Will this always be tmp_VRegs[0]; */ 16064458f48STaylor Simpson #define GATHER_FUNCTION(EA, OFFSET, IDX, LEN, ELEMENT_SIZE, BANK_IDX, QVAL) \ 16164458f48STaylor Simpson do { \ 16264458f48STaylor Simpson int i0; \ 16364458f48STaylor Simpson target_ulong va = EA; \ 16464458f48STaylor Simpson target_ulong va_high = EA + LEN; \ 16564458f48STaylor Simpson uintptr_t ra = GETPC(); \ 16664458f48STaylor Simpson int log_byte = 0; \ 16764458f48STaylor Simpson for (i0 = 0; i0 < ELEMENT_SIZE; i0++) { \ 16864458f48STaylor Simpson log_byte = ((va + i0) <= va_high) && QVAL; \ 16964458f48STaylor Simpson uint8_t B; \ 17064458f48STaylor Simpson B = cpu_ldub_data_ra(env, EA + i0, ra); \ 17164458f48STaylor Simpson env->tmp_VRegs[0].ub[ELEMENT_SIZE * IDX + i0] = B; \ 17264458f48STaylor Simpson LOG_VTCM_BYTE(va + i0, log_byte, B, ELEMENT_SIZE * IDX + i0); \ 17364458f48STaylor Simpson } \ 17464458f48STaylor Simpson } while (0) 17564458f48STaylor Simpson #define fVLOG_VTCM_GATHER_WORD(EA, OFFSET, IDX, LEN) \ 17664458f48STaylor Simpson do { \ 17764458f48STaylor Simpson GATHER_FUNCTION(EA, OFFSET, IDX, LEN, 4, IDX, 1); \ 17864458f48STaylor Simpson } while (0) 17964458f48STaylor Simpson #define fVLOG_VTCM_GATHER_HALFWORD(EA, OFFSET, IDX, LEN) \ 18064458f48STaylor Simpson do { \ 18164458f48STaylor Simpson GATHER_FUNCTION(EA, OFFSET, IDX, LEN, 2, IDX, 1); \ 18264458f48STaylor Simpson } while (0) 18364458f48STaylor Simpson #define fVLOG_VTCM_GATHER_HALFWORD_DV(EA, OFFSET, IDX, IDX2, IDX_H, LEN) \ 18464458f48STaylor Simpson do { \ 18564458f48STaylor Simpson GATHER_FUNCTION(EA, OFFSET, IDX, LEN, 2, (2 * IDX2 + IDX_H), 1); \ 18664458f48STaylor Simpson } while (0) 18764458f48STaylor Simpson #define fVLOG_VTCM_GATHER_WORDQ(EA, OFFSET, IDX, Q, LEN) \ 18864458f48STaylor Simpson do { \ 18964458f48STaylor Simpson GATHER_FUNCTION(EA, OFFSET, IDX, LEN, 4, IDX, \ 19064458f48STaylor Simpson fGETQBIT(QsV, 4 * IDX + i0)); \ 19164458f48STaylor Simpson } while (0) 19264458f48STaylor Simpson #define fVLOG_VTCM_GATHER_HALFWORDQ(EA, OFFSET, IDX, Q, LEN) \ 19364458f48STaylor Simpson do { \ 19464458f48STaylor Simpson GATHER_FUNCTION(EA, OFFSET, IDX, LEN, 2, IDX, \ 19564458f48STaylor Simpson fGETQBIT(QsV, 2 * IDX + i0)); \ 19664458f48STaylor Simpson } while (0) 19764458f48STaylor Simpson #define fVLOG_VTCM_GATHER_HALFWORDQ_DV(EA, OFFSET, IDX, IDX2, IDX_H, Q, LEN) \ 19864458f48STaylor Simpson do { \ 19964458f48STaylor Simpson GATHER_FUNCTION(EA, OFFSET, IDX, LEN, 2, (2 * IDX2 + IDX_H), \ 20064458f48STaylor Simpson fGETQBIT(QsV, 2 * IDX + i0)); \ 20164458f48STaylor Simpson } while (0) 20264458f48STaylor Simpson #define SCATTER_OP_WRITE_TO_MEM(TYPE) \ 20364458f48STaylor Simpson do { \ 204*20c34a92SBrian Cain ra = GETPC(); \ 20564458f48STaylor Simpson for (int i = 0; i < sizeof(MMVector); i += sizeof(TYPE)) { \ 20664458f48STaylor Simpson if (test_bit(i, env->vtcm_log.mask)) { \ 20764458f48STaylor Simpson TYPE dst = 0; \ 20864458f48STaylor Simpson TYPE inc = 0; \ 20964458f48STaylor Simpson for (int j = 0; j < sizeof(TYPE); j++) { \ 21064458f48STaylor Simpson uint8_t val; \ 21164458f48STaylor Simpson val = cpu_ldub_data_ra(env, env->vtcm_log.va[i + j], ra); \ 21264458f48STaylor Simpson dst |= val << (8 * j); \ 21364458f48STaylor Simpson inc |= env->vtcm_log.data.ub[j + i] << (8 * j); \ 21464458f48STaylor Simpson clear_bit(j + i, env->vtcm_log.mask); \ 21564458f48STaylor Simpson env->vtcm_log.data.ub[j + i] = 0; \ 21664458f48STaylor Simpson } \ 21764458f48STaylor Simpson dst += inc; \ 21864458f48STaylor Simpson for (int j = 0; j < sizeof(TYPE); j++) { \ 21964458f48STaylor Simpson cpu_stb_data_ra(env, env->vtcm_log.va[i + j], \ 22064458f48STaylor Simpson (dst >> (8 * j)) & 0xFF, ra); \ 22164458f48STaylor Simpson } \ 22264458f48STaylor Simpson } \ 22364458f48STaylor Simpson } \ 22464458f48STaylor Simpson } while (0) 22564458f48STaylor Simpson #define SCATTER_OP_PROBE_MEM(TYPE, MMU_IDX, RETADDR) \ 22664458f48STaylor Simpson do { \ 22764458f48STaylor Simpson for (int i = 0; i < sizeof(MMVector); i += sizeof(TYPE)) { \ 22864458f48STaylor Simpson if (test_bit(i, env->vtcm_log.mask)) { \ 22964458f48STaylor Simpson for (int j = 0; j < sizeof(TYPE); j++) { \ 23064458f48STaylor Simpson probe_read(env, env->vtcm_log.va[i + j], 1, \ 23164458f48STaylor Simpson MMU_IDX, RETADDR); \ 23264458f48STaylor Simpson probe_write(env, env->vtcm_log.va[i + j], 1, \ 23364458f48STaylor Simpson MMU_IDX, RETADDR); \ 23464458f48STaylor Simpson } \ 23564458f48STaylor Simpson } \ 23664458f48STaylor Simpson } \ 23764458f48STaylor Simpson } while (0) 23864458f48STaylor Simpson #define SCATTER_FUNCTION(EA, OFFSET, IDX, LEN, ELEM_SIZE, BANK_IDX, QVAL, IN) \ 23964458f48STaylor Simpson do { \ 24064458f48STaylor Simpson int i0; \ 24164458f48STaylor Simpson target_ulong va = EA; \ 24264458f48STaylor Simpson target_ulong va_high = EA + LEN; \ 24364458f48STaylor Simpson int log_byte = 0; \ 24464458f48STaylor Simpson for (i0 = 0; i0 < ELEM_SIZE; i0++) { \ 24564458f48STaylor Simpson log_byte = ((va + i0) <= va_high) && QVAL; \ 24664458f48STaylor Simpson LOG_VTCM_BYTE(va + i0, log_byte, IN.ub[ELEM_SIZE * IDX + i0], \ 24764458f48STaylor Simpson ELEM_SIZE * IDX + i0); \ 24864458f48STaylor Simpson } \ 24964458f48STaylor Simpson } while (0) 25064458f48STaylor Simpson #define fVLOG_VTCM_HALFWORD(EA, OFFSET, IN, IDX, LEN) \ 25164458f48STaylor Simpson do { \ 25264458f48STaylor Simpson SCATTER_FUNCTION(EA, OFFSET, IDX, LEN, 2, IDX, 1, IN); \ 25364458f48STaylor Simpson } while (0) 25464458f48STaylor Simpson #define fVLOG_VTCM_WORD(EA, OFFSET, IN, IDX, LEN) \ 25564458f48STaylor Simpson do { \ 25664458f48STaylor Simpson SCATTER_FUNCTION(EA, OFFSET, IDX, LEN, 4, IDX, 1, IN); \ 25764458f48STaylor Simpson } while (0) 25864458f48STaylor Simpson #define fVLOG_VTCM_HALFWORDQ(EA, OFFSET, IN, IDX, Q, LEN) \ 25964458f48STaylor Simpson do { \ 26064458f48STaylor Simpson SCATTER_FUNCTION(EA, OFFSET, IDX, LEN, 2, IDX, \ 26164458f48STaylor Simpson fGETQBIT(QsV, 2 * IDX + i0), IN); \ 26264458f48STaylor Simpson } while (0) 26364458f48STaylor Simpson #define fVLOG_VTCM_WORDQ(EA, OFFSET, IN, IDX, Q, LEN) \ 26464458f48STaylor Simpson do { \ 26564458f48STaylor Simpson SCATTER_FUNCTION(EA, OFFSET, IDX, LEN, 4, IDX, \ 26664458f48STaylor Simpson fGETQBIT(QsV, 4 * IDX + i0), IN); \ 26764458f48STaylor Simpson } while (0) 26864458f48STaylor Simpson #define fVLOG_VTCM_HALFWORD_DV(EA, OFFSET, IN, IDX, IDX2, IDX_H, LEN) \ 26964458f48STaylor Simpson do { \ 27064458f48STaylor Simpson SCATTER_FUNCTION(EA, OFFSET, IDX, LEN, 2, \ 27164458f48STaylor Simpson (2 * IDX2 + IDX_H), 1, IN); \ 27264458f48STaylor Simpson } while (0) 27364458f48STaylor Simpson #define fVLOG_VTCM_HALFWORDQ_DV(EA, OFFSET, IN, IDX, Q, IDX2, IDX_H, LEN) \ 27464458f48STaylor Simpson do { \ 27564458f48STaylor Simpson SCATTER_FUNCTION(EA, OFFSET, IDX, LEN, 2, (2 * IDX2 + IDX_H), \ 27664458f48STaylor Simpson fGETQBIT(QsV, 2 * IDX + i0), IN); \ 27764458f48STaylor Simpson } while (0) 27864458f48STaylor Simpson #define fSTORERELEASE(EA, TYPE) \ 27964458f48STaylor Simpson do { \ 28064458f48STaylor Simpson fV_AL_CHECK(EA, fVECSIZE() - 1); \ 28164458f48STaylor Simpson } while (0) 28264458f48STaylor Simpson #ifdef QEMU_GENERATE 28364458f48STaylor Simpson #define fLOADMMV(EA, DST) gen_vreg_load(ctx, DST##_off, EA, true) 28464458f48STaylor Simpson #endif 28564458f48STaylor Simpson #ifdef QEMU_GENERATE 28664458f48STaylor Simpson #define fLOADMMVU(EA, DST) gen_vreg_load(ctx, DST##_off, EA, false) 28764458f48STaylor Simpson #endif 28864458f48STaylor Simpson #ifdef QEMU_GENERATE 28964458f48STaylor Simpson #define fSTOREMMV(EA, SRC) \ 2901e536334STaylor Simpson gen_vreg_store(ctx, EA, SRC##_off, insn->slot, true) 29164458f48STaylor Simpson #endif 29264458f48STaylor Simpson #ifdef QEMU_GENERATE 29364458f48STaylor Simpson #define fSTOREMMVQ(EA, SRC, MASK) \ 29464458f48STaylor Simpson gen_vreg_masked_store(ctx, EA, SRC##_off, MASK##_off, insn->slot, false) 29564458f48STaylor Simpson #endif 29664458f48STaylor Simpson #ifdef QEMU_GENERATE 29764458f48STaylor Simpson #define fSTOREMMVNQ(EA, SRC, MASK) \ 29864458f48STaylor Simpson gen_vreg_masked_store(ctx, EA, SRC##_off, MASK##_off, insn->slot, true) 29964458f48STaylor Simpson #endif 30064458f48STaylor Simpson #ifdef QEMU_GENERATE 30164458f48STaylor Simpson #define fSTOREMMVU(EA, SRC) \ 3021e536334STaylor Simpson gen_vreg_store(ctx, EA, SRC##_off, insn->slot, false) 30364458f48STaylor Simpson #endif 30464458f48STaylor Simpson #define fVFOREACH(WIDTH, VAR) for (VAR = 0; VAR < fVELEM(WIDTH); VAR++) 30564458f48STaylor Simpson #define fVARRAY_ELEMENT_ACCESS(ARRAY, TYPE, INDEX) \ 30664458f48STaylor Simpson ARRAY.v[(INDEX) / (fVECSIZE() / (sizeof(ARRAY.TYPE[0])))].TYPE[(INDEX) % \ 30764458f48STaylor Simpson (fVECSIZE() / (sizeof(ARRAY.TYPE[0])))] 30864458f48STaylor Simpson 30964458f48STaylor Simpson #define fVSATDW(U, V) fVSATW(((((long long)U) << 32) | fZXTN(32, 64, V))) 31064458f48STaylor Simpson #define fVASL_SATHI(U, V) fVSATW(((U) << 1) | ((V) >> 31)) 31164458f48STaylor Simpson #define fVUADDSAT(WIDTH, U, V) \ 31264458f48STaylor Simpson fVSATUN(WIDTH, fZXTN(WIDTH, 2 * WIDTH, U) + fZXTN(WIDTH, 2 * WIDTH, V)) 31364458f48STaylor Simpson #define fVSADDSAT(WIDTH, U, V) \ 31464458f48STaylor Simpson fVSATN(WIDTH, fSXTN(WIDTH, 2 * WIDTH, U) + fSXTN(WIDTH, 2 * WIDTH, V)) 31564458f48STaylor Simpson #define fVUSUBSAT(WIDTH, U, V) \ 31664458f48STaylor Simpson fVSATUN(WIDTH, fZXTN(WIDTH, 2 * WIDTH, U) - fZXTN(WIDTH, 2 * WIDTH, V)) 31764458f48STaylor Simpson #define fVSSUBSAT(WIDTH, U, V) \ 31864458f48STaylor Simpson fVSATN(WIDTH, fSXTN(WIDTH, 2 * WIDTH, U) - fSXTN(WIDTH, 2 * WIDTH, V)) 31964458f48STaylor Simpson #define fVAVGU(WIDTH, U, V) \ 32064458f48STaylor Simpson ((fZXTN(WIDTH, 2 * WIDTH, U) + fZXTN(WIDTH, 2 * WIDTH, V)) >> 1) 32164458f48STaylor Simpson #define fVAVGURND(WIDTH, U, V) \ 32264458f48STaylor Simpson ((fZXTN(WIDTH, 2 * WIDTH, U) + fZXTN(WIDTH, 2 * WIDTH, V) + 1) >> 1) 32364458f48STaylor Simpson #define fVNAVGU(WIDTH, U, V) \ 32464458f48STaylor Simpson ((fZXTN(WIDTH, 2 * WIDTH, U) - fZXTN(WIDTH, 2 * WIDTH, V)) >> 1) 32564458f48STaylor Simpson #define fVNAVGURNDSAT(WIDTH, U, V) \ 32664458f48STaylor Simpson fVSATUN(WIDTH, ((fZXTN(WIDTH, 2 * WIDTH, U) - \ 32764458f48STaylor Simpson fZXTN(WIDTH, 2 * WIDTH, V) + 1) >> 1)) 32864458f48STaylor Simpson #define fVAVGS(WIDTH, U, V) \ 32964458f48STaylor Simpson ((fSXTN(WIDTH, 2 * WIDTH, U) + fSXTN(WIDTH, 2 * WIDTH, V)) >> 1) 33064458f48STaylor Simpson #define fVAVGSRND(WIDTH, U, V) \ 33164458f48STaylor Simpson ((fSXTN(WIDTH, 2 * WIDTH, U) + fSXTN(WIDTH, 2 * WIDTH, V) + 1) >> 1) 33264458f48STaylor Simpson #define fVNAVGS(WIDTH, U, V) \ 33364458f48STaylor Simpson ((fSXTN(WIDTH, 2 * WIDTH, U) - fSXTN(WIDTH, 2 * WIDTH, V)) >> 1) 33464458f48STaylor Simpson #define fVNAVGSRND(WIDTH, U, V) \ 33564458f48STaylor Simpson ((fSXTN(WIDTH, 2 * WIDTH, U) - fSXTN(WIDTH, 2 * WIDTH, V) + 1) >> 1) 33664458f48STaylor Simpson #define fVNAVGSRNDSAT(WIDTH, U, V) \ 33764458f48STaylor Simpson fVSATN(WIDTH, ((fSXTN(WIDTH, 2 * WIDTH, U) - \ 33864458f48STaylor Simpson fSXTN(WIDTH, 2 * WIDTH, V) + 1) >> 1)) 33964458f48STaylor Simpson #define fVNOROUND(VAL, SHAMT) VAL 34064458f48STaylor Simpson #define fVNOSAT(VAL) VAL 34164458f48STaylor Simpson #define fVROUND(VAL, SHAMT) \ 34264458f48STaylor Simpson ((VAL) + (((SHAMT) > 0) ? (1LL << ((SHAMT) - 1)) : 0)) 34364458f48STaylor Simpson #define fCARRY_FROM_ADD32(A, B, C) \ 34464458f48STaylor Simpson (((fZXTN(32, 64, A) + fZXTN(32, 64, B) + C) >> 32) & 1) 34564458f48STaylor Simpson #define fUARCH_NOTE_PUMP_4X() 34664458f48STaylor Simpson #define fUARCH_NOTE_PUMP_2X() 34764458f48STaylor Simpson 34864458f48STaylor Simpson #define IV1DEAD() 349f128c0feSTaylor Simpson 350f128c0feSTaylor Simpson #define fGET10BIT(COE, VAL, POS) \ 351f128c0feSTaylor Simpson do { \ 352f128c0feSTaylor Simpson COE = (sextract32(VAL, 24 + 2 * POS, 2) << 8) | \ 353f128c0feSTaylor Simpson extract32(VAL, POS * 8, 8); \ 354f128c0feSTaylor Simpson } while (0); 355f128c0feSTaylor Simpson 35664458f48STaylor Simpson #endif 357