xref: /openbmc/qemu/target/hexagon/mmvec/macros.h (revision fd9a38fd437c4c31705071c240f4be11394ca1f8)
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