1*64458f48STaylor Simpson /* 2*64458f48STaylor Simpson * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. 3*64458f48STaylor Simpson * 4*64458f48STaylor Simpson * This program is free software; you can redistribute it and/or modify 5*64458f48STaylor Simpson * it under the terms of the GNU General Public License as published by 6*64458f48STaylor Simpson * the Free Software Foundation; either version 2 of the License, or 7*64458f48STaylor Simpson * (at your option) any later version. 8*64458f48STaylor Simpson * 9*64458f48STaylor Simpson * This program is distributed in the hope that it will be useful, 10*64458f48STaylor Simpson * but WITHOUT ANY WARRANTY; without even the implied warranty of 11*64458f48STaylor Simpson * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12*64458f48STaylor Simpson * GNU General Public License for more details. 13*64458f48STaylor Simpson * 14*64458f48STaylor Simpson * You should have received a copy of the GNU General Public License 15*64458f48STaylor Simpson * along with this program; if not, see <http://www.gnu.org/licenses/>. 16*64458f48STaylor Simpson */ 17*64458f48STaylor Simpson 18*64458f48STaylor Simpson #ifndef HEXAGON_MMVEC_MACROS_H 19*64458f48STaylor Simpson #define HEXAGON_MMVEC_MACROS_H 20*64458f48STaylor Simpson 21*64458f48STaylor Simpson #include "qemu/osdep.h" 22*64458f48STaylor Simpson #include "qemu/host-utils.h" 23*64458f48STaylor Simpson #include "arch.h" 24*64458f48STaylor Simpson #include "mmvec/system_ext_mmvec.h" 25*64458f48STaylor Simpson 26*64458f48STaylor Simpson #ifndef QEMU_GENERATE 27*64458f48STaylor Simpson #define VdV (*(MMVector *)(VdV_void)) 28*64458f48STaylor Simpson #define VsV (*(MMVector *)(VsV_void)) 29*64458f48STaylor Simpson #define VuV (*(MMVector *)(VuV_void)) 30*64458f48STaylor Simpson #define VvV (*(MMVector *)(VvV_void)) 31*64458f48STaylor Simpson #define VwV (*(MMVector *)(VwV_void)) 32*64458f48STaylor Simpson #define VxV (*(MMVector *)(VxV_void)) 33*64458f48STaylor Simpson #define VyV (*(MMVector *)(VyV_void)) 34*64458f48STaylor Simpson 35*64458f48STaylor Simpson #define VddV (*(MMVectorPair *)(VddV_void)) 36*64458f48STaylor Simpson #define VuuV (*(MMVectorPair *)(VuuV_void)) 37*64458f48STaylor Simpson #define VvvV (*(MMVectorPair *)(VvvV_void)) 38*64458f48STaylor Simpson #define VxxV (*(MMVectorPair *)(VxxV_void)) 39*64458f48STaylor Simpson 40*64458f48STaylor Simpson #define QeV (*(MMQReg *)(QeV_void)) 41*64458f48STaylor Simpson #define QdV (*(MMQReg *)(QdV_void)) 42*64458f48STaylor Simpson #define QsV (*(MMQReg *)(QsV_void)) 43*64458f48STaylor Simpson #define QtV (*(MMQReg *)(QtV_void)) 44*64458f48STaylor Simpson #define QuV (*(MMQReg *)(QuV_void)) 45*64458f48STaylor Simpson #define QvV (*(MMQReg *)(QvV_void)) 46*64458f48STaylor Simpson #define QxV (*(MMQReg *)(QxV_void)) 47*64458f48STaylor Simpson #endif 48*64458f48STaylor Simpson 49*64458f48STaylor Simpson #define LOG_VTCM_BYTE(VA, MASK, VAL, IDX) \ 50*64458f48STaylor Simpson do { \ 51*64458f48STaylor Simpson env->vtcm_log.data.ub[IDX] = (VAL); \ 52*64458f48STaylor Simpson if (MASK) { \ 53*64458f48STaylor Simpson set_bit((IDX), env->vtcm_log.mask); \ 54*64458f48STaylor Simpson } else { \ 55*64458f48STaylor Simpson clear_bit((IDX), env->vtcm_log.mask); \ 56*64458f48STaylor Simpson } \ 57*64458f48STaylor Simpson env->vtcm_log.va[IDX] = (VA); \ 58*64458f48STaylor Simpson } while (0) 59*64458f48STaylor Simpson 60*64458f48STaylor Simpson #define fNOTQ(VAL) \ 61*64458f48STaylor Simpson ({ \ 62*64458f48STaylor Simpson MMQReg _ret; \ 63*64458f48STaylor Simpson int _i_; \ 64*64458f48STaylor Simpson for (_i_ = 0; _i_ < fVECSIZE() / 64; _i_++) { \ 65*64458f48STaylor Simpson _ret.ud[_i_] = ~VAL.ud[_i_]; \ 66*64458f48STaylor Simpson } \ 67*64458f48STaylor Simpson _ret;\ 68*64458f48STaylor Simpson }) 69*64458f48STaylor Simpson #define fGETQBITS(REG, WIDTH, MASK, BITNO) \ 70*64458f48STaylor Simpson ((MASK) & (REG.w[(BITNO) >> 5] >> ((BITNO) & 0x1f))) 71*64458f48STaylor Simpson #define fGETQBIT(REG, BITNO) fGETQBITS(REG, 1, 1, BITNO) 72*64458f48STaylor Simpson #define fGENMASKW(QREG, IDX) \ 73*64458f48STaylor Simpson (((fGETQBIT(QREG, (IDX * 4 + 0)) ? 0xFF : 0x0) << 0) | \ 74*64458f48STaylor Simpson ((fGETQBIT(QREG, (IDX * 4 + 1)) ? 0xFF : 0x0) << 8) | \ 75*64458f48STaylor Simpson ((fGETQBIT(QREG, (IDX * 4 + 2)) ? 0xFF : 0x0) << 16) | \ 76*64458f48STaylor Simpson ((fGETQBIT(QREG, (IDX * 4 + 3)) ? 0xFF : 0x0) << 24)) 77*64458f48STaylor Simpson #define fGETNIBBLE(IDX, SRC) (fSXTN(4, 8, (SRC >> (4 * IDX)) & 0xF)) 78*64458f48STaylor Simpson #define fGETCRUMB(IDX, SRC) (fSXTN(2, 8, (SRC >> (2 * IDX)) & 0x3)) 79*64458f48STaylor Simpson #define fGETCRUMB_SYMMETRIC(IDX, SRC) \ 80*64458f48STaylor Simpson ((fGETCRUMB(IDX, SRC) >= 0 ? (2 - fGETCRUMB(IDX, SRC)) \ 81*64458f48STaylor Simpson : fGETCRUMB(IDX, SRC))) 82*64458f48STaylor Simpson #define fGENMASKH(QREG, IDX) \ 83*64458f48STaylor Simpson (((fGETQBIT(QREG, (IDX * 2 + 0)) ? 0xFF : 0x0) << 0) | \ 84*64458f48STaylor Simpson ((fGETQBIT(QREG, (IDX * 2 + 1)) ? 0xFF : 0x0) << 8)) 85*64458f48STaylor Simpson #define fGETMASKW(VREG, QREG, IDX) (VREG.w[IDX] & fGENMASKW((QREG), IDX)) 86*64458f48STaylor Simpson #define fGETMASKH(VREG, QREG, IDX) (VREG.h[IDX] & fGENMASKH((QREG), IDX)) 87*64458f48STaylor Simpson #define fCONDMASK8(QREG, IDX, YESVAL, NOVAL) \ 88*64458f48STaylor Simpson (fGETQBIT(QREG, IDX) ? (YESVAL) : (NOVAL)) 89*64458f48STaylor Simpson #define fCONDMASK16(QREG, IDX, YESVAL, NOVAL) \ 90*64458f48STaylor Simpson ((fGENMASKH(QREG, IDX) & (YESVAL)) | \ 91*64458f48STaylor Simpson (fGENMASKH(fNOTQ(QREG), IDX) & (NOVAL))) 92*64458f48STaylor Simpson #define fCONDMASK32(QREG, IDX, YESVAL, NOVAL) \ 93*64458f48STaylor Simpson ((fGENMASKW(QREG, IDX) & (YESVAL)) | \ 94*64458f48STaylor Simpson (fGENMASKW(fNOTQ(QREG), IDX) & (NOVAL))) 95*64458f48STaylor Simpson #define fSETQBITS(REG, WIDTH, MASK, BITNO, VAL) \ 96*64458f48STaylor Simpson do { \ 97*64458f48STaylor Simpson uint32_t __TMP = (VAL); \ 98*64458f48STaylor Simpson REG.w[(BITNO) >> 5] &= ~((MASK) << ((BITNO) & 0x1f)); \ 99*64458f48STaylor Simpson REG.w[(BITNO) >> 5] |= (((__TMP) & (MASK)) << ((BITNO) & 0x1f)); \ 100*64458f48STaylor Simpson } while (0) 101*64458f48STaylor Simpson #define fSETQBIT(REG, BITNO, VAL) fSETQBITS(REG, 1, 1, BITNO, VAL) 102*64458f48STaylor Simpson #define fVBYTES() (fVECSIZE()) 103*64458f48STaylor Simpson #define fVALIGN(ADDR, LOG2_ALIGNMENT) (ADDR = ADDR & ~(LOG2_ALIGNMENT - 1)) 104*64458f48STaylor Simpson #define fVLASTBYTE(ADDR, LOG2_ALIGNMENT) (ADDR = ADDR | (LOG2_ALIGNMENT - 1)) 105*64458f48STaylor Simpson #define fVELEM(WIDTH) ((fVECSIZE() * 8) / WIDTH) 106*64458f48STaylor Simpson #define fVECLOGSIZE() (7) 107*64458f48STaylor Simpson #define fVECSIZE() (1 << fVECLOGSIZE()) 108*64458f48STaylor Simpson #define fSWAPB(A, B) do { uint8_t tmp = A; A = B; B = tmp; } while (0) 109*64458f48STaylor Simpson #define fV_AL_CHECK(EA, MASK) \ 110*64458f48STaylor Simpson if ((EA) & (MASK)) { \ 111*64458f48STaylor Simpson warn("aligning misaligned vector. EA=%08x", (EA)); \ 112*64458f48STaylor Simpson } 113*64458f48STaylor Simpson #define fSCATTER_INIT(REGION_START, LENGTH, ELEMENT_SIZE) \ 114*64458f48STaylor Simpson mem_vector_scatter_init(env) 115*64458f48STaylor Simpson #define fGATHER_INIT(REGION_START, LENGTH, ELEMENT_SIZE) \ 116*64458f48STaylor Simpson mem_vector_gather_init(env) 117*64458f48STaylor Simpson #define fSCATTER_FINISH(OP) 118*64458f48STaylor Simpson #define fGATHER_FINISH() 119*64458f48STaylor Simpson #define fLOG_SCATTER_OP(SIZE) \ 120*64458f48STaylor Simpson do { \ 121*64458f48STaylor Simpson env->vtcm_log.op = true; \ 122*64458f48STaylor Simpson env->vtcm_log.op_size = SIZE; \ 123*64458f48STaylor Simpson } while (0) 124*64458f48STaylor Simpson #define fVLOG_VTCM_WORD_INCREMENT(EA, OFFSET, INC, IDX, ALIGNMENT, LEN) \ 125*64458f48STaylor Simpson do { \ 126*64458f48STaylor Simpson int log_byte = 0; \ 127*64458f48STaylor Simpson target_ulong va = EA; \ 128*64458f48STaylor Simpson target_ulong va_high = EA + LEN; \ 129*64458f48STaylor Simpson for (int i0 = 0; i0 < 4; i0++) { \ 130*64458f48STaylor Simpson log_byte = (va + i0) <= va_high; \ 131*64458f48STaylor Simpson LOG_VTCM_BYTE(va + i0, log_byte, INC. ub[4 * IDX + i0], \ 132*64458f48STaylor Simpson 4 * IDX + i0); \ 133*64458f48STaylor Simpson } \ 134*64458f48STaylor Simpson } while (0) 135*64458f48STaylor Simpson #define fVLOG_VTCM_HALFWORD_INCREMENT(EA, OFFSET, INC, IDX, ALIGNMENT, LEN) \ 136*64458f48STaylor Simpson do { \ 137*64458f48STaylor Simpson int log_byte = 0; \ 138*64458f48STaylor Simpson target_ulong va = EA; \ 139*64458f48STaylor Simpson target_ulong va_high = EA + LEN; \ 140*64458f48STaylor Simpson for (int i0 = 0; i0 < 2; i0++) { \ 141*64458f48STaylor Simpson log_byte = (va + i0) <= va_high; \ 142*64458f48STaylor Simpson LOG_VTCM_BYTE(va + i0, log_byte, INC.ub[2 * IDX + i0], \ 143*64458f48STaylor Simpson 2 * IDX + i0); \ 144*64458f48STaylor Simpson } \ 145*64458f48STaylor Simpson } while (0) 146*64458f48STaylor Simpson 147*64458f48STaylor Simpson #define fVLOG_VTCM_HALFWORD_INCREMENT_DV(EA, OFFSET, INC, IDX, IDX2, IDX_H, \ 148*64458f48STaylor Simpson ALIGNMENT, LEN) \ 149*64458f48STaylor Simpson do { \ 150*64458f48STaylor Simpson int log_byte = 0; \ 151*64458f48STaylor Simpson target_ulong va = EA; \ 152*64458f48STaylor Simpson target_ulong va_high = EA + LEN; \ 153*64458f48STaylor Simpson for (int i0 = 0; i0 < 2; i0++) { \ 154*64458f48STaylor Simpson log_byte = (va + i0) <= va_high; \ 155*64458f48STaylor Simpson LOG_VTCM_BYTE(va + i0, log_byte, INC.ub[2 * IDX + i0], \ 156*64458f48STaylor Simpson 2 * IDX + i0); \ 157*64458f48STaylor Simpson } \ 158*64458f48STaylor Simpson } while (0) 159*64458f48STaylor Simpson 160*64458f48STaylor Simpson /* NOTE - Will this always be tmp_VRegs[0]; */ 161*64458f48STaylor Simpson #define GATHER_FUNCTION(EA, OFFSET, IDX, LEN, ELEMENT_SIZE, BANK_IDX, QVAL) \ 162*64458f48STaylor Simpson do { \ 163*64458f48STaylor Simpson int i0; \ 164*64458f48STaylor Simpson target_ulong va = EA; \ 165*64458f48STaylor Simpson target_ulong va_high = EA + LEN; \ 166*64458f48STaylor Simpson uintptr_t ra = GETPC(); \ 167*64458f48STaylor Simpson int log_bank = 0; \ 168*64458f48STaylor Simpson int log_byte = 0; \ 169*64458f48STaylor Simpson for (i0 = 0; i0 < ELEMENT_SIZE; i0++) { \ 170*64458f48STaylor Simpson log_byte = ((va + i0) <= va_high) && QVAL; \ 171*64458f48STaylor Simpson log_bank |= (log_byte << i0); \ 172*64458f48STaylor Simpson uint8_t B; \ 173*64458f48STaylor Simpson B = cpu_ldub_data_ra(env, EA + i0, ra); \ 174*64458f48STaylor Simpson env->tmp_VRegs[0].ub[ELEMENT_SIZE * IDX + i0] = B; \ 175*64458f48STaylor Simpson LOG_VTCM_BYTE(va + i0, log_byte, B, ELEMENT_SIZE * IDX + i0); \ 176*64458f48STaylor Simpson } \ 177*64458f48STaylor Simpson } while (0) 178*64458f48STaylor Simpson #define fVLOG_VTCM_GATHER_WORD(EA, OFFSET, IDX, LEN) \ 179*64458f48STaylor Simpson do { \ 180*64458f48STaylor Simpson GATHER_FUNCTION(EA, OFFSET, IDX, LEN, 4, IDX, 1); \ 181*64458f48STaylor Simpson } while (0) 182*64458f48STaylor Simpson #define fVLOG_VTCM_GATHER_HALFWORD(EA, OFFSET, IDX, LEN) \ 183*64458f48STaylor Simpson do { \ 184*64458f48STaylor Simpson GATHER_FUNCTION(EA, OFFSET, IDX, LEN, 2, IDX, 1); \ 185*64458f48STaylor Simpson } while (0) 186*64458f48STaylor Simpson #define fVLOG_VTCM_GATHER_HALFWORD_DV(EA, OFFSET, IDX, IDX2, IDX_H, LEN) \ 187*64458f48STaylor Simpson do { \ 188*64458f48STaylor Simpson GATHER_FUNCTION(EA, OFFSET, IDX, LEN, 2, (2 * IDX2 + IDX_H), 1); \ 189*64458f48STaylor Simpson } while (0) 190*64458f48STaylor Simpson #define fVLOG_VTCM_GATHER_WORDQ(EA, OFFSET, IDX, Q, LEN) \ 191*64458f48STaylor Simpson do { \ 192*64458f48STaylor Simpson GATHER_FUNCTION(EA, OFFSET, IDX, LEN, 4, IDX, \ 193*64458f48STaylor Simpson fGETQBIT(QsV, 4 * IDX + i0)); \ 194*64458f48STaylor Simpson } while (0) 195*64458f48STaylor Simpson #define fVLOG_VTCM_GATHER_HALFWORDQ(EA, OFFSET, IDX, Q, LEN) \ 196*64458f48STaylor Simpson do { \ 197*64458f48STaylor Simpson GATHER_FUNCTION(EA, OFFSET, IDX, LEN, 2, IDX, \ 198*64458f48STaylor Simpson fGETQBIT(QsV, 2 * IDX + i0)); \ 199*64458f48STaylor Simpson } while (0) 200*64458f48STaylor Simpson #define fVLOG_VTCM_GATHER_HALFWORDQ_DV(EA, OFFSET, IDX, IDX2, IDX_H, Q, LEN) \ 201*64458f48STaylor Simpson do { \ 202*64458f48STaylor Simpson GATHER_FUNCTION(EA, OFFSET, IDX, LEN, 2, (2 * IDX2 + IDX_H), \ 203*64458f48STaylor Simpson fGETQBIT(QsV, 2 * IDX + i0)); \ 204*64458f48STaylor Simpson } while (0) 205*64458f48STaylor Simpson #define SCATTER_OP_WRITE_TO_MEM(TYPE) \ 206*64458f48STaylor Simpson do { \ 207*64458f48STaylor Simpson uintptr_t ra = GETPC(); \ 208*64458f48STaylor Simpson for (int i = 0; i < sizeof(MMVector); i += sizeof(TYPE)) { \ 209*64458f48STaylor Simpson if (test_bit(i, env->vtcm_log.mask)) { \ 210*64458f48STaylor Simpson TYPE dst = 0; \ 211*64458f48STaylor Simpson TYPE inc = 0; \ 212*64458f48STaylor Simpson for (int j = 0; j < sizeof(TYPE); j++) { \ 213*64458f48STaylor Simpson uint8_t val; \ 214*64458f48STaylor Simpson val = cpu_ldub_data_ra(env, env->vtcm_log.va[i + j], ra); \ 215*64458f48STaylor Simpson dst |= val << (8 * j); \ 216*64458f48STaylor Simpson inc |= env->vtcm_log.data.ub[j + i] << (8 * j); \ 217*64458f48STaylor Simpson clear_bit(j + i, env->vtcm_log.mask); \ 218*64458f48STaylor Simpson env->vtcm_log.data.ub[j + i] = 0; \ 219*64458f48STaylor Simpson } \ 220*64458f48STaylor Simpson dst += inc; \ 221*64458f48STaylor Simpson for (int j = 0; j < sizeof(TYPE); j++) { \ 222*64458f48STaylor Simpson cpu_stb_data_ra(env, env->vtcm_log.va[i + j], \ 223*64458f48STaylor Simpson (dst >> (8 * j)) & 0xFF, ra); \ 224*64458f48STaylor Simpson } \ 225*64458f48STaylor Simpson } \ 226*64458f48STaylor Simpson } \ 227*64458f48STaylor Simpson } while (0) 228*64458f48STaylor Simpson #define SCATTER_OP_PROBE_MEM(TYPE, MMU_IDX, RETADDR) \ 229*64458f48STaylor Simpson do { \ 230*64458f48STaylor Simpson for (int i = 0; i < sizeof(MMVector); i += sizeof(TYPE)) { \ 231*64458f48STaylor Simpson if (test_bit(i, env->vtcm_log.mask)) { \ 232*64458f48STaylor Simpson for (int j = 0; j < sizeof(TYPE); j++) { \ 233*64458f48STaylor Simpson probe_read(env, env->vtcm_log.va[i + j], 1, \ 234*64458f48STaylor Simpson MMU_IDX, RETADDR); \ 235*64458f48STaylor Simpson probe_write(env, env->vtcm_log.va[i + j], 1, \ 236*64458f48STaylor Simpson MMU_IDX, RETADDR); \ 237*64458f48STaylor Simpson } \ 238*64458f48STaylor Simpson } \ 239*64458f48STaylor Simpson } \ 240*64458f48STaylor Simpson } while (0) 241*64458f48STaylor Simpson #define SCATTER_FUNCTION(EA, OFFSET, IDX, LEN, ELEM_SIZE, BANK_IDX, QVAL, IN) \ 242*64458f48STaylor Simpson do { \ 243*64458f48STaylor Simpson int i0; \ 244*64458f48STaylor Simpson target_ulong va = EA; \ 245*64458f48STaylor Simpson target_ulong va_high = EA + LEN; \ 246*64458f48STaylor Simpson int log_bank = 0; \ 247*64458f48STaylor Simpson int log_byte = 0; \ 248*64458f48STaylor Simpson for (i0 = 0; i0 < ELEM_SIZE; i0++) { \ 249*64458f48STaylor Simpson log_byte = ((va + i0) <= va_high) && QVAL; \ 250*64458f48STaylor Simpson log_bank |= (log_byte << i0); \ 251*64458f48STaylor Simpson LOG_VTCM_BYTE(va + i0, log_byte, IN.ub[ELEM_SIZE * IDX + i0], \ 252*64458f48STaylor Simpson ELEM_SIZE * IDX + i0); \ 253*64458f48STaylor Simpson } \ 254*64458f48STaylor Simpson } while (0) 255*64458f48STaylor Simpson #define fVLOG_VTCM_HALFWORD(EA, OFFSET, IN, IDX, LEN) \ 256*64458f48STaylor Simpson do { \ 257*64458f48STaylor Simpson SCATTER_FUNCTION(EA, OFFSET, IDX, LEN, 2, IDX, 1, IN); \ 258*64458f48STaylor Simpson } while (0) 259*64458f48STaylor Simpson #define fVLOG_VTCM_WORD(EA, OFFSET, IN, IDX, LEN) \ 260*64458f48STaylor Simpson do { \ 261*64458f48STaylor Simpson SCATTER_FUNCTION(EA, OFFSET, IDX, LEN, 4, IDX, 1, IN); \ 262*64458f48STaylor Simpson } while (0) 263*64458f48STaylor Simpson #define fVLOG_VTCM_HALFWORDQ(EA, OFFSET, IN, IDX, Q, LEN) \ 264*64458f48STaylor Simpson do { \ 265*64458f48STaylor Simpson SCATTER_FUNCTION(EA, OFFSET, IDX, LEN, 2, IDX, \ 266*64458f48STaylor Simpson fGETQBIT(QsV, 2 * IDX + i0), IN); \ 267*64458f48STaylor Simpson } while (0) 268*64458f48STaylor Simpson #define fVLOG_VTCM_WORDQ(EA, OFFSET, IN, IDX, Q, LEN) \ 269*64458f48STaylor Simpson do { \ 270*64458f48STaylor Simpson SCATTER_FUNCTION(EA, OFFSET, IDX, LEN, 4, IDX, \ 271*64458f48STaylor Simpson fGETQBIT(QsV, 4 * IDX + i0), IN); \ 272*64458f48STaylor Simpson } while (0) 273*64458f48STaylor Simpson #define fVLOG_VTCM_HALFWORD_DV(EA, OFFSET, IN, IDX, IDX2, IDX_H, LEN) \ 274*64458f48STaylor Simpson do { \ 275*64458f48STaylor Simpson SCATTER_FUNCTION(EA, OFFSET, IDX, LEN, 2, \ 276*64458f48STaylor Simpson (2 * IDX2 + IDX_H), 1, IN); \ 277*64458f48STaylor Simpson } while (0) 278*64458f48STaylor Simpson #define fVLOG_VTCM_HALFWORDQ_DV(EA, OFFSET, IN, IDX, Q, IDX2, IDX_H, LEN) \ 279*64458f48STaylor Simpson do { \ 280*64458f48STaylor Simpson SCATTER_FUNCTION(EA, OFFSET, IDX, LEN, 2, (2 * IDX2 + IDX_H), \ 281*64458f48STaylor Simpson fGETQBIT(QsV, 2 * IDX + i0), IN); \ 282*64458f48STaylor Simpson } while (0) 283*64458f48STaylor Simpson #define fSTORERELEASE(EA, TYPE) \ 284*64458f48STaylor Simpson do { \ 285*64458f48STaylor Simpson fV_AL_CHECK(EA, fVECSIZE() - 1); \ 286*64458f48STaylor Simpson } while (0) 287*64458f48STaylor Simpson #ifdef QEMU_GENERATE 288*64458f48STaylor Simpson #define fLOADMMV(EA, DST) gen_vreg_load(ctx, DST##_off, EA, true) 289*64458f48STaylor Simpson #endif 290*64458f48STaylor Simpson #ifdef QEMU_GENERATE 291*64458f48STaylor Simpson #define fLOADMMVU(EA, DST) gen_vreg_load(ctx, DST##_off, EA, false) 292*64458f48STaylor Simpson #endif 293*64458f48STaylor Simpson #ifdef QEMU_GENERATE 294*64458f48STaylor Simpson #define fSTOREMMV(EA, SRC) \ 295*64458f48STaylor Simpson gen_vreg_store(ctx, insn, pkt, EA, SRC##_off, insn->slot, true) 296*64458f48STaylor Simpson #endif 297*64458f48STaylor Simpson #ifdef QEMU_GENERATE 298*64458f48STaylor Simpson #define fSTOREMMVQ(EA, SRC, MASK) \ 299*64458f48STaylor Simpson gen_vreg_masked_store(ctx, EA, SRC##_off, MASK##_off, insn->slot, false) 300*64458f48STaylor Simpson #endif 301*64458f48STaylor Simpson #ifdef QEMU_GENERATE 302*64458f48STaylor Simpson #define fSTOREMMVNQ(EA, SRC, MASK) \ 303*64458f48STaylor Simpson gen_vreg_masked_store(ctx, EA, SRC##_off, MASK##_off, insn->slot, true) 304*64458f48STaylor Simpson #endif 305*64458f48STaylor Simpson #ifdef QEMU_GENERATE 306*64458f48STaylor Simpson #define fSTOREMMVU(EA, SRC) \ 307*64458f48STaylor Simpson gen_vreg_store(ctx, insn, pkt, EA, SRC##_off, insn->slot, false) 308*64458f48STaylor Simpson #endif 309*64458f48STaylor Simpson #define fVFOREACH(WIDTH, VAR) for (VAR = 0; VAR < fVELEM(WIDTH); VAR++) 310*64458f48STaylor Simpson #define fVARRAY_ELEMENT_ACCESS(ARRAY, TYPE, INDEX) \ 311*64458f48STaylor Simpson ARRAY.v[(INDEX) / (fVECSIZE() / (sizeof(ARRAY.TYPE[0])))].TYPE[(INDEX) % \ 312*64458f48STaylor Simpson (fVECSIZE() / (sizeof(ARRAY.TYPE[0])))] 313*64458f48STaylor Simpson 314*64458f48STaylor Simpson #define fVSATDW(U, V) fVSATW(((((long long)U) << 32) | fZXTN(32, 64, V))) 315*64458f48STaylor Simpson #define fVASL_SATHI(U, V) fVSATW(((U) << 1) | ((V) >> 31)) 316*64458f48STaylor Simpson #define fVUADDSAT(WIDTH, U, V) \ 317*64458f48STaylor Simpson fVSATUN(WIDTH, fZXTN(WIDTH, 2 * WIDTH, U) + fZXTN(WIDTH, 2 * WIDTH, V)) 318*64458f48STaylor Simpson #define fVSADDSAT(WIDTH, U, V) \ 319*64458f48STaylor Simpson fVSATN(WIDTH, fSXTN(WIDTH, 2 * WIDTH, U) + fSXTN(WIDTH, 2 * WIDTH, V)) 320*64458f48STaylor Simpson #define fVUSUBSAT(WIDTH, U, V) \ 321*64458f48STaylor Simpson fVSATUN(WIDTH, fZXTN(WIDTH, 2 * WIDTH, U) - fZXTN(WIDTH, 2 * WIDTH, V)) 322*64458f48STaylor Simpson #define fVSSUBSAT(WIDTH, U, V) \ 323*64458f48STaylor Simpson fVSATN(WIDTH, fSXTN(WIDTH, 2 * WIDTH, U) - fSXTN(WIDTH, 2 * WIDTH, V)) 324*64458f48STaylor Simpson #define fVAVGU(WIDTH, U, V) \ 325*64458f48STaylor Simpson ((fZXTN(WIDTH, 2 * WIDTH, U) + fZXTN(WIDTH, 2 * WIDTH, V)) >> 1) 326*64458f48STaylor Simpson #define fVAVGURND(WIDTH, U, V) \ 327*64458f48STaylor Simpson ((fZXTN(WIDTH, 2 * WIDTH, U) + fZXTN(WIDTH, 2 * WIDTH, V) + 1) >> 1) 328*64458f48STaylor Simpson #define fVNAVGU(WIDTH, U, V) \ 329*64458f48STaylor Simpson ((fZXTN(WIDTH, 2 * WIDTH, U) - fZXTN(WIDTH, 2 * WIDTH, V)) >> 1) 330*64458f48STaylor Simpson #define fVNAVGURNDSAT(WIDTH, U, V) \ 331*64458f48STaylor Simpson fVSATUN(WIDTH, ((fZXTN(WIDTH, 2 * WIDTH, U) - \ 332*64458f48STaylor Simpson fZXTN(WIDTH, 2 * WIDTH, V) + 1) >> 1)) 333*64458f48STaylor Simpson #define fVAVGS(WIDTH, U, V) \ 334*64458f48STaylor Simpson ((fSXTN(WIDTH, 2 * WIDTH, U) + fSXTN(WIDTH, 2 * WIDTH, V)) >> 1) 335*64458f48STaylor Simpson #define fVAVGSRND(WIDTH, U, V) \ 336*64458f48STaylor Simpson ((fSXTN(WIDTH, 2 * WIDTH, U) + fSXTN(WIDTH, 2 * WIDTH, V) + 1) >> 1) 337*64458f48STaylor Simpson #define fVNAVGS(WIDTH, U, V) \ 338*64458f48STaylor Simpson ((fSXTN(WIDTH, 2 * WIDTH, U) - fSXTN(WIDTH, 2 * WIDTH, V)) >> 1) 339*64458f48STaylor Simpson #define fVNAVGSRND(WIDTH, U, V) \ 340*64458f48STaylor Simpson ((fSXTN(WIDTH, 2 * WIDTH, U) - fSXTN(WIDTH, 2 * WIDTH, V) + 1) >> 1) 341*64458f48STaylor Simpson #define fVNAVGSRNDSAT(WIDTH, U, V) \ 342*64458f48STaylor Simpson fVSATN(WIDTH, ((fSXTN(WIDTH, 2 * WIDTH, U) - \ 343*64458f48STaylor Simpson fSXTN(WIDTH, 2 * WIDTH, V) + 1) >> 1)) 344*64458f48STaylor Simpson #define fVNOROUND(VAL, SHAMT) VAL 345*64458f48STaylor Simpson #define fVNOSAT(VAL) VAL 346*64458f48STaylor Simpson #define fVROUND(VAL, SHAMT) \ 347*64458f48STaylor Simpson ((VAL) + (((SHAMT) > 0) ? (1LL << ((SHAMT) - 1)) : 0)) 348*64458f48STaylor Simpson #define fCARRY_FROM_ADD32(A, B, C) \ 349*64458f48STaylor Simpson (((fZXTN(32, 64, A) + fZXTN(32, 64, B) + C) >> 32) & 1) 350*64458f48STaylor Simpson #define fUARCH_NOTE_PUMP_4X() 351*64458f48STaylor Simpson #define fUARCH_NOTE_PUMP_2X() 352*64458f48STaylor Simpson 353*64458f48STaylor Simpson #define IV1DEAD() 354*64458f48STaylor Simpson #endif 355