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