1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include "qemu/osdep.h"
21#include "cpu.h"
22#include "internal.h"
23#include "exec/exec-all.h"
24#include "exec/helper-proto.h"
25#include "fpu/softfloat.h"
26
27
28#define DF_BITS(df) (1 << ((df) + 3))
29
30#define DF_MAX_INT(df) (int64_t)((1LL << (DF_BITS(df) - 1)) - 1)
31#define M_MAX_INT(m) (int64_t)((1LL << ((m) - 1)) - 1)
32
33#define DF_MIN_INT(df) (int64_t)(-(1LL << (DF_BITS(df) - 1)))
34#define M_MIN_INT(m) (int64_t)(-(1LL << ((m) - 1)))
35
36#define DF_MAX_UINT(df) (uint64_t)(-1ULL >> (64 - DF_BITS(df)))
37#define M_MAX_UINT(m) (uint64_t)(-1ULL >> (64 - (m)))
38
39#define UNSIGNED(x, df) ((x) & DF_MAX_UINT(df))
40#define SIGNED(x, df) \
41 ((((int64_t)x) << (64 - DF_BITS(df))) >> (64 - DF_BITS(df)))
42
43
44#define DF_ELEMENTS(df) (MSA_WRLEN / DF_BITS(df))
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68static inline int64_t msa_nlzc_df(uint32_t df, int64_t arg)
69{
70 uint64_t x, y;
71 int n, c;
72
73 x = UNSIGNED(arg, df);
74 n = DF_BITS(df);
75 c = DF_BITS(df) / 2;
76
77 do {
78 y = x >> c;
79 if (y != 0) {
80 n = n - c;
81 x = y;
82 }
83 c = c >> 1;
84 } while (c != 0);
85
86 return n - x;
87}
88
89static inline int64_t msa_nloc_df(uint32_t df, int64_t arg)
90{
91 return msa_nlzc_df(df, UNSIGNED((~arg), df));
92}
93
94void helper_msa_nloc_b(CPUMIPSState *env, uint32_t wd, uint32_t ws)
95{
96 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
97 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
98
99 pwd->b[0] = msa_nloc_df(DF_BYTE, pws->b[0]);
100 pwd->b[1] = msa_nloc_df(DF_BYTE, pws->b[1]);
101 pwd->b[2] = msa_nloc_df(DF_BYTE, pws->b[2]);
102 pwd->b[3] = msa_nloc_df(DF_BYTE, pws->b[3]);
103 pwd->b[4] = msa_nloc_df(DF_BYTE, pws->b[4]);
104 pwd->b[5] = msa_nloc_df(DF_BYTE, pws->b[5]);
105 pwd->b[6] = msa_nloc_df(DF_BYTE, pws->b[6]);
106 pwd->b[7] = msa_nloc_df(DF_BYTE, pws->b[7]);
107 pwd->b[8] = msa_nloc_df(DF_BYTE, pws->b[8]);
108 pwd->b[9] = msa_nloc_df(DF_BYTE, pws->b[9]);
109 pwd->b[10] = msa_nloc_df(DF_BYTE, pws->b[10]);
110 pwd->b[11] = msa_nloc_df(DF_BYTE, pws->b[11]);
111 pwd->b[12] = msa_nloc_df(DF_BYTE, pws->b[12]);
112 pwd->b[13] = msa_nloc_df(DF_BYTE, pws->b[13]);
113 pwd->b[14] = msa_nloc_df(DF_BYTE, pws->b[14]);
114 pwd->b[15] = msa_nloc_df(DF_BYTE, pws->b[15]);
115}
116
117void helper_msa_nloc_h(CPUMIPSState *env, uint32_t wd, uint32_t ws)
118{
119 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
120 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
121
122 pwd->h[0] = msa_nloc_df(DF_HALF, pws->h[0]);
123 pwd->h[1] = msa_nloc_df(DF_HALF, pws->h[1]);
124 pwd->h[2] = msa_nloc_df(DF_HALF, pws->h[2]);
125 pwd->h[3] = msa_nloc_df(DF_HALF, pws->h[3]);
126 pwd->h[4] = msa_nloc_df(DF_HALF, pws->h[4]);
127 pwd->h[5] = msa_nloc_df(DF_HALF, pws->h[5]);
128 pwd->h[6] = msa_nloc_df(DF_HALF, pws->h[6]);
129 pwd->h[7] = msa_nloc_df(DF_HALF, pws->h[7]);
130}
131
132void helper_msa_nloc_w(CPUMIPSState *env, uint32_t wd, uint32_t ws)
133{
134 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
135 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
136
137 pwd->w[0] = msa_nloc_df(DF_WORD, pws->w[0]);
138 pwd->w[1] = msa_nloc_df(DF_WORD, pws->w[1]);
139 pwd->w[2] = msa_nloc_df(DF_WORD, pws->w[2]);
140 pwd->w[3] = msa_nloc_df(DF_WORD, pws->w[3]);
141}
142
143void helper_msa_nloc_d(CPUMIPSState *env, uint32_t wd, uint32_t ws)
144{
145 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
146 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
147
148 pwd->d[0] = msa_nloc_df(DF_DOUBLE, pws->d[0]);
149 pwd->d[1] = msa_nloc_df(DF_DOUBLE, pws->d[1]);
150}
151
152void helper_msa_nlzc_b(CPUMIPSState *env, uint32_t wd, uint32_t ws)
153{
154 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
155 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
156
157 pwd->b[0] = msa_nlzc_df(DF_BYTE, pws->b[0]);
158 pwd->b[1] = msa_nlzc_df(DF_BYTE, pws->b[1]);
159 pwd->b[2] = msa_nlzc_df(DF_BYTE, pws->b[2]);
160 pwd->b[3] = msa_nlzc_df(DF_BYTE, pws->b[3]);
161 pwd->b[4] = msa_nlzc_df(DF_BYTE, pws->b[4]);
162 pwd->b[5] = msa_nlzc_df(DF_BYTE, pws->b[5]);
163 pwd->b[6] = msa_nlzc_df(DF_BYTE, pws->b[6]);
164 pwd->b[7] = msa_nlzc_df(DF_BYTE, pws->b[7]);
165 pwd->b[8] = msa_nlzc_df(DF_BYTE, pws->b[8]);
166 pwd->b[9] = msa_nlzc_df(DF_BYTE, pws->b[9]);
167 pwd->b[10] = msa_nlzc_df(DF_BYTE, pws->b[10]);
168 pwd->b[11] = msa_nlzc_df(DF_BYTE, pws->b[11]);
169 pwd->b[12] = msa_nlzc_df(DF_BYTE, pws->b[12]);
170 pwd->b[13] = msa_nlzc_df(DF_BYTE, pws->b[13]);
171 pwd->b[14] = msa_nlzc_df(DF_BYTE, pws->b[14]);
172 pwd->b[15] = msa_nlzc_df(DF_BYTE, pws->b[15]);
173}
174
175void helper_msa_nlzc_h(CPUMIPSState *env, uint32_t wd, uint32_t ws)
176{
177 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
178 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
179
180 pwd->h[0] = msa_nlzc_df(DF_HALF, pws->h[0]);
181 pwd->h[1] = msa_nlzc_df(DF_HALF, pws->h[1]);
182 pwd->h[2] = msa_nlzc_df(DF_HALF, pws->h[2]);
183 pwd->h[3] = msa_nlzc_df(DF_HALF, pws->h[3]);
184 pwd->h[4] = msa_nlzc_df(DF_HALF, pws->h[4]);
185 pwd->h[5] = msa_nlzc_df(DF_HALF, pws->h[5]);
186 pwd->h[6] = msa_nlzc_df(DF_HALF, pws->h[6]);
187 pwd->h[7] = msa_nlzc_df(DF_HALF, pws->h[7]);
188}
189
190void helper_msa_nlzc_w(CPUMIPSState *env, uint32_t wd, uint32_t ws)
191{
192 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
193 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
194
195 pwd->w[0] = msa_nlzc_df(DF_WORD, pws->w[0]);
196 pwd->w[1] = msa_nlzc_df(DF_WORD, pws->w[1]);
197 pwd->w[2] = msa_nlzc_df(DF_WORD, pws->w[2]);
198 pwd->w[3] = msa_nlzc_df(DF_WORD, pws->w[3]);
199}
200
201void helper_msa_nlzc_d(CPUMIPSState *env, uint32_t wd, uint32_t ws)
202{
203 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
204 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
205
206 pwd->d[0] = msa_nlzc_df(DF_DOUBLE, pws->d[0]);
207 pwd->d[1] = msa_nlzc_df(DF_DOUBLE, pws->d[1]);
208}
209
210static inline int64_t msa_pcnt_df(uint32_t df, int64_t arg)
211{
212 uint64_t x;
213
214 x = UNSIGNED(arg, df);
215
216 x = (x & 0x5555555555555555ULL) + ((x >> 1) & 0x5555555555555555ULL);
217 x = (x & 0x3333333333333333ULL) + ((x >> 2) & 0x3333333333333333ULL);
218 x = (x & 0x0F0F0F0F0F0F0F0FULL) + ((x >> 4) & 0x0F0F0F0F0F0F0F0FULL);
219 x = (x & 0x00FF00FF00FF00FFULL) + ((x >> 8) & 0x00FF00FF00FF00FFULL);
220 x = (x & 0x0000FFFF0000FFFFULL) + ((x >> 16) & 0x0000FFFF0000FFFFULL);
221 x = (x & 0x00000000FFFFFFFFULL) + ((x >> 32));
222
223 return x;
224}
225
226void helper_msa_pcnt_b(CPUMIPSState *env, uint32_t wd, uint32_t ws)
227{
228 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
229 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
230
231 pwd->b[0] = msa_pcnt_df(DF_BYTE, pws->b[0]);
232 pwd->b[1] = msa_pcnt_df(DF_BYTE, pws->b[1]);
233 pwd->b[2] = msa_pcnt_df(DF_BYTE, pws->b[2]);
234 pwd->b[3] = msa_pcnt_df(DF_BYTE, pws->b[3]);
235 pwd->b[4] = msa_pcnt_df(DF_BYTE, pws->b[4]);
236 pwd->b[5] = msa_pcnt_df(DF_BYTE, pws->b[5]);
237 pwd->b[6] = msa_pcnt_df(DF_BYTE, pws->b[6]);
238 pwd->b[7] = msa_pcnt_df(DF_BYTE, pws->b[7]);
239 pwd->b[8] = msa_pcnt_df(DF_BYTE, pws->b[8]);
240 pwd->b[9] = msa_pcnt_df(DF_BYTE, pws->b[9]);
241 pwd->b[10] = msa_pcnt_df(DF_BYTE, pws->b[10]);
242 pwd->b[11] = msa_pcnt_df(DF_BYTE, pws->b[11]);
243 pwd->b[12] = msa_pcnt_df(DF_BYTE, pws->b[12]);
244 pwd->b[13] = msa_pcnt_df(DF_BYTE, pws->b[13]);
245 pwd->b[14] = msa_pcnt_df(DF_BYTE, pws->b[14]);
246 pwd->b[15] = msa_pcnt_df(DF_BYTE, pws->b[15]);
247}
248
249void helper_msa_pcnt_h(CPUMIPSState *env, uint32_t wd, uint32_t ws)
250{
251 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
252 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
253
254 pwd->h[0] = msa_pcnt_df(DF_HALF, pws->h[0]);
255 pwd->h[1] = msa_pcnt_df(DF_HALF, pws->h[1]);
256 pwd->h[2] = msa_pcnt_df(DF_HALF, pws->h[2]);
257 pwd->h[3] = msa_pcnt_df(DF_HALF, pws->h[3]);
258 pwd->h[4] = msa_pcnt_df(DF_HALF, pws->h[4]);
259 pwd->h[5] = msa_pcnt_df(DF_HALF, pws->h[5]);
260 pwd->h[6] = msa_pcnt_df(DF_HALF, pws->h[6]);
261 pwd->h[7] = msa_pcnt_df(DF_HALF, pws->h[7]);
262}
263
264void helper_msa_pcnt_w(CPUMIPSState *env, uint32_t wd, uint32_t ws)
265{
266 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
267 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
268
269 pwd->w[0] = msa_pcnt_df(DF_WORD, pws->w[0]);
270 pwd->w[1] = msa_pcnt_df(DF_WORD, pws->w[1]);
271 pwd->w[2] = msa_pcnt_df(DF_WORD, pws->w[2]);
272 pwd->w[3] = msa_pcnt_df(DF_WORD, pws->w[3]);
273}
274
275void helper_msa_pcnt_d(CPUMIPSState *env, uint32_t wd, uint32_t ws)
276{
277 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
278 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
279
280 pwd->d[0] = msa_pcnt_df(DF_DOUBLE, pws->d[0]);
281 pwd->d[1] = msa_pcnt_df(DF_DOUBLE, pws->d[1]);
282}
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305#define BIT_POSITION(x, df) ((uint64_t)(x) % DF_BITS(df))
306
307static inline int64_t msa_binsl_df(uint32_t df,
308 int64_t dest, int64_t arg1, int64_t arg2)
309{
310 uint64_t u_arg1 = UNSIGNED(arg1, df);
311 uint64_t u_dest = UNSIGNED(dest, df);
312 int32_t sh_d = BIT_POSITION(arg2, df) + 1;
313 int32_t sh_a = DF_BITS(df) - sh_d;
314 if (sh_d == DF_BITS(df)) {
315 return u_arg1;
316 } else {
317 return UNSIGNED(UNSIGNED(u_dest << sh_d, df) >> sh_d, df) |
318 UNSIGNED(UNSIGNED(u_arg1 >> sh_a, df) << sh_a, df);
319 }
320}
321
322void helper_msa_binsl_b(CPUMIPSState *env,
323 uint32_t wd, uint32_t ws, uint32_t wt)
324{
325 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
326 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
327 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
328
329 pwd->b[0] = msa_binsl_df(DF_BYTE, pwd->b[0], pws->b[0], pwt->b[0]);
330 pwd->b[1] = msa_binsl_df(DF_BYTE, pwd->b[1], pws->b[1], pwt->b[1]);
331 pwd->b[2] = msa_binsl_df(DF_BYTE, pwd->b[2], pws->b[2], pwt->b[2]);
332 pwd->b[3] = msa_binsl_df(DF_BYTE, pwd->b[3], pws->b[3], pwt->b[3]);
333 pwd->b[4] = msa_binsl_df(DF_BYTE, pwd->b[4], pws->b[4], pwt->b[4]);
334 pwd->b[5] = msa_binsl_df(DF_BYTE, pwd->b[5], pws->b[5], pwt->b[5]);
335 pwd->b[6] = msa_binsl_df(DF_BYTE, pwd->b[6], pws->b[6], pwt->b[6]);
336 pwd->b[7] = msa_binsl_df(DF_BYTE, pwd->b[7], pws->b[7], pwt->b[7]);
337 pwd->b[8] = msa_binsl_df(DF_BYTE, pwd->b[8], pws->b[8], pwt->b[8]);
338 pwd->b[9] = msa_binsl_df(DF_BYTE, pwd->b[9], pws->b[9], pwt->b[9]);
339 pwd->b[10] = msa_binsl_df(DF_BYTE, pwd->b[10], pws->b[10], pwt->b[10]);
340 pwd->b[11] = msa_binsl_df(DF_BYTE, pwd->b[11], pws->b[11], pwt->b[11]);
341 pwd->b[12] = msa_binsl_df(DF_BYTE, pwd->b[12], pws->b[12], pwt->b[12]);
342 pwd->b[13] = msa_binsl_df(DF_BYTE, pwd->b[13], pws->b[13], pwt->b[13]);
343 pwd->b[14] = msa_binsl_df(DF_BYTE, pwd->b[14], pws->b[14], pwt->b[14]);
344 pwd->b[15] = msa_binsl_df(DF_BYTE, pwd->b[15], pws->b[15], pwt->b[15]);
345}
346
347void helper_msa_binsl_h(CPUMIPSState *env,
348 uint32_t wd, uint32_t ws, uint32_t wt)
349{
350 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
351 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
352 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
353
354 pwd->h[0] = msa_binsl_df(DF_HALF, pwd->h[0], pws->h[0], pwt->h[0]);
355 pwd->h[1] = msa_binsl_df(DF_HALF, pwd->h[1], pws->h[1], pwt->h[1]);
356 pwd->h[2] = msa_binsl_df(DF_HALF, pwd->h[2], pws->h[2], pwt->h[2]);
357 pwd->h[3] = msa_binsl_df(DF_HALF, pwd->h[3], pws->h[3], pwt->h[3]);
358 pwd->h[4] = msa_binsl_df(DF_HALF, pwd->h[4], pws->h[4], pwt->h[4]);
359 pwd->h[5] = msa_binsl_df(DF_HALF, pwd->h[5], pws->h[5], pwt->h[5]);
360 pwd->h[6] = msa_binsl_df(DF_HALF, pwd->h[6], pws->h[6], pwt->h[6]);
361 pwd->h[7] = msa_binsl_df(DF_HALF, pwd->h[7], pws->h[7], pwt->h[7]);
362}
363
364void helper_msa_binsl_w(CPUMIPSState *env,
365 uint32_t wd, uint32_t ws, uint32_t wt)
366{
367 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
368 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
369 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
370
371 pwd->w[0] = msa_binsl_df(DF_WORD, pwd->w[0], pws->w[0], pwt->w[0]);
372 pwd->w[1] = msa_binsl_df(DF_WORD, pwd->w[1], pws->w[1], pwt->w[1]);
373 pwd->w[2] = msa_binsl_df(DF_WORD, pwd->w[2], pws->w[2], pwt->w[2]);
374 pwd->w[3] = msa_binsl_df(DF_WORD, pwd->w[3], pws->w[3], pwt->w[3]);
375}
376
377void helper_msa_binsl_d(CPUMIPSState *env,
378 uint32_t wd, uint32_t ws, uint32_t wt)
379{
380 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
381 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
382 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
383
384 pwd->d[0] = msa_binsl_df(DF_DOUBLE, pwd->d[0], pws->d[0], pwt->d[0]);
385 pwd->d[1] = msa_binsl_df(DF_DOUBLE, pwd->d[1], pws->d[1], pwt->d[1]);
386}
387
388static inline int64_t msa_binsr_df(uint32_t df,
389 int64_t dest, int64_t arg1, int64_t arg2)
390{
391 uint64_t u_arg1 = UNSIGNED(arg1, df);
392 uint64_t u_dest = UNSIGNED(dest, df);
393 int32_t sh_d = BIT_POSITION(arg2, df) + 1;
394 int32_t sh_a = DF_BITS(df) - sh_d;
395 if (sh_d == DF_BITS(df)) {
396 return u_arg1;
397 } else {
398 return UNSIGNED(UNSIGNED(u_dest >> sh_d, df) << sh_d, df) |
399 UNSIGNED(UNSIGNED(u_arg1 << sh_a, df) >> sh_a, df);
400 }
401}
402
403void helper_msa_binsr_b(CPUMIPSState *env,
404 uint32_t wd, uint32_t ws, uint32_t wt)
405{
406 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
407 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
408 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
409
410 pwd->b[0] = msa_binsr_df(DF_BYTE, pwd->b[0], pws->b[0], pwt->b[0]);
411 pwd->b[1] = msa_binsr_df(DF_BYTE, pwd->b[1], pws->b[1], pwt->b[1]);
412 pwd->b[2] = msa_binsr_df(DF_BYTE, pwd->b[2], pws->b[2], pwt->b[2]);
413 pwd->b[3] = msa_binsr_df(DF_BYTE, pwd->b[3], pws->b[3], pwt->b[3]);
414 pwd->b[4] = msa_binsr_df(DF_BYTE, pwd->b[4], pws->b[4], pwt->b[4]);
415 pwd->b[5] = msa_binsr_df(DF_BYTE, pwd->b[5], pws->b[5], pwt->b[5]);
416 pwd->b[6] = msa_binsr_df(DF_BYTE, pwd->b[6], pws->b[6], pwt->b[6]);
417 pwd->b[7] = msa_binsr_df(DF_BYTE, pwd->b[7], pws->b[7], pwt->b[7]);
418 pwd->b[8] = msa_binsr_df(DF_BYTE, pwd->b[8], pws->b[8], pwt->b[8]);
419 pwd->b[9] = msa_binsr_df(DF_BYTE, pwd->b[9], pws->b[9], pwt->b[9]);
420 pwd->b[10] = msa_binsr_df(DF_BYTE, pwd->b[10], pws->b[10], pwt->b[10]);
421 pwd->b[11] = msa_binsr_df(DF_BYTE, pwd->b[11], pws->b[11], pwt->b[11]);
422 pwd->b[12] = msa_binsr_df(DF_BYTE, pwd->b[12], pws->b[12], pwt->b[12]);
423 pwd->b[13] = msa_binsr_df(DF_BYTE, pwd->b[13], pws->b[13], pwt->b[13]);
424 pwd->b[14] = msa_binsr_df(DF_BYTE, pwd->b[14], pws->b[14], pwt->b[14]);
425 pwd->b[15] = msa_binsr_df(DF_BYTE, pwd->b[15], pws->b[15], pwt->b[15]);
426}
427
428void helper_msa_binsr_h(CPUMIPSState *env,
429 uint32_t wd, uint32_t ws, uint32_t wt)
430{
431 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
432 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
433 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
434
435 pwd->h[0] = msa_binsr_df(DF_HALF, pwd->h[0], pws->h[0], pwt->h[0]);
436 pwd->h[1] = msa_binsr_df(DF_HALF, pwd->h[1], pws->h[1], pwt->h[1]);
437 pwd->h[2] = msa_binsr_df(DF_HALF, pwd->h[2], pws->h[2], pwt->h[2]);
438 pwd->h[3] = msa_binsr_df(DF_HALF, pwd->h[3], pws->h[3], pwt->h[3]);
439 pwd->h[4] = msa_binsr_df(DF_HALF, pwd->h[4], pws->h[4], pwt->h[4]);
440 pwd->h[5] = msa_binsr_df(DF_HALF, pwd->h[5], pws->h[5], pwt->h[5]);
441 pwd->h[6] = msa_binsr_df(DF_HALF, pwd->h[6], pws->h[6], pwt->h[6]);
442 pwd->h[7] = msa_binsr_df(DF_HALF, pwd->h[7], pws->h[7], pwt->h[7]);
443}
444
445void helper_msa_binsr_w(CPUMIPSState *env,
446 uint32_t wd, uint32_t ws, uint32_t wt)
447{
448 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
449 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
450 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
451
452 pwd->w[0] = msa_binsr_df(DF_WORD, pwd->w[0], pws->w[0], pwt->w[0]);
453 pwd->w[1] = msa_binsr_df(DF_WORD, pwd->w[1], pws->w[1], pwt->w[1]);
454 pwd->w[2] = msa_binsr_df(DF_WORD, pwd->w[2], pws->w[2], pwt->w[2]);
455 pwd->w[3] = msa_binsr_df(DF_WORD, pwd->w[3], pws->w[3], pwt->w[3]);
456}
457
458void helper_msa_binsr_d(CPUMIPSState *env,
459 uint32_t wd, uint32_t ws, uint32_t wt)
460{
461 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
462 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
463 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
464
465 pwd->d[0] = msa_binsr_df(DF_DOUBLE, pwd->d[0], pws->d[0], pwt->d[0]);
466 pwd->d[1] = msa_binsr_df(DF_DOUBLE, pwd->d[1], pws->d[1], pwt->d[1]);
467}
468
469void helper_msa_bmnz_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
470{
471 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
472 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
473 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
474
475 pwd->d[0] = UNSIGNED( \
476 ((pwd->d[0] & (~pwt->d[0])) | (pws->d[0] & pwt->d[0])), DF_DOUBLE);
477 pwd->d[1] = UNSIGNED( \
478 ((pwd->d[1] & (~pwt->d[1])) | (pws->d[1] & pwt->d[1])), DF_DOUBLE);
479}
480
481void helper_msa_bmz_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
482{
483 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
484 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
485 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
486
487 pwd->d[0] = UNSIGNED( \
488 ((pwd->d[0] & pwt->d[0]) | (pws->d[0] & (~pwt->d[0]))), DF_DOUBLE);
489 pwd->d[1] = UNSIGNED( \
490 ((pwd->d[1] & pwt->d[1]) | (pws->d[1] & (~pwt->d[1]))), DF_DOUBLE);
491}
492
493void helper_msa_bsel_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
494{
495 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
496 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
497 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
498
499 pwd->d[0] = UNSIGNED( \
500 (pws->d[0] & (~pwd->d[0])) | (pwt->d[0] & pwd->d[0]), DF_DOUBLE);
501 pwd->d[1] = UNSIGNED( \
502 (pws->d[1] & (~pwd->d[1])) | (pwt->d[1] & pwd->d[1]), DF_DOUBLE);
503}
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526static inline int64_t msa_bclr_df(uint32_t df, int64_t arg1, int64_t arg2)
527{
528 int32_t b_arg2 = BIT_POSITION(arg2, df);
529 return UNSIGNED(arg1 & (~(1LL << b_arg2)), df);
530}
531
532void helper_msa_bclr_b(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
533{
534 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
535 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
536 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
537
538 pwd->b[0] = msa_bclr_df(DF_BYTE, pws->b[0], pwt->b[0]);
539 pwd->b[1] = msa_bclr_df(DF_BYTE, pws->b[1], pwt->b[1]);
540 pwd->b[2] = msa_bclr_df(DF_BYTE, pws->b[2], pwt->b[2]);
541 pwd->b[3] = msa_bclr_df(DF_BYTE, pws->b[3], pwt->b[3]);
542 pwd->b[4] = msa_bclr_df(DF_BYTE, pws->b[4], pwt->b[4]);
543 pwd->b[5] = msa_bclr_df(DF_BYTE, pws->b[5], pwt->b[5]);
544 pwd->b[6] = msa_bclr_df(DF_BYTE, pws->b[6], pwt->b[6]);
545 pwd->b[7] = msa_bclr_df(DF_BYTE, pws->b[7], pwt->b[7]);
546 pwd->b[8] = msa_bclr_df(DF_BYTE, pws->b[8], pwt->b[8]);
547 pwd->b[9] = msa_bclr_df(DF_BYTE, pws->b[9], pwt->b[9]);
548 pwd->b[10] = msa_bclr_df(DF_BYTE, pws->b[10], pwt->b[10]);
549 pwd->b[11] = msa_bclr_df(DF_BYTE, pws->b[11], pwt->b[11]);
550 pwd->b[12] = msa_bclr_df(DF_BYTE, pws->b[12], pwt->b[12]);
551 pwd->b[13] = msa_bclr_df(DF_BYTE, pws->b[13], pwt->b[13]);
552 pwd->b[14] = msa_bclr_df(DF_BYTE, pws->b[14], pwt->b[14]);
553 pwd->b[15] = msa_bclr_df(DF_BYTE, pws->b[15], pwt->b[15]);
554}
555
556void helper_msa_bclr_h(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
557{
558 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
559 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
560 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
561
562 pwd->h[0] = msa_bclr_df(DF_HALF, pws->h[0], pwt->h[0]);
563 pwd->h[1] = msa_bclr_df(DF_HALF, pws->h[1], pwt->h[1]);
564 pwd->h[2] = msa_bclr_df(DF_HALF, pws->h[2], pwt->h[2]);
565 pwd->h[3] = msa_bclr_df(DF_HALF, pws->h[3], pwt->h[3]);
566 pwd->h[4] = msa_bclr_df(DF_HALF, pws->h[4], pwt->h[4]);
567 pwd->h[5] = msa_bclr_df(DF_HALF, pws->h[5], pwt->h[5]);
568 pwd->h[6] = msa_bclr_df(DF_HALF, pws->h[6], pwt->h[6]);
569 pwd->h[7] = msa_bclr_df(DF_HALF, pws->h[7], pwt->h[7]);
570}
571
572void helper_msa_bclr_w(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
573{
574 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
575 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
576 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
577
578 pwd->w[0] = msa_bclr_df(DF_WORD, pws->w[0], pwt->w[0]);
579 pwd->w[1] = msa_bclr_df(DF_WORD, pws->w[1], pwt->w[1]);
580 pwd->w[2] = msa_bclr_df(DF_WORD, pws->w[2], pwt->w[2]);
581 pwd->w[3] = msa_bclr_df(DF_WORD, pws->w[3], pwt->w[3]);
582}
583
584void helper_msa_bclr_d(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
585{
586 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
587 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
588 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
589
590 pwd->d[0] = msa_bclr_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
591 pwd->d[1] = msa_bclr_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
592}
593
594static inline int64_t msa_bneg_df(uint32_t df, int64_t arg1, int64_t arg2)
595{
596 int32_t b_arg2 = BIT_POSITION(arg2, df);
597 return UNSIGNED(arg1 ^ (1LL << b_arg2), df);
598}
599
600void helper_msa_bneg_b(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
601{
602 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
603 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
604 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
605
606 pwd->b[0] = msa_bneg_df(DF_BYTE, pws->b[0], pwt->b[0]);
607 pwd->b[1] = msa_bneg_df(DF_BYTE, pws->b[1], pwt->b[1]);
608 pwd->b[2] = msa_bneg_df(DF_BYTE, pws->b[2], pwt->b[2]);
609 pwd->b[3] = msa_bneg_df(DF_BYTE, pws->b[3], pwt->b[3]);
610 pwd->b[4] = msa_bneg_df(DF_BYTE, pws->b[4], pwt->b[4]);
611 pwd->b[5] = msa_bneg_df(DF_BYTE, pws->b[5], pwt->b[5]);
612 pwd->b[6] = msa_bneg_df(DF_BYTE, pws->b[6], pwt->b[6]);
613 pwd->b[7] = msa_bneg_df(DF_BYTE, pws->b[7], pwt->b[7]);
614 pwd->b[8] = msa_bneg_df(DF_BYTE, pws->b[8], pwt->b[8]);
615 pwd->b[9] = msa_bneg_df(DF_BYTE, pws->b[9], pwt->b[9]);
616 pwd->b[10] = msa_bneg_df(DF_BYTE, pws->b[10], pwt->b[10]);
617 pwd->b[11] = msa_bneg_df(DF_BYTE, pws->b[11], pwt->b[11]);
618 pwd->b[12] = msa_bneg_df(DF_BYTE, pws->b[12], pwt->b[12]);
619 pwd->b[13] = msa_bneg_df(DF_BYTE, pws->b[13], pwt->b[13]);
620 pwd->b[14] = msa_bneg_df(DF_BYTE, pws->b[14], pwt->b[14]);
621 pwd->b[15] = msa_bneg_df(DF_BYTE, pws->b[15], pwt->b[15]);
622}
623
624void helper_msa_bneg_h(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
625{
626 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
627 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
628 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
629
630 pwd->h[0] = msa_bneg_df(DF_HALF, pws->h[0], pwt->h[0]);
631 pwd->h[1] = msa_bneg_df(DF_HALF, pws->h[1], pwt->h[1]);
632 pwd->h[2] = msa_bneg_df(DF_HALF, pws->h[2], pwt->h[2]);
633 pwd->h[3] = msa_bneg_df(DF_HALF, pws->h[3], pwt->h[3]);
634 pwd->h[4] = msa_bneg_df(DF_HALF, pws->h[4], pwt->h[4]);
635 pwd->h[5] = msa_bneg_df(DF_HALF, pws->h[5], pwt->h[5]);
636 pwd->h[6] = msa_bneg_df(DF_HALF, pws->h[6], pwt->h[6]);
637 pwd->h[7] = msa_bneg_df(DF_HALF, pws->h[7], pwt->h[7]);
638}
639
640void helper_msa_bneg_w(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
641{
642 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
643 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
644 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
645
646 pwd->w[0] = msa_bneg_df(DF_WORD, pws->w[0], pwt->w[0]);
647 pwd->w[1] = msa_bneg_df(DF_WORD, pws->w[1], pwt->w[1]);
648 pwd->w[2] = msa_bneg_df(DF_WORD, pws->w[2], pwt->w[2]);
649 pwd->w[3] = msa_bneg_df(DF_WORD, pws->w[3], pwt->w[3]);
650}
651
652void helper_msa_bneg_d(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
653{
654 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
655 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
656 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
657
658 pwd->d[0] = msa_bneg_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
659 pwd->d[1] = msa_bneg_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
660}
661
662static inline int64_t msa_bset_df(uint32_t df, int64_t arg1,
663 int64_t arg2)
664{
665 int32_t b_arg2 = BIT_POSITION(arg2, df);
666 return UNSIGNED(arg1 | (1LL << b_arg2), df);
667}
668
669void helper_msa_bset_b(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
670{
671 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
672 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
673 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
674
675 pwd->b[0] = msa_bset_df(DF_BYTE, pws->b[0], pwt->b[0]);
676 pwd->b[1] = msa_bset_df(DF_BYTE, pws->b[1], pwt->b[1]);
677 pwd->b[2] = msa_bset_df(DF_BYTE, pws->b[2], pwt->b[2]);
678 pwd->b[3] = msa_bset_df(DF_BYTE, pws->b[3], pwt->b[3]);
679 pwd->b[4] = msa_bset_df(DF_BYTE, pws->b[4], pwt->b[4]);
680 pwd->b[5] = msa_bset_df(DF_BYTE, pws->b[5], pwt->b[5]);
681 pwd->b[6] = msa_bset_df(DF_BYTE, pws->b[6], pwt->b[6]);
682 pwd->b[7] = msa_bset_df(DF_BYTE, pws->b[7], pwt->b[7]);
683 pwd->b[8] = msa_bset_df(DF_BYTE, pws->b[8], pwt->b[8]);
684 pwd->b[9] = msa_bset_df(DF_BYTE, pws->b[9], pwt->b[9]);
685 pwd->b[10] = msa_bset_df(DF_BYTE, pws->b[10], pwt->b[10]);
686 pwd->b[11] = msa_bset_df(DF_BYTE, pws->b[11], pwt->b[11]);
687 pwd->b[12] = msa_bset_df(DF_BYTE, pws->b[12], pwt->b[12]);
688 pwd->b[13] = msa_bset_df(DF_BYTE, pws->b[13], pwt->b[13]);
689 pwd->b[14] = msa_bset_df(DF_BYTE, pws->b[14], pwt->b[14]);
690 pwd->b[15] = msa_bset_df(DF_BYTE, pws->b[15], pwt->b[15]);
691}
692
693void helper_msa_bset_h(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
694{
695 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
696 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
697 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
698
699 pwd->h[0] = msa_bset_df(DF_HALF, pws->h[0], pwt->h[0]);
700 pwd->h[1] = msa_bset_df(DF_HALF, pws->h[1], pwt->h[1]);
701 pwd->h[2] = msa_bset_df(DF_HALF, pws->h[2], pwt->h[2]);
702 pwd->h[3] = msa_bset_df(DF_HALF, pws->h[3], pwt->h[3]);
703 pwd->h[4] = msa_bset_df(DF_HALF, pws->h[4], pwt->h[4]);
704 pwd->h[5] = msa_bset_df(DF_HALF, pws->h[5], pwt->h[5]);
705 pwd->h[6] = msa_bset_df(DF_HALF, pws->h[6], pwt->h[6]);
706 pwd->h[7] = msa_bset_df(DF_HALF, pws->h[7], pwt->h[7]);
707}
708
709void helper_msa_bset_w(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
710{
711 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
712 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
713 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
714
715 pwd->w[0] = msa_bset_df(DF_WORD, pws->w[0], pwt->w[0]);
716 pwd->w[1] = msa_bset_df(DF_WORD, pws->w[1], pwt->w[1]);
717 pwd->w[2] = msa_bset_df(DF_WORD, pws->w[2], pwt->w[2]);
718 pwd->w[3] = msa_bset_df(DF_WORD, pws->w[3], pwt->w[3]);
719}
720
721void helper_msa_bset_d(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
722{
723 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
724 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
725 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
726
727 pwd->d[0] = msa_bset_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
728 pwd->d[1] = msa_bset_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
729}
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809static inline int64_t msa_add_a_df(uint32_t df, int64_t arg1, int64_t arg2)
810{
811 uint64_t abs_arg1 = arg1 >= 0 ? arg1 : -arg1;
812 uint64_t abs_arg2 = arg2 >= 0 ? arg2 : -arg2;
813 return abs_arg1 + abs_arg2;
814}
815
816void helper_msa_add_a_b(CPUMIPSState *env,
817 uint32_t wd, uint32_t ws, uint32_t wt)
818{
819 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
820 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
821 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
822
823 pwd->b[0] = msa_add_a_df(DF_BYTE, pws->b[0], pwt->b[0]);
824 pwd->b[1] = msa_add_a_df(DF_BYTE, pws->b[1], pwt->b[1]);
825 pwd->b[2] = msa_add_a_df(DF_BYTE, pws->b[2], pwt->b[2]);
826 pwd->b[3] = msa_add_a_df(DF_BYTE, pws->b[3], pwt->b[3]);
827 pwd->b[4] = msa_add_a_df(DF_BYTE, pws->b[4], pwt->b[4]);
828 pwd->b[5] = msa_add_a_df(DF_BYTE, pws->b[5], pwt->b[5]);
829 pwd->b[6] = msa_add_a_df(DF_BYTE, pws->b[6], pwt->b[6]);
830 pwd->b[7] = msa_add_a_df(DF_BYTE, pws->b[7], pwt->b[7]);
831 pwd->b[8] = msa_add_a_df(DF_BYTE, pws->b[8], pwt->b[8]);
832 pwd->b[9] = msa_add_a_df(DF_BYTE, pws->b[9], pwt->b[9]);
833 pwd->b[10] = msa_add_a_df(DF_BYTE, pws->b[10], pwt->b[10]);
834 pwd->b[11] = msa_add_a_df(DF_BYTE, pws->b[11], pwt->b[11]);
835 pwd->b[12] = msa_add_a_df(DF_BYTE, pws->b[12], pwt->b[12]);
836 pwd->b[13] = msa_add_a_df(DF_BYTE, pws->b[13], pwt->b[13]);
837 pwd->b[14] = msa_add_a_df(DF_BYTE, pws->b[14], pwt->b[14]);
838 pwd->b[15] = msa_add_a_df(DF_BYTE, pws->b[15], pwt->b[15]);
839}
840
841void helper_msa_add_a_h(CPUMIPSState *env,
842 uint32_t wd, uint32_t ws, uint32_t wt)
843{
844 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
845 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
846 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
847
848 pwd->h[0] = msa_add_a_df(DF_HALF, pws->h[0], pwt->h[0]);
849 pwd->h[1] = msa_add_a_df(DF_HALF, pws->h[1], pwt->h[1]);
850 pwd->h[2] = msa_add_a_df(DF_HALF, pws->h[2], pwt->h[2]);
851 pwd->h[3] = msa_add_a_df(DF_HALF, pws->h[3], pwt->h[3]);
852 pwd->h[4] = msa_add_a_df(DF_HALF, pws->h[4], pwt->h[4]);
853 pwd->h[5] = msa_add_a_df(DF_HALF, pws->h[5], pwt->h[5]);
854 pwd->h[6] = msa_add_a_df(DF_HALF, pws->h[6], pwt->h[6]);
855 pwd->h[7] = msa_add_a_df(DF_HALF, pws->h[7], pwt->h[7]);
856}
857
858void helper_msa_add_a_w(CPUMIPSState *env,
859 uint32_t wd, uint32_t ws, uint32_t wt)
860{
861 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
862 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
863 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
864
865 pwd->w[0] = msa_add_a_df(DF_WORD, pws->w[0], pwt->w[0]);
866 pwd->w[1] = msa_add_a_df(DF_WORD, pws->w[1], pwt->w[1]);
867 pwd->w[2] = msa_add_a_df(DF_WORD, pws->w[2], pwt->w[2]);
868 pwd->w[3] = msa_add_a_df(DF_WORD, pws->w[3], pwt->w[3]);
869}
870
871void helper_msa_add_a_d(CPUMIPSState *env,
872 uint32_t wd, uint32_t ws, uint32_t wt)
873{
874 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
875 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
876 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
877
878 pwd->d[0] = msa_add_a_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
879 pwd->d[1] = msa_add_a_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
880}
881
882
883static inline int64_t msa_adds_a_df(uint32_t df, int64_t arg1, int64_t arg2)
884{
885 uint64_t max_int = (uint64_t)DF_MAX_INT(df);
886 uint64_t abs_arg1 = arg1 >= 0 ? arg1 : -arg1;
887 uint64_t abs_arg2 = arg2 >= 0 ? arg2 : -arg2;
888 if (abs_arg1 > max_int || abs_arg2 > max_int) {
889 return (int64_t)max_int;
890 } else {
891 return (abs_arg1 < max_int - abs_arg2) ? abs_arg1 + abs_arg2 : max_int;
892 }
893}
894
895void helper_msa_adds_a_b(CPUMIPSState *env,
896 uint32_t wd, uint32_t ws, uint32_t wt)
897{
898 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
899 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
900 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
901
902 pwd->b[0] = msa_adds_a_df(DF_BYTE, pws->b[0], pwt->b[0]);
903 pwd->b[1] = msa_adds_a_df(DF_BYTE, pws->b[1], pwt->b[1]);
904 pwd->b[2] = msa_adds_a_df(DF_BYTE, pws->b[2], pwt->b[2]);
905 pwd->b[3] = msa_adds_a_df(DF_BYTE, pws->b[3], pwt->b[3]);
906 pwd->b[4] = msa_adds_a_df(DF_BYTE, pws->b[4], pwt->b[4]);
907 pwd->b[5] = msa_adds_a_df(DF_BYTE, pws->b[5], pwt->b[5]);
908 pwd->b[6] = msa_adds_a_df(DF_BYTE, pws->b[6], pwt->b[6]);
909 pwd->b[7] = msa_adds_a_df(DF_BYTE, pws->b[7], pwt->b[7]);
910 pwd->b[8] = msa_adds_a_df(DF_BYTE, pws->b[8], pwt->b[8]);
911 pwd->b[9] = msa_adds_a_df(DF_BYTE, pws->b[9], pwt->b[9]);
912 pwd->b[10] = msa_adds_a_df(DF_BYTE, pws->b[10], pwt->b[10]);
913 pwd->b[11] = msa_adds_a_df(DF_BYTE, pws->b[11], pwt->b[11]);
914 pwd->b[12] = msa_adds_a_df(DF_BYTE, pws->b[12], pwt->b[12]);
915 pwd->b[13] = msa_adds_a_df(DF_BYTE, pws->b[13], pwt->b[13]);
916 pwd->b[14] = msa_adds_a_df(DF_BYTE, pws->b[14], pwt->b[14]);
917 pwd->b[15] = msa_adds_a_df(DF_BYTE, pws->b[15], pwt->b[15]);
918}
919
920void helper_msa_adds_a_h(CPUMIPSState *env,
921 uint32_t wd, uint32_t ws, uint32_t wt)
922{
923 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
924 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
925 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
926
927 pwd->h[0] = msa_adds_a_df(DF_HALF, pws->h[0], pwt->h[0]);
928 pwd->h[1] = msa_adds_a_df(DF_HALF, pws->h[1], pwt->h[1]);
929 pwd->h[2] = msa_adds_a_df(DF_HALF, pws->h[2], pwt->h[2]);
930 pwd->h[3] = msa_adds_a_df(DF_HALF, pws->h[3], pwt->h[3]);
931 pwd->h[4] = msa_adds_a_df(DF_HALF, pws->h[4], pwt->h[4]);
932 pwd->h[5] = msa_adds_a_df(DF_HALF, pws->h[5], pwt->h[5]);
933 pwd->h[6] = msa_adds_a_df(DF_HALF, pws->h[6], pwt->h[6]);
934 pwd->h[7] = msa_adds_a_df(DF_HALF, pws->h[7], pwt->h[7]);
935}
936
937void helper_msa_adds_a_w(CPUMIPSState *env,
938 uint32_t wd, uint32_t ws, uint32_t wt)
939{
940 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
941 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
942 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
943
944 pwd->w[0] = msa_adds_a_df(DF_WORD, pws->w[0], pwt->w[0]);
945 pwd->w[1] = msa_adds_a_df(DF_WORD, pws->w[1], pwt->w[1]);
946 pwd->w[2] = msa_adds_a_df(DF_WORD, pws->w[2], pwt->w[2]);
947 pwd->w[3] = msa_adds_a_df(DF_WORD, pws->w[3], pwt->w[3]);
948}
949
950void helper_msa_adds_a_d(CPUMIPSState *env,
951 uint32_t wd, uint32_t ws, uint32_t wt)
952{
953 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
954 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
955 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
956
957 pwd->d[0] = msa_adds_a_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
958 pwd->d[1] = msa_adds_a_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
959}
960
961
962static inline int64_t msa_adds_s_df(uint32_t df, int64_t arg1, int64_t arg2)
963{
964 int64_t max_int = DF_MAX_INT(df);
965 int64_t min_int = DF_MIN_INT(df);
966 if (arg1 < 0) {
967 return (min_int - arg1 < arg2) ? arg1 + arg2 : min_int;
968 } else {
969 return (arg2 < max_int - arg1) ? arg1 + arg2 : max_int;
970 }
971}
972
973void helper_msa_adds_s_b(CPUMIPSState *env,
974 uint32_t wd, uint32_t ws, uint32_t wt)
975{
976 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
977 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
978 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
979
980 pwd->b[0] = msa_adds_s_df(DF_BYTE, pws->b[0], pwt->b[0]);
981 pwd->b[1] = msa_adds_s_df(DF_BYTE, pws->b[1], pwt->b[1]);
982 pwd->b[2] = msa_adds_s_df(DF_BYTE, pws->b[2], pwt->b[2]);
983 pwd->b[3] = msa_adds_s_df(DF_BYTE, pws->b[3], pwt->b[3]);
984 pwd->b[4] = msa_adds_s_df(DF_BYTE, pws->b[4], pwt->b[4]);
985 pwd->b[5] = msa_adds_s_df(DF_BYTE, pws->b[5], pwt->b[5]);
986 pwd->b[6] = msa_adds_s_df(DF_BYTE, pws->b[6], pwt->b[6]);
987 pwd->b[7] = msa_adds_s_df(DF_BYTE, pws->b[7], pwt->b[7]);
988 pwd->b[8] = msa_adds_s_df(DF_BYTE, pws->b[8], pwt->b[8]);
989 pwd->b[9] = msa_adds_s_df(DF_BYTE, pws->b[9], pwt->b[9]);
990 pwd->b[10] = msa_adds_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
991 pwd->b[11] = msa_adds_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
992 pwd->b[12] = msa_adds_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
993 pwd->b[13] = msa_adds_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
994 pwd->b[14] = msa_adds_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
995 pwd->b[15] = msa_adds_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
996}
997
998void helper_msa_adds_s_h(CPUMIPSState *env,
999 uint32_t wd, uint32_t ws, uint32_t wt)
1000{
1001 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1002 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1003 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1004
1005 pwd->h[0] = msa_adds_s_df(DF_HALF, pws->h[0], pwt->h[0]);
1006 pwd->h[1] = msa_adds_s_df(DF_HALF, pws->h[1], pwt->h[1]);
1007 pwd->h[2] = msa_adds_s_df(DF_HALF, pws->h[2], pwt->h[2]);
1008 pwd->h[3] = msa_adds_s_df(DF_HALF, pws->h[3], pwt->h[3]);
1009 pwd->h[4] = msa_adds_s_df(DF_HALF, pws->h[4], pwt->h[4]);
1010 pwd->h[5] = msa_adds_s_df(DF_HALF, pws->h[5], pwt->h[5]);
1011 pwd->h[6] = msa_adds_s_df(DF_HALF, pws->h[6], pwt->h[6]);
1012 pwd->h[7] = msa_adds_s_df(DF_HALF, pws->h[7], pwt->h[7]);
1013}
1014
1015void helper_msa_adds_s_w(CPUMIPSState *env,
1016 uint32_t wd, uint32_t ws, uint32_t wt)
1017{
1018 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1019 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1020 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1021
1022 pwd->w[0] = msa_adds_s_df(DF_WORD, pws->w[0], pwt->w[0]);
1023 pwd->w[1] = msa_adds_s_df(DF_WORD, pws->w[1], pwt->w[1]);
1024 pwd->w[2] = msa_adds_s_df(DF_WORD, pws->w[2], pwt->w[2]);
1025 pwd->w[3] = msa_adds_s_df(DF_WORD, pws->w[3], pwt->w[3]);
1026}
1027
1028void helper_msa_adds_s_d(CPUMIPSState *env,
1029 uint32_t wd, uint32_t ws, uint32_t wt)
1030{
1031 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1032 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1033 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1034
1035 pwd->d[0] = msa_adds_s_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
1036 pwd->d[1] = msa_adds_s_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
1037}
1038
1039
1040static inline uint64_t msa_adds_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
1041{
1042 uint64_t max_uint = DF_MAX_UINT(df);
1043 uint64_t u_arg1 = UNSIGNED(arg1, df);
1044 uint64_t u_arg2 = UNSIGNED(arg2, df);
1045 return (u_arg1 < max_uint - u_arg2) ? u_arg1 + u_arg2 : max_uint;
1046}
1047
1048void helper_msa_adds_u_b(CPUMIPSState *env,
1049 uint32_t wd, uint32_t ws, uint32_t wt)
1050{
1051 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1052 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1053 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1054
1055 pwd->b[0] = msa_adds_u_df(DF_BYTE, pws->b[0], pwt->b[0]);
1056 pwd->b[1] = msa_adds_u_df(DF_BYTE, pws->b[1], pwt->b[1]);
1057 pwd->b[2] = msa_adds_u_df(DF_BYTE, pws->b[2], pwt->b[2]);
1058 pwd->b[3] = msa_adds_u_df(DF_BYTE, pws->b[3], pwt->b[3]);
1059 pwd->b[4] = msa_adds_u_df(DF_BYTE, pws->b[4], pwt->b[4]);
1060 pwd->b[5] = msa_adds_u_df(DF_BYTE, pws->b[5], pwt->b[5]);
1061 pwd->b[6] = msa_adds_u_df(DF_BYTE, pws->b[6], pwt->b[6]);
1062 pwd->b[7] = msa_adds_u_df(DF_BYTE, pws->b[7], pwt->b[7]);
1063 pwd->b[8] = msa_adds_u_df(DF_BYTE, pws->b[8], pwt->b[8]);
1064 pwd->b[9] = msa_adds_u_df(DF_BYTE, pws->b[9], pwt->b[9]);
1065 pwd->b[10] = msa_adds_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
1066 pwd->b[11] = msa_adds_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
1067 pwd->b[12] = msa_adds_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
1068 pwd->b[13] = msa_adds_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
1069 pwd->b[14] = msa_adds_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
1070 pwd->b[15] = msa_adds_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
1071}
1072
1073void helper_msa_adds_u_h(CPUMIPSState *env,
1074 uint32_t wd, uint32_t ws, uint32_t wt)
1075{
1076 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1077 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1078 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1079
1080 pwd->h[0] = msa_adds_u_df(DF_HALF, pws->h[0], pwt->h[0]);
1081 pwd->h[1] = msa_adds_u_df(DF_HALF, pws->h[1], pwt->h[1]);
1082 pwd->h[2] = msa_adds_u_df(DF_HALF, pws->h[2], pwt->h[2]);
1083 pwd->h[3] = msa_adds_u_df(DF_HALF, pws->h[3], pwt->h[3]);
1084 pwd->h[4] = msa_adds_u_df(DF_HALF, pws->h[4], pwt->h[4]);
1085 pwd->h[5] = msa_adds_u_df(DF_HALF, pws->h[5], pwt->h[5]);
1086 pwd->h[6] = msa_adds_u_df(DF_HALF, pws->h[6], pwt->h[6]);
1087 pwd->h[7] = msa_adds_u_df(DF_HALF, pws->h[7], pwt->h[7]);
1088}
1089
1090void helper_msa_adds_u_w(CPUMIPSState *env,
1091 uint32_t wd, uint32_t ws, uint32_t wt)
1092{
1093 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1094 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1095 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1096
1097 pwd->w[0] = msa_adds_u_df(DF_WORD, pws->w[0], pwt->w[0]);
1098 pwd->w[1] = msa_adds_u_df(DF_WORD, pws->w[1], pwt->w[1]);
1099 pwd->w[2] = msa_adds_u_df(DF_WORD, pws->w[2], pwt->w[2]);
1100 pwd->w[3] = msa_adds_u_df(DF_WORD, pws->w[3], pwt->w[3]);
1101}
1102
1103void helper_msa_adds_u_d(CPUMIPSState *env,
1104 uint32_t wd, uint32_t ws, uint32_t wt)
1105{
1106 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1107 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1108 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1109
1110 pwd->d[0] = msa_adds_u_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
1111 pwd->d[1] = msa_adds_u_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
1112}
1113
1114
1115static inline int64_t msa_addv_df(uint32_t df, int64_t arg1, int64_t arg2)
1116{
1117 return arg1 + arg2;
1118}
1119
1120void helper_msa_addv_b(CPUMIPSState *env,
1121 uint32_t wd, uint32_t ws, uint32_t wt)
1122{
1123 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1124 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1125 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1126
1127 pwd->b[0] = msa_addv_df(DF_BYTE, pws->b[0], pwt->b[0]);
1128 pwd->b[1] = msa_addv_df(DF_BYTE, pws->b[1], pwt->b[1]);
1129 pwd->b[2] = msa_addv_df(DF_BYTE, pws->b[2], pwt->b[2]);
1130 pwd->b[3] = msa_addv_df(DF_BYTE, pws->b[3], pwt->b[3]);
1131 pwd->b[4] = msa_addv_df(DF_BYTE, pws->b[4], pwt->b[4]);
1132 pwd->b[5] = msa_addv_df(DF_BYTE, pws->b[5], pwt->b[5]);
1133 pwd->b[6] = msa_addv_df(DF_BYTE, pws->b[6], pwt->b[6]);
1134 pwd->b[7] = msa_addv_df(DF_BYTE, pws->b[7], pwt->b[7]);
1135 pwd->b[8] = msa_addv_df(DF_BYTE, pws->b[8], pwt->b[8]);
1136 pwd->b[9] = msa_addv_df(DF_BYTE, pws->b[9], pwt->b[9]);
1137 pwd->b[10] = msa_addv_df(DF_BYTE, pws->b[10], pwt->b[10]);
1138 pwd->b[11] = msa_addv_df(DF_BYTE, pws->b[11], pwt->b[11]);
1139 pwd->b[12] = msa_addv_df(DF_BYTE, pws->b[12], pwt->b[12]);
1140 pwd->b[13] = msa_addv_df(DF_BYTE, pws->b[13], pwt->b[13]);
1141 pwd->b[14] = msa_addv_df(DF_BYTE, pws->b[14], pwt->b[14]);
1142 pwd->b[15] = msa_addv_df(DF_BYTE, pws->b[15], pwt->b[15]);
1143}
1144
1145void helper_msa_addv_h(CPUMIPSState *env,
1146 uint32_t wd, uint32_t ws, uint32_t wt)
1147{
1148 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1149 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1150 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1151
1152 pwd->h[0] = msa_addv_df(DF_HALF, pws->h[0], pwt->h[0]);
1153 pwd->h[1] = msa_addv_df(DF_HALF, pws->h[1], pwt->h[1]);
1154 pwd->h[2] = msa_addv_df(DF_HALF, pws->h[2], pwt->h[2]);
1155 pwd->h[3] = msa_addv_df(DF_HALF, pws->h[3], pwt->h[3]);
1156 pwd->h[4] = msa_addv_df(DF_HALF, pws->h[4], pwt->h[4]);
1157 pwd->h[5] = msa_addv_df(DF_HALF, pws->h[5], pwt->h[5]);
1158 pwd->h[6] = msa_addv_df(DF_HALF, pws->h[6], pwt->h[6]);
1159 pwd->h[7] = msa_addv_df(DF_HALF, pws->h[7], pwt->h[7]);
1160}
1161
1162void helper_msa_addv_w(CPUMIPSState *env,
1163 uint32_t wd, uint32_t ws, uint32_t wt)
1164{
1165 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1166 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1167 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1168
1169 pwd->w[0] = msa_addv_df(DF_WORD, pws->w[0], pwt->w[0]);
1170 pwd->w[1] = msa_addv_df(DF_WORD, pws->w[1], pwt->w[1]);
1171 pwd->w[2] = msa_addv_df(DF_WORD, pws->w[2], pwt->w[2]);
1172 pwd->w[3] = msa_addv_df(DF_WORD, pws->w[3], pwt->w[3]);
1173}
1174
1175void helper_msa_addv_d(CPUMIPSState *env,
1176 uint32_t wd, uint32_t ws, uint32_t wt)
1177{
1178 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1179 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1180 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1181
1182 pwd->d[0] = msa_addv_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
1183 pwd->d[1] = msa_addv_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
1184}
1185
1186
1187#define SIGNED_EVEN(a, df) \
1188 ((((int64_t)(a)) << (64 - DF_BITS(df) / 2)) >> (64 - DF_BITS(df) / 2))
1189
1190#define UNSIGNED_EVEN(a, df) \
1191 ((((uint64_t)(a)) << (64 - DF_BITS(df) / 2)) >> (64 - DF_BITS(df) / 2))
1192
1193#define SIGNED_ODD(a, df) \
1194 ((((int64_t)(a)) << (64 - DF_BITS(df))) >> (64 - DF_BITS(df) / 2))
1195
1196#define UNSIGNED_ODD(a, df) \
1197 ((((uint64_t)(a)) << (64 - DF_BITS(df))) >> (64 - DF_BITS(df) / 2))
1198
1199
1200static inline int64_t msa_hadd_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1201{
1202 return SIGNED_ODD(arg1, df) + SIGNED_EVEN(arg2, df);
1203}
1204
1205void helper_msa_hadd_s_h(CPUMIPSState *env,
1206 uint32_t wd, uint32_t ws, uint32_t wt)
1207{
1208 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1209 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1210 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1211
1212 pwd->h[0] = msa_hadd_s_df(DF_HALF, pws->h[0], pwt->h[0]);
1213 pwd->h[1] = msa_hadd_s_df(DF_HALF, pws->h[1], pwt->h[1]);
1214 pwd->h[2] = msa_hadd_s_df(DF_HALF, pws->h[2], pwt->h[2]);
1215 pwd->h[3] = msa_hadd_s_df(DF_HALF, pws->h[3], pwt->h[3]);
1216 pwd->h[4] = msa_hadd_s_df(DF_HALF, pws->h[4], pwt->h[4]);
1217 pwd->h[5] = msa_hadd_s_df(DF_HALF, pws->h[5], pwt->h[5]);
1218 pwd->h[6] = msa_hadd_s_df(DF_HALF, pws->h[6], pwt->h[6]);
1219 pwd->h[7] = msa_hadd_s_df(DF_HALF, pws->h[7], pwt->h[7]);
1220}
1221
1222void helper_msa_hadd_s_w(CPUMIPSState *env,
1223 uint32_t wd, uint32_t ws, uint32_t wt)
1224{
1225 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1226 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1227 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1228
1229 pwd->w[0] = msa_hadd_s_df(DF_WORD, pws->w[0], pwt->w[0]);
1230 pwd->w[1] = msa_hadd_s_df(DF_WORD, pws->w[1], pwt->w[1]);
1231 pwd->w[2] = msa_hadd_s_df(DF_WORD, pws->w[2], pwt->w[2]);
1232 pwd->w[3] = msa_hadd_s_df(DF_WORD, pws->w[3], pwt->w[3]);
1233}
1234
1235void helper_msa_hadd_s_d(CPUMIPSState *env,
1236 uint32_t wd, uint32_t ws, uint32_t wt)
1237{
1238 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1239 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1240 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1241
1242 pwd->d[0] = msa_hadd_s_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
1243 pwd->d[1] = msa_hadd_s_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
1244}
1245
1246
1247static inline int64_t msa_hadd_u_df(uint32_t df, int64_t arg1, int64_t arg2)
1248{
1249 return UNSIGNED_ODD(arg1, df) + UNSIGNED_EVEN(arg2, df);
1250}
1251
1252void helper_msa_hadd_u_h(CPUMIPSState *env,
1253 uint32_t wd, uint32_t ws, uint32_t wt)
1254{
1255 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1256 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1257 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1258
1259 pwd->h[0] = msa_hadd_u_df(DF_HALF, pws->h[0], pwt->h[0]);
1260 pwd->h[1] = msa_hadd_u_df(DF_HALF, pws->h[1], pwt->h[1]);
1261 pwd->h[2] = msa_hadd_u_df(DF_HALF, pws->h[2], pwt->h[2]);
1262 pwd->h[3] = msa_hadd_u_df(DF_HALF, pws->h[3], pwt->h[3]);
1263 pwd->h[4] = msa_hadd_u_df(DF_HALF, pws->h[4], pwt->h[4]);
1264 pwd->h[5] = msa_hadd_u_df(DF_HALF, pws->h[5], pwt->h[5]);
1265 pwd->h[6] = msa_hadd_u_df(DF_HALF, pws->h[6], pwt->h[6]);
1266 pwd->h[7] = msa_hadd_u_df(DF_HALF, pws->h[7], pwt->h[7]);
1267}
1268
1269void helper_msa_hadd_u_w(CPUMIPSState *env,
1270 uint32_t wd, uint32_t ws, uint32_t wt)
1271{
1272 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1273 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1274 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1275
1276 pwd->w[0] = msa_hadd_u_df(DF_WORD, pws->w[0], pwt->w[0]);
1277 pwd->w[1] = msa_hadd_u_df(DF_WORD, pws->w[1], pwt->w[1]);
1278 pwd->w[2] = msa_hadd_u_df(DF_WORD, pws->w[2], pwt->w[2]);
1279 pwd->w[3] = msa_hadd_u_df(DF_WORD, pws->w[3], pwt->w[3]);
1280}
1281
1282void helper_msa_hadd_u_d(CPUMIPSState *env,
1283 uint32_t wd, uint32_t ws, uint32_t wt)
1284{
1285 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1286 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1287 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1288
1289 pwd->d[0] = msa_hadd_u_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
1290 pwd->d[1] = msa_hadd_u_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
1291}
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318static inline int64_t msa_ave_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1319{
1320
1321 return (arg1 >> 1) + (arg2 >> 1) + (arg1 & arg2 & 1);
1322}
1323
1324void helper_msa_ave_s_b(CPUMIPSState *env,
1325 uint32_t wd, uint32_t ws, uint32_t wt)
1326{
1327 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1328 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1329 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1330
1331 pwd->b[0] = msa_ave_s_df(DF_BYTE, pws->b[0], pwt->b[0]);
1332 pwd->b[1] = msa_ave_s_df(DF_BYTE, pws->b[1], pwt->b[1]);
1333 pwd->b[2] = msa_ave_s_df(DF_BYTE, pws->b[2], pwt->b[2]);
1334 pwd->b[3] = msa_ave_s_df(DF_BYTE, pws->b[3], pwt->b[3]);
1335 pwd->b[4] = msa_ave_s_df(DF_BYTE, pws->b[4], pwt->b[4]);
1336 pwd->b[5] = msa_ave_s_df(DF_BYTE, pws->b[5], pwt->b[5]);
1337 pwd->b[6] = msa_ave_s_df(DF_BYTE, pws->b[6], pwt->b[6]);
1338 pwd->b[7] = msa_ave_s_df(DF_BYTE, pws->b[7], pwt->b[7]);
1339 pwd->b[8] = msa_ave_s_df(DF_BYTE, pws->b[8], pwt->b[8]);
1340 pwd->b[9] = msa_ave_s_df(DF_BYTE, pws->b[9], pwt->b[9]);
1341 pwd->b[10] = msa_ave_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
1342 pwd->b[11] = msa_ave_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
1343 pwd->b[12] = msa_ave_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
1344 pwd->b[13] = msa_ave_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
1345 pwd->b[14] = msa_ave_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
1346 pwd->b[15] = msa_ave_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
1347}
1348
1349void helper_msa_ave_s_h(CPUMIPSState *env,
1350 uint32_t wd, uint32_t ws, uint32_t wt)
1351{
1352 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1353 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1354 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1355
1356 pwd->h[0] = msa_ave_s_df(DF_HALF, pws->h[0], pwt->h[0]);
1357 pwd->h[1] = msa_ave_s_df(DF_HALF, pws->h[1], pwt->h[1]);
1358 pwd->h[2] = msa_ave_s_df(DF_HALF, pws->h[2], pwt->h[2]);
1359 pwd->h[3] = msa_ave_s_df(DF_HALF, pws->h[3], pwt->h[3]);
1360 pwd->h[4] = msa_ave_s_df(DF_HALF, pws->h[4], pwt->h[4]);
1361 pwd->h[5] = msa_ave_s_df(DF_HALF, pws->h[5], pwt->h[5]);
1362 pwd->h[6] = msa_ave_s_df(DF_HALF, pws->h[6], pwt->h[6]);
1363 pwd->h[7] = msa_ave_s_df(DF_HALF, pws->h[7], pwt->h[7]);
1364}
1365
1366void helper_msa_ave_s_w(CPUMIPSState *env,
1367 uint32_t wd, uint32_t ws, uint32_t wt)
1368{
1369 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1370 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1371 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1372
1373 pwd->w[0] = msa_ave_s_df(DF_WORD, pws->w[0], pwt->w[0]);
1374 pwd->w[1] = msa_ave_s_df(DF_WORD, pws->w[1], pwt->w[1]);
1375 pwd->w[2] = msa_ave_s_df(DF_WORD, pws->w[2], pwt->w[2]);
1376 pwd->w[3] = msa_ave_s_df(DF_WORD, pws->w[3], pwt->w[3]);
1377}
1378
1379void helper_msa_ave_s_d(CPUMIPSState *env,
1380 uint32_t wd, uint32_t ws, uint32_t wt)
1381{
1382 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1383 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1384 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1385
1386 pwd->d[0] = msa_ave_s_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
1387 pwd->d[1] = msa_ave_s_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
1388}
1389
1390static inline uint64_t msa_ave_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
1391{
1392 uint64_t u_arg1 = UNSIGNED(arg1, df);
1393 uint64_t u_arg2 = UNSIGNED(arg2, df);
1394
1395 return (u_arg1 >> 1) + (u_arg2 >> 1) + (u_arg1 & u_arg2 & 1);
1396}
1397
1398void helper_msa_ave_u_b(CPUMIPSState *env,
1399 uint32_t wd, uint32_t ws, uint32_t wt)
1400{
1401 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1402 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1403 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1404
1405 pwd->b[0] = msa_ave_u_df(DF_BYTE, pws->b[0], pwt->b[0]);
1406 pwd->b[1] = msa_ave_u_df(DF_BYTE, pws->b[1], pwt->b[1]);
1407 pwd->b[2] = msa_ave_u_df(DF_BYTE, pws->b[2], pwt->b[2]);
1408 pwd->b[3] = msa_ave_u_df(DF_BYTE, pws->b[3], pwt->b[3]);
1409 pwd->b[4] = msa_ave_u_df(DF_BYTE, pws->b[4], pwt->b[4]);
1410 pwd->b[5] = msa_ave_u_df(DF_BYTE, pws->b[5], pwt->b[5]);
1411 pwd->b[6] = msa_ave_u_df(DF_BYTE, pws->b[6], pwt->b[6]);
1412 pwd->b[7] = msa_ave_u_df(DF_BYTE, pws->b[7], pwt->b[7]);
1413 pwd->b[8] = msa_ave_u_df(DF_BYTE, pws->b[8], pwt->b[8]);
1414 pwd->b[9] = msa_ave_u_df(DF_BYTE, pws->b[9], pwt->b[9]);
1415 pwd->b[10] = msa_ave_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
1416 pwd->b[11] = msa_ave_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
1417 pwd->b[12] = msa_ave_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
1418 pwd->b[13] = msa_ave_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
1419 pwd->b[14] = msa_ave_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
1420 pwd->b[15] = msa_ave_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
1421}
1422
1423void helper_msa_ave_u_h(CPUMIPSState *env,
1424 uint32_t wd, uint32_t ws, uint32_t wt)
1425{
1426 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1427 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1428 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1429
1430 pwd->h[0] = msa_ave_u_df(DF_HALF, pws->h[0], pwt->h[0]);
1431 pwd->h[1] = msa_ave_u_df(DF_HALF, pws->h[1], pwt->h[1]);
1432 pwd->h[2] = msa_ave_u_df(DF_HALF, pws->h[2], pwt->h[2]);
1433 pwd->h[3] = msa_ave_u_df(DF_HALF, pws->h[3], pwt->h[3]);
1434 pwd->h[4] = msa_ave_u_df(DF_HALF, pws->h[4], pwt->h[4]);
1435 pwd->h[5] = msa_ave_u_df(DF_HALF, pws->h[5], pwt->h[5]);
1436 pwd->h[6] = msa_ave_u_df(DF_HALF, pws->h[6], pwt->h[6]);
1437 pwd->h[7] = msa_ave_u_df(DF_HALF, pws->h[7], pwt->h[7]);
1438}
1439
1440void helper_msa_ave_u_w(CPUMIPSState *env,
1441 uint32_t wd, uint32_t ws, uint32_t wt)
1442{
1443 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1444 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1445 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1446
1447 pwd->w[0] = msa_ave_u_df(DF_WORD, pws->w[0], pwt->w[0]);
1448 pwd->w[1] = msa_ave_u_df(DF_WORD, pws->w[1], pwt->w[1]);
1449 pwd->w[2] = msa_ave_u_df(DF_WORD, pws->w[2], pwt->w[2]);
1450 pwd->w[3] = msa_ave_u_df(DF_WORD, pws->w[3], pwt->w[3]);
1451}
1452
1453void helper_msa_ave_u_d(CPUMIPSState *env,
1454 uint32_t wd, uint32_t ws, uint32_t wt)
1455{
1456 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1457 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1458 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1459
1460 pwd->d[0] = msa_ave_u_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
1461 pwd->d[1] = msa_ave_u_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
1462}
1463
1464static inline int64_t msa_aver_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1465{
1466
1467 return (arg1 >> 1) + (arg2 >> 1) + ((arg1 | arg2) & 1);
1468}
1469
1470void helper_msa_aver_s_b(CPUMIPSState *env,
1471 uint32_t wd, uint32_t ws, uint32_t wt)
1472{
1473 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1474 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1475 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1476
1477 pwd->b[0] = msa_aver_s_df(DF_BYTE, pws->b[0], pwt->b[0]);
1478 pwd->b[1] = msa_aver_s_df(DF_BYTE, pws->b[1], pwt->b[1]);
1479 pwd->b[2] = msa_aver_s_df(DF_BYTE, pws->b[2], pwt->b[2]);
1480 pwd->b[3] = msa_aver_s_df(DF_BYTE, pws->b[3], pwt->b[3]);
1481 pwd->b[4] = msa_aver_s_df(DF_BYTE, pws->b[4], pwt->b[4]);
1482 pwd->b[5] = msa_aver_s_df(DF_BYTE, pws->b[5], pwt->b[5]);
1483 pwd->b[6] = msa_aver_s_df(DF_BYTE, pws->b[6], pwt->b[6]);
1484 pwd->b[7] = msa_aver_s_df(DF_BYTE, pws->b[7], pwt->b[7]);
1485 pwd->b[8] = msa_aver_s_df(DF_BYTE, pws->b[8], pwt->b[8]);
1486 pwd->b[9] = msa_aver_s_df(DF_BYTE, pws->b[9], pwt->b[9]);
1487 pwd->b[10] = msa_aver_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
1488 pwd->b[11] = msa_aver_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
1489 pwd->b[12] = msa_aver_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
1490 pwd->b[13] = msa_aver_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
1491 pwd->b[14] = msa_aver_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
1492 pwd->b[15] = msa_aver_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
1493}
1494
1495void helper_msa_aver_s_h(CPUMIPSState *env,
1496 uint32_t wd, uint32_t ws, uint32_t wt)
1497{
1498 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1499 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1500 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1501
1502 pwd->h[0] = msa_aver_s_df(DF_HALF, pws->h[0], pwt->h[0]);
1503 pwd->h[1] = msa_aver_s_df(DF_HALF, pws->h[1], pwt->h[1]);
1504 pwd->h[2] = msa_aver_s_df(DF_HALF, pws->h[2], pwt->h[2]);
1505 pwd->h[3] = msa_aver_s_df(DF_HALF, pws->h[3], pwt->h[3]);
1506 pwd->h[4] = msa_aver_s_df(DF_HALF, pws->h[4], pwt->h[4]);
1507 pwd->h[5] = msa_aver_s_df(DF_HALF, pws->h[5], pwt->h[5]);
1508 pwd->h[6] = msa_aver_s_df(DF_HALF, pws->h[6], pwt->h[6]);
1509 pwd->h[7] = msa_aver_s_df(DF_HALF, pws->h[7], pwt->h[7]);
1510}
1511
1512void helper_msa_aver_s_w(CPUMIPSState *env,
1513 uint32_t wd, uint32_t ws, uint32_t wt)
1514{
1515 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1516 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1517 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1518
1519 pwd->w[0] = msa_aver_s_df(DF_WORD, pws->w[0], pwt->w[0]);
1520 pwd->w[1] = msa_aver_s_df(DF_WORD, pws->w[1], pwt->w[1]);
1521 pwd->w[2] = msa_aver_s_df(DF_WORD, pws->w[2], pwt->w[2]);
1522 pwd->w[3] = msa_aver_s_df(DF_WORD, pws->w[3], pwt->w[3]);
1523}
1524
1525void helper_msa_aver_s_d(CPUMIPSState *env,
1526 uint32_t wd, uint32_t ws, uint32_t wt)
1527{
1528 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1529 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1530 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1531
1532 pwd->d[0] = msa_aver_s_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
1533 pwd->d[1] = msa_aver_s_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
1534}
1535
1536static inline uint64_t msa_aver_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
1537{
1538 uint64_t u_arg1 = UNSIGNED(arg1, df);
1539 uint64_t u_arg2 = UNSIGNED(arg2, df);
1540
1541 return (u_arg1 >> 1) + (u_arg2 >> 1) + ((u_arg1 | u_arg2) & 1);
1542}
1543
1544void helper_msa_aver_u_b(CPUMIPSState *env,
1545 uint32_t wd, uint32_t ws, uint32_t wt)
1546{
1547 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1548 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1549 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1550
1551 pwd->b[0] = msa_aver_u_df(DF_BYTE, pws->b[0], pwt->b[0]);
1552 pwd->b[1] = msa_aver_u_df(DF_BYTE, pws->b[1], pwt->b[1]);
1553 pwd->b[2] = msa_aver_u_df(DF_BYTE, pws->b[2], pwt->b[2]);
1554 pwd->b[3] = msa_aver_u_df(DF_BYTE, pws->b[3], pwt->b[3]);
1555 pwd->b[4] = msa_aver_u_df(DF_BYTE, pws->b[4], pwt->b[4]);
1556 pwd->b[5] = msa_aver_u_df(DF_BYTE, pws->b[5], pwt->b[5]);
1557 pwd->b[6] = msa_aver_u_df(DF_BYTE, pws->b[6], pwt->b[6]);
1558 pwd->b[7] = msa_aver_u_df(DF_BYTE, pws->b[7], pwt->b[7]);
1559 pwd->b[8] = msa_aver_u_df(DF_BYTE, pws->b[8], pwt->b[8]);
1560 pwd->b[9] = msa_aver_u_df(DF_BYTE, pws->b[9], pwt->b[9]);
1561 pwd->b[10] = msa_aver_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
1562 pwd->b[11] = msa_aver_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
1563 pwd->b[12] = msa_aver_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
1564 pwd->b[13] = msa_aver_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
1565 pwd->b[14] = msa_aver_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
1566 pwd->b[15] = msa_aver_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
1567}
1568
1569void helper_msa_aver_u_h(CPUMIPSState *env,
1570 uint32_t wd, uint32_t ws, uint32_t wt)
1571{
1572 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1573 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1574 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1575
1576 pwd->h[0] = msa_aver_u_df(DF_HALF, pws->h[0], pwt->h[0]);
1577 pwd->h[1] = msa_aver_u_df(DF_HALF, pws->h[1], pwt->h[1]);
1578 pwd->h[2] = msa_aver_u_df(DF_HALF, pws->h[2], pwt->h[2]);
1579 pwd->h[3] = msa_aver_u_df(DF_HALF, pws->h[3], pwt->h[3]);
1580 pwd->h[4] = msa_aver_u_df(DF_HALF, pws->h[4], pwt->h[4]);
1581 pwd->h[5] = msa_aver_u_df(DF_HALF, pws->h[5], pwt->h[5]);
1582 pwd->h[6] = msa_aver_u_df(DF_HALF, pws->h[6], pwt->h[6]);
1583 pwd->h[7] = msa_aver_u_df(DF_HALF, pws->h[7], pwt->h[7]);
1584}
1585
1586void helper_msa_aver_u_w(CPUMIPSState *env,
1587 uint32_t wd, uint32_t ws, uint32_t wt)
1588{
1589 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1590 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1591 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1592
1593 pwd->w[0] = msa_aver_u_df(DF_WORD, pws->w[0], pwt->w[0]);
1594 pwd->w[1] = msa_aver_u_df(DF_WORD, pws->w[1], pwt->w[1]);
1595 pwd->w[2] = msa_aver_u_df(DF_WORD, pws->w[2], pwt->w[2]);
1596 pwd->w[3] = msa_aver_u_df(DF_WORD, pws->w[3], pwt->w[3]);
1597}
1598
1599void helper_msa_aver_u_d(CPUMIPSState *env,
1600 uint32_t wd, uint32_t ws, uint32_t wt)
1601{
1602 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1603 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1604 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1605
1606 pwd->d[0] = msa_aver_u_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
1607 pwd->d[1] = msa_aver_u_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
1608}
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639static inline int64_t msa_ceq_df(uint32_t df, int64_t arg1, int64_t arg2)
1640{
1641 return arg1 == arg2 ? -1 : 0;
1642}
1643
1644static inline int8_t msa_ceq_b(int8_t arg1, int8_t arg2)
1645{
1646 return arg1 == arg2 ? -1 : 0;
1647}
1648
1649void helper_msa_ceq_b(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
1650{
1651 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1652 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1653 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1654
1655 pwd->b[0] = msa_ceq_b(pws->b[0], pwt->b[0]);
1656 pwd->b[1] = msa_ceq_b(pws->b[1], pwt->b[1]);
1657 pwd->b[2] = msa_ceq_b(pws->b[2], pwt->b[2]);
1658 pwd->b[3] = msa_ceq_b(pws->b[3], pwt->b[3]);
1659 pwd->b[4] = msa_ceq_b(pws->b[4], pwt->b[4]);
1660 pwd->b[5] = msa_ceq_b(pws->b[5], pwt->b[5]);
1661 pwd->b[6] = msa_ceq_b(pws->b[6], pwt->b[6]);
1662 pwd->b[7] = msa_ceq_b(pws->b[7], pwt->b[7]);
1663 pwd->b[8] = msa_ceq_b(pws->b[8], pwt->b[8]);
1664 pwd->b[9] = msa_ceq_b(pws->b[9], pwt->b[9]);
1665 pwd->b[10] = msa_ceq_b(pws->b[10], pwt->b[10]);
1666 pwd->b[11] = msa_ceq_b(pws->b[11], pwt->b[11]);
1667 pwd->b[12] = msa_ceq_b(pws->b[12], pwt->b[12]);
1668 pwd->b[13] = msa_ceq_b(pws->b[13], pwt->b[13]);
1669 pwd->b[14] = msa_ceq_b(pws->b[14], pwt->b[14]);
1670 pwd->b[15] = msa_ceq_b(pws->b[15], pwt->b[15]);
1671}
1672
1673static inline int16_t msa_ceq_h(int16_t arg1, int16_t arg2)
1674{
1675 return arg1 == arg2 ? -1 : 0;
1676}
1677
1678void helper_msa_ceq_h(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
1679{
1680 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1681 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1682 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1683
1684 pwd->h[0] = msa_ceq_h(pws->h[0], pwt->h[0]);
1685 pwd->h[1] = msa_ceq_h(pws->h[1], pwt->h[1]);
1686 pwd->h[2] = msa_ceq_h(pws->h[2], pwt->h[2]);
1687 pwd->h[3] = msa_ceq_h(pws->h[3], pwt->h[3]);
1688 pwd->h[4] = msa_ceq_h(pws->h[4], pwt->h[4]);
1689 pwd->h[5] = msa_ceq_h(pws->h[5], pwt->h[5]);
1690 pwd->h[6] = msa_ceq_h(pws->h[6], pwt->h[6]);
1691 pwd->h[7] = msa_ceq_h(pws->h[7], pwt->h[7]);
1692}
1693
1694static inline int32_t msa_ceq_w(int32_t arg1, int32_t arg2)
1695{
1696 return arg1 == arg2 ? -1 : 0;
1697}
1698
1699void helper_msa_ceq_w(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
1700{
1701 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1702 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1703 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1704
1705 pwd->w[0] = msa_ceq_w(pws->w[0], pwt->w[0]);
1706 pwd->w[1] = msa_ceq_w(pws->w[1], pwt->w[1]);
1707 pwd->w[2] = msa_ceq_w(pws->w[2], pwt->w[2]);
1708 pwd->w[3] = msa_ceq_w(pws->w[3], pwt->w[3]);
1709}
1710
1711static inline int64_t msa_ceq_d(int64_t arg1, int64_t arg2)
1712{
1713 return arg1 == arg2 ? -1 : 0;
1714}
1715
1716void helper_msa_ceq_d(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
1717{
1718 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1719 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1720 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1721
1722 pwd->d[0] = msa_ceq_d(pws->d[0], pwt->d[0]);
1723 pwd->d[1] = msa_ceq_d(pws->d[1], pwt->d[1]);
1724}
1725
1726static inline int64_t msa_cle_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1727{
1728 return arg1 <= arg2 ? -1 : 0;
1729}
1730
1731void helper_msa_cle_s_b(CPUMIPSState *env,
1732 uint32_t wd, uint32_t ws, uint32_t wt)
1733{
1734 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1735 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1736 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1737
1738 pwd->b[0] = msa_cle_s_df(DF_BYTE, pws->b[0], pwt->b[0]);
1739 pwd->b[1] = msa_cle_s_df(DF_BYTE, pws->b[1], pwt->b[1]);
1740 pwd->b[2] = msa_cle_s_df(DF_BYTE, pws->b[2], pwt->b[2]);
1741 pwd->b[3] = msa_cle_s_df(DF_BYTE, pws->b[3], pwt->b[3]);
1742 pwd->b[4] = msa_cle_s_df(DF_BYTE, pws->b[4], pwt->b[4]);
1743 pwd->b[5] = msa_cle_s_df(DF_BYTE, pws->b[5], pwt->b[5]);
1744 pwd->b[6] = msa_cle_s_df(DF_BYTE, pws->b[6], pwt->b[6]);
1745 pwd->b[7] = msa_cle_s_df(DF_BYTE, pws->b[7], pwt->b[7]);
1746 pwd->b[8] = msa_cle_s_df(DF_BYTE, pws->b[8], pwt->b[8]);
1747 pwd->b[9] = msa_cle_s_df(DF_BYTE, pws->b[9], pwt->b[9]);
1748 pwd->b[10] = msa_cle_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
1749 pwd->b[11] = msa_cle_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
1750 pwd->b[12] = msa_cle_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
1751 pwd->b[13] = msa_cle_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
1752 pwd->b[14] = msa_cle_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
1753 pwd->b[15] = msa_cle_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
1754}
1755
1756void helper_msa_cle_s_h(CPUMIPSState *env,
1757 uint32_t wd, uint32_t ws, uint32_t wt)
1758{
1759 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1760 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1761 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1762
1763 pwd->h[0] = msa_cle_s_df(DF_HALF, pws->h[0], pwt->h[0]);
1764 pwd->h[1] = msa_cle_s_df(DF_HALF, pws->h[1], pwt->h[1]);
1765 pwd->h[2] = msa_cle_s_df(DF_HALF, pws->h[2], pwt->h[2]);
1766 pwd->h[3] = msa_cle_s_df(DF_HALF, pws->h[3], pwt->h[3]);
1767 pwd->h[4] = msa_cle_s_df(DF_HALF, pws->h[4], pwt->h[4]);
1768 pwd->h[5] = msa_cle_s_df(DF_HALF, pws->h[5], pwt->h[5]);
1769 pwd->h[6] = msa_cle_s_df(DF_HALF, pws->h[6], pwt->h[6]);
1770 pwd->h[7] = msa_cle_s_df(DF_HALF, pws->h[7], pwt->h[7]);
1771}
1772
1773void helper_msa_cle_s_w(CPUMIPSState *env,
1774 uint32_t wd, uint32_t ws, uint32_t wt)
1775{
1776 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1777 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1778 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1779
1780 pwd->w[0] = msa_cle_s_df(DF_WORD, pws->w[0], pwt->w[0]);
1781 pwd->w[1] = msa_cle_s_df(DF_WORD, pws->w[1], pwt->w[1]);
1782 pwd->w[2] = msa_cle_s_df(DF_WORD, pws->w[2], pwt->w[2]);
1783 pwd->w[3] = msa_cle_s_df(DF_WORD, pws->w[3], pwt->w[3]);
1784}
1785
1786void helper_msa_cle_s_d(CPUMIPSState *env,
1787 uint32_t wd, uint32_t ws, uint32_t wt)
1788{
1789 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1790 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1791 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1792
1793 pwd->d[0] = msa_cle_s_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
1794 pwd->d[1] = msa_cle_s_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
1795}
1796
1797static inline int64_t msa_cle_u_df(uint32_t df, int64_t arg1, int64_t arg2)
1798{
1799 uint64_t u_arg1 = UNSIGNED(arg1, df);
1800 uint64_t u_arg2 = UNSIGNED(arg2, df);
1801 return u_arg1 <= u_arg2 ? -1 : 0;
1802}
1803
1804void helper_msa_cle_u_b(CPUMIPSState *env,
1805 uint32_t wd, uint32_t ws, uint32_t wt)
1806{
1807 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1808 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1809 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1810
1811 pwd->b[0] = msa_cle_u_df(DF_BYTE, pws->b[0], pwt->b[0]);
1812 pwd->b[1] = msa_cle_u_df(DF_BYTE, pws->b[1], pwt->b[1]);
1813 pwd->b[2] = msa_cle_u_df(DF_BYTE, pws->b[2], pwt->b[2]);
1814 pwd->b[3] = msa_cle_u_df(DF_BYTE, pws->b[3], pwt->b[3]);
1815 pwd->b[4] = msa_cle_u_df(DF_BYTE, pws->b[4], pwt->b[4]);
1816 pwd->b[5] = msa_cle_u_df(DF_BYTE, pws->b[5], pwt->b[5]);
1817 pwd->b[6] = msa_cle_u_df(DF_BYTE, pws->b[6], pwt->b[6]);
1818 pwd->b[7] = msa_cle_u_df(DF_BYTE, pws->b[7], pwt->b[7]);
1819 pwd->b[8] = msa_cle_u_df(DF_BYTE, pws->b[8], pwt->b[8]);
1820 pwd->b[9] = msa_cle_u_df(DF_BYTE, pws->b[9], pwt->b[9]);
1821 pwd->b[10] = msa_cle_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
1822 pwd->b[11] = msa_cle_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
1823 pwd->b[12] = msa_cle_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
1824 pwd->b[13] = msa_cle_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
1825 pwd->b[14] = msa_cle_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
1826 pwd->b[15] = msa_cle_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
1827}
1828
1829void helper_msa_cle_u_h(CPUMIPSState *env,
1830 uint32_t wd, uint32_t ws, uint32_t wt)
1831{
1832 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1833 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1834 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1835
1836 pwd->h[0] = msa_cle_u_df(DF_HALF, pws->h[0], pwt->h[0]);
1837 pwd->h[1] = msa_cle_u_df(DF_HALF, pws->h[1], pwt->h[1]);
1838 pwd->h[2] = msa_cle_u_df(DF_HALF, pws->h[2], pwt->h[2]);
1839 pwd->h[3] = msa_cle_u_df(DF_HALF, pws->h[3], pwt->h[3]);
1840 pwd->h[4] = msa_cle_u_df(DF_HALF, pws->h[4], pwt->h[4]);
1841 pwd->h[5] = msa_cle_u_df(DF_HALF, pws->h[5], pwt->h[5]);
1842 pwd->h[6] = msa_cle_u_df(DF_HALF, pws->h[6], pwt->h[6]);
1843 pwd->h[7] = msa_cle_u_df(DF_HALF, pws->h[7], pwt->h[7]);
1844}
1845
1846void helper_msa_cle_u_w(CPUMIPSState *env,
1847 uint32_t wd, uint32_t ws, uint32_t wt)
1848{
1849 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1850 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1851 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1852
1853 pwd->w[0] = msa_cle_u_df(DF_WORD, pws->w[0], pwt->w[0]);
1854 pwd->w[1] = msa_cle_u_df(DF_WORD, pws->w[1], pwt->w[1]);
1855 pwd->w[2] = msa_cle_u_df(DF_WORD, pws->w[2], pwt->w[2]);
1856 pwd->w[3] = msa_cle_u_df(DF_WORD, pws->w[3], pwt->w[3]);
1857}
1858
1859void helper_msa_cle_u_d(CPUMIPSState *env,
1860 uint32_t wd, uint32_t ws, uint32_t wt)
1861{
1862 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1863 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1864 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1865
1866 pwd->d[0] = msa_cle_u_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
1867 pwd->d[1] = msa_cle_u_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
1868}
1869
1870static inline int64_t msa_clt_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1871{
1872 return arg1 < arg2 ? -1 : 0;
1873}
1874
1875static inline int8_t msa_clt_s_b(int8_t arg1, int8_t arg2)
1876{
1877 return arg1 < arg2 ? -1 : 0;
1878}
1879
1880void helper_msa_clt_s_b(CPUMIPSState *env,
1881 uint32_t wd, uint32_t ws, uint32_t wt)
1882{
1883 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1884 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1885 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1886
1887 pwd->b[0] = msa_clt_s_b(pws->b[0], pwt->b[0]);
1888 pwd->b[1] = msa_clt_s_b(pws->b[1], pwt->b[1]);
1889 pwd->b[2] = msa_clt_s_b(pws->b[2], pwt->b[2]);
1890 pwd->b[3] = msa_clt_s_b(pws->b[3], pwt->b[3]);
1891 pwd->b[4] = msa_clt_s_b(pws->b[4], pwt->b[4]);
1892 pwd->b[5] = msa_clt_s_b(pws->b[5], pwt->b[5]);
1893 pwd->b[6] = msa_clt_s_b(pws->b[6], pwt->b[6]);
1894 pwd->b[7] = msa_clt_s_b(pws->b[7], pwt->b[7]);
1895 pwd->b[8] = msa_clt_s_b(pws->b[8], pwt->b[8]);
1896 pwd->b[9] = msa_clt_s_b(pws->b[9], pwt->b[9]);
1897 pwd->b[10] = msa_clt_s_b(pws->b[10], pwt->b[10]);
1898 pwd->b[11] = msa_clt_s_b(pws->b[11], pwt->b[11]);
1899 pwd->b[12] = msa_clt_s_b(pws->b[12], pwt->b[12]);
1900 pwd->b[13] = msa_clt_s_b(pws->b[13], pwt->b[13]);
1901 pwd->b[14] = msa_clt_s_b(pws->b[14], pwt->b[14]);
1902 pwd->b[15] = msa_clt_s_b(pws->b[15], pwt->b[15]);
1903}
1904
1905static inline int16_t msa_clt_s_h(int16_t arg1, int16_t arg2)
1906{
1907 return arg1 < arg2 ? -1 : 0;
1908}
1909
1910void helper_msa_clt_s_h(CPUMIPSState *env,
1911 uint32_t wd, uint32_t ws, uint32_t wt)
1912{
1913 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1914 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1915 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1916
1917 pwd->h[0] = msa_clt_s_h(pws->h[0], pwt->h[0]);
1918 pwd->h[1] = msa_clt_s_h(pws->h[1], pwt->h[1]);
1919 pwd->h[2] = msa_clt_s_h(pws->h[2], pwt->h[2]);
1920 pwd->h[3] = msa_clt_s_h(pws->h[3], pwt->h[3]);
1921 pwd->h[4] = msa_clt_s_h(pws->h[4], pwt->h[4]);
1922 pwd->h[5] = msa_clt_s_h(pws->h[5], pwt->h[5]);
1923 pwd->h[6] = msa_clt_s_h(pws->h[6], pwt->h[6]);
1924 pwd->h[7] = msa_clt_s_h(pws->h[7], pwt->h[7]);
1925}
1926
1927static inline int32_t msa_clt_s_w(int32_t arg1, int32_t arg2)
1928{
1929 return arg1 < arg2 ? -1 : 0;
1930}
1931
1932void helper_msa_clt_s_w(CPUMIPSState *env,
1933 uint32_t wd, uint32_t ws, uint32_t wt)
1934{
1935 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1936 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1937 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1938
1939 pwd->w[0] = msa_clt_s_w(pws->w[0], pwt->w[0]);
1940 pwd->w[1] = msa_clt_s_w(pws->w[1], pwt->w[1]);
1941 pwd->w[2] = msa_clt_s_w(pws->w[2], pwt->w[2]);
1942 pwd->w[3] = msa_clt_s_w(pws->w[3], pwt->w[3]);
1943}
1944
1945static inline int64_t msa_clt_s_d(int64_t arg1, int64_t arg2)
1946{
1947 return arg1 < arg2 ? -1 : 0;
1948}
1949
1950void helper_msa_clt_s_d(CPUMIPSState *env,
1951 uint32_t wd, uint32_t ws, uint32_t wt)
1952{
1953 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1954 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1955 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1956
1957 pwd->d[0] = msa_clt_s_d(pws->d[0], pwt->d[0]);
1958 pwd->d[1] = msa_clt_s_d(pws->d[1], pwt->d[1]);
1959}
1960
1961static inline int64_t msa_clt_u_df(uint32_t df, int64_t arg1, int64_t arg2)
1962{
1963 uint64_t u_arg1 = UNSIGNED(arg1, df);
1964 uint64_t u_arg2 = UNSIGNED(arg2, df);
1965 return u_arg1 < u_arg2 ? -1 : 0;
1966}
1967
1968void helper_msa_clt_u_b(CPUMIPSState *env,
1969 uint32_t wd, uint32_t ws, uint32_t wt)
1970{
1971 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1972 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1973 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1974
1975 pwd->b[0] = msa_clt_u_df(DF_BYTE, pws->b[0], pwt->b[0]);
1976 pwd->b[1] = msa_clt_u_df(DF_BYTE, pws->b[1], pwt->b[1]);
1977 pwd->b[2] = msa_clt_u_df(DF_BYTE, pws->b[2], pwt->b[2]);
1978 pwd->b[3] = msa_clt_u_df(DF_BYTE, pws->b[3], pwt->b[3]);
1979 pwd->b[4] = msa_clt_u_df(DF_BYTE, pws->b[4], pwt->b[4]);
1980 pwd->b[5] = msa_clt_u_df(DF_BYTE, pws->b[5], pwt->b[5]);
1981 pwd->b[6] = msa_clt_u_df(DF_BYTE, pws->b[6], pwt->b[6]);
1982 pwd->b[7] = msa_clt_u_df(DF_BYTE, pws->b[7], pwt->b[7]);
1983 pwd->b[8] = msa_clt_u_df(DF_BYTE, pws->b[8], pwt->b[8]);
1984 pwd->b[9] = msa_clt_u_df(DF_BYTE, pws->b[9], pwt->b[9]);
1985 pwd->b[10] = msa_clt_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
1986 pwd->b[11] = msa_clt_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
1987 pwd->b[12] = msa_clt_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
1988 pwd->b[13] = msa_clt_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
1989 pwd->b[14] = msa_clt_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
1990 pwd->b[15] = msa_clt_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
1991}
1992
1993void helper_msa_clt_u_h(CPUMIPSState *env,
1994 uint32_t wd, uint32_t ws, uint32_t wt)
1995{
1996 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1997 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1998 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1999
2000 pwd->h[0] = msa_clt_u_df(DF_HALF, pws->h[0], pwt->h[0]);
2001 pwd->h[1] = msa_clt_u_df(DF_HALF, pws->h[1], pwt->h[1]);
2002 pwd->h[2] = msa_clt_u_df(DF_HALF, pws->h[2], pwt->h[2]);
2003 pwd->h[3] = msa_clt_u_df(DF_HALF, pws->h[3], pwt->h[3]);
2004 pwd->h[4] = msa_clt_u_df(DF_HALF, pws->h[4], pwt->h[4]);
2005 pwd->h[5] = msa_clt_u_df(DF_HALF, pws->h[5], pwt->h[5]);
2006 pwd->h[6] = msa_clt_u_df(DF_HALF, pws->h[6], pwt->h[6]);
2007 pwd->h[7] = msa_clt_u_df(DF_HALF, pws->h[7], pwt->h[7]);
2008}
2009
2010void helper_msa_clt_u_w(CPUMIPSState *env,
2011 uint32_t wd, uint32_t ws, uint32_t wt)
2012{
2013 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2014 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2015 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2016
2017 pwd->w[0] = msa_clt_u_df(DF_WORD, pws->w[0], pwt->w[0]);
2018 pwd->w[1] = msa_clt_u_df(DF_WORD, pws->w[1], pwt->w[1]);
2019 pwd->w[2] = msa_clt_u_df(DF_WORD, pws->w[2], pwt->w[2]);
2020 pwd->w[3] = msa_clt_u_df(DF_WORD, pws->w[3], pwt->w[3]);
2021}
2022
2023void helper_msa_clt_u_d(CPUMIPSState *env,
2024 uint32_t wd, uint32_t ws, uint32_t wt)
2025{
2026 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2027 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2028 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2029
2030 pwd->d[0] = msa_clt_u_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
2031 pwd->d[1] = msa_clt_u_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
2032}
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052static inline int64_t msa_div_s_df(uint32_t df, int64_t arg1, int64_t arg2)
2053{
2054 if (arg1 == DF_MIN_INT(df) && arg2 == -1) {
2055 return DF_MIN_INT(df);
2056 }
2057 return arg2 ? arg1 / arg2
2058 : arg1 >= 0 ? -1 : 1;
2059}
2060
2061void helper_msa_div_s_b(CPUMIPSState *env,
2062 uint32_t wd, uint32_t ws, uint32_t wt)
2063{
2064 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2065 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2066 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2067
2068 pwd->b[0] = msa_div_s_df(DF_BYTE, pws->b[0], pwt->b[0]);
2069 pwd->b[1] = msa_div_s_df(DF_BYTE, pws->b[1], pwt->b[1]);
2070 pwd->b[2] = msa_div_s_df(DF_BYTE, pws->b[2], pwt->b[2]);
2071 pwd->b[3] = msa_div_s_df(DF_BYTE, pws->b[3], pwt->b[3]);
2072 pwd->b[4] = msa_div_s_df(DF_BYTE, pws->b[4], pwt->b[4]);
2073 pwd->b[5] = msa_div_s_df(DF_BYTE, pws->b[5], pwt->b[5]);
2074 pwd->b[6] = msa_div_s_df(DF_BYTE, pws->b[6], pwt->b[6]);
2075 pwd->b[7] = msa_div_s_df(DF_BYTE, pws->b[7], pwt->b[7]);
2076 pwd->b[8] = msa_div_s_df(DF_BYTE, pws->b[8], pwt->b[8]);
2077 pwd->b[9] = msa_div_s_df(DF_BYTE, pws->b[9], pwt->b[9]);
2078 pwd->b[10] = msa_div_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
2079 pwd->b[11] = msa_div_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
2080 pwd->b[12] = msa_div_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
2081 pwd->b[13] = msa_div_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
2082 pwd->b[14] = msa_div_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
2083 pwd->b[15] = msa_div_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
2084}
2085
2086void helper_msa_div_s_h(CPUMIPSState *env,
2087 uint32_t wd, uint32_t ws, uint32_t wt)
2088{
2089 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2090 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2091 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2092
2093 pwd->h[0] = msa_div_s_df(DF_HALF, pws->h[0], pwt->h[0]);
2094 pwd->h[1] = msa_div_s_df(DF_HALF, pws->h[1], pwt->h[1]);
2095 pwd->h[2] = msa_div_s_df(DF_HALF, pws->h[2], pwt->h[2]);
2096 pwd->h[3] = msa_div_s_df(DF_HALF, pws->h[3], pwt->h[3]);
2097 pwd->h[4] = msa_div_s_df(DF_HALF, pws->h[4], pwt->h[4]);
2098 pwd->h[5] = msa_div_s_df(DF_HALF, pws->h[5], pwt->h[5]);
2099 pwd->h[6] = msa_div_s_df(DF_HALF, pws->h[6], pwt->h[6]);
2100 pwd->h[7] = msa_div_s_df(DF_HALF, pws->h[7], pwt->h[7]);
2101}
2102
2103void helper_msa_div_s_w(CPUMIPSState *env,
2104 uint32_t wd, uint32_t ws, uint32_t wt)
2105{
2106 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2107 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2108 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2109
2110 pwd->w[0] = msa_div_s_df(DF_WORD, pws->w[0], pwt->w[0]);
2111 pwd->w[1] = msa_div_s_df(DF_WORD, pws->w[1], pwt->w[1]);
2112 pwd->w[2] = msa_div_s_df(DF_WORD, pws->w[2], pwt->w[2]);
2113 pwd->w[3] = msa_div_s_df(DF_WORD, pws->w[3], pwt->w[3]);
2114}
2115
2116void helper_msa_div_s_d(CPUMIPSState *env,
2117 uint32_t wd, uint32_t ws, uint32_t wt)
2118{
2119 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2120 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2121 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2122
2123 pwd->d[0] = msa_div_s_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
2124 pwd->d[1] = msa_div_s_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
2125}
2126
2127static inline int64_t msa_div_u_df(uint32_t df, int64_t arg1, int64_t arg2)
2128{
2129 uint64_t u_arg1 = UNSIGNED(arg1, df);
2130 uint64_t u_arg2 = UNSIGNED(arg2, df);
2131 return arg2 ? u_arg1 / u_arg2 : -1;
2132}
2133
2134void helper_msa_div_u_b(CPUMIPSState *env,
2135 uint32_t wd, uint32_t ws, uint32_t wt)
2136{
2137 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2138 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2139 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2140
2141 pwd->b[0] = msa_div_u_df(DF_BYTE, pws->b[0], pwt->b[0]);
2142 pwd->b[1] = msa_div_u_df(DF_BYTE, pws->b[1], pwt->b[1]);
2143 pwd->b[2] = msa_div_u_df(DF_BYTE, pws->b[2], pwt->b[2]);
2144 pwd->b[3] = msa_div_u_df(DF_BYTE, pws->b[3], pwt->b[3]);
2145 pwd->b[4] = msa_div_u_df(DF_BYTE, pws->b[4], pwt->b[4]);
2146 pwd->b[5] = msa_div_u_df(DF_BYTE, pws->b[5], pwt->b[5]);
2147 pwd->b[6] = msa_div_u_df(DF_BYTE, pws->b[6], pwt->b[6]);
2148 pwd->b[7] = msa_div_u_df(DF_BYTE, pws->b[7], pwt->b[7]);
2149 pwd->b[8] = msa_div_u_df(DF_BYTE, pws->b[8], pwt->b[8]);
2150 pwd->b[9] = msa_div_u_df(DF_BYTE, pws->b[9], pwt->b[9]);
2151 pwd->b[10] = msa_div_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
2152 pwd->b[11] = msa_div_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
2153 pwd->b[12] = msa_div_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
2154 pwd->b[13] = msa_div_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
2155 pwd->b[14] = msa_div_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
2156 pwd->b[15] = msa_div_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
2157}
2158
2159void helper_msa_div_u_h(CPUMIPSState *env,
2160 uint32_t wd, uint32_t ws, uint32_t wt)
2161{
2162 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2163 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2164 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2165
2166 pwd->h[0] = msa_div_u_df(DF_HALF, pws->h[0], pwt->h[0]);
2167 pwd->h[1] = msa_div_u_df(DF_HALF, pws->h[1], pwt->h[1]);
2168 pwd->h[2] = msa_div_u_df(DF_HALF, pws->h[2], pwt->h[2]);
2169 pwd->h[3] = msa_div_u_df(DF_HALF, pws->h[3], pwt->h[3]);
2170 pwd->h[4] = msa_div_u_df(DF_HALF, pws->h[4], pwt->h[4]);
2171 pwd->h[5] = msa_div_u_df(DF_HALF, pws->h[5], pwt->h[5]);
2172 pwd->h[6] = msa_div_u_df(DF_HALF, pws->h[6], pwt->h[6]);
2173 pwd->h[7] = msa_div_u_df(DF_HALF, pws->h[7], pwt->h[7]);
2174}
2175
2176void helper_msa_div_u_w(CPUMIPSState *env,
2177 uint32_t wd, uint32_t ws, uint32_t wt)
2178{
2179 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2180 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2181 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2182
2183 pwd->w[0] = msa_div_u_df(DF_WORD, pws->w[0], pwt->w[0]);
2184 pwd->w[1] = msa_div_u_df(DF_WORD, pws->w[1], pwt->w[1]);
2185 pwd->w[2] = msa_div_u_df(DF_WORD, pws->w[2], pwt->w[2]);
2186 pwd->w[3] = msa_div_u_df(DF_WORD, pws->w[3], pwt->w[3]);
2187}
2188
2189void helper_msa_div_u_d(CPUMIPSState *env,
2190 uint32_t wd, uint32_t ws, uint32_t wt)
2191{
2192 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2193 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2194 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2195
2196 pwd->d[0] = msa_div_u_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
2197 pwd->d[1] = msa_div_u_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
2198}
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262static inline int64_t msa_max_a_df(uint32_t df, int64_t arg1, int64_t arg2)
2263{
2264 uint64_t abs_arg1 = arg1 >= 0 ? arg1 : -arg1;
2265 uint64_t abs_arg2 = arg2 >= 0 ? arg2 : -arg2;
2266 return abs_arg1 > abs_arg2 ? arg1 : arg2;
2267}
2268
2269void helper_msa_max_a_b(CPUMIPSState *env,
2270 uint32_t wd, uint32_t ws, uint32_t wt)
2271{
2272 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2273 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2274 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2275
2276 pwd->b[0] = msa_max_a_df(DF_BYTE, pws->b[0], pwt->b[0]);
2277 pwd->b[1] = msa_max_a_df(DF_BYTE, pws->b[1], pwt->b[1]);
2278 pwd->b[2] = msa_max_a_df(DF_BYTE, pws->b[2], pwt->b[2]);
2279 pwd->b[3] = msa_max_a_df(DF_BYTE, pws->b[3], pwt->b[3]);
2280 pwd->b[4] = msa_max_a_df(DF_BYTE, pws->b[4], pwt->b[4]);
2281 pwd->b[5] = msa_max_a_df(DF_BYTE, pws->b[5], pwt->b[5]);
2282 pwd->b[6] = msa_max_a_df(DF_BYTE, pws->b[6], pwt->b[6]);
2283 pwd->b[7] = msa_max_a_df(DF_BYTE, pws->b[7], pwt->b[7]);
2284 pwd->b[8] = msa_max_a_df(DF_BYTE, pws->b[8], pwt->b[8]);
2285 pwd->b[9] = msa_max_a_df(DF_BYTE, pws->b[9], pwt->b[9]);
2286 pwd->b[10] = msa_max_a_df(DF_BYTE, pws->b[10], pwt->b[10]);
2287 pwd->b[11] = msa_max_a_df(DF_BYTE, pws->b[11], pwt->b[11]);
2288 pwd->b[12] = msa_max_a_df(DF_BYTE, pws->b[12], pwt->b[12]);
2289 pwd->b[13] = msa_max_a_df(DF_BYTE, pws->b[13], pwt->b[13]);
2290 pwd->b[14] = msa_max_a_df(DF_BYTE, pws->b[14], pwt->b[14]);
2291 pwd->b[15] = msa_max_a_df(DF_BYTE, pws->b[15], pwt->b[15]);
2292}
2293
2294void helper_msa_max_a_h(CPUMIPSState *env,
2295 uint32_t wd, uint32_t ws, uint32_t wt)
2296{
2297 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2298 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2299 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2300
2301 pwd->h[0] = msa_max_a_df(DF_HALF, pws->h[0], pwt->h[0]);
2302 pwd->h[1] = msa_max_a_df(DF_HALF, pws->h[1], pwt->h[1]);
2303 pwd->h[2] = msa_max_a_df(DF_HALF, pws->h[2], pwt->h[2]);
2304 pwd->h[3] = msa_max_a_df(DF_HALF, pws->h[3], pwt->h[3]);
2305 pwd->h[4] = msa_max_a_df(DF_HALF, pws->h[4], pwt->h[4]);
2306 pwd->h[5] = msa_max_a_df(DF_HALF, pws->h[5], pwt->h[5]);
2307 pwd->h[6] = msa_max_a_df(DF_HALF, pws->h[6], pwt->h[6]);
2308 pwd->h[7] = msa_max_a_df(DF_HALF, pws->h[7], pwt->h[7]);
2309}
2310
2311void helper_msa_max_a_w(CPUMIPSState *env,
2312 uint32_t wd, uint32_t ws, uint32_t wt)
2313{
2314 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2315 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2316 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2317
2318 pwd->w[0] = msa_max_a_df(DF_WORD, pws->w[0], pwt->w[0]);
2319 pwd->w[1] = msa_max_a_df(DF_WORD, pws->w[1], pwt->w[1]);
2320 pwd->w[2] = msa_max_a_df(DF_WORD, pws->w[2], pwt->w[2]);
2321 pwd->w[3] = msa_max_a_df(DF_WORD, pws->w[3], pwt->w[3]);
2322}
2323
2324void helper_msa_max_a_d(CPUMIPSState *env,
2325 uint32_t wd, uint32_t ws, uint32_t wt)
2326{
2327 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2328 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2329 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2330
2331 pwd->d[0] = msa_max_a_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
2332 pwd->d[1] = msa_max_a_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
2333}
2334
2335
2336static inline int64_t msa_max_s_df(uint32_t df, int64_t arg1, int64_t arg2)
2337{
2338 return arg1 > arg2 ? arg1 : arg2;
2339}
2340
2341void helper_msa_max_s_b(CPUMIPSState *env,
2342 uint32_t wd, uint32_t ws, uint32_t wt)
2343{
2344 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2345 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2346 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2347
2348 pwd->b[0] = msa_max_s_df(DF_BYTE, pws->b[0], pwt->b[0]);
2349 pwd->b[1] = msa_max_s_df(DF_BYTE, pws->b[1], pwt->b[1]);
2350 pwd->b[2] = msa_max_s_df(DF_BYTE, pws->b[2], pwt->b[2]);
2351 pwd->b[3] = msa_max_s_df(DF_BYTE, pws->b[3], pwt->b[3]);
2352 pwd->b[4] = msa_max_s_df(DF_BYTE, pws->b[4], pwt->b[4]);
2353 pwd->b[5] = msa_max_s_df(DF_BYTE, pws->b[5], pwt->b[5]);
2354 pwd->b[6] = msa_max_s_df(DF_BYTE, pws->b[6], pwt->b[6]);
2355 pwd->b[7] = msa_max_s_df(DF_BYTE, pws->b[7], pwt->b[7]);
2356 pwd->b[8] = msa_max_s_df(DF_BYTE, pws->b[8], pwt->b[8]);
2357 pwd->b[9] = msa_max_s_df(DF_BYTE, pws->b[9], pwt->b[9]);
2358 pwd->b[10] = msa_max_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
2359 pwd->b[11] = msa_max_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
2360 pwd->b[12] = msa_max_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
2361 pwd->b[13] = msa_max_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
2362 pwd->b[14] = msa_max_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
2363 pwd->b[15] = msa_max_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
2364}
2365
2366void helper_msa_max_s_h(CPUMIPSState *env,
2367 uint32_t wd, uint32_t ws, uint32_t wt)
2368{
2369 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2370 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2371 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2372
2373 pwd->h[0] = msa_max_s_df(DF_HALF, pws->h[0], pwt->h[0]);
2374 pwd->h[1] = msa_max_s_df(DF_HALF, pws->h[1], pwt->h[1]);
2375 pwd->h[2] = msa_max_s_df(DF_HALF, pws->h[2], pwt->h[2]);
2376 pwd->h[3] = msa_max_s_df(DF_HALF, pws->h[3], pwt->h[3]);
2377 pwd->h[4] = msa_max_s_df(DF_HALF, pws->h[4], pwt->h[4]);
2378 pwd->h[5] = msa_max_s_df(DF_HALF, pws->h[5], pwt->h[5]);
2379 pwd->h[6] = msa_max_s_df(DF_HALF, pws->h[6], pwt->h[6]);
2380 pwd->h[7] = msa_max_s_df(DF_HALF, pws->h[7], pwt->h[7]);
2381}
2382
2383void helper_msa_max_s_w(CPUMIPSState *env,
2384 uint32_t wd, uint32_t ws, uint32_t wt)
2385{
2386 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2387 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2388 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2389
2390 pwd->w[0] = msa_max_s_df(DF_WORD, pws->w[0], pwt->w[0]);
2391 pwd->w[1] = msa_max_s_df(DF_WORD, pws->w[1], pwt->w[1]);
2392 pwd->w[2] = msa_max_s_df(DF_WORD, pws->w[2], pwt->w[2]);
2393 pwd->w[3] = msa_max_s_df(DF_WORD, pws->w[3], pwt->w[3]);
2394}
2395
2396void helper_msa_max_s_d(CPUMIPSState *env,
2397 uint32_t wd, uint32_t ws, uint32_t wt)
2398{
2399 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2400 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2401 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2402
2403 pwd->d[0] = msa_max_s_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
2404 pwd->d[1] = msa_max_s_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
2405}
2406
2407
2408static inline int64_t msa_max_u_df(uint32_t df, int64_t arg1, int64_t arg2)
2409{
2410 uint64_t u_arg1 = UNSIGNED(arg1, df);
2411 uint64_t u_arg2 = UNSIGNED(arg2, df);
2412 return u_arg1 > u_arg2 ? arg1 : arg2;
2413}
2414
2415void helper_msa_max_u_b(CPUMIPSState *env,
2416 uint32_t wd, uint32_t ws, uint32_t wt)
2417{
2418 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2419 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2420 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2421
2422 pwd->b[0] = msa_max_u_df(DF_BYTE, pws->b[0], pwt->b[0]);
2423 pwd->b[1] = msa_max_u_df(DF_BYTE, pws->b[1], pwt->b[1]);
2424 pwd->b[2] = msa_max_u_df(DF_BYTE, pws->b[2], pwt->b[2]);
2425 pwd->b[3] = msa_max_u_df(DF_BYTE, pws->b[3], pwt->b[3]);
2426 pwd->b[4] = msa_max_u_df(DF_BYTE, pws->b[4], pwt->b[4]);
2427 pwd->b[5] = msa_max_u_df(DF_BYTE, pws->b[5], pwt->b[5]);
2428 pwd->b[6] = msa_max_u_df(DF_BYTE, pws->b[6], pwt->b[6]);
2429 pwd->b[7] = msa_max_u_df(DF_BYTE, pws->b[7], pwt->b[7]);
2430 pwd->b[8] = msa_max_u_df(DF_BYTE, pws->b[8], pwt->b[8]);
2431 pwd->b[9] = msa_max_u_df(DF_BYTE, pws->b[9], pwt->b[9]);
2432 pwd->b[10] = msa_max_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
2433 pwd->b[11] = msa_max_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
2434 pwd->b[12] = msa_max_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
2435 pwd->b[13] = msa_max_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
2436 pwd->b[14] = msa_max_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
2437 pwd->b[15] = msa_max_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
2438}
2439
2440void helper_msa_max_u_h(CPUMIPSState *env,
2441 uint32_t wd, uint32_t ws, uint32_t wt)
2442{
2443 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2444 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2445 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2446
2447 pwd->h[0] = msa_max_u_df(DF_HALF, pws->h[0], pwt->h[0]);
2448 pwd->h[1] = msa_max_u_df(DF_HALF, pws->h[1], pwt->h[1]);
2449 pwd->h[2] = msa_max_u_df(DF_HALF, pws->h[2], pwt->h[2]);
2450 pwd->h[3] = msa_max_u_df(DF_HALF, pws->h[3], pwt->h[3]);
2451 pwd->h[4] = msa_max_u_df(DF_HALF, pws->h[4], pwt->h[4]);
2452 pwd->h[5] = msa_max_u_df(DF_HALF, pws->h[5], pwt->h[5]);
2453 pwd->h[6] = msa_max_u_df(DF_HALF, pws->h[6], pwt->h[6]);
2454 pwd->h[7] = msa_max_u_df(DF_HALF, pws->h[7], pwt->h[7]);
2455}
2456
2457void helper_msa_max_u_w(CPUMIPSState *env,
2458 uint32_t wd, uint32_t ws, uint32_t wt)
2459{
2460 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2461 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2462 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2463
2464 pwd->w[0] = msa_max_u_df(DF_WORD, pws->w[0], pwt->w[0]);
2465 pwd->w[1] = msa_max_u_df(DF_WORD, pws->w[1], pwt->w[1]);
2466 pwd->w[2] = msa_max_u_df(DF_WORD, pws->w[2], pwt->w[2]);
2467 pwd->w[3] = msa_max_u_df(DF_WORD, pws->w[3], pwt->w[3]);
2468}
2469
2470void helper_msa_max_u_d(CPUMIPSState *env,
2471 uint32_t wd, uint32_t ws, uint32_t wt)
2472{
2473 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2474 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2475 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2476
2477 pwd->d[0] = msa_max_u_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
2478 pwd->d[1] = msa_max_u_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
2479}
2480
2481
2482static inline int64_t msa_min_a_df(uint32_t df, int64_t arg1, int64_t arg2)
2483{
2484 uint64_t abs_arg1 = arg1 >= 0 ? arg1 : -arg1;
2485 uint64_t abs_arg2 = arg2 >= 0 ? arg2 : -arg2;
2486 return abs_arg1 < abs_arg2 ? arg1 : arg2;
2487}
2488
2489void helper_msa_min_a_b(CPUMIPSState *env,
2490 uint32_t wd, uint32_t ws, uint32_t wt)
2491{
2492 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2493 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2494 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2495
2496 pwd->b[0] = msa_min_a_df(DF_BYTE, pws->b[0], pwt->b[0]);
2497 pwd->b[1] = msa_min_a_df(DF_BYTE, pws->b[1], pwt->b[1]);
2498 pwd->b[2] = msa_min_a_df(DF_BYTE, pws->b[2], pwt->b[2]);
2499 pwd->b[3] = msa_min_a_df(DF_BYTE, pws->b[3], pwt->b[3]);
2500 pwd->b[4] = msa_min_a_df(DF_BYTE, pws->b[4], pwt->b[4]);
2501 pwd->b[5] = msa_min_a_df(DF_BYTE, pws->b[5], pwt->b[5]);
2502 pwd->b[6] = msa_min_a_df(DF_BYTE, pws->b[6], pwt->b[6]);
2503 pwd->b[7] = msa_min_a_df(DF_BYTE, pws->b[7], pwt->b[7]);
2504 pwd->b[8] = msa_min_a_df(DF_BYTE, pws->b[8], pwt->b[8]);
2505 pwd->b[9] = msa_min_a_df(DF_BYTE, pws->b[9], pwt->b[9]);
2506 pwd->b[10] = msa_min_a_df(DF_BYTE, pws->b[10], pwt->b[10]);
2507 pwd->b[11] = msa_min_a_df(DF_BYTE, pws->b[11], pwt->b[11]);
2508 pwd->b[12] = msa_min_a_df(DF_BYTE, pws->b[12], pwt->b[12]);
2509 pwd->b[13] = msa_min_a_df(DF_BYTE, pws->b[13], pwt->b[13]);
2510 pwd->b[14] = msa_min_a_df(DF_BYTE, pws->b[14], pwt->b[14]);
2511 pwd->b[15] = msa_min_a_df(DF_BYTE, pws->b[15], pwt->b[15]);
2512}
2513
2514void helper_msa_min_a_h(CPUMIPSState *env,
2515 uint32_t wd, uint32_t ws, uint32_t wt)
2516{
2517 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2518 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2519 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2520
2521 pwd->h[0] = msa_min_a_df(DF_HALF, pws->h[0], pwt->h[0]);
2522 pwd->h[1] = msa_min_a_df(DF_HALF, pws->h[1], pwt->h[1]);
2523 pwd->h[2] = msa_min_a_df(DF_HALF, pws->h[2], pwt->h[2]);
2524 pwd->h[3] = msa_min_a_df(DF_HALF, pws->h[3], pwt->h[3]);
2525 pwd->h[4] = msa_min_a_df(DF_HALF, pws->h[4], pwt->h[4]);
2526 pwd->h[5] = msa_min_a_df(DF_HALF, pws->h[5], pwt->h[5]);
2527 pwd->h[6] = msa_min_a_df(DF_HALF, pws->h[6], pwt->h[6]);
2528 pwd->h[7] = msa_min_a_df(DF_HALF, pws->h[7], pwt->h[7]);
2529}
2530
2531void helper_msa_min_a_w(CPUMIPSState *env,
2532 uint32_t wd, uint32_t ws, uint32_t wt)
2533{
2534 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2535 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2536 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2537
2538 pwd->w[0] = msa_min_a_df(DF_WORD, pws->w[0], pwt->w[0]);
2539 pwd->w[1] = msa_min_a_df(DF_WORD, pws->w[1], pwt->w[1]);
2540 pwd->w[2] = msa_min_a_df(DF_WORD, pws->w[2], pwt->w[2]);
2541 pwd->w[3] = msa_min_a_df(DF_WORD, pws->w[3], pwt->w[3]);
2542}
2543
2544void helper_msa_min_a_d(CPUMIPSState *env,
2545 uint32_t wd, uint32_t ws, uint32_t wt)
2546{
2547 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2548 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2549 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2550
2551 pwd->d[0] = msa_min_a_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
2552 pwd->d[1] = msa_min_a_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
2553}
2554
2555
2556static inline int64_t msa_min_s_df(uint32_t df, int64_t arg1, int64_t arg2)
2557{
2558 return arg1 < arg2 ? arg1 : arg2;
2559}
2560
2561void helper_msa_min_s_b(CPUMIPSState *env,
2562 uint32_t wd, uint32_t ws, uint32_t wt)
2563{
2564 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2565 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2566 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2567
2568 pwd->b[0] = msa_min_s_df(DF_BYTE, pws->b[0], pwt->b[0]);
2569 pwd->b[1] = msa_min_s_df(DF_BYTE, pws->b[1], pwt->b[1]);
2570 pwd->b[2] = msa_min_s_df(DF_BYTE, pws->b[2], pwt->b[2]);
2571 pwd->b[3] = msa_min_s_df(DF_BYTE, pws->b[3], pwt->b[3]);
2572 pwd->b[4] = msa_min_s_df(DF_BYTE, pws->b[4], pwt->b[4]);
2573 pwd->b[5] = msa_min_s_df(DF_BYTE, pws->b[5], pwt->b[5]);
2574 pwd->b[6] = msa_min_s_df(DF_BYTE, pws->b[6], pwt->b[6]);
2575 pwd->b[7] = msa_min_s_df(DF_BYTE, pws->b[7], pwt->b[7]);
2576 pwd->b[8] = msa_min_s_df(DF_BYTE, pws->b[8], pwt->b[8]);
2577 pwd->b[9] = msa_min_s_df(DF_BYTE, pws->b[9], pwt->b[9]);
2578 pwd->b[10] = msa_min_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
2579 pwd->b[11] = msa_min_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
2580 pwd->b[12] = msa_min_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
2581 pwd->b[13] = msa_min_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
2582 pwd->b[14] = msa_min_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
2583 pwd->b[15] = msa_min_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
2584}
2585
2586void helper_msa_min_s_h(CPUMIPSState *env,
2587 uint32_t wd, uint32_t ws, uint32_t wt)
2588{
2589 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2590 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2591 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2592
2593 pwd->h[0] = msa_min_s_df(DF_HALF, pws->h[0], pwt->h[0]);
2594 pwd->h[1] = msa_min_s_df(DF_HALF, pws->h[1], pwt->h[1]);
2595 pwd->h[2] = msa_min_s_df(DF_HALF, pws->h[2], pwt->h[2]);
2596 pwd->h[3] = msa_min_s_df(DF_HALF, pws->h[3], pwt->h[3]);
2597 pwd->h[4] = msa_min_s_df(DF_HALF, pws->h[4], pwt->h[4]);
2598 pwd->h[5] = msa_min_s_df(DF_HALF, pws->h[5], pwt->h[5]);
2599 pwd->h[6] = msa_min_s_df(DF_HALF, pws->h[6], pwt->h[6]);
2600 pwd->h[7] = msa_min_s_df(DF_HALF, pws->h[7], pwt->h[7]);
2601}
2602
2603void helper_msa_min_s_w(CPUMIPSState *env,
2604 uint32_t wd, uint32_t ws, uint32_t wt)
2605{
2606 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2607 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2608 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2609
2610 pwd->w[0] = msa_min_s_df(DF_WORD, pws->w[0], pwt->w[0]);
2611 pwd->w[1] = msa_min_s_df(DF_WORD, pws->w[1], pwt->w[1]);
2612 pwd->w[2] = msa_min_s_df(DF_WORD, pws->w[2], pwt->w[2]);
2613 pwd->w[3] = msa_min_s_df(DF_WORD, pws->w[3], pwt->w[3]);
2614}
2615
2616void helper_msa_min_s_d(CPUMIPSState *env,
2617 uint32_t wd, uint32_t ws, uint32_t wt)
2618{
2619 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2620 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2621 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2622
2623 pwd->d[0] = msa_min_s_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
2624 pwd->d[1] = msa_min_s_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
2625}
2626
2627
2628static inline int64_t msa_min_u_df(uint32_t df, int64_t arg1, int64_t arg2)
2629{
2630 uint64_t u_arg1 = UNSIGNED(arg1, df);
2631 uint64_t u_arg2 = UNSIGNED(arg2, df);
2632 return u_arg1 < u_arg2 ? arg1 : arg2;
2633}
2634
2635void helper_msa_min_u_b(CPUMIPSState *env,
2636 uint32_t wd, uint32_t ws, uint32_t wt)
2637{
2638 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2639 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2640 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2641
2642 pwd->b[0] = msa_min_u_df(DF_BYTE, pws->b[0], pwt->b[0]);
2643 pwd->b[1] = msa_min_u_df(DF_BYTE, pws->b[1], pwt->b[1]);
2644 pwd->b[2] = msa_min_u_df(DF_BYTE, pws->b[2], pwt->b[2]);
2645 pwd->b[3] = msa_min_u_df(DF_BYTE, pws->b[3], pwt->b[3]);
2646 pwd->b[4] = msa_min_u_df(DF_BYTE, pws->b[4], pwt->b[4]);
2647 pwd->b[5] = msa_min_u_df(DF_BYTE, pws->b[5], pwt->b[5]);
2648 pwd->b[6] = msa_min_u_df(DF_BYTE, pws->b[6], pwt->b[6]);
2649 pwd->b[7] = msa_min_u_df(DF_BYTE, pws->b[7], pwt->b[7]);
2650 pwd->b[8] = msa_min_u_df(DF_BYTE, pws->b[8], pwt->b[8]);
2651 pwd->b[9] = msa_min_u_df(DF_BYTE, pws->b[9], pwt->b[9]);
2652 pwd->b[10] = msa_min_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
2653 pwd->b[11] = msa_min_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
2654 pwd->b[12] = msa_min_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
2655 pwd->b[13] = msa_min_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
2656 pwd->b[14] = msa_min_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
2657 pwd->b[15] = msa_min_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
2658}
2659
2660void helper_msa_min_u_h(CPUMIPSState *env,
2661 uint32_t wd, uint32_t ws, uint32_t wt)
2662{
2663 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2664 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2665 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2666
2667 pwd->h[0] = msa_min_u_df(DF_HALF, pws->h[0], pwt->h[0]);
2668 pwd->h[1] = msa_min_u_df(DF_HALF, pws->h[1], pwt->h[1]);
2669 pwd->h[2] = msa_min_u_df(DF_HALF, pws->h[2], pwt->h[2]);
2670 pwd->h[3] = msa_min_u_df(DF_HALF, pws->h[3], pwt->h[3]);
2671 pwd->h[4] = msa_min_u_df(DF_HALF, pws->h[4], pwt->h[4]);
2672 pwd->h[5] = msa_min_u_df(DF_HALF, pws->h[5], pwt->h[5]);
2673 pwd->h[6] = msa_min_u_df(DF_HALF, pws->h[6], pwt->h[6]);
2674 pwd->h[7] = msa_min_u_df(DF_HALF, pws->h[7], pwt->h[7]);
2675}
2676
2677void helper_msa_min_u_w(CPUMIPSState *env,
2678 uint32_t wd, uint32_t ws, uint32_t wt)
2679{
2680 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2681 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2682 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2683
2684 pwd->w[0] = msa_min_u_df(DF_WORD, pws->w[0], pwt->w[0]);
2685 pwd->w[1] = msa_min_u_df(DF_WORD, pws->w[1], pwt->w[1]);
2686 pwd->w[2] = msa_min_u_df(DF_WORD, pws->w[2], pwt->w[2]);
2687 pwd->w[3] = msa_min_u_df(DF_WORD, pws->w[3], pwt->w[3]);
2688}
2689
2690void helper_msa_min_u_d(CPUMIPSState *env,
2691 uint32_t wd, uint32_t ws, uint32_t wt)
2692{
2693 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2694 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2695 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2696
2697 pwd->d[0] = msa_min_u_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
2698 pwd->d[1] = msa_min_u_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
2699}
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718static inline int64_t msa_mod_s_df(uint32_t df, int64_t arg1, int64_t arg2)
2719{
2720 if (arg1 == DF_MIN_INT(df) && arg2 == -1) {
2721 return 0;
2722 }
2723 return arg2 ? arg1 % arg2 : arg1;
2724}
2725
2726void helper_msa_mod_s_b(CPUMIPSState *env,
2727 uint32_t wd, uint32_t ws, uint32_t wt)
2728{
2729 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2730 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2731 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2732
2733 pwd->b[0] = msa_mod_s_df(DF_BYTE, pws->b[0], pwt->b[0]);
2734 pwd->b[1] = msa_mod_s_df(DF_BYTE, pws->b[1], pwt->b[1]);
2735 pwd->b[2] = msa_mod_s_df(DF_BYTE, pws->b[2], pwt->b[2]);
2736 pwd->b[3] = msa_mod_s_df(DF_BYTE, pws->b[3], pwt->b[3]);
2737 pwd->b[4] = msa_mod_s_df(DF_BYTE, pws->b[4], pwt->b[4]);
2738 pwd->b[5] = msa_mod_s_df(DF_BYTE, pws->b[5], pwt->b[5]);
2739 pwd->b[6] = msa_mod_s_df(DF_BYTE, pws->b[6], pwt->b[6]);
2740 pwd->b[7] = msa_mod_s_df(DF_BYTE, pws->b[7], pwt->b[7]);
2741 pwd->b[8] = msa_mod_s_df(DF_BYTE, pws->b[8], pwt->b[8]);
2742 pwd->b[9] = msa_mod_s_df(DF_BYTE, pws->b[9], pwt->b[9]);
2743 pwd->b[10] = msa_mod_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
2744 pwd->b[11] = msa_mod_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
2745 pwd->b[12] = msa_mod_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
2746 pwd->b[13] = msa_mod_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
2747 pwd->b[14] = msa_mod_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
2748 pwd->b[15] = msa_mod_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
2749}
2750
2751void helper_msa_mod_s_h(CPUMIPSState *env,
2752 uint32_t wd, uint32_t ws, uint32_t wt)
2753{
2754 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2755 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2756 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2757
2758 pwd->h[0] = msa_mod_s_df(DF_HALF, pws->h[0], pwt->h[0]);
2759 pwd->h[1] = msa_mod_s_df(DF_HALF, pws->h[1], pwt->h[1]);
2760 pwd->h[2] = msa_mod_s_df(DF_HALF, pws->h[2], pwt->h[2]);
2761 pwd->h[3] = msa_mod_s_df(DF_HALF, pws->h[3], pwt->h[3]);
2762 pwd->h[4] = msa_mod_s_df(DF_HALF, pws->h[4], pwt->h[4]);
2763 pwd->h[5] = msa_mod_s_df(DF_HALF, pws->h[5], pwt->h[5]);
2764 pwd->h[6] = msa_mod_s_df(DF_HALF, pws->h[6], pwt->h[6]);
2765 pwd->h[7] = msa_mod_s_df(DF_HALF, pws->h[7], pwt->h[7]);
2766}
2767
2768void helper_msa_mod_s_w(CPUMIPSState *env,
2769 uint32_t wd, uint32_t ws, uint32_t wt)
2770{
2771 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2772 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2773 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2774
2775 pwd->w[0] = msa_mod_s_df(DF_WORD, pws->w[0], pwt->w[0]);
2776 pwd->w[1] = msa_mod_s_df(DF_WORD, pws->w[1], pwt->w[1]);
2777 pwd->w[2] = msa_mod_s_df(DF_WORD, pws->w[2], pwt->w[2]);
2778 pwd->w[3] = msa_mod_s_df(DF_WORD, pws->w[3], pwt->w[3]);
2779}
2780
2781void helper_msa_mod_s_d(CPUMIPSState *env,
2782 uint32_t wd, uint32_t ws, uint32_t wt)
2783{
2784 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2785 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2786 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2787
2788 pwd->d[0] = msa_mod_s_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
2789 pwd->d[1] = msa_mod_s_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
2790}
2791
2792static inline int64_t msa_mod_u_df(uint32_t df, int64_t arg1, int64_t arg2)
2793{
2794 uint64_t u_arg1 = UNSIGNED(arg1, df);
2795 uint64_t u_arg2 = UNSIGNED(arg2, df);
2796 return u_arg2 ? u_arg1 % u_arg2 : u_arg1;
2797}
2798
2799void helper_msa_mod_u_b(CPUMIPSState *env,
2800 uint32_t wd, uint32_t ws, uint32_t wt)
2801{
2802 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2803 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2804 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2805
2806 pwd->b[0] = msa_mod_u_df(DF_BYTE, pws->b[0], pwt->b[0]);
2807 pwd->b[1] = msa_mod_u_df(DF_BYTE, pws->b[1], pwt->b[1]);
2808 pwd->b[2] = msa_mod_u_df(DF_BYTE, pws->b[2], pwt->b[2]);
2809 pwd->b[3] = msa_mod_u_df(DF_BYTE, pws->b[3], pwt->b[3]);
2810 pwd->b[4] = msa_mod_u_df(DF_BYTE, pws->b[4], pwt->b[4]);
2811 pwd->b[5] = msa_mod_u_df(DF_BYTE, pws->b[5], pwt->b[5]);
2812 pwd->b[6] = msa_mod_u_df(DF_BYTE, pws->b[6], pwt->b[6]);
2813 pwd->b[7] = msa_mod_u_df(DF_BYTE, pws->b[7], pwt->b[7]);
2814 pwd->b[8] = msa_mod_u_df(DF_BYTE, pws->b[8], pwt->b[8]);
2815 pwd->b[9] = msa_mod_u_df(DF_BYTE, pws->b[9], pwt->b[9]);
2816 pwd->b[10] = msa_mod_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
2817 pwd->b[11] = msa_mod_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
2818 pwd->b[12] = msa_mod_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
2819 pwd->b[13] = msa_mod_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
2820 pwd->b[14] = msa_mod_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
2821 pwd->b[15] = msa_mod_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
2822}
2823
2824void helper_msa_mod_u_h(CPUMIPSState *env,
2825 uint32_t wd, uint32_t ws, uint32_t wt)
2826{
2827 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2828 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2829 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2830
2831 pwd->h[0] = msa_mod_u_df(DF_HALF, pws->h[0], pwt->h[0]);
2832 pwd->h[1] = msa_mod_u_df(DF_HALF, pws->h[1], pwt->h[1]);
2833 pwd->h[2] = msa_mod_u_df(DF_HALF, pws->h[2], pwt->h[2]);
2834 pwd->h[3] = msa_mod_u_df(DF_HALF, pws->h[3], pwt->h[3]);
2835 pwd->h[4] = msa_mod_u_df(DF_HALF, pws->h[4], pwt->h[4]);
2836 pwd->h[5] = msa_mod_u_df(DF_HALF, pws->h[5], pwt->h[5]);
2837 pwd->h[6] = msa_mod_u_df(DF_HALF, pws->h[6], pwt->h[6]);
2838 pwd->h[7] = msa_mod_u_df(DF_HALF, pws->h[7], pwt->h[7]);
2839}
2840
2841void helper_msa_mod_u_w(CPUMIPSState *env,
2842 uint32_t wd, uint32_t ws, uint32_t wt)
2843{
2844 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2845 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2846 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2847
2848 pwd->w[0] = msa_mod_u_df(DF_WORD, pws->w[0], pwt->w[0]);
2849 pwd->w[1] = msa_mod_u_df(DF_WORD, pws->w[1], pwt->w[1]);
2850 pwd->w[2] = msa_mod_u_df(DF_WORD, pws->w[2], pwt->w[2]);
2851 pwd->w[3] = msa_mod_u_df(DF_WORD, pws->w[3], pwt->w[3]);
2852}
2853
2854void helper_msa_mod_u_d(CPUMIPSState *env,
2855 uint32_t wd, uint32_t ws, uint32_t wt)
2856{
2857 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2858 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2859 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2860
2861 pwd->d[0] = msa_mod_u_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
2862 pwd->d[1] = msa_mod_u_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
2863}
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932static inline int64_t msa_asub_s_df(uint32_t df, int64_t arg1, int64_t arg2)
2933{
2934
2935 return (arg1 < arg2) ?
2936 (uint64_t)(arg2 - arg1) : (uint64_t)(arg1 - arg2);
2937}
2938
2939void helper_msa_asub_s_b(CPUMIPSState *env,
2940 uint32_t wd, uint32_t ws, uint32_t wt)
2941{
2942 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2943 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2944 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2945
2946 pwd->b[0] = msa_asub_s_df(DF_BYTE, pws->b[0], pwt->b[0]);
2947 pwd->b[1] = msa_asub_s_df(DF_BYTE, pws->b[1], pwt->b[1]);
2948 pwd->b[2] = msa_asub_s_df(DF_BYTE, pws->b[2], pwt->b[2]);
2949 pwd->b[3] = msa_asub_s_df(DF_BYTE, pws->b[3], pwt->b[3]);
2950 pwd->b[4] = msa_asub_s_df(DF_BYTE, pws->b[4], pwt->b[4]);
2951 pwd->b[5] = msa_asub_s_df(DF_BYTE, pws->b[5], pwt->b[5]);
2952 pwd->b[6] = msa_asub_s_df(DF_BYTE, pws->b[6], pwt->b[6]);
2953 pwd->b[7] = msa_asub_s_df(DF_BYTE, pws->b[7], pwt->b[7]);
2954 pwd->b[8] = msa_asub_s_df(DF_BYTE, pws->b[8], pwt->b[8]);
2955 pwd->b[9] = msa_asub_s_df(DF_BYTE, pws->b[9], pwt->b[9]);
2956 pwd->b[10] = msa_asub_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
2957 pwd->b[11] = msa_asub_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
2958 pwd->b[12] = msa_asub_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
2959 pwd->b[13] = msa_asub_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
2960 pwd->b[14] = msa_asub_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
2961 pwd->b[15] = msa_asub_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
2962}
2963
2964void helper_msa_asub_s_h(CPUMIPSState *env,
2965 uint32_t wd, uint32_t ws, uint32_t wt)
2966{
2967 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2968 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2969 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2970
2971 pwd->h[0] = msa_asub_s_df(DF_HALF, pws->h[0], pwt->h[0]);
2972 pwd->h[1] = msa_asub_s_df(DF_HALF, pws->h[1], pwt->h[1]);
2973 pwd->h[2] = msa_asub_s_df(DF_HALF, pws->h[2], pwt->h[2]);
2974 pwd->h[3] = msa_asub_s_df(DF_HALF, pws->h[3], pwt->h[3]);
2975 pwd->h[4] = msa_asub_s_df(DF_HALF, pws->h[4], pwt->h[4]);
2976 pwd->h[5] = msa_asub_s_df(DF_HALF, pws->h[5], pwt->h[5]);
2977 pwd->h[6] = msa_asub_s_df(DF_HALF, pws->h[6], pwt->h[6]);
2978 pwd->h[7] = msa_asub_s_df(DF_HALF, pws->h[7], pwt->h[7]);
2979}
2980
2981void helper_msa_asub_s_w(CPUMIPSState *env,
2982 uint32_t wd, uint32_t ws, uint32_t wt)
2983{
2984 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2985 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2986 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2987
2988 pwd->w[0] = msa_asub_s_df(DF_WORD, pws->w[0], pwt->w[0]);
2989 pwd->w[1] = msa_asub_s_df(DF_WORD, pws->w[1], pwt->w[1]);
2990 pwd->w[2] = msa_asub_s_df(DF_WORD, pws->w[2], pwt->w[2]);
2991 pwd->w[3] = msa_asub_s_df(DF_WORD, pws->w[3], pwt->w[3]);
2992}
2993
2994void helper_msa_asub_s_d(CPUMIPSState *env,
2995 uint32_t wd, uint32_t ws, uint32_t wt)
2996{
2997 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2998 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2999 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3000
3001 pwd->d[0] = msa_asub_s_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
3002 pwd->d[1] = msa_asub_s_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
3003}
3004
3005
3006static inline uint64_t msa_asub_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
3007{
3008 uint64_t u_arg1 = UNSIGNED(arg1, df);
3009 uint64_t u_arg2 = UNSIGNED(arg2, df);
3010
3011 return (u_arg1 < u_arg2) ?
3012 (uint64_t)(u_arg2 - u_arg1) : (uint64_t)(u_arg1 - u_arg2);
3013}
3014
3015void helper_msa_asub_u_b(CPUMIPSState *env,
3016 uint32_t wd, uint32_t ws, uint32_t wt)
3017{
3018 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3019 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3020 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3021
3022 pwd->b[0] = msa_asub_u_df(DF_BYTE, pws->b[0], pwt->b[0]);
3023 pwd->b[1] = msa_asub_u_df(DF_BYTE, pws->b[1], pwt->b[1]);
3024 pwd->b[2] = msa_asub_u_df(DF_BYTE, pws->b[2], pwt->b[2]);
3025 pwd->b[3] = msa_asub_u_df(DF_BYTE, pws->b[3], pwt->b[3]);
3026 pwd->b[4] = msa_asub_u_df(DF_BYTE, pws->b[4], pwt->b[4]);
3027 pwd->b[5] = msa_asub_u_df(DF_BYTE, pws->b[5], pwt->b[5]);
3028 pwd->b[6] = msa_asub_u_df(DF_BYTE, pws->b[6], pwt->b[6]);
3029 pwd->b[7] = msa_asub_u_df(DF_BYTE, pws->b[7], pwt->b[7]);
3030 pwd->b[8] = msa_asub_u_df(DF_BYTE, pws->b[8], pwt->b[8]);
3031 pwd->b[9] = msa_asub_u_df(DF_BYTE, pws->b[9], pwt->b[9]);
3032 pwd->b[10] = msa_asub_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
3033 pwd->b[11] = msa_asub_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
3034 pwd->b[12] = msa_asub_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
3035 pwd->b[13] = msa_asub_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
3036 pwd->b[14] = msa_asub_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
3037 pwd->b[15] = msa_asub_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
3038}
3039
3040void helper_msa_asub_u_h(CPUMIPSState *env,
3041 uint32_t wd, uint32_t ws, uint32_t wt)
3042{
3043 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3044 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3045 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3046
3047 pwd->h[0] = msa_asub_u_df(DF_HALF, pws->h[0], pwt->h[0]);
3048 pwd->h[1] = msa_asub_u_df(DF_HALF, pws->h[1], pwt->h[1]);
3049 pwd->h[2] = msa_asub_u_df(DF_HALF, pws->h[2], pwt->h[2]);
3050 pwd->h[3] = msa_asub_u_df(DF_HALF, pws->h[3], pwt->h[3]);
3051 pwd->h[4] = msa_asub_u_df(DF_HALF, pws->h[4], pwt->h[4]);
3052 pwd->h[5] = msa_asub_u_df(DF_HALF, pws->h[5], pwt->h[5]);
3053 pwd->h[6] = msa_asub_u_df(DF_HALF, pws->h[6], pwt->h[6]);
3054 pwd->h[7] = msa_asub_u_df(DF_HALF, pws->h[7], pwt->h[7]);
3055}
3056
3057void helper_msa_asub_u_w(CPUMIPSState *env,
3058 uint32_t wd, uint32_t ws, uint32_t wt)
3059{
3060 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3061 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3062 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3063
3064 pwd->w[0] = msa_asub_u_df(DF_WORD, pws->w[0], pwt->w[0]);
3065 pwd->w[1] = msa_asub_u_df(DF_WORD, pws->w[1], pwt->w[1]);
3066 pwd->w[2] = msa_asub_u_df(DF_WORD, pws->w[2], pwt->w[2]);
3067 pwd->w[3] = msa_asub_u_df(DF_WORD, pws->w[3], pwt->w[3]);
3068}
3069
3070void helper_msa_asub_u_d(CPUMIPSState *env,
3071 uint32_t wd, uint32_t ws, uint32_t wt)
3072{
3073 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3074 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3075 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3076
3077 pwd->d[0] = msa_asub_u_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
3078 pwd->d[1] = msa_asub_u_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
3079}
3080
3081
3082
3083
3084
3085static inline int64_t msa_hsub_s_df(uint32_t df, int64_t arg1, int64_t arg2)
3086{
3087 return SIGNED_ODD(arg1, df) - SIGNED_EVEN(arg2, df);
3088}
3089
3090void helper_msa_hsub_s_h(CPUMIPSState *env,
3091 uint32_t wd, uint32_t ws, uint32_t wt)
3092{
3093 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3094 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3095 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3096
3097 pwd->h[0] = msa_hsub_s_df(DF_HALF, pws->h[0], pwt->h[0]);
3098 pwd->h[1] = msa_hsub_s_df(DF_HALF, pws->h[1], pwt->h[1]);
3099 pwd->h[2] = msa_hsub_s_df(DF_HALF, pws->h[2], pwt->h[2]);
3100 pwd->h[3] = msa_hsub_s_df(DF_HALF, pws->h[3], pwt->h[3]);
3101 pwd->h[4] = msa_hsub_s_df(DF_HALF, pws->h[4], pwt->h[4]);
3102 pwd->h[5] = msa_hsub_s_df(DF_HALF, pws->h[5], pwt->h[5]);
3103 pwd->h[6] = msa_hsub_s_df(DF_HALF, pws->h[6], pwt->h[6]);
3104 pwd->h[7] = msa_hsub_s_df(DF_HALF, pws->h[7], pwt->h[7]);
3105}
3106
3107void helper_msa_hsub_s_w(CPUMIPSState *env,
3108 uint32_t wd, uint32_t ws, uint32_t wt)
3109{
3110 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3111 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3112 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3113
3114 pwd->w[0] = msa_hsub_s_df(DF_WORD, pws->w[0], pwt->w[0]);
3115 pwd->w[1] = msa_hsub_s_df(DF_WORD, pws->w[1], pwt->w[1]);
3116 pwd->w[2] = msa_hsub_s_df(DF_WORD, pws->w[2], pwt->w[2]);
3117 pwd->w[3] = msa_hsub_s_df(DF_WORD, pws->w[3], pwt->w[3]);
3118}
3119
3120void helper_msa_hsub_s_d(CPUMIPSState *env,
3121 uint32_t wd, uint32_t ws, uint32_t wt)
3122{
3123 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3124 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3125 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3126
3127 pwd->d[0] = msa_hsub_s_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
3128 pwd->d[1] = msa_hsub_s_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
3129}
3130
3131
3132static inline int64_t msa_hsub_u_df(uint32_t df, int64_t arg1, int64_t arg2)
3133{
3134 return UNSIGNED_ODD(arg1, df) - UNSIGNED_EVEN(arg2, df);
3135}
3136
3137void helper_msa_hsub_u_h(CPUMIPSState *env,
3138 uint32_t wd, uint32_t ws, uint32_t wt)
3139{
3140 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3141 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3142 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3143
3144 pwd->h[0] = msa_hsub_u_df(DF_HALF, pws->h[0], pwt->h[0]);
3145 pwd->h[1] = msa_hsub_u_df(DF_HALF, pws->h[1], pwt->h[1]);
3146 pwd->h[2] = msa_hsub_u_df(DF_HALF, pws->h[2], pwt->h[2]);
3147 pwd->h[3] = msa_hsub_u_df(DF_HALF, pws->h[3], pwt->h[3]);
3148 pwd->h[4] = msa_hsub_u_df(DF_HALF, pws->h[4], pwt->h[4]);
3149 pwd->h[5] = msa_hsub_u_df(DF_HALF, pws->h[5], pwt->h[5]);
3150 pwd->h[6] = msa_hsub_u_df(DF_HALF, pws->h[6], pwt->h[6]);
3151 pwd->h[7] = msa_hsub_u_df(DF_HALF, pws->h[7], pwt->h[7]);
3152}
3153
3154void helper_msa_hsub_u_w(CPUMIPSState *env,
3155 uint32_t wd, uint32_t ws, uint32_t wt)
3156{
3157 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3158 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3159 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3160
3161 pwd->w[0] = msa_hsub_u_df(DF_WORD, pws->w[0], pwt->w[0]);
3162 pwd->w[1] = msa_hsub_u_df(DF_WORD, pws->w[1], pwt->w[1]);
3163 pwd->w[2] = msa_hsub_u_df(DF_WORD, pws->w[2], pwt->w[2]);
3164 pwd->w[3] = msa_hsub_u_df(DF_WORD, pws->w[3], pwt->w[3]);
3165}
3166
3167void helper_msa_hsub_u_d(CPUMIPSState *env,
3168 uint32_t wd, uint32_t ws, uint32_t wt)
3169{
3170 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3171 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3172 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3173
3174 pwd->d[0] = msa_hsub_u_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
3175 pwd->d[1] = msa_hsub_u_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
3176}
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204void helper_msa_ilvev_b(CPUMIPSState *env,
3205 uint32_t wd, uint32_t ws, uint32_t wt)
3206{
3207 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3208 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3209 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3210
3211#if defined(HOST_WORDS_BIGENDIAN)
3212 pwd->b[8] = pws->b[9];
3213 pwd->b[9] = pwt->b[9];
3214 pwd->b[10] = pws->b[11];
3215 pwd->b[11] = pwt->b[11];
3216 pwd->b[12] = pws->b[13];
3217 pwd->b[13] = pwt->b[13];
3218 pwd->b[14] = pws->b[15];
3219 pwd->b[15] = pwt->b[15];
3220 pwd->b[0] = pws->b[1];
3221 pwd->b[1] = pwt->b[1];
3222 pwd->b[2] = pws->b[3];
3223 pwd->b[3] = pwt->b[3];
3224 pwd->b[4] = pws->b[5];
3225 pwd->b[5] = pwt->b[5];
3226 pwd->b[6] = pws->b[7];
3227 pwd->b[7] = pwt->b[7];
3228#else
3229 pwd->b[15] = pws->b[14];
3230 pwd->b[14] = pwt->b[14];
3231 pwd->b[13] = pws->b[12];
3232 pwd->b[12] = pwt->b[12];
3233 pwd->b[11] = pws->b[10];
3234 pwd->b[10] = pwt->b[10];
3235 pwd->b[9] = pws->b[8];
3236 pwd->b[8] = pwt->b[8];
3237 pwd->b[7] = pws->b[6];
3238 pwd->b[6] = pwt->b[6];
3239 pwd->b[5] = pws->b[4];
3240 pwd->b[4] = pwt->b[4];
3241 pwd->b[3] = pws->b[2];
3242 pwd->b[2] = pwt->b[2];
3243 pwd->b[1] = pws->b[0];
3244 pwd->b[0] = pwt->b[0];
3245#endif
3246}
3247
3248void helper_msa_ilvev_h(CPUMIPSState *env,
3249 uint32_t wd, uint32_t ws, uint32_t wt)
3250{
3251 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3252 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3253 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3254
3255#if defined(HOST_WORDS_BIGENDIAN)
3256 pwd->h[4] = pws->h[5];
3257 pwd->h[5] = pwt->h[5];
3258 pwd->h[6] = pws->h[7];
3259 pwd->h[7] = pwt->h[7];
3260 pwd->h[0] = pws->h[1];
3261 pwd->h[1] = pwt->h[1];
3262 pwd->h[2] = pws->h[3];
3263 pwd->h[3] = pwt->h[3];
3264#else
3265 pwd->h[7] = pws->h[6];
3266 pwd->h[6] = pwt->h[6];
3267 pwd->h[5] = pws->h[4];
3268 pwd->h[4] = pwt->h[4];
3269 pwd->h[3] = pws->h[2];
3270 pwd->h[2] = pwt->h[2];
3271 pwd->h[1] = pws->h[0];
3272 pwd->h[0] = pwt->h[0];
3273#endif
3274}
3275
3276void helper_msa_ilvev_w(CPUMIPSState *env,
3277 uint32_t wd, uint32_t ws, uint32_t wt)
3278{
3279 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3280 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3281 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3282
3283#if defined(HOST_WORDS_BIGENDIAN)
3284 pwd->w[2] = pws->w[3];
3285 pwd->w[3] = pwt->w[3];
3286 pwd->w[0] = pws->w[1];
3287 pwd->w[1] = pwt->w[1];
3288#else
3289 pwd->w[3] = pws->w[2];
3290 pwd->w[2] = pwt->w[2];
3291 pwd->w[1] = pws->w[0];
3292 pwd->w[0] = pwt->w[0];
3293#endif
3294}
3295
3296void helper_msa_ilvev_d(CPUMIPSState *env,
3297 uint32_t wd, uint32_t ws, uint32_t wt)
3298{
3299 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3300 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3301 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3302
3303 pwd->d[1] = pws->d[0];
3304 pwd->d[0] = pwt->d[0];
3305}
3306
3307
3308void helper_msa_ilvod_b(CPUMIPSState *env,
3309 uint32_t wd, uint32_t ws, uint32_t wt)
3310{
3311 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3312 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3313 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3314
3315#if defined(HOST_WORDS_BIGENDIAN)
3316 pwd->b[7] = pwt->b[6];
3317 pwd->b[6] = pws->b[6];
3318 pwd->b[5] = pwt->b[4];
3319 pwd->b[4] = pws->b[4];
3320 pwd->b[3] = pwt->b[2];
3321 pwd->b[2] = pws->b[2];
3322 pwd->b[1] = pwt->b[0];
3323 pwd->b[0] = pws->b[0];
3324 pwd->b[15] = pwt->b[14];
3325 pwd->b[14] = pws->b[14];
3326 pwd->b[13] = pwt->b[12];
3327 pwd->b[12] = pws->b[12];
3328 pwd->b[11] = pwt->b[10];
3329 pwd->b[10] = pws->b[10];
3330 pwd->b[9] = pwt->b[8];
3331 pwd->b[8] = pws->b[8];
3332#else
3333 pwd->b[0] = pwt->b[1];
3334 pwd->b[1] = pws->b[1];
3335 pwd->b[2] = pwt->b[3];
3336 pwd->b[3] = pws->b[3];
3337 pwd->b[4] = pwt->b[5];
3338 pwd->b[5] = pws->b[5];
3339 pwd->b[6] = pwt->b[7];
3340 pwd->b[7] = pws->b[7];
3341 pwd->b[8] = pwt->b[9];
3342 pwd->b[9] = pws->b[9];
3343 pwd->b[10] = pwt->b[11];
3344 pwd->b[11] = pws->b[11];
3345 pwd->b[12] = pwt->b[13];
3346 pwd->b[13] = pws->b[13];
3347 pwd->b[14] = pwt->b[15];
3348 pwd->b[15] = pws->b[15];
3349#endif
3350}
3351
3352void helper_msa_ilvod_h(CPUMIPSState *env,
3353 uint32_t wd, uint32_t ws, uint32_t wt)
3354{
3355 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3356 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3357 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3358
3359#if defined(HOST_WORDS_BIGENDIAN)
3360 pwd->h[3] = pwt->h[2];
3361 pwd->h[2] = pws->h[2];
3362 pwd->h[1] = pwt->h[0];
3363 pwd->h[0] = pws->h[0];
3364 pwd->h[7] = pwt->h[6];
3365 pwd->h[6] = pws->h[6];
3366 pwd->h[5] = pwt->h[4];
3367 pwd->h[4] = pws->h[4];
3368#else
3369 pwd->h[0] = pwt->h[1];
3370 pwd->h[1] = pws->h[1];
3371 pwd->h[2] = pwt->h[3];
3372 pwd->h[3] = pws->h[3];
3373 pwd->h[4] = pwt->h[5];
3374 pwd->h[5] = pws->h[5];
3375 pwd->h[6] = pwt->h[7];
3376 pwd->h[7] = pws->h[7];
3377#endif
3378}
3379
3380void helper_msa_ilvod_w(CPUMIPSState *env,
3381 uint32_t wd, uint32_t ws, uint32_t wt)
3382{
3383 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3384 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3385 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3386
3387#if defined(HOST_WORDS_BIGENDIAN)
3388 pwd->w[1] = pwt->w[0];
3389 pwd->w[0] = pws->w[0];
3390 pwd->w[3] = pwt->w[2];
3391 pwd->w[2] = pws->w[2];
3392#else
3393 pwd->w[0] = pwt->w[1];
3394 pwd->w[1] = pws->w[1];
3395 pwd->w[2] = pwt->w[3];
3396 pwd->w[3] = pws->w[3];
3397#endif
3398}
3399
3400void helper_msa_ilvod_d(CPUMIPSState *env,
3401 uint32_t wd, uint32_t ws, uint32_t wt)
3402{
3403 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3404 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3405 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3406
3407 pwd->d[0] = pwt->d[1];
3408 pwd->d[1] = pws->d[1];
3409}
3410
3411
3412void helper_msa_ilvl_b(CPUMIPSState *env,
3413 uint32_t wd, uint32_t ws, uint32_t wt)
3414{
3415 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3416 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3417 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3418
3419#if defined(HOST_WORDS_BIGENDIAN)
3420 pwd->b[7] = pwt->b[15];
3421 pwd->b[6] = pws->b[15];
3422 pwd->b[5] = pwt->b[14];
3423 pwd->b[4] = pws->b[14];
3424 pwd->b[3] = pwt->b[13];
3425 pwd->b[2] = pws->b[13];
3426 pwd->b[1] = pwt->b[12];
3427 pwd->b[0] = pws->b[12];
3428 pwd->b[15] = pwt->b[11];
3429 pwd->b[14] = pws->b[11];
3430 pwd->b[13] = pwt->b[10];
3431 pwd->b[12] = pws->b[10];
3432 pwd->b[11] = pwt->b[9];
3433 pwd->b[10] = pws->b[9];
3434 pwd->b[9] = pwt->b[8];
3435 pwd->b[8] = pws->b[8];
3436#else
3437 pwd->b[0] = pwt->b[8];
3438 pwd->b[1] = pws->b[8];
3439 pwd->b[2] = pwt->b[9];
3440 pwd->b[3] = pws->b[9];
3441 pwd->b[4] = pwt->b[10];
3442 pwd->b[5] = pws->b[10];
3443 pwd->b[6] = pwt->b[11];
3444 pwd->b[7] = pws->b[11];
3445 pwd->b[8] = pwt->b[12];
3446 pwd->b[9] = pws->b[12];
3447 pwd->b[10] = pwt->b[13];
3448 pwd->b[11] = pws->b[13];
3449 pwd->b[12] = pwt->b[14];
3450 pwd->b[13] = pws->b[14];
3451 pwd->b[14] = pwt->b[15];
3452 pwd->b[15] = pws->b[15];
3453#endif
3454}
3455
3456void helper_msa_ilvl_h(CPUMIPSState *env,
3457 uint32_t wd, uint32_t ws, uint32_t wt)
3458{
3459 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3460 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3461 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3462
3463#if defined(HOST_WORDS_BIGENDIAN)
3464 pwd->h[3] = pwt->h[7];
3465 pwd->h[2] = pws->h[7];
3466 pwd->h[1] = pwt->h[6];
3467 pwd->h[0] = pws->h[6];
3468 pwd->h[7] = pwt->h[5];
3469 pwd->h[6] = pws->h[5];
3470 pwd->h[5] = pwt->h[4];
3471 pwd->h[4] = pws->h[4];
3472#else
3473 pwd->h[0] = pwt->h[4];
3474 pwd->h[1] = pws->h[4];
3475 pwd->h[2] = pwt->h[5];
3476 pwd->h[3] = pws->h[5];
3477 pwd->h[4] = pwt->h[6];
3478 pwd->h[5] = pws->h[6];
3479 pwd->h[6] = pwt->h[7];
3480 pwd->h[7] = pws->h[7];
3481#endif
3482}
3483
3484void helper_msa_ilvl_w(CPUMIPSState *env,
3485 uint32_t wd, uint32_t ws, uint32_t wt)
3486{
3487 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3488 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3489 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3490
3491#if defined(HOST_WORDS_BIGENDIAN)
3492 pwd->w[1] = pwt->w[3];
3493 pwd->w[0] = pws->w[3];
3494 pwd->w[3] = pwt->w[2];
3495 pwd->w[2] = pws->w[2];
3496#else
3497 pwd->w[0] = pwt->w[2];
3498 pwd->w[1] = pws->w[2];
3499 pwd->w[2] = pwt->w[3];
3500 pwd->w[3] = pws->w[3];
3501#endif
3502}
3503
3504void helper_msa_ilvl_d(CPUMIPSState *env,
3505 uint32_t wd, uint32_t ws, uint32_t wt)
3506{
3507 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3508 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3509 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3510
3511 pwd->d[0] = pwt->d[1];
3512 pwd->d[1] = pws->d[1];
3513}
3514
3515
3516void helper_msa_ilvr_b(CPUMIPSState *env,
3517 uint32_t wd, uint32_t ws, uint32_t wt)
3518{
3519 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3520 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3521 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3522
3523#if defined(HOST_WORDS_BIGENDIAN)
3524 pwd->b[8] = pws->b[0];
3525 pwd->b[9] = pwt->b[0];
3526 pwd->b[10] = pws->b[1];
3527 pwd->b[11] = pwt->b[1];
3528 pwd->b[12] = pws->b[2];
3529 pwd->b[13] = pwt->b[2];
3530 pwd->b[14] = pws->b[3];
3531 pwd->b[15] = pwt->b[3];
3532 pwd->b[0] = pws->b[4];
3533 pwd->b[1] = pwt->b[4];
3534 pwd->b[2] = pws->b[5];
3535 pwd->b[3] = pwt->b[5];
3536 pwd->b[4] = pws->b[6];
3537 pwd->b[5] = pwt->b[6];
3538 pwd->b[6] = pws->b[7];
3539 pwd->b[7] = pwt->b[7];
3540#else
3541 pwd->b[15] = pws->b[7];
3542 pwd->b[14] = pwt->b[7];
3543 pwd->b[13] = pws->b[6];
3544 pwd->b[12] = pwt->b[6];
3545 pwd->b[11] = pws->b[5];
3546 pwd->b[10] = pwt->b[5];
3547 pwd->b[9] = pws->b[4];
3548 pwd->b[8] = pwt->b[4];
3549 pwd->b[7] = pws->b[3];
3550 pwd->b[6] = pwt->b[3];
3551 pwd->b[5] = pws->b[2];
3552 pwd->b[4] = pwt->b[2];
3553 pwd->b[3] = pws->b[1];
3554 pwd->b[2] = pwt->b[1];
3555 pwd->b[1] = pws->b[0];
3556 pwd->b[0] = pwt->b[0];
3557#endif
3558}
3559
3560void helper_msa_ilvr_h(CPUMIPSState *env,
3561 uint32_t wd, uint32_t ws, uint32_t wt)
3562{
3563 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3564 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3565 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3566
3567#if defined(HOST_WORDS_BIGENDIAN)
3568 pwd->h[4] = pws->h[0];
3569 pwd->h[5] = pwt->h[0];
3570 pwd->h[6] = pws->h[1];
3571 pwd->h[7] = pwt->h[1];
3572 pwd->h[0] = pws->h[2];
3573 pwd->h[1] = pwt->h[2];
3574 pwd->h[2] = pws->h[3];
3575 pwd->h[3] = pwt->h[3];
3576#else
3577 pwd->h[7] = pws->h[3];
3578 pwd->h[6] = pwt->h[3];
3579 pwd->h[5] = pws->h[2];
3580 pwd->h[4] = pwt->h[2];
3581 pwd->h[3] = pws->h[1];
3582 pwd->h[2] = pwt->h[1];
3583 pwd->h[1] = pws->h[0];
3584 pwd->h[0] = pwt->h[0];
3585#endif
3586}
3587
3588void helper_msa_ilvr_w(CPUMIPSState *env,
3589 uint32_t wd, uint32_t ws, uint32_t wt)
3590{
3591 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3592 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3593 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3594
3595#if defined(HOST_WORDS_BIGENDIAN)
3596 pwd->w[2] = pws->w[0];
3597 pwd->w[3] = pwt->w[0];
3598 pwd->w[0] = pws->w[1];
3599 pwd->w[1] = pwt->w[1];
3600#else
3601 pwd->w[3] = pws->w[1];
3602 pwd->w[2] = pwt->w[1];
3603 pwd->w[1] = pws->w[0];
3604 pwd->w[0] = pwt->w[0];
3605#endif
3606}
3607
3608void helper_msa_ilvr_d(CPUMIPSState *env,
3609 uint32_t wd, uint32_t ws, uint32_t wt)
3610{
3611 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3612 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3613 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3614
3615 pwd->d[1] = pws->d[0];
3616 pwd->d[0] = pwt->d[0];
3617}
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633void helper_msa_and_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
3634{
3635 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3636 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3637 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3638
3639 pwd->d[0] = pws->d[0] & pwt->d[0];
3640 pwd->d[1] = pws->d[1] & pwt->d[1];
3641}
3642
3643void helper_msa_nor_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
3644{
3645 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3646 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3647 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3648
3649 pwd->d[0] = ~(pws->d[0] | pwt->d[0]);
3650 pwd->d[1] = ~(pws->d[1] | pwt->d[1]);
3651}
3652
3653void helper_msa_or_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
3654{
3655 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3656 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3657 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3658
3659 pwd->d[0] = pws->d[0] | pwt->d[0];
3660 pwd->d[1] = pws->d[1] | pwt->d[1];
3661}
3662
3663void helper_msa_xor_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
3664{
3665 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3666 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3667 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3668
3669 pwd->d[0] = pws->d[0] ^ pwt->d[0];
3670 pwd->d[1] = pws->d[1] ^ pwt->d[1];
3671}
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683static inline void msa_move_v(wr_t *pwd, wr_t *pws)
3684{
3685 pwd->d[0] = pws->d[0];
3686 pwd->d[1] = pws->d[1];
3687}
3688
3689void helper_msa_move_v(CPUMIPSState *env, uint32_t wd, uint32_t ws)
3690{
3691 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3692 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3693
3694 msa_move_v(pwd, pws);
3695}
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719void helper_msa_pckev_b(CPUMIPSState *env,
3720 uint32_t wd, uint32_t ws, uint32_t wt)
3721{
3722 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3723 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3724 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3725
3726#if defined(HOST_WORDS_BIGENDIAN)
3727 pwd->b[8] = pws->b[9];
3728 pwd->b[10] = pws->b[13];
3729 pwd->b[12] = pws->b[1];
3730 pwd->b[14] = pws->b[5];
3731 pwd->b[0] = pwt->b[9];
3732 pwd->b[2] = pwt->b[13];
3733 pwd->b[4] = pwt->b[1];
3734 pwd->b[6] = pwt->b[5];
3735 pwd->b[9] = pws->b[11];
3736 pwd->b[13] = pws->b[3];
3737 pwd->b[1] = pwt->b[11];
3738 pwd->b[5] = pwt->b[3];
3739 pwd->b[11] = pws->b[15];
3740 pwd->b[3] = pwt->b[15];
3741 pwd->b[15] = pws->b[7];
3742 pwd->b[7] = pwt->b[7];
3743#else
3744 pwd->b[15] = pws->b[14];
3745 pwd->b[13] = pws->b[10];
3746 pwd->b[11] = pws->b[6];
3747 pwd->b[9] = pws->b[2];
3748 pwd->b[7] = pwt->b[14];
3749 pwd->b[5] = pwt->b[10];
3750 pwd->b[3] = pwt->b[6];
3751 pwd->b[1] = pwt->b[2];
3752 pwd->b[14] = pws->b[12];
3753 pwd->b[10] = pws->b[4];
3754 pwd->b[6] = pwt->b[12];
3755 pwd->b[2] = pwt->b[4];
3756 pwd->b[12] = pws->b[8];
3757 pwd->b[4] = pwt->b[8];
3758 pwd->b[8] = pws->b[0];
3759 pwd->b[0] = pwt->b[0];
3760#endif
3761}
3762
3763void helper_msa_pckev_h(CPUMIPSState *env,
3764 uint32_t wd, uint32_t ws, uint32_t wt)
3765{
3766 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3767 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3768 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3769
3770#if defined(HOST_WORDS_BIGENDIAN)
3771 pwd->h[4] = pws->h[5];
3772 pwd->h[6] = pws->h[1];
3773 pwd->h[0] = pwt->h[5];
3774 pwd->h[2] = pwt->h[1];
3775 pwd->h[5] = pws->h[7];
3776 pwd->h[1] = pwt->h[7];
3777 pwd->h[7] = pws->h[3];
3778 pwd->h[3] = pwt->h[3];
3779#else
3780 pwd->h[7] = pws->h[6];
3781 pwd->h[5] = pws->h[2];
3782 pwd->h[3] = pwt->h[6];
3783 pwd->h[1] = pwt->h[2];
3784 pwd->h[6] = pws->h[4];
3785 pwd->h[2] = pwt->h[4];
3786 pwd->h[4] = pws->h[0];
3787 pwd->h[0] = pwt->h[0];
3788#endif
3789}
3790
3791void helper_msa_pckev_w(CPUMIPSState *env,
3792 uint32_t wd, uint32_t ws, uint32_t wt)
3793{
3794 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3795 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3796 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3797
3798#if defined(HOST_WORDS_BIGENDIAN)
3799 pwd->w[2] = pws->w[3];
3800 pwd->w[0] = pwt->w[3];
3801 pwd->w[3] = pws->w[1];
3802 pwd->w[1] = pwt->w[1];
3803#else
3804 pwd->w[3] = pws->w[2];
3805 pwd->w[1] = pwt->w[2];
3806 pwd->w[2] = pws->w[0];
3807 pwd->w[0] = pwt->w[0];
3808#endif
3809}
3810
3811void helper_msa_pckev_d(CPUMIPSState *env,
3812 uint32_t wd, uint32_t ws, uint32_t wt)
3813{
3814 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3815 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3816 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3817
3818 pwd->d[1] = pws->d[0];
3819 pwd->d[0] = pwt->d[0];
3820}
3821
3822
3823void helper_msa_pckod_b(CPUMIPSState *env,
3824 uint32_t wd, uint32_t ws, uint32_t wt)
3825{
3826 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3827 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3828 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3829
3830#if defined(HOST_WORDS_BIGENDIAN)
3831 pwd->b[7] = pwt->b[6];
3832 pwd->b[5] = pwt->b[2];
3833 pwd->b[3] = pwt->b[14];
3834 pwd->b[1] = pwt->b[10];
3835 pwd->b[15] = pws->b[6];
3836 pwd->b[13] = pws->b[2];
3837 pwd->b[11] = pws->b[14];
3838 pwd->b[9] = pws->b[10];
3839 pwd->b[6] = pwt->b[4];
3840 pwd->b[2] = pwt->b[12];
3841 pwd->b[14] = pws->b[4];
3842 pwd->b[10] = pws->b[12];
3843 pwd->b[4] = pwt->b[0];
3844 pwd->b[12] = pws->b[0];
3845 pwd->b[0] = pwt->b[8];
3846 pwd->b[8] = pws->b[8];
3847#else
3848 pwd->b[0] = pwt->b[1];
3849 pwd->b[2] = pwt->b[5];
3850 pwd->b[4] = pwt->b[9];
3851 pwd->b[6] = pwt->b[13];
3852 pwd->b[8] = pws->b[1];
3853 pwd->b[10] = pws->b[5];
3854 pwd->b[12] = pws->b[9];
3855 pwd->b[14] = pws->b[13];
3856 pwd->b[1] = pwt->b[3];
3857 pwd->b[5] = pwt->b[11];
3858 pwd->b[9] = pws->b[3];
3859 pwd->b[13] = pws->b[11];
3860 pwd->b[3] = pwt->b[7];
3861 pwd->b[11] = pws->b[7];
3862 pwd->b[7] = pwt->b[15];
3863 pwd->b[15] = pws->b[15];
3864#endif
3865
3866}
3867
3868void helper_msa_pckod_h(CPUMIPSState *env,
3869 uint32_t wd, uint32_t ws, uint32_t wt)
3870{
3871 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3872 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3873 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3874
3875#if defined(HOST_WORDS_BIGENDIAN)
3876 pwd->h[3] = pwt->h[2];
3877 pwd->h[1] = pwt->h[6];
3878 pwd->h[7] = pws->h[2];
3879 pwd->h[5] = pws->h[6];
3880 pwd->h[2] = pwt->h[0];
3881 pwd->h[6] = pws->h[0];
3882 pwd->h[0] = pwt->h[4];
3883 pwd->h[4] = pws->h[4];
3884#else
3885 pwd->h[0] = pwt->h[1];
3886 pwd->h[2] = pwt->h[5];
3887 pwd->h[4] = pws->h[1];
3888 pwd->h[6] = pws->h[5];
3889 pwd->h[1] = pwt->h[3];
3890 pwd->h[5] = pws->h[3];
3891 pwd->h[3] = pwt->h[7];
3892 pwd->h[7] = pws->h[7];
3893#endif
3894}
3895
3896void helper_msa_pckod_w(CPUMIPSState *env,
3897 uint32_t wd, uint32_t ws, uint32_t wt)
3898{
3899 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3900 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3901 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3902
3903#if defined(HOST_WORDS_BIGENDIAN)
3904 pwd->w[1] = pwt->w[0];
3905 pwd->w[3] = pws->w[0];
3906 pwd->w[0] = pwt->w[2];
3907 pwd->w[2] = pws->w[2];
3908#else
3909 pwd->w[0] = pwt->w[1];
3910 pwd->w[2] = pws->w[1];
3911 pwd->w[1] = pwt->w[3];
3912 pwd->w[3] = pws->w[3];
3913#endif
3914}
3915
3916void helper_msa_pckod_d(CPUMIPSState *env,
3917 uint32_t wd, uint32_t ws, uint32_t wt)
3918{
3919 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3920 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3921 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3922
3923 pwd->d[0] = pwt->d[1];
3924 pwd->d[1] = pws->d[1];
3925}
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957static inline int64_t msa_sll_df(uint32_t df, int64_t arg1, int64_t arg2)
3958{
3959 int32_t b_arg2 = BIT_POSITION(arg2, df);
3960 return arg1 << b_arg2;
3961}
3962
3963void helper_msa_sll_b(CPUMIPSState *env,
3964 uint32_t wd, uint32_t ws, uint32_t wt)
3965{
3966 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3967 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3968 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3969
3970 pwd->b[0] = msa_sll_df(DF_BYTE, pws->b[0], pwt->b[0]);
3971 pwd->b[1] = msa_sll_df(DF_BYTE, pws->b[1], pwt->b[1]);
3972 pwd->b[2] = msa_sll_df(DF_BYTE, pws->b[2], pwt->b[2]);
3973 pwd->b[3] = msa_sll_df(DF_BYTE, pws->b[3], pwt->b[3]);
3974 pwd->b[4] = msa_sll_df(DF_BYTE, pws->b[4], pwt->b[4]);
3975 pwd->b[5] = msa_sll_df(DF_BYTE, pws->b[5], pwt->b[5]);
3976 pwd->b[6] = msa_sll_df(DF_BYTE, pws->b[6], pwt->b[6]);
3977 pwd->b[7] = msa_sll_df(DF_BYTE, pws->b[7], pwt->b[7]);
3978 pwd->b[8] = msa_sll_df(DF_BYTE, pws->b[8], pwt->b[8]);
3979 pwd->b[9] = msa_sll_df(DF_BYTE, pws->b[9], pwt->b[9]);
3980 pwd->b[10] = msa_sll_df(DF_BYTE, pws->b[10], pwt->b[10]);
3981 pwd->b[11] = msa_sll_df(DF_BYTE, pws->b[11], pwt->b[11]);
3982 pwd->b[12] = msa_sll_df(DF_BYTE, pws->b[12], pwt->b[12]);
3983 pwd->b[13] = msa_sll_df(DF_BYTE, pws->b[13], pwt->b[13]);
3984 pwd->b[14] = msa_sll_df(DF_BYTE, pws->b[14], pwt->b[14]);
3985 pwd->b[15] = msa_sll_df(DF_BYTE, pws->b[15], pwt->b[15]);
3986}
3987
3988void helper_msa_sll_h(CPUMIPSState *env,
3989 uint32_t wd, uint32_t ws, uint32_t wt)
3990{
3991 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3992 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3993 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3994
3995 pwd->h[0] = msa_sll_df(DF_HALF, pws->h[0], pwt->h[0]);
3996 pwd->h[1] = msa_sll_df(DF_HALF, pws->h[1], pwt->h[1]);
3997 pwd->h[2] = msa_sll_df(DF_HALF, pws->h[2], pwt->h[2]);
3998 pwd->h[3] = msa_sll_df(DF_HALF, pws->h[3], pwt->h[3]);
3999 pwd->h[4] = msa_sll_df(DF_HALF, pws->h[4], pwt->h[4]);
4000 pwd->h[5] = msa_sll_df(DF_HALF, pws->h[5], pwt->h[5]);
4001 pwd->h[6] = msa_sll_df(DF_HALF, pws->h[6], pwt->h[6]);
4002 pwd->h[7] = msa_sll_df(DF_HALF, pws->h[7], pwt->h[7]);
4003}
4004
4005void helper_msa_sll_w(CPUMIPSState *env,
4006 uint32_t wd, uint32_t ws, uint32_t wt)
4007{
4008 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4009 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4010 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4011
4012 pwd->w[0] = msa_sll_df(DF_WORD, pws->w[0], pwt->w[0]);
4013 pwd->w[1] = msa_sll_df(DF_WORD, pws->w[1], pwt->w[1]);
4014 pwd->w[2] = msa_sll_df(DF_WORD, pws->w[2], pwt->w[2]);
4015 pwd->w[3] = msa_sll_df(DF_WORD, pws->w[3], pwt->w[3]);
4016}
4017
4018void helper_msa_sll_d(CPUMIPSState *env,
4019 uint32_t wd, uint32_t ws, uint32_t wt)
4020{
4021 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4022 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4023 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4024
4025 pwd->d[0] = msa_sll_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
4026 pwd->d[1] = msa_sll_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
4027}
4028
4029
4030static inline int64_t msa_sra_df(uint32_t df, int64_t arg1, int64_t arg2)
4031{
4032 int32_t b_arg2 = BIT_POSITION(arg2, df);
4033 return arg1 >> b_arg2;
4034}
4035
4036void helper_msa_sra_b(CPUMIPSState *env,
4037 uint32_t wd, uint32_t ws, uint32_t wt)
4038{
4039 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4040 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4041 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4042
4043 pwd->b[0] = msa_sra_df(DF_BYTE, pws->b[0], pwt->b[0]);
4044 pwd->b[1] = msa_sra_df(DF_BYTE, pws->b[1], pwt->b[1]);
4045 pwd->b[2] = msa_sra_df(DF_BYTE, pws->b[2], pwt->b[2]);
4046 pwd->b[3] = msa_sra_df(DF_BYTE, pws->b[3], pwt->b[3]);
4047 pwd->b[4] = msa_sra_df(DF_BYTE, pws->b[4], pwt->b[4]);
4048 pwd->b[5] = msa_sra_df(DF_BYTE, pws->b[5], pwt->b[5]);
4049 pwd->b[6] = msa_sra_df(DF_BYTE, pws->b[6], pwt->b[6]);
4050 pwd->b[7] = msa_sra_df(DF_BYTE, pws->b[7], pwt->b[7]);
4051 pwd->b[8] = msa_sra_df(DF_BYTE, pws->b[8], pwt->b[8]);
4052 pwd->b[9] = msa_sra_df(DF_BYTE, pws->b[9], pwt->b[9]);
4053 pwd->b[10] = msa_sra_df(DF_BYTE, pws->b[10], pwt->b[10]);
4054 pwd->b[11] = msa_sra_df(DF_BYTE, pws->b[11], pwt->b[11]);
4055 pwd->b[12] = msa_sra_df(DF_BYTE, pws->b[12], pwt->b[12]);
4056 pwd->b[13] = msa_sra_df(DF_BYTE, pws->b[13], pwt->b[13]);
4057 pwd->b[14] = msa_sra_df(DF_BYTE, pws->b[14], pwt->b[14]);
4058 pwd->b[15] = msa_sra_df(DF_BYTE, pws->b[15], pwt->b[15]);
4059}
4060
4061void helper_msa_sra_h(CPUMIPSState *env,
4062 uint32_t wd, uint32_t ws, uint32_t wt)
4063{
4064 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4065 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4066 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4067
4068 pwd->h[0] = msa_sra_df(DF_HALF, pws->h[0], pwt->h[0]);
4069 pwd->h[1] = msa_sra_df(DF_HALF, pws->h[1], pwt->h[1]);
4070 pwd->h[2] = msa_sra_df(DF_HALF, pws->h[2], pwt->h[2]);
4071 pwd->h[3] = msa_sra_df(DF_HALF, pws->h[3], pwt->h[3]);
4072 pwd->h[4] = msa_sra_df(DF_HALF, pws->h[4], pwt->h[4]);
4073 pwd->h[5] = msa_sra_df(DF_HALF, pws->h[5], pwt->h[5]);
4074 pwd->h[6] = msa_sra_df(DF_HALF, pws->h[6], pwt->h[6]);
4075 pwd->h[7] = msa_sra_df(DF_HALF, pws->h[7], pwt->h[7]);
4076}
4077
4078void helper_msa_sra_w(CPUMIPSState *env,
4079 uint32_t wd, uint32_t ws, uint32_t wt)
4080{
4081 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4082 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4083 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4084
4085 pwd->w[0] = msa_sra_df(DF_WORD, pws->w[0], pwt->w[0]);
4086 pwd->w[1] = msa_sra_df(DF_WORD, pws->w[1], pwt->w[1]);
4087 pwd->w[2] = msa_sra_df(DF_WORD, pws->w[2], pwt->w[2]);
4088 pwd->w[3] = msa_sra_df(DF_WORD, pws->w[3], pwt->w[3]);
4089}
4090
4091void helper_msa_sra_d(CPUMIPSState *env,
4092 uint32_t wd, uint32_t ws, uint32_t wt)
4093{
4094 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4095 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4096 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4097
4098 pwd->d[0] = msa_sra_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
4099 pwd->d[1] = msa_sra_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
4100}
4101
4102
4103static inline int64_t msa_srar_df(uint32_t df, int64_t arg1, int64_t arg2)
4104{
4105 int32_t b_arg2 = BIT_POSITION(arg2, df);
4106 if (b_arg2 == 0) {
4107 return arg1;
4108 } else {
4109 int64_t r_bit = (arg1 >> (b_arg2 - 1)) & 1;
4110 return (arg1 >> b_arg2) + r_bit;
4111 }
4112}
4113
4114void helper_msa_srar_b(CPUMIPSState *env,
4115 uint32_t wd, uint32_t ws, uint32_t wt)
4116{
4117 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4118 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4119 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4120
4121 pwd->b[0] = msa_srar_df(DF_BYTE, pws->b[0], pwt->b[0]);
4122 pwd->b[1] = msa_srar_df(DF_BYTE, pws->b[1], pwt->b[1]);
4123 pwd->b[2] = msa_srar_df(DF_BYTE, pws->b[2], pwt->b[2]);
4124 pwd->b[3] = msa_srar_df(DF_BYTE, pws->b[3], pwt->b[3]);
4125 pwd->b[4] = msa_srar_df(DF_BYTE, pws->b[4], pwt->b[4]);
4126 pwd->b[5] = msa_srar_df(DF_BYTE, pws->b[5], pwt->b[5]);
4127 pwd->b[6] = msa_srar_df(DF_BYTE, pws->b[6], pwt->b[6]);
4128 pwd->b[7] = msa_srar_df(DF_BYTE, pws->b[7], pwt->b[7]);
4129 pwd->b[8] = msa_srar_df(DF_BYTE, pws->b[8], pwt->b[8]);
4130 pwd->b[9] = msa_srar_df(DF_BYTE, pws->b[9], pwt->b[9]);
4131 pwd->b[10] = msa_srar_df(DF_BYTE, pws->b[10], pwt->b[10]);
4132 pwd->b[11] = msa_srar_df(DF_BYTE, pws->b[11], pwt->b[11]);
4133 pwd->b[12] = msa_srar_df(DF_BYTE, pws->b[12], pwt->b[12]);
4134 pwd->b[13] = msa_srar_df(DF_BYTE, pws->b[13], pwt->b[13]);
4135 pwd->b[14] = msa_srar_df(DF_BYTE, pws->b[14], pwt->b[14]);
4136 pwd->b[15] = msa_srar_df(DF_BYTE, pws->b[15], pwt->b[15]);
4137}
4138
4139void helper_msa_srar_h(CPUMIPSState *env,
4140 uint32_t wd, uint32_t ws, uint32_t wt)
4141{
4142 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4143 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4144 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4145
4146 pwd->h[0] = msa_srar_df(DF_HALF, pws->h[0], pwt->h[0]);
4147 pwd->h[1] = msa_srar_df(DF_HALF, pws->h[1], pwt->h[1]);
4148 pwd->h[2] = msa_srar_df(DF_HALF, pws->h[2], pwt->h[2]);
4149 pwd->h[3] = msa_srar_df(DF_HALF, pws->h[3], pwt->h[3]);
4150 pwd->h[4] = msa_srar_df(DF_HALF, pws->h[4], pwt->h[4]);
4151 pwd->h[5] = msa_srar_df(DF_HALF, pws->h[5], pwt->h[5]);
4152 pwd->h[6] = msa_srar_df(DF_HALF, pws->h[6], pwt->h[6]);
4153 pwd->h[7] = msa_srar_df(DF_HALF, pws->h[7], pwt->h[7]);
4154}
4155
4156void helper_msa_srar_w(CPUMIPSState *env,
4157 uint32_t wd, uint32_t ws, uint32_t wt)
4158{
4159 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4160 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4161 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4162
4163 pwd->w[0] = msa_srar_df(DF_WORD, pws->w[0], pwt->w[0]);
4164 pwd->w[1] = msa_srar_df(DF_WORD, pws->w[1], pwt->w[1]);
4165 pwd->w[2] = msa_srar_df(DF_WORD, pws->w[2], pwt->w[2]);
4166 pwd->w[3] = msa_srar_df(DF_WORD, pws->w[3], pwt->w[3]);
4167}
4168
4169void helper_msa_srar_d(CPUMIPSState *env,
4170 uint32_t wd, uint32_t ws, uint32_t wt)
4171{
4172 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4173 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4174 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4175
4176 pwd->d[0] = msa_srar_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
4177 pwd->d[1] = msa_srar_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
4178}
4179
4180
4181static inline int64_t msa_srl_df(uint32_t df, int64_t arg1, int64_t arg2)
4182{
4183 uint64_t u_arg1 = UNSIGNED(arg1, df);
4184 int32_t b_arg2 = BIT_POSITION(arg2, df);
4185 return u_arg1 >> b_arg2;
4186}
4187
4188void helper_msa_srl_b(CPUMIPSState *env,
4189 uint32_t wd, uint32_t ws, uint32_t wt)
4190{
4191 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4192 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4193 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4194
4195 pwd->b[0] = msa_srl_df(DF_BYTE, pws->b[0], pwt->b[0]);
4196 pwd->b[1] = msa_srl_df(DF_BYTE, pws->b[1], pwt->b[1]);
4197 pwd->b[2] = msa_srl_df(DF_BYTE, pws->b[2], pwt->b[2]);
4198 pwd->b[3] = msa_srl_df(DF_BYTE, pws->b[3], pwt->b[3]);
4199 pwd->b[4] = msa_srl_df(DF_BYTE, pws->b[4], pwt->b[4]);
4200 pwd->b[5] = msa_srl_df(DF_BYTE, pws->b[5], pwt->b[5]);
4201 pwd->b[6] = msa_srl_df(DF_BYTE, pws->b[6], pwt->b[6]);
4202 pwd->b[7] = msa_srl_df(DF_BYTE, pws->b[7], pwt->b[7]);
4203 pwd->b[8] = msa_srl_df(DF_BYTE, pws->b[8], pwt->b[8]);
4204 pwd->b[9] = msa_srl_df(DF_BYTE, pws->b[9], pwt->b[9]);
4205 pwd->b[10] = msa_srl_df(DF_BYTE, pws->b[10], pwt->b[10]);
4206 pwd->b[11] = msa_srl_df(DF_BYTE, pws->b[11], pwt->b[11]);
4207 pwd->b[12] = msa_srl_df(DF_BYTE, pws->b[12], pwt->b[12]);
4208 pwd->b[13] = msa_srl_df(DF_BYTE, pws->b[13], pwt->b[13]);
4209 pwd->b[14] = msa_srl_df(DF_BYTE, pws->b[14], pwt->b[14]);
4210 pwd->b[15] = msa_srl_df(DF_BYTE, pws->b[15], pwt->b[15]);
4211}
4212
4213void helper_msa_srl_h(CPUMIPSState *env,
4214 uint32_t wd, uint32_t ws, uint32_t wt)
4215{
4216 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4217 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4218 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4219
4220 pwd->h[0] = msa_srl_df(DF_HALF, pws->h[0], pwt->h[0]);
4221 pwd->h[1] = msa_srl_df(DF_HALF, pws->h[1], pwt->h[1]);
4222 pwd->h[2] = msa_srl_df(DF_HALF, pws->h[2], pwt->h[2]);
4223 pwd->h[3] = msa_srl_df(DF_HALF, pws->h[3], pwt->h[3]);
4224 pwd->h[4] = msa_srl_df(DF_HALF, pws->h[4], pwt->h[4]);
4225 pwd->h[5] = msa_srl_df(DF_HALF, pws->h[5], pwt->h[5]);
4226 pwd->h[6] = msa_srl_df(DF_HALF, pws->h[6], pwt->h[6]);
4227 pwd->h[7] = msa_srl_df(DF_HALF, pws->h[7], pwt->h[7]);
4228}
4229
4230void helper_msa_srl_w(CPUMIPSState *env,
4231 uint32_t wd, uint32_t ws, uint32_t wt)
4232{
4233 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4234 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4235 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4236
4237 pwd->w[0] = msa_srl_df(DF_WORD, pws->w[0], pwt->w[0]);
4238 pwd->w[1] = msa_srl_df(DF_WORD, pws->w[1], pwt->w[1]);
4239 pwd->w[2] = msa_srl_df(DF_WORD, pws->w[2], pwt->w[2]);
4240 pwd->w[3] = msa_srl_df(DF_WORD, pws->w[3], pwt->w[3]);
4241}
4242
4243void helper_msa_srl_d(CPUMIPSState *env,
4244 uint32_t wd, uint32_t ws, uint32_t wt)
4245{
4246 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4247 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4248 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4249
4250 pwd->d[0] = msa_srl_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
4251 pwd->d[1] = msa_srl_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
4252}
4253
4254
4255static inline int64_t msa_srlr_df(uint32_t df, int64_t arg1, int64_t arg2)
4256{
4257 uint64_t u_arg1 = UNSIGNED(arg1, df);
4258 int32_t b_arg2 = BIT_POSITION(arg2, df);
4259 if (b_arg2 == 0) {
4260 return u_arg1;
4261 } else {
4262 uint64_t r_bit = (u_arg1 >> (b_arg2 - 1)) & 1;
4263 return (u_arg1 >> b_arg2) + r_bit;
4264 }
4265}
4266
4267void helper_msa_srlr_b(CPUMIPSState *env,
4268 uint32_t wd, uint32_t ws, uint32_t wt)
4269{
4270 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4271 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4272 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4273
4274 pwd->b[0] = msa_srlr_df(DF_BYTE, pws->b[0], pwt->b[0]);
4275 pwd->b[1] = msa_srlr_df(DF_BYTE, pws->b[1], pwt->b[1]);
4276 pwd->b[2] = msa_srlr_df(DF_BYTE, pws->b[2], pwt->b[2]);
4277 pwd->b[3] = msa_srlr_df(DF_BYTE, pws->b[3], pwt->b[3]);
4278 pwd->b[4] = msa_srlr_df(DF_BYTE, pws->b[4], pwt->b[4]);
4279 pwd->b[5] = msa_srlr_df(DF_BYTE, pws->b[5], pwt->b[5]);
4280 pwd->b[6] = msa_srlr_df(DF_BYTE, pws->b[6], pwt->b[6]);
4281 pwd->b[7] = msa_srlr_df(DF_BYTE, pws->b[7], pwt->b[7]);
4282 pwd->b[8] = msa_srlr_df(DF_BYTE, pws->b[8], pwt->b[8]);
4283 pwd->b[9] = msa_srlr_df(DF_BYTE, pws->b[9], pwt->b[9]);
4284 pwd->b[10] = msa_srlr_df(DF_BYTE, pws->b[10], pwt->b[10]);
4285 pwd->b[11] = msa_srlr_df(DF_BYTE, pws->b[11], pwt->b[11]);
4286 pwd->b[12] = msa_srlr_df(DF_BYTE, pws->b[12], pwt->b[12]);
4287 pwd->b[13] = msa_srlr_df(DF_BYTE, pws->b[13], pwt->b[13]);
4288 pwd->b[14] = msa_srlr_df(DF_BYTE, pws->b[14], pwt->b[14]);
4289 pwd->b[15] = msa_srlr_df(DF_BYTE, pws->b[15], pwt->b[15]);
4290}
4291
4292void helper_msa_srlr_h(CPUMIPSState *env,
4293 uint32_t wd, uint32_t ws, uint32_t wt)
4294{
4295 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4296 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4297 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4298
4299 pwd->h[0] = msa_srlr_df(DF_HALF, pws->h[0], pwt->h[0]);
4300 pwd->h[1] = msa_srlr_df(DF_HALF, pws->h[1], pwt->h[1]);
4301 pwd->h[2] = msa_srlr_df(DF_HALF, pws->h[2], pwt->h[2]);
4302 pwd->h[3] = msa_srlr_df(DF_HALF, pws->h[3], pwt->h[3]);
4303 pwd->h[4] = msa_srlr_df(DF_HALF, pws->h[4], pwt->h[4]);
4304 pwd->h[5] = msa_srlr_df(DF_HALF, pws->h[5], pwt->h[5]);
4305 pwd->h[6] = msa_srlr_df(DF_HALF, pws->h[6], pwt->h[6]);
4306 pwd->h[7] = msa_srlr_df(DF_HALF, pws->h[7], pwt->h[7]);
4307}
4308
4309void helper_msa_srlr_w(CPUMIPSState *env,
4310 uint32_t wd, uint32_t ws, uint32_t wt)
4311{
4312 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4313 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4314 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4315
4316 pwd->w[0] = msa_srlr_df(DF_WORD, pws->w[0], pwt->w[0]);
4317 pwd->w[1] = msa_srlr_df(DF_WORD, pws->w[1], pwt->w[1]);
4318 pwd->w[2] = msa_srlr_df(DF_WORD, pws->w[2], pwt->w[2]);
4319 pwd->w[3] = msa_srlr_df(DF_WORD, pws->w[3], pwt->w[3]);
4320}
4321
4322void helper_msa_srlr_d(CPUMIPSState *env,
4323 uint32_t wd, uint32_t ws, uint32_t wt)
4324{
4325 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4326 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4327 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4328
4329 pwd->d[0] = msa_srlr_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
4330 pwd->d[1] = msa_srlr_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
4331}
4332
4333
4334#define MSA_FN_IMM8(FUNC, DEST, OPERATION) \
4335void helper_msa_ ## FUNC(CPUMIPSState *env, uint32_t wd, uint32_t ws, \
4336 uint32_t i8) \
4337{ \
4338 wr_t *pwd = &(env->active_fpu.fpr[wd].wr); \
4339 wr_t *pws = &(env->active_fpu.fpr[ws].wr); \
4340 uint32_t i; \
4341 for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) { \
4342 DEST = OPERATION; \
4343 } \
4344}
4345
4346MSA_FN_IMM8(andi_b, pwd->b[i], pws->b[i] & i8)
4347MSA_FN_IMM8(ori_b, pwd->b[i], pws->b[i] | i8)
4348MSA_FN_IMM8(nori_b, pwd->b[i], ~(pws->b[i] | i8))
4349MSA_FN_IMM8(xori_b, pwd->b[i], pws->b[i] ^ i8)
4350
4351#define BIT_MOVE_IF_NOT_ZERO(dest, arg1, arg2, df) \
4352 UNSIGNED(((dest & (~arg2)) | (arg1 & arg2)), df)
4353MSA_FN_IMM8(bmnzi_b, pwd->b[i],
4354 BIT_MOVE_IF_NOT_ZERO(pwd->b[i], pws->b[i], i8, DF_BYTE))
4355
4356#define BIT_MOVE_IF_ZERO(dest, arg1, arg2, df) \
4357 UNSIGNED((dest & arg2) | (arg1 & (~arg2)), df)
4358MSA_FN_IMM8(bmzi_b, pwd->b[i],
4359 BIT_MOVE_IF_ZERO(pwd->b[i], pws->b[i], i8, DF_BYTE))
4360
4361#define BIT_SELECT(dest, arg1, arg2, df) \
4362 UNSIGNED((arg1 & (~dest)) | (arg2 & dest), df)
4363MSA_FN_IMM8(bseli_b, pwd->b[i],
4364 BIT_SELECT(pwd->b[i], pws->b[i], i8, DF_BYTE))
4365
4366#undef BIT_SELECT
4367#undef BIT_MOVE_IF_ZERO
4368#undef BIT_MOVE_IF_NOT_ZERO
4369#undef MSA_FN_IMM8
4370
4371#define SHF_POS(i, imm) (((i) & 0xfc) + (((imm) >> (2 * ((i) & 0x03))) & 0x03))
4372
4373void helper_msa_shf_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
4374 uint32_t ws, uint32_t imm)
4375{
4376 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4377 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4378 wr_t wx, *pwx = &wx;
4379 uint32_t i;
4380
4381 switch (df) {
4382 case DF_BYTE:
4383 for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) {
4384 pwx->b[i] = pws->b[SHF_POS(i, imm)];
4385 }
4386 break;
4387 case DF_HALF:
4388 for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) {
4389 pwx->h[i] = pws->h[SHF_POS(i, imm)];
4390 }
4391 break;
4392 case DF_WORD:
4393 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
4394 pwx->w[i] = pws->w[SHF_POS(i, imm)];
4395 }
4396 break;
4397 default:
4398 assert(0);
4399 }
4400 msa_move_v(pwd, pwx);
4401}
4402
4403static inline int64_t msa_subv_df(uint32_t df, int64_t arg1, int64_t arg2)
4404{
4405 return arg1 - arg2;
4406}
4407
4408#define MSA_BINOP_IMM_DF(helper, func) \
4409void helper_msa_ ## helper ## _df(CPUMIPSState *env, uint32_t df, \
4410 uint32_t wd, uint32_t ws, int32_t u5) \
4411{ \
4412 wr_t *pwd = &(env->active_fpu.fpr[wd].wr); \
4413 wr_t *pws = &(env->active_fpu.fpr[ws].wr); \
4414 uint32_t i; \
4415 \
4416 switch (df) { \
4417 case DF_BYTE: \
4418 for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) { \
4419 pwd->b[i] = msa_ ## func ## _df(df, pws->b[i], u5); \
4420 } \
4421 break; \
4422 case DF_HALF: \
4423 for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) { \
4424 pwd->h[i] = msa_ ## func ## _df(df, pws->h[i], u5); \
4425 } \
4426 break; \
4427 case DF_WORD: \
4428 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) { \
4429 pwd->w[i] = msa_ ## func ## _df(df, pws->w[i], u5); \
4430 } \
4431 break; \
4432 case DF_DOUBLE: \
4433 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) { \
4434 pwd->d[i] = msa_ ## func ## _df(df, pws->d[i], u5); \
4435 } \
4436 break; \
4437 default: \
4438 assert(0); \
4439 } \
4440}
4441
4442MSA_BINOP_IMM_DF(addvi, addv)
4443MSA_BINOP_IMM_DF(subvi, subv)
4444MSA_BINOP_IMM_DF(ceqi, ceq)
4445MSA_BINOP_IMM_DF(clei_s, cle_s)
4446MSA_BINOP_IMM_DF(clei_u, cle_u)
4447MSA_BINOP_IMM_DF(clti_s, clt_s)
4448MSA_BINOP_IMM_DF(clti_u, clt_u)
4449MSA_BINOP_IMM_DF(maxi_s, max_s)
4450MSA_BINOP_IMM_DF(maxi_u, max_u)
4451MSA_BINOP_IMM_DF(mini_s, min_s)
4452MSA_BINOP_IMM_DF(mini_u, min_u)
4453#undef MSA_BINOP_IMM_DF
4454
4455void helper_msa_ldi_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
4456 int32_t s10)
4457{
4458 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4459 uint32_t i;
4460
4461 switch (df) {
4462 case DF_BYTE:
4463 for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) {
4464 pwd->b[i] = (int8_t)s10;
4465 }
4466 break;
4467 case DF_HALF:
4468 for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) {
4469 pwd->h[i] = (int16_t)s10;
4470 }
4471 break;
4472 case DF_WORD:
4473 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
4474 pwd->w[i] = (int32_t)s10;
4475 }
4476 break;
4477 case DF_DOUBLE:
4478 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
4479 pwd->d[i] = (int64_t)s10;
4480 }
4481 break;
4482 default:
4483 assert(0);
4484 }
4485}
4486
4487static inline int64_t msa_sat_s_df(uint32_t df, int64_t arg, uint32_t m)
4488{
4489 return arg < M_MIN_INT(m + 1) ? M_MIN_INT(m + 1) :
4490 arg > M_MAX_INT(m + 1) ? M_MAX_INT(m + 1) :
4491 arg;
4492}
4493
4494static inline int64_t msa_sat_u_df(uint32_t df, int64_t arg, uint32_t m)
4495{
4496 uint64_t u_arg = UNSIGNED(arg, df);
4497 return u_arg < M_MAX_UINT(m + 1) ? u_arg :
4498 M_MAX_UINT(m + 1);
4499}
4500
4501#define MSA_BINOP_IMMU_DF(helper, func) \
4502void helper_msa_ ## helper ## _df(CPUMIPSState *env, uint32_t df, uint32_t wd, \
4503 uint32_t ws, uint32_t u5) \
4504{ \
4505 wr_t *pwd = &(env->active_fpu.fpr[wd].wr); \
4506 wr_t *pws = &(env->active_fpu.fpr[ws].wr); \
4507 uint32_t i; \
4508 \
4509 switch (df) { \
4510 case DF_BYTE: \
4511 for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) { \
4512 pwd->b[i] = msa_ ## func ## _df(df, pws->b[i], u5); \
4513 } \
4514 break; \
4515 case DF_HALF: \
4516 for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) { \
4517 pwd->h[i] = msa_ ## func ## _df(df, pws->h[i], u5); \
4518 } \
4519 break; \
4520 case DF_WORD: \
4521 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) { \
4522 pwd->w[i] = msa_ ## func ## _df(df, pws->w[i], u5); \
4523 } \
4524 break; \
4525 case DF_DOUBLE: \
4526 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) { \
4527 pwd->d[i] = msa_ ## func ## _df(df, pws->d[i], u5); \
4528 } \
4529 break; \
4530 default: \
4531 assert(0); \
4532 } \
4533}
4534
4535MSA_BINOP_IMMU_DF(slli, sll)
4536MSA_BINOP_IMMU_DF(srai, sra)
4537MSA_BINOP_IMMU_DF(srli, srl)
4538MSA_BINOP_IMMU_DF(bclri, bclr)
4539MSA_BINOP_IMMU_DF(bseti, bset)
4540MSA_BINOP_IMMU_DF(bnegi, bneg)
4541MSA_BINOP_IMMU_DF(sat_s, sat_s)
4542MSA_BINOP_IMMU_DF(sat_u, sat_u)
4543MSA_BINOP_IMMU_DF(srari, srar)
4544MSA_BINOP_IMMU_DF(srlri, srlr)
4545#undef MSA_BINOP_IMMU_DF
4546
4547#define MSA_TEROP_IMMU_DF(helper, func) \
4548void helper_msa_ ## helper ## _df(CPUMIPSState *env, uint32_t df, \
4549 uint32_t wd, uint32_t ws, uint32_t u5) \
4550{ \
4551 wr_t *pwd = &(env->active_fpu.fpr[wd].wr); \
4552 wr_t *pws = &(env->active_fpu.fpr[ws].wr); \
4553 uint32_t i; \
4554 \
4555 switch (df) { \
4556 case DF_BYTE: \
4557 for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) { \
4558 pwd->b[i] = msa_ ## func ## _df(df, pwd->b[i], pws->b[i], \
4559 u5); \
4560 } \
4561 break; \
4562 case DF_HALF: \
4563 for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) { \
4564 pwd->h[i] = msa_ ## func ## _df(df, pwd->h[i], pws->h[i], \
4565 u5); \
4566 } \
4567 break; \
4568 case DF_WORD: \
4569 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) { \
4570 pwd->w[i] = msa_ ## func ## _df(df, pwd->w[i], pws->w[i], \
4571 u5); \
4572 } \
4573 break; \
4574 case DF_DOUBLE: \
4575 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) { \
4576 pwd->d[i] = msa_ ## func ## _df(df, pwd->d[i], pws->d[i], \
4577 u5); \
4578 } \
4579 break; \
4580 default: \
4581 assert(0); \
4582 } \
4583}
4584
4585MSA_TEROP_IMMU_DF(binsli, binsl)
4586MSA_TEROP_IMMU_DF(binsri, binsr)
4587#undef MSA_TEROP_IMMU_DF
4588
4589static inline int64_t msa_subs_s_df(uint32_t df, int64_t arg1, int64_t arg2)
4590{
4591 int64_t max_int = DF_MAX_INT(df);
4592 int64_t min_int = DF_MIN_INT(df);
4593 if (arg2 > 0) {
4594 return (min_int + arg2 < arg1) ? arg1 - arg2 : min_int;
4595 } else {
4596 return (arg1 < max_int + arg2) ? arg1 - arg2 : max_int;
4597 }
4598}
4599
4600static inline int64_t msa_subs_u_df(uint32_t df, int64_t arg1, int64_t arg2)
4601{
4602 uint64_t u_arg1 = UNSIGNED(arg1, df);
4603 uint64_t u_arg2 = UNSIGNED(arg2, df);
4604 return (u_arg1 > u_arg2) ? u_arg1 - u_arg2 : 0;
4605}
4606
4607static inline int64_t msa_subsus_u_df(uint32_t df, int64_t arg1, int64_t arg2)
4608{
4609 uint64_t u_arg1 = UNSIGNED(arg1, df);
4610 uint64_t max_uint = DF_MAX_UINT(df);
4611 if (arg2 >= 0) {
4612 uint64_t u_arg2 = (uint64_t)arg2;
4613 return (u_arg1 > u_arg2) ?
4614 (int64_t)(u_arg1 - u_arg2) :
4615 0;
4616 } else {
4617 uint64_t u_arg2 = (uint64_t)(-arg2);
4618 return (u_arg1 < max_uint - u_arg2) ?
4619 (int64_t)(u_arg1 + u_arg2) :
4620 (int64_t)max_uint;
4621 }
4622}
4623
4624static inline int64_t msa_subsuu_s_df(uint32_t df, int64_t arg1, int64_t arg2)
4625{
4626 uint64_t u_arg1 = UNSIGNED(arg1, df);
4627 uint64_t u_arg2 = UNSIGNED(arg2, df);
4628 int64_t max_int = DF_MAX_INT(df);
4629 int64_t min_int = DF_MIN_INT(df);
4630 if (u_arg1 > u_arg2) {
4631 return u_arg1 - u_arg2 < (uint64_t)max_int ?
4632 (int64_t)(u_arg1 - u_arg2) :
4633 max_int;
4634 } else {
4635 return u_arg2 - u_arg1 < (uint64_t)(-min_int) ?
4636 (int64_t)(u_arg1 - u_arg2) :
4637 min_int;
4638 }
4639}
4640
4641static inline int64_t msa_mulv_df(uint32_t df, int64_t arg1, int64_t arg2)
4642{
4643 return arg1 * arg2;
4644}
4645
4646#define SIGNED_EXTRACT(e, o, a, df) \
4647 do { \
4648 e = SIGNED_EVEN(a, df); \
4649 o = SIGNED_ODD(a, df); \
4650 } while (0)
4651
4652#define UNSIGNED_EXTRACT(e, o, a, df) \
4653 do { \
4654 e = UNSIGNED_EVEN(a, df); \
4655 o = UNSIGNED_ODD(a, df); \
4656 } while (0)
4657
4658static inline int64_t msa_dotp_s_df(uint32_t df, int64_t arg1, int64_t arg2)
4659{
4660 int64_t even_arg1;
4661 int64_t even_arg2;
4662 int64_t odd_arg1;
4663 int64_t odd_arg2;
4664 SIGNED_EXTRACT(even_arg1, odd_arg1, arg1, df);
4665 SIGNED_EXTRACT(even_arg2, odd_arg2, arg2, df);
4666 return (even_arg1 * even_arg2) + (odd_arg1 * odd_arg2);
4667}
4668
4669static inline int64_t msa_dotp_u_df(uint32_t df, int64_t arg1, int64_t arg2)
4670{
4671 int64_t even_arg1;
4672 int64_t even_arg2;
4673 int64_t odd_arg1;
4674 int64_t odd_arg2;
4675 UNSIGNED_EXTRACT(even_arg1, odd_arg1, arg1, df);
4676 UNSIGNED_EXTRACT(even_arg2, odd_arg2, arg2, df);
4677 return (even_arg1 * even_arg2) + (odd_arg1 * odd_arg2);
4678}
4679
4680#define CONCATENATE_AND_SLIDE(s, k) \
4681 do { \
4682 for (i = 0; i < s; i++) { \
4683 v[i] = pws->b[s * k + i]; \
4684 v[i + s] = pwd->b[s * k + i]; \
4685 } \
4686 for (i = 0; i < s; i++) { \
4687 pwd->b[s * k + i] = v[i + n]; \
4688 } \
4689 } while (0)
4690
4691static inline void msa_sld_df(uint32_t df, wr_t *pwd,
4692 wr_t *pws, target_ulong rt)
4693{
4694 uint32_t n = rt % DF_ELEMENTS(df);
4695 uint8_t v[64];
4696 uint32_t i, k;
4697
4698 switch (df) {
4699 case DF_BYTE:
4700 CONCATENATE_AND_SLIDE(DF_ELEMENTS(DF_BYTE), 0);
4701 break;
4702 case DF_HALF:
4703 for (k = 0; k < 2; k++) {
4704 CONCATENATE_AND_SLIDE(DF_ELEMENTS(DF_HALF), k);
4705 }
4706 break;
4707 case DF_WORD:
4708 for (k = 0; k < 4; k++) {
4709 CONCATENATE_AND_SLIDE(DF_ELEMENTS(DF_WORD), k);
4710 }
4711 break;
4712 case DF_DOUBLE:
4713 for (k = 0; k < 8; k++) {
4714 CONCATENATE_AND_SLIDE(DF_ELEMENTS(DF_DOUBLE), k);
4715 }
4716 break;
4717 default:
4718 assert(0);
4719 }
4720}
4721
4722static inline int64_t msa_mul_q_df(uint32_t df, int64_t arg1, int64_t arg2)
4723{
4724 int64_t q_min = DF_MIN_INT(df);
4725 int64_t q_max = DF_MAX_INT(df);
4726
4727 if (arg1 == q_min && arg2 == q_min) {
4728 return q_max;
4729 }
4730 return (arg1 * arg2) >> (DF_BITS(df) - 1);
4731}
4732
4733static inline int64_t msa_mulr_q_df(uint32_t df, int64_t arg1, int64_t arg2)
4734{
4735 int64_t q_min = DF_MIN_INT(df);
4736 int64_t q_max = DF_MAX_INT(df);
4737 int64_t r_bit = 1 << (DF_BITS(df) - 2);
4738
4739 if (arg1 == q_min && arg2 == q_min) {
4740 return q_max;
4741 }
4742 return (arg1 * arg2 + r_bit) >> (DF_BITS(df) - 1);
4743}
4744
4745#define MSA_BINOP_DF(func) \
4746void helper_msa_ ## func ## _df(CPUMIPSState *env, uint32_t df, \
4747 uint32_t wd, uint32_t ws, uint32_t wt) \
4748{ \
4749 wr_t *pwd = &(env->active_fpu.fpr[wd].wr); \
4750 wr_t *pws = &(env->active_fpu.fpr[ws].wr); \
4751 wr_t *pwt = &(env->active_fpu.fpr[wt].wr); \
4752 \
4753 switch (df) { \
4754 case DF_BYTE: \
4755 pwd->b[0] = msa_ ## func ## _df(df, pws->b[0], pwt->b[0]); \
4756 pwd->b[1] = msa_ ## func ## _df(df, pws->b[1], pwt->b[1]); \
4757 pwd->b[2] = msa_ ## func ## _df(df, pws->b[2], pwt->b[2]); \
4758 pwd->b[3] = msa_ ## func ## _df(df, pws->b[3], pwt->b[3]); \
4759 pwd->b[4] = msa_ ## func ## _df(df, pws->b[4], pwt->b[4]); \
4760 pwd->b[5] = msa_ ## func ## _df(df, pws->b[5], pwt->b[5]); \
4761 pwd->b[6] = msa_ ## func ## _df(df, pws->b[6], pwt->b[6]); \
4762 pwd->b[7] = msa_ ## func ## _df(df, pws->b[7], pwt->b[7]); \
4763 pwd->b[8] = msa_ ## func ## _df(df, pws->b[8], pwt->b[8]); \
4764 pwd->b[9] = msa_ ## func ## _df(df, pws->b[9], pwt->b[9]); \
4765 pwd->b[10] = msa_ ## func ## _df(df, pws->b[10], pwt->b[10]); \
4766 pwd->b[11] = msa_ ## func ## _df(df, pws->b[11], pwt->b[11]); \
4767 pwd->b[12] = msa_ ## func ## _df(df, pws->b[12], pwt->b[12]); \
4768 pwd->b[13] = msa_ ## func ## _df(df, pws->b[13], pwt->b[13]); \
4769 pwd->b[14] = msa_ ## func ## _df(df, pws->b[14], pwt->b[14]); \
4770 pwd->b[15] = msa_ ## func ## _df(df, pws->b[15], pwt->b[15]); \
4771 break; \
4772 case DF_HALF: \
4773 pwd->h[0] = msa_ ## func ## _df(df, pws->h[0], pwt->h[0]); \
4774 pwd->h[1] = msa_ ## func ## _df(df, pws->h[1], pwt->h[1]); \
4775 pwd->h[2] = msa_ ## func ## _df(df, pws->h[2], pwt->h[2]); \
4776 pwd->h[3] = msa_ ## func ## _df(df, pws->h[3], pwt->h[3]); \
4777 pwd->h[4] = msa_ ## func ## _df(df, pws->h[4], pwt->h[4]); \
4778 pwd->h[5] = msa_ ## func ## _df(df, pws->h[5], pwt->h[5]); \
4779 pwd->h[6] = msa_ ## func ## _df(df, pws->h[6], pwt->h[6]); \
4780 pwd->h[7] = msa_ ## func ## _df(df, pws->h[7], pwt->h[7]); \
4781 break; \
4782 case DF_WORD: \
4783 pwd->w[0] = msa_ ## func ## _df(df, pws->w[0], pwt->w[0]); \
4784 pwd->w[1] = msa_ ## func ## _df(df, pws->w[1], pwt->w[1]); \
4785 pwd->w[2] = msa_ ## func ## _df(df, pws->w[2], pwt->w[2]); \
4786 pwd->w[3] = msa_ ## func ## _df(df, pws->w[3], pwt->w[3]); \
4787 break; \
4788 case DF_DOUBLE: \
4789 pwd->d[0] = msa_ ## func ## _df(df, pws->d[0], pwt->d[0]); \
4790 pwd->d[1] = msa_ ## func ## _df(df, pws->d[1], pwt->d[1]); \
4791 break; \
4792 default: \
4793 assert(0); \
4794 } \
4795}
4796
4797MSA_BINOP_DF(subv)
4798MSA_BINOP_DF(subs_s)
4799MSA_BINOP_DF(subs_u)
4800MSA_BINOP_DF(subsus_u)
4801MSA_BINOP_DF(subsuu_s)
4802MSA_BINOP_DF(mulv)
4803MSA_BINOP_DF(dotp_s)
4804MSA_BINOP_DF(dotp_u)
4805
4806MSA_BINOP_DF(mul_q)
4807MSA_BINOP_DF(mulr_q)
4808#undef MSA_BINOP_DF
4809
4810void helper_msa_sld_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
4811 uint32_t ws, uint32_t rt)
4812{
4813 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4814 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4815
4816 msa_sld_df(df, pwd, pws, env->active_tc.gpr[rt]);
4817}
4818
4819static inline int64_t msa_maddv_df(uint32_t df, int64_t dest, int64_t arg1,
4820 int64_t arg2)
4821{
4822 return dest + arg1 * arg2;
4823}
4824
4825static inline int64_t msa_msubv_df(uint32_t df, int64_t dest, int64_t arg1,
4826 int64_t arg2)
4827{
4828 return dest - arg1 * arg2;
4829}
4830
4831static inline int64_t msa_dpadd_s_df(uint32_t df, int64_t dest, int64_t arg1,
4832 int64_t arg2)
4833{
4834 int64_t even_arg1;
4835 int64_t even_arg2;
4836 int64_t odd_arg1;
4837 int64_t odd_arg2;
4838 SIGNED_EXTRACT(even_arg1, odd_arg1, arg1, df);
4839 SIGNED_EXTRACT(even_arg2, odd_arg2, arg2, df);
4840 return dest + (even_arg1 * even_arg2) + (odd_arg1 * odd_arg2);
4841}
4842
4843static inline int64_t msa_dpadd_u_df(uint32_t df, int64_t dest, int64_t arg1,
4844 int64_t arg2)
4845{
4846 int64_t even_arg1;
4847 int64_t even_arg2;
4848 int64_t odd_arg1;
4849 int64_t odd_arg2;
4850 UNSIGNED_EXTRACT(even_arg1, odd_arg1, arg1, df);
4851 UNSIGNED_EXTRACT(even_arg2, odd_arg2, arg2, df);
4852 return dest + (even_arg1 * even_arg2) + (odd_arg1 * odd_arg2);
4853}
4854
4855static inline int64_t msa_dpsub_s_df(uint32_t df, int64_t dest, int64_t arg1,
4856 int64_t arg2)
4857{
4858 int64_t even_arg1;
4859 int64_t even_arg2;
4860 int64_t odd_arg1;
4861 int64_t odd_arg2;
4862 SIGNED_EXTRACT(even_arg1, odd_arg1, arg1, df);
4863 SIGNED_EXTRACT(even_arg2, odd_arg2, arg2, df);
4864 return dest - ((even_arg1 * even_arg2) + (odd_arg1 * odd_arg2));
4865}
4866
4867static inline int64_t msa_dpsub_u_df(uint32_t df, int64_t dest, int64_t arg1,
4868 int64_t arg2)
4869{
4870 int64_t even_arg1;
4871 int64_t even_arg2;
4872 int64_t odd_arg1;
4873 int64_t odd_arg2;
4874 UNSIGNED_EXTRACT(even_arg1, odd_arg1, arg1, df);
4875 UNSIGNED_EXTRACT(even_arg2, odd_arg2, arg2, df);
4876 return dest - ((even_arg1 * even_arg2) + (odd_arg1 * odd_arg2));
4877}
4878
4879static inline int64_t msa_madd_q_df(uint32_t df, int64_t dest, int64_t arg1,
4880 int64_t arg2)
4881{
4882 int64_t q_prod, q_ret;
4883
4884 int64_t q_max = DF_MAX_INT(df);
4885 int64_t q_min = DF_MIN_INT(df);
4886
4887 q_prod = arg1 * arg2;
4888 q_ret = ((dest << (DF_BITS(df) - 1)) + q_prod) >> (DF_BITS(df) - 1);
4889
4890 return (q_ret < q_min) ? q_min : (q_max < q_ret) ? q_max : q_ret;
4891}
4892
4893static inline int64_t msa_msub_q_df(uint32_t df, int64_t dest, int64_t arg1,
4894 int64_t arg2)
4895{
4896 int64_t q_prod, q_ret;
4897
4898 int64_t q_max = DF_MAX_INT(df);
4899 int64_t q_min = DF_MIN_INT(df);
4900
4901 q_prod = arg1 * arg2;
4902 q_ret = ((dest << (DF_BITS(df) - 1)) - q_prod) >> (DF_BITS(df) - 1);
4903
4904 return (q_ret < q_min) ? q_min : (q_max < q_ret) ? q_max : q_ret;
4905}
4906
4907static inline int64_t msa_maddr_q_df(uint32_t df, int64_t dest, int64_t arg1,
4908 int64_t arg2)
4909{
4910 int64_t q_prod, q_ret;
4911
4912 int64_t q_max = DF_MAX_INT(df);
4913 int64_t q_min = DF_MIN_INT(df);
4914 int64_t r_bit = 1 << (DF_BITS(df) - 2);
4915
4916 q_prod = arg1 * arg2;
4917 q_ret = ((dest << (DF_BITS(df) - 1)) + q_prod + r_bit) >> (DF_BITS(df) - 1);
4918
4919 return (q_ret < q_min) ? q_min : (q_max < q_ret) ? q_max : q_ret;
4920}
4921
4922static inline int64_t msa_msubr_q_df(uint32_t df, int64_t dest, int64_t arg1,
4923 int64_t arg2)
4924{
4925 int64_t q_prod, q_ret;
4926
4927 int64_t q_max = DF_MAX_INT(df);
4928 int64_t q_min = DF_MIN_INT(df);
4929 int64_t r_bit = 1 << (DF_BITS(df) - 2);
4930
4931 q_prod = arg1 * arg2;
4932 q_ret = ((dest << (DF_BITS(df) - 1)) - q_prod + r_bit) >> (DF_BITS(df) - 1);
4933
4934 return (q_ret < q_min) ? q_min : (q_max < q_ret) ? q_max : q_ret;
4935}
4936
4937#define MSA_TEROP_DF(func) \
4938void helper_msa_ ## func ## _df(CPUMIPSState *env, uint32_t df, uint32_t wd, \
4939 uint32_t ws, uint32_t wt) \
4940{ \
4941 wr_t *pwd = &(env->active_fpu.fpr[wd].wr); \
4942 wr_t *pws = &(env->active_fpu.fpr[ws].wr); \
4943 wr_t *pwt = &(env->active_fpu.fpr[wt].wr); \
4944 \
4945 switch (df) { \
4946 case DF_BYTE: \
4947 pwd->b[0] = msa_ ## func ## _df(df, pwd->b[0], pws->b[0], \
4948 pwt->b[0]); \
4949 pwd->b[1] = msa_ ## func ## _df(df, pwd->b[1], pws->b[1], \
4950 pwt->b[1]); \
4951 pwd->b[2] = msa_ ## func ## _df(df, pwd->b[2], pws->b[2], \
4952 pwt->b[2]); \
4953 pwd->b[3] = msa_ ## func ## _df(df, pwd->b[3], pws->b[3], \
4954 pwt->b[3]); \
4955 pwd->b[4] = msa_ ## func ## _df(df, pwd->b[4], pws->b[4], \
4956 pwt->b[4]); \
4957 pwd->b[5] = msa_ ## func ## _df(df, pwd->b[5], pws->b[5], \
4958 pwt->b[5]); \
4959 pwd->b[6] = msa_ ## func ## _df(df, pwd->b[6], pws->b[6], \
4960 pwt->b[6]); \
4961 pwd->b[7] = msa_ ## func ## _df(df, pwd->b[7], pws->b[7], \
4962 pwt->b[7]); \
4963 pwd->b[8] = msa_ ## func ## _df(df, pwd->b[8], pws->b[8], \
4964 pwt->b[8]); \
4965 pwd->b[9] = msa_ ## func ## _df(df, pwd->b[9], pws->b[9], \
4966 pwt->b[9]); \
4967 pwd->b[10] = msa_ ## func ## _df(df, pwd->b[10], pws->b[10], \
4968 pwt->b[10]); \
4969 pwd->b[11] = msa_ ## func ## _df(df, pwd->b[11], pws->b[11], \
4970 pwt->b[11]); \
4971 pwd->b[12] = msa_ ## func ## _df(df, pwd->b[12], pws->b[12], \
4972 pwt->b[12]); \
4973 pwd->b[13] = msa_ ## func ## _df(df, pwd->b[13], pws->b[13], \
4974 pwt->b[13]); \
4975 pwd->b[14] = msa_ ## func ## _df(df, pwd->b[14], pws->b[14], \
4976 pwt->b[14]); \
4977 pwd->b[15] = msa_ ## func ## _df(df, pwd->b[15], pws->b[15], \
4978 pwt->b[15]); \
4979 break; \
4980 case DF_HALF: \
4981 pwd->h[0] = msa_ ## func ## _df(df, pwd->h[0], pws->h[0], pwt->h[0]); \
4982 pwd->h[1] = msa_ ## func ## _df(df, pwd->h[1], pws->h[1], pwt->h[1]); \
4983 pwd->h[2] = msa_ ## func ## _df(df, pwd->h[2], pws->h[2], pwt->h[2]); \
4984 pwd->h[3] = msa_ ## func ## _df(df, pwd->h[3], pws->h[3], pwt->h[3]); \
4985 pwd->h[4] = msa_ ## func ## _df(df, pwd->h[4], pws->h[4], pwt->h[4]); \
4986 pwd->h[5] = msa_ ## func ## _df(df, pwd->h[5], pws->h[5], pwt->h[5]); \
4987 pwd->h[6] = msa_ ## func ## _df(df, pwd->h[6], pws->h[6], pwt->h[6]); \
4988 pwd->h[7] = msa_ ## func ## _df(df, pwd->h[7], pws->h[7], pwt->h[7]); \
4989 break; \
4990 case DF_WORD: \
4991 pwd->w[0] = msa_ ## func ## _df(df, pwd->w[0], pws->w[0], pwt->w[0]); \
4992 pwd->w[1] = msa_ ## func ## _df(df, pwd->w[1], pws->w[1], pwt->w[1]); \
4993 pwd->w[2] = msa_ ## func ## _df(df, pwd->w[2], pws->w[2], pwt->w[2]); \
4994 pwd->w[3] = msa_ ## func ## _df(df, pwd->w[3], pws->w[3], pwt->w[3]); \
4995 break; \
4996 case DF_DOUBLE: \
4997 pwd->d[0] = msa_ ## func ## _df(df, pwd->d[0], pws->d[0], pwt->d[0]); \
4998 pwd->d[1] = msa_ ## func ## _df(df, pwd->d[1], pws->d[1], pwt->d[1]); \
4999 break; \
5000 default: \
5001 assert(0); \
5002 } \
5003}
5004
5005MSA_TEROP_DF(maddv)
5006MSA_TEROP_DF(msubv)
5007MSA_TEROP_DF(dpadd_s)
5008MSA_TEROP_DF(dpadd_u)
5009MSA_TEROP_DF(dpsub_s)
5010MSA_TEROP_DF(dpsub_u)
5011MSA_TEROP_DF(binsl)
5012MSA_TEROP_DF(binsr)
5013MSA_TEROP_DF(madd_q)
5014MSA_TEROP_DF(msub_q)
5015MSA_TEROP_DF(maddr_q)
5016MSA_TEROP_DF(msubr_q)
5017#undef MSA_TEROP_DF
5018
5019static inline void msa_splat_df(uint32_t df, wr_t *pwd,
5020 wr_t *pws, target_ulong rt)
5021{
5022 uint32_t n = rt % DF_ELEMENTS(df);
5023 uint32_t i;
5024
5025 switch (df) {
5026 case DF_BYTE:
5027 for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) {
5028 pwd->b[i] = pws->b[n];
5029 }
5030 break;
5031 case DF_HALF:
5032 for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) {
5033 pwd->h[i] = pws->h[n];
5034 }
5035 break;
5036 case DF_WORD:
5037 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
5038 pwd->w[i] = pws->w[n];
5039 }
5040 break;
5041 case DF_DOUBLE:
5042 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
5043 pwd->d[i] = pws->d[n];
5044 }
5045 break;
5046 default:
5047 assert(0);
5048 }
5049}
5050
5051void helper_msa_splat_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
5052 uint32_t ws, uint32_t rt)
5053{
5054 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5055 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
5056
5057 msa_splat_df(df, pwd, pws, env->active_tc.gpr[rt]);
5058}
5059
5060#define MSA_DO_B MSA_DO(b)
5061#define MSA_DO_H MSA_DO(h)
5062#define MSA_DO_W MSA_DO(w)
5063#define MSA_DO_D MSA_DO(d)
5064
5065#define MSA_LOOP_B MSA_LOOP(B)
5066#define MSA_LOOP_H MSA_LOOP(H)
5067#define MSA_LOOP_W MSA_LOOP(W)
5068#define MSA_LOOP_D MSA_LOOP(D)
5069
5070#define MSA_LOOP_COND_B MSA_LOOP_COND(DF_BYTE)
5071#define MSA_LOOP_COND_H MSA_LOOP_COND(DF_HALF)
5072#define MSA_LOOP_COND_W MSA_LOOP_COND(DF_WORD)
5073#define MSA_LOOP_COND_D MSA_LOOP_COND(DF_DOUBLE)
5074
5075#define MSA_LOOP(DF) \
5076 do { \
5077 for (i = 0; i < (MSA_LOOP_COND_ ## DF) ; i++) { \
5078 MSA_DO_ ## DF; \
5079 } \
5080 } while (0)
5081
5082#define MSA_FN_DF(FUNC) \
5083void helper_msa_##FUNC(CPUMIPSState *env, uint32_t df, uint32_t wd, \
5084 uint32_t ws, uint32_t wt) \
5085{ \
5086 wr_t *pwd = &(env->active_fpu.fpr[wd].wr); \
5087 wr_t *pws = &(env->active_fpu.fpr[ws].wr); \
5088 wr_t *pwt = &(env->active_fpu.fpr[wt].wr); \
5089 wr_t wx, *pwx = &wx; \
5090 uint32_t i; \
5091 switch (df) { \
5092 case DF_BYTE: \
5093 MSA_LOOP_B; \
5094 break; \
5095 case DF_HALF: \
5096 MSA_LOOP_H; \
5097 break; \
5098 case DF_WORD: \
5099 MSA_LOOP_W; \
5100 break; \
5101 case DF_DOUBLE: \
5102 MSA_LOOP_D; \
5103 break; \
5104 default: \
5105 assert(0); \
5106 } \
5107 msa_move_v(pwd, pwx); \
5108}
5109
5110#define MSA_LOOP_COND(DF) \
5111 (DF_ELEMENTS(DF) / 2)
5112
5113#define Rb(pwr, i) (pwr->b[i])
5114#define Lb(pwr, i) (pwr->b[i + DF_ELEMENTS(DF_BYTE) / 2])
5115#define Rh(pwr, i) (pwr->h[i])
5116#define Lh(pwr, i) (pwr->h[i + DF_ELEMENTS(DF_HALF) / 2])
5117#define Rw(pwr, i) (pwr->w[i])
5118#define Lw(pwr, i) (pwr->w[i + DF_ELEMENTS(DF_WORD) / 2])
5119#define Rd(pwr, i) (pwr->d[i])
5120#define Ld(pwr, i) (pwr->d[i + DF_ELEMENTS(DF_DOUBLE) / 2])
5121
5122#undef MSA_LOOP_COND
5123
5124#define MSA_LOOP_COND(DF) \
5125 (DF_ELEMENTS(DF))
5126
5127#define MSA_DO(DF) \
5128 do { \
5129 uint32_t n = DF_ELEMENTS(df); \
5130 uint32_t k = (pwd->DF[i] & 0x3f) % (2 * n); \
5131 pwx->DF[i] = \
5132 (pwd->DF[i] & 0xc0) ? 0 : k < n ? pwt->DF[k] : pws->DF[k - n]; \
5133 } while (0)
5134MSA_FN_DF(vshf_df)
5135#undef MSA_DO
5136#undef MSA_LOOP_COND
5137#undef MSA_FN_DF
5138
5139
5140void helper_msa_sldi_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
5141 uint32_t ws, uint32_t n)
5142{
5143 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5144 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
5145
5146 msa_sld_df(df, pwd, pws, n);
5147}
5148
5149void helper_msa_splati_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
5150 uint32_t ws, uint32_t n)
5151{
5152 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5153 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
5154
5155 msa_splat_df(df, pwd, pws, n);
5156}
5157
5158void helper_msa_copy_s_b(CPUMIPSState *env, uint32_t rd,
5159 uint32_t ws, uint32_t n)
5160{
5161 n %= 16;
5162#if defined(HOST_WORDS_BIGENDIAN)
5163 if (n < 8) {
5164 n = 8 - n - 1;
5165 } else {
5166 n = 24 - n - 1;
5167 }
5168#endif
5169 env->active_tc.gpr[rd] = (int8_t)env->active_fpu.fpr[ws].wr.b[n];
5170}
5171
5172void helper_msa_copy_s_h(CPUMIPSState *env, uint32_t rd,
5173 uint32_t ws, uint32_t n)
5174{
5175 n %= 8;
5176#if defined(HOST_WORDS_BIGENDIAN)
5177 if (n < 4) {
5178 n = 4 - n - 1;
5179 } else {
5180 n = 12 - n - 1;
5181 }
5182#endif
5183 env->active_tc.gpr[rd] = (int16_t)env->active_fpu.fpr[ws].wr.h[n];
5184}
5185
5186void helper_msa_copy_s_w(CPUMIPSState *env, uint32_t rd,
5187 uint32_t ws, uint32_t n)
5188{
5189 n %= 4;
5190#if defined(HOST_WORDS_BIGENDIAN)
5191 if (n < 2) {
5192 n = 2 - n - 1;
5193 } else {
5194 n = 6 - n - 1;
5195 }
5196#endif
5197 env->active_tc.gpr[rd] = (int32_t)env->active_fpu.fpr[ws].wr.w[n];
5198}
5199
5200void helper_msa_copy_s_d(CPUMIPSState *env, uint32_t rd,
5201 uint32_t ws, uint32_t n)
5202{
5203 n %= 2;
5204 env->active_tc.gpr[rd] = (int64_t)env->active_fpu.fpr[ws].wr.d[n];
5205}
5206
5207void helper_msa_copy_u_b(CPUMIPSState *env, uint32_t rd,
5208 uint32_t ws, uint32_t n)
5209{
5210 n %= 16;
5211#if defined(HOST_WORDS_BIGENDIAN)
5212 if (n < 8) {
5213 n = 8 - n - 1;
5214 } else {
5215 n = 24 - n - 1;
5216 }
5217#endif
5218 env->active_tc.gpr[rd] = (uint8_t)env->active_fpu.fpr[ws].wr.b[n];
5219}
5220
5221void helper_msa_copy_u_h(CPUMIPSState *env, uint32_t rd,
5222 uint32_t ws, uint32_t n)
5223{
5224 n %= 8;
5225#if defined(HOST_WORDS_BIGENDIAN)
5226 if (n < 4) {
5227 n = 4 - n - 1;
5228 } else {
5229 n = 12 - n - 1;
5230 }
5231#endif
5232 env->active_tc.gpr[rd] = (uint16_t)env->active_fpu.fpr[ws].wr.h[n];
5233}
5234
5235void helper_msa_copy_u_w(CPUMIPSState *env, uint32_t rd,
5236 uint32_t ws, uint32_t n)
5237{
5238 n %= 4;
5239#if defined(HOST_WORDS_BIGENDIAN)
5240 if (n < 2) {
5241 n = 2 - n - 1;
5242 } else {
5243 n = 6 - n - 1;
5244 }
5245#endif
5246 env->active_tc.gpr[rd] = (uint32_t)env->active_fpu.fpr[ws].wr.w[n];
5247}
5248
5249void helper_msa_insert_b(CPUMIPSState *env, uint32_t wd,
5250 uint32_t rs_num, uint32_t n)
5251{
5252 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5253 target_ulong rs = env->active_tc.gpr[rs_num];
5254 n %= 16;
5255#if defined(HOST_WORDS_BIGENDIAN)
5256 if (n < 8) {
5257 n = 8 - n - 1;
5258 } else {
5259 n = 24 - n - 1;
5260 }
5261#endif
5262 pwd->b[n] = (int8_t)rs;
5263}
5264
5265void helper_msa_insert_h(CPUMIPSState *env, uint32_t wd,
5266 uint32_t rs_num, uint32_t n)
5267{
5268 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5269 target_ulong rs = env->active_tc.gpr[rs_num];
5270 n %= 8;
5271#if defined(HOST_WORDS_BIGENDIAN)
5272 if (n < 4) {
5273 n = 4 - n - 1;
5274 } else {
5275 n = 12 - n - 1;
5276 }
5277#endif
5278 pwd->h[n] = (int16_t)rs;
5279}
5280
5281void helper_msa_insert_w(CPUMIPSState *env, uint32_t wd,
5282 uint32_t rs_num, uint32_t n)
5283{
5284 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5285 target_ulong rs = env->active_tc.gpr[rs_num];
5286 n %= 4;
5287#if defined(HOST_WORDS_BIGENDIAN)
5288 if (n < 2) {
5289 n = 2 - n - 1;
5290 } else {
5291 n = 6 - n - 1;
5292 }
5293#endif
5294 pwd->w[n] = (int32_t)rs;
5295}
5296
5297void helper_msa_insert_d(CPUMIPSState *env, uint32_t wd,
5298 uint32_t rs_num, uint32_t n)
5299{
5300 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5301 target_ulong rs = env->active_tc.gpr[rs_num];
5302 n %= 2;
5303 pwd->d[n] = (int64_t)rs;
5304}
5305
5306void helper_msa_insve_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
5307 uint32_t ws, uint32_t n)
5308{
5309 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5310 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
5311
5312 switch (df) {
5313 case DF_BYTE:
5314 pwd->b[n] = (int8_t)pws->b[0];
5315 break;
5316 case DF_HALF:
5317 pwd->h[n] = (int16_t)pws->h[0];
5318 break;
5319 case DF_WORD:
5320 pwd->w[n] = (int32_t)pws->w[0];
5321 break;
5322 case DF_DOUBLE:
5323 pwd->d[n] = (int64_t)pws->d[0];
5324 break;
5325 default:
5326 assert(0);
5327 }
5328}
5329
5330void helper_msa_ctcmsa(CPUMIPSState *env, target_ulong elm, uint32_t cd)
5331{
5332 switch (cd) {
5333 case 0:
5334 break;
5335 case 1:
5336 env->active_tc.msacsr = (int32_t)elm & MSACSR_MASK;
5337 restore_msa_fp_status(env);
5338
5339 if ((GET_FP_ENABLE(env->active_tc.msacsr) | FP_UNIMPLEMENTED)
5340 & GET_FP_CAUSE(env->active_tc.msacsr)) {
5341 do_raise_exception(env, EXCP_MSAFPE, GETPC());
5342 }
5343 break;
5344 }
5345}
5346
5347target_ulong helper_msa_cfcmsa(CPUMIPSState *env, uint32_t cs)
5348{
5349 switch (cs) {
5350 case 0:
5351 return env->msair;
5352 case 1:
5353 return env->active_tc.msacsr & MSACSR_MASK;
5354 }
5355 return 0;
5356}
5357
5358void helper_msa_fill_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
5359 uint32_t rs)
5360{
5361 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5362 uint32_t i;
5363
5364 switch (df) {
5365 case DF_BYTE:
5366 for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) {
5367 pwd->b[i] = (int8_t)env->active_tc.gpr[rs];
5368 }
5369 break;
5370 case DF_HALF:
5371 for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) {
5372 pwd->h[i] = (int16_t)env->active_tc.gpr[rs];
5373 }
5374 break;
5375 case DF_WORD:
5376 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
5377 pwd->w[i] = (int32_t)env->active_tc.gpr[rs];
5378 }
5379 break;
5380 case DF_DOUBLE:
5381 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
5382 pwd->d[i] = (int64_t)env->active_tc.gpr[rs];
5383 }
5384 break;
5385 default:
5386 assert(0);
5387 }
5388}
5389
5390
5391#define FLOAT_ONE32 make_float32(0x3f8 << 20)
5392#define FLOAT_ONE64 make_float64(0x3ffULL << 52)
5393
5394#define FLOAT_SNAN16(s) (float16_default_nan(s) ^ 0x0220)
5395
5396#define FLOAT_SNAN32(s) (float32_default_nan(s) ^ 0x00400020)
5397
5398#define FLOAT_SNAN64(s) (float64_default_nan(s) ^ 0x0008000000000020ULL)
5399
5400
5401static inline void clear_msacsr_cause(CPUMIPSState *env)
5402{
5403 SET_FP_CAUSE(env->active_tc.msacsr, 0);
5404}
5405
5406static inline void check_msacsr_cause(CPUMIPSState *env, uintptr_t retaddr)
5407{
5408 if ((GET_FP_CAUSE(env->active_tc.msacsr) &
5409 (GET_FP_ENABLE(env->active_tc.msacsr) | FP_UNIMPLEMENTED)) == 0) {
5410 UPDATE_FP_FLAGS(env->active_tc.msacsr,
5411 GET_FP_CAUSE(env->active_tc.msacsr));
5412 } else {
5413 do_raise_exception(env, EXCP_MSAFPE, retaddr);
5414 }
5415}
5416
5417
5418#define CLEAR_FS_UNDERFLOW 1
5419#define CLEAR_IS_INEXACT 2
5420#define RECIPROCAL_INEXACT 4
5421
5422static inline int update_msacsr(CPUMIPSState *env, int action, int denormal)
5423{
5424 int ieee_ex;
5425
5426 int c;
5427 int cause;
5428 int enable;
5429
5430 ieee_ex = get_float_exception_flags(&env->active_tc.msa_fp_status);
5431
5432
5433 if (denormal) {
5434 ieee_ex |= float_flag_underflow;
5435 }
5436
5437 c = ieee_ex_to_mips(ieee_ex);
5438 enable = GET_FP_ENABLE(env->active_tc.msacsr) | FP_UNIMPLEMENTED;
5439
5440
5441 if ((ieee_ex & float_flag_input_denormal) &&
5442 (env->active_tc.msacsr & MSACSR_FS_MASK) != 0) {
5443 if (action & CLEAR_IS_INEXACT) {
5444 c &= ~FP_INEXACT;
5445 } else {
5446 c |= FP_INEXACT;
5447 }
5448 }
5449
5450
5451 if ((ieee_ex & float_flag_output_denormal) &&
5452 (env->active_tc.msacsr & MSACSR_FS_MASK) != 0) {
5453 c |= FP_INEXACT;
5454 if (action & CLEAR_FS_UNDERFLOW) {
5455 c &= ~FP_UNDERFLOW;
5456 } else {
5457 c |= FP_UNDERFLOW;
5458 }
5459 }
5460
5461
5462 if ((c & FP_OVERFLOW) != 0 && (enable & FP_OVERFLOW) == 0) {
5463 c |= FP_INEXACT;
5464 }
5465
5466
5467 if ((c & FP_UNDERFLOW) != 0 && (enable & FP_UNDERFLOW) == 0 &&
5468 (c & FP_INEXACT) == 0) {
5469 c &= ~FP_UNDERFLOW;
5470 }
5471
5472
5473
5474
5475
5476 if ((action & RECIPROCAL_INEXACT) &&
5477 (c & (FP_INVALID | FP_DIV0)) == 0) {
5478 c = FP_INEXACT;
5479 }
5480
5481 cause = c & enable;
5482
5483 if (cause == 0) {
5484
5485
5486
5487
5488 SET_FP_CAUSE(env->active_tc.msacsr,
5489 (GET_FP_CAUSE(env->active_tc.msacsr) | c));
5490 } else {
5491
5492 if ((env->active_tc.msacsr & MSACSR_NX_MASK) == 0) {
5493
5494
5495
5496
5497 SET_FP_CAUSE(env->active_tc.msacsr,
5498 (GET_FP_CAUSE(env->active_tc.msacsr) | c));
5499 }
5500 }
5501
5502 return c;
5503}
5504
5505static inline int get_enabled_exceptions(const CPUMIPSState *env, int c)
5506{
5507 int enable = GET_FP_ENABLE(env->active_tc.msacsr) | FP_UNIMPLEMENTED;
5508 return c & enable;
5509}
5510
5511static inline float16 float16_from_float32(int32_t a, flag ieee,
5512 float_status *status)
5513{
5514 float16 f_val;
5515
5516 f_val = float32_to_float16((float32)a, ieee, status);
5517
5518 return a < 0 ? (f_val | (1 << 15)) : f_val;
5519}
5520
5521static inline float32 float32_from_float64(int64_t a, float_status *status)
5522{
5523 float32 f_val;
5524
5525 f_val = float64_to_float32((float64)a, status);
5526
5527 return a < 0 ? (f_val | (1 << 31)) : f_val;
5528}
5529
5530static inline float32 float32_from_float16(int16_t a, flag ieee,
5531 float_status *status)
5532{
5533 float32 f_val;
5534
5535 f_val = float16_to_float32((float16)a, ieee, status);
5536
5537 return a < 0 ? (f_val | (1 << 31)) : f_val;
5538}
5539
5540static inline float64 float64_from_float32(int32_t a, float_status *status)
5541{
5542 float64 f_val;
5543
5544 f_val = float32_to_float64((float64)a, status);
5545
5546 return a < 0 ? (f_val | (1ULL << 63)) : f_val;
5547}
5548
5549static inline float32 float32_from_q16(int16_t a, float_status *status)
5550{
5551 float32 f_val;
5552
5553
5554 f_val = int32_to_float32(a, status);
5555 f_val = float32_scalbn(f_val, -15, status);
5556
5557 return f_val;
5558}
5559
5560static inline float64 float64_from_q32(int32_t a, float_status *status)
5561{
5562 float64 f_val;
5563
5564
5565 f_val = int32_to_float64(a, status);
5566 f_val = float64_scalbn(f_val, -31, status);
5567
5568 return f_val;
5569}
5570
5571static inline int16_t float32_to_q16(float32 a, float_status *status)
5572{
5573 int32_t q_val;
5574 int32_t q_min = 0xffff8000;
5575 int32_t q_max = 0x00007fff;
5576
5577 int ieee_ex;
5578
5579 if (float32_is_any_nan(a)) {
5580 float_raise(float_flag_invalid, status);
5581 return 0;
5582 }
5583
5584
5585 a = float32_scalbn(a, 15, status);
5586
5587 ieee_ex = get_float_exception_flags(status);
5588 set_float_exception_flags(ieee_ex & (~float_flag_underflow)
5589 , status);
5590
5591 if (ieee_ex & float_flag_overflow) {
5592 float_raise(float_flag_inexact, status);
5593 return (int32_t)a < 0 ? q_min : q_max;
5594 }
5595
5596
5597 q_val = float32_to_int32(a, status);
5598
5599 ieee_ex = get_float_exception_flags(status);
5600 set_float_exception_flags(ieee_ex & (~float_flag_underflow)
5601 , status);
5602
5603 if (ieee_ex & float_flag_invalid) {
5604 set_float_exception_flags(ieee_ex & (~float_flag_invalid)
5605 , status);
5606 float_raise(float_flag_overflow | float_flag_inexact, status);
5607 return (int32_t)a < 0 ? q_min : q_max;
5608 }
5609
5610 if (q_val < q_min) {
5611 float_raise(float_flag_overflow | float_flag_inexact, status);
5612 return (int16_t)q_min;
5613 }
5614
5615 if (q_max < q_val) {
5616 float_raise(float_flag_overflow | float_flag_inexact, status);
5617 return (int16_t)q_max;
5618 }
5619
5620 return (int16_t)q_val;
5621}
5622
5623static inline int32_t float64_to_q32(float64 a, float_status *status)
5624{
5625 int64_t q_val;
5626 int64_t q_min = 0xffffffff80000000LL;
5627 int64_t q_max = 0x000000007fffffffLL;
5628
5629 int ieee_ex;
5630
5631 if (float64_is_any_nan(a)) {
5632 float_raise(float_flag_invalid, status);
5633 return 0;
5634 }
5635
5636
5637 a = float64_scalbn(a, 31, status);
5638
5639 ieee_ex = get_float_exception_flags(status);
5640 set_float_exception_flags(ieee_ex & (~float_flag_underflow)
5641 , status);
5642
5643 if (ieee_ex & float_flag_overflow) {
5644 float_raise(float_flag_inexact, status);
5645 return (int64_t)a < 0 ? q_min : q_max;
5646 }
5647
5648
5649 q_val = float64_to_int64(a, status);
5650
5651 ieee_ex = get_float_exception_flags(status);
5652 set_float_exception_flags(ieee_ex & (~float_flag_underflow)
5653 , status);
5654
5655 if (ieee_ex & float_flag_invalid) {
5656 set_float_exception_flags(ieee_ex & (~float_flag_invalid)
5657 , status);
5658 float_raise(float_flag_overflow | float_flag_inexact, status);
5659 return (int64_t)a < 0 ? q_min : q_max;
5660 }
5661
5662 if (q_val < q_min) {
5663 float_raise(float_flag_overflow | float_flag_inexact, status);
5664 return (int32_t)q_min;
5665 }
5666
5667 if (q_max < q_val) {
5668 float_raise(float_flag_overflow | float_flag_inexact, status);
5669 return (int32_t)q_max;
5670 }
5671
5672 return (int32_t)q_val;
5673}
5674
5675#define MSA_FLOAT_COND(DEST, OP, ARG1, ARG2, BITS, QUIET) \
5676 do { \
5677 float_status *status = &env->active_tc.msa_fp_status; \
5678 int c; \
5679 int64_t cond; \
5680 set_float_exception_flags(0, status); \
5681 if (!QUIET) { \
5682 cond = float ## BITS ## _ ## OP(ARG1, ARG2, status); \
5683 } else { \
5684 cond = float ## BITS ## _ ## OP ## _quiet(ARG1, ARG2, status); \
5685 } \
5686 DEST = cond ? M_MAX_UINT(BITS) : 0; \
5687 c = update_msacsr(env, CLEAR_IS_INEXACT, 0); \
5688 \
5689 if (get_enabled_exceptions(env, c)) { \
5690 DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c; \
5691 } \
5692 } while (0)
5693
5694#define MSA_FLOAT_AF(DEST, ARG1, ARG2, BITS, QUIET) \
5695 do { \
5696 MSA_FLOAT_COND(DEST, eq, ARG1, ARG2, BITS, QUIET); \
5697 if ((DEST & M_MAX_UINT(BITS)) == M_MAX_UINT(BITS)) { \
5698 DEST = 0; \
5699 } \
5700 } while (0)
5701
5702#define MSA_FLOAT_UEQ(DEST, ARG1, ARG2, BITS, QUIET) \
5703 do { \
5704 MSA_FLOAT_COND(DEST, unordered, ARG1, ARG2, BITS, QUIET); \
5705 if (DEST == 0) { \
5706 MSA_FLOAT_COND(DEST, eq, ARG1, ARG2, BITS, QUIET); \
5707 } \
5708 } while (0)
5709
5710#define MSA_FLOAT_NE(DEST, ARG1, ARG2, BITS, QUIET) \
5711 do { \
5712 MSA_FLOAT_COND(DEST, lt, ARG1, ARG2, BITS, QUIET); \
5713 if (DEST == 0) { \
5714 MSA_FLOAT_COND(DEST, lt, ARG2, ARG1, BITS, QUIET); \
5715 } \
5716 } while (0)
5717
5718#define MSA_FLOAT_UNE(DEST, ARG1, ARG2, BITS, QUIET) \
5719 do { \
5720 MSA_FLOAT_COND(DEST, unordered, ARG1, ARG2, BITS, QUIET); \
5721 if (DEST == 0) { \
5722 MSA_FLOAT_COND(DEST, lt, ARG1, ARG2, BITS, QUIET); \
5723 if (DEST == 0) { \
5724 MSA_FLOAT_COND(DEST, lt, ARG2, ARG1, BITS, QUIET); \
5725 } \
5726 } \
5727 } while (0)
5728
5729#define MSA_FLOAT_ULE(DEST, ARG1, ARG2, BITS, QUIET) \
5730 do { \
5731 MSA_FLOAT_COND(DEST, unordered, ARG1, ARG2, BITS, QUIET); \
5732 if (DEST == 0) { \
5733 MSA_FLOAT_COND(DEST, le, ARG1, ARG2, BITS, QUIET); \
5734 } \
5735 } while (0)
5736
5737#define MSA_FLOAT_ULT(DEST, ARG1, ARG2, BITS, QUIET) \
5738 do { \
5739 MSA_FLOAT_COND(DEST, unordered, ARG1, ARG2, BITS, QUIET); \
5740 if (DEST == 0) { \
5741 MSA_FLOAT_COND(DEST, lt, ARG1, ARG2, BITS, QUIET); \
5742 } \
5743 } while (0)
5744
5745#define MSA_FLOAT_OR(DEST, ARG1, ARG2, BITS, QUIET) \
5746 do { \
5747 MSA_FLOAT_COND(DEST, le, ARG1, ARG2, BITS, QUIET); \
5748 if (DEST == 0) { \
5749 MSA_FLOAT_COND(DEST, le, ARG2, ARG1, BITS, QUIET); \
5750 } \
5751 } while (0)
5752
5753static inline void compare_af(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
5754 wr_t *pwt, uint32_t df, int quiet,
5755 uintptr_t retaddr)
5756{
5757 wr_t wx, *pwx = &wx;
5758 uint32_t i;
5759
5760 clear_msacsr_cause(env);
5761
5762 switch (df) {
5763 case DF_WORD:
5764 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
5765 MSA_FLOAT_AF(pwx->w[i], pws->w[i], pwt->w[i], 32, quiet);
5766 }
5767 break;
5768 case DF_DOUBLE:
5769 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
5770 MSA_FLOAT_AF(pwx->d[i], pws->d[i], pwt->d[i], 64, quiet);
5771 }
5772 break;
5773 default:
5774 assert(0);
5775 }
5776
5777 check_msacsr_cause(env, retaddr);
5778
5779 msa_move_v(pwd, pwx);
5780}
5781
5782static inline void compare_un(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
5783 wr_t *pwt, uint32_t df, int quiet,
5784 uintptr_t retaddr)
5785{
5786 wr_t wx, *pwx = &wx;
5787 uint32_t i;
5788
5789 clear_msacsr_cause(env);
5790
5791 switch (df) {
5792 case DF_WORD:
5793 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
5794 MSA_FLOAT_COND(pwx->w[i], unordered, pws->w[i], pwt->w[i], 32,
5795 quiet);
5796 }
5797 break;
5798 case DF_DOUBLE:
5799 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
5800 MSA_FLOAT_COND(pwx->d[i], unordered, pws->d[i], pwt->d[i], 64,
5801 quiet);
5802 }
5803 break;
5804 default:
5805 assert(0);
5806 }
5807
5808 check_msacsr_cause(env, retaddr);
5809
5810 msa_move_v(pwd, pwx);
5811}
5812
5813static inline void compare_eq(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
5814 wr_t *pwt, uint32_t df, int quiet,
5815 uintptr_t retaddr)
5816{
5817 wr_t wx, *pwx = &wx;
5818 uint32_t i;
5819
5820 clear_msacsr_cause(env);
5821
5822 switch (df) {
5823 case DF_WORD:
5824 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
5825 MSA_FLOAT_COND(pwx->w[i], eq, pws->w[i], pwt->w[i], 32, quiet);
5826 }
5827 break;
5828 case DF_DOUBLE:
5829 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
5830 MSA_FLOAT_COND(pwx->d[i], eq, pws->d[i], pwt->d[i], 64, quiet);
5831 }
5832 break;
5833 default:
5834 assert(0);
5835 }
5836
5837 check_msacsr_cause(env, retaddr);
5838
5839 msa_move_v(pwd, pwx);
5840}
5841
5842static inline void compare_ueq(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
5843 wr_t *pwt, uint32_t df, int quiet,
5844 uintptr_t retaddr)
5845{
5846 wr_t wx, *pwx = &wx;
5847 uint32_t i;
5848
5849 clear_msacsr_cause(env);
5850
5851 switch (df) {
5852 case DF_WORD:
5853 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
5854 MSA_FLOAT_UEQ(pwx->w[i], pws->w[i], pwt->w[i], 32, quiet);
5855 }
5856 break;
5857 case DF_DOUBLE:
5858 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
5859 MSA_FLOAT_UEQ(pwx->d[i], pws->d[i], pwt->d[i], 64, quiet);
5860 }
5861 break;
5862 default:
5863 assert(0);
5864 }
5865
5866 check_msacsr_cause(env, retaddr);
5867
5868 msa_move_v(pwd, pwx);
5869}
5870
5871static inline void compare_lt(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
5872 wr_t *pwt, uint32_t df, int quiet,
5873 uintptr_t retaddr)
5874{
5875 wr_t wx, *pwx = &wx;
5876 uint32_t i;
5877
5878 clear_msacsr_cause(env);
5879
5880 switch (df) {
5881 case DF_WORD:
5882 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
5883 MSA_FLOAT_COND(pwx->w[i], lt, pws->w[i], pwt->w[i], 32, quiet);
5884 }
5885 break;
5886 case DF_DOUBLE:
5887 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
5888 MSA_FLOAT_COND(pwx->d[i], lt, pws->d[i], pwt->d[i], 64, quiet);
5889 }
5890 break;
5891 default:
5892 assert(0);
5893 }
5894
5895 check_msacsr_cause(env, retaddr);
5896
5897 msa_move_v(pwd, pwx);
5898}
5899
5900static inline void compare_ult(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
5901 wr_t *pwt, uint32_t df, int quiet,
5902 uintptr_t retaddr)
5903{
5904 wr_t wx, *pwx = &wx;
5905 uint32_t i;
5906
5907 clear_msacsr_cause(env);
5908
5909 switch (df) {
5910 case DF_WORD:
5911 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
5912 MSA_FLOAT_ULT(pwx->w[i], pws->w[i], pwt->w[i], 32, quiet);
5913 }
5914 break;
5915 case DF_DOUBLE:
5916 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
5917 MSA_FLOAT_ULT(pwx->d[i], pws->d[i], pwt->d[i], 64, quiet);
5918 }
5919 break;
5920 default:
5921 assert(0);
5922 }
5923
5924 check_msacsr_cause(env, retaddr);
5925
5926 msa_move_v(pwd, pwx);
5927}
5928
5929static inline void compare_le(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
5930 wr_t *pwt, uint32_t df, int quiet,
5931 uintptr_t retaddr)
5932{
5933 wr_t wx, *pwx = &wx;
5934 uint32_t i;
5935
5936 clear_msacsr_cause(env);
5937
5938 switch (df) {
5939 case DF_WORD:
5940 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
5941 MSA_FLOAT_COND(pwx->w[i], le, pws->w[i], pwt->w[i], 32, quiet);
5942 }
5943 break;
5944 case DF_DOUBLE:
5945 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
5946 MSA_FLOAT_COND(pwx->d[i], le, pws->d[i], pwt->d[i], 64, quiet);
5947 }
5948 break;
5949 default:
5950 assert(0);
5951 }
5952
5953 check_msacsr_cause(env, retaddr);
5954
5955 msa_move_v(pwd, pwx);
5956}
5957
5958static inline void compare_ule(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
5959 wr_t *pwt, uint32_t df, int quiet,
5960 uintptr_t retaddr)
5961{
5962 wr_t wx, *pwx = &wx;
5963 uint32_t i;
5964
5965 clear_msacsr_cause(env);
5966
5967 switch (df) {
5968 case DF_WORD:
5969 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
5970 MSA_FLOAT_ULE(pwx->w[i], pws->w[i], pwt->w[i], 32, quiet);
5971 }
5972 break;
5973 case DF_DOUBLE:
5974 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
5975 MSA_FLOAT_ULE(pwx->d[i], pws->d[i], pwt->d[i], 64, quiet);
5976 }
5977 break;
5978 default:
5979 assert(0);
5980 }
5981
5982 check_msacsr_cause(env, retaddr);
5983
5984 msa_move_v(pwd, pwx);
5985}
5986
5987static inline void compare_or(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
5988 wr_t *pwt, uint32_t df, int quiet,
5989 uintptr_t retaddr)
5990{
5991 wr_t wx, *pwx = &wx;
5992 uint32_t i;
5993
5994 clear_msacsr_cause(env);
5995
5996 switch (df) {
5997 case DF_WORD:
5998 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
5999 MSA_FLOAT_OR(pwx->w[i], pws->w[i], pwt->w[i], 32, quiet);
6000 }
6001 break;
6002 case DF_DOUBLE:
6003 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6004 MSA_FLOAT_OR(pwx->d[i], pws->d[i], pwt->d[i], 64, quiet);
6005 }
6006 break;
6007 default:
6008 assert(0);
6009 }
6010
6011 check_msacsr_cause(env, retaddr);
6012
6013 msa_move_v(pwd, pwx);
6014}
6015
6016static inline void compare_une(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
6017 wr_t *pwt, uint32_t df, int quiet,
6018 uintptr_t retaddr)
6019{
6020 wr_t wx, *pwx = &wx;
6021 uint32_t i;
6022
6023 clear_msacsr_cause(env);
6024
6025 switch (df) {
6026 case DF_WORD:
6027 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6028 MSA_FLOAT_UNE(pwx->w[i], pws->w[i], pwt->w[i], 32, quiet);
6029 }
6030 break;
6031 case DF_DOUBLE:
6032 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6033 MSA_FLOAT_UNE(pwx->d[i], pws->d[i], pwt->d[i], 64, quiet);
6034 }
6035 break;
6036 default:
6037 assert(0);
6038 }
6039
6040 check_msacsr_cause(env, retaddr);
6041
6042 msa_move_v(pwd, pwx);
6043}
6044
6045static inline void compare_ne(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
6046 wr_t *pwt, uint32_t df, int quiet,
6047 uintptr_t retaddr)
6048{
6049 wr_t wx, *pwx = &wx;
6050 uint32_t i;
6051
6052 clear_msacsr_cause(env);
6053
6054 switch (df) {
6055 case DF_WORD:
6056 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6057 MSA_FLOAT_NE(pwx->w[i], pws->w[i], pwt->w[i], 32, quiet);
6058 }
6059 break;
6060 case DF_DOUBLE:
6061 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6062 MSA_FLOAT_NE(pwx->d[i], pws->d[i], pwt->d[i], 64, quiet);
6063 }
6064 break;
6065 default:
6066 assert(0);
6067 }
6068
6069 check_msacsr_cause(env, retaddr);
6070
6071 msa_move_v(pwd, pwx);
6072}
6073
6074void helper_msa_fcaf_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6075 uint32_t ws, uint32_t wt)
6076{
6077 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6078 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6079 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6080 compare_af(env, pwd, pws, pwt, df, 1, GETPC());
6081}
6082
6083void helper_msa_fcun_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6084 uint32_t ws, uint32_t wt)
6085{
6086 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6087 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6088 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6089 compare_un(env, pwd, pws, pwt, df, 1, GETPC());
6090}
6091
6092void helper_msa_fceq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6093 uint32_t ws, uint32_t wt)
6094{
6095 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6096 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6097 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6098 compare_eq(env, pwd, pws, pwt, df, 1, GETPC());
6099}
6100
6101void helper_msa_fcueq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6102 uint32_t ws, uint32_t wt)
6103{
6104 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6105 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6106 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6107 compare_ueq(env, pwd, pws, pwt, df, 1, GETPC());
6108}
6109
6110void helper_msa_fclt_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6111 uint32_t ws, uint32_t wt)
6112{
6113 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6114 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6115 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6116 compare_lt(env, pwd, pws, pwt, df, 1, GETPC());
6117}
6118
6119void helper_msa_fcult_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6120 uint32_t ws, uint32_t wt)
6121{
6122 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6123 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6124 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6125 compare_ult(env, pwd, pws, pwt, df, 1, GETPC());
6126}
6127
6128void helper_msa_fcle_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6129 uint32_t ws, uint32_t wt)
6130{
6131 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6132 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6133 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6134 compare_le(env, pwd, pws, pwt, df, 1, GETPC());
6135}
6136
6137void helper_msa_fcule_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6138 uint32_t ws, uint32_t wt)
6139{
6140 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6141 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6142 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6143 compare_ule(env, pwd, pws, pwt, df, 1, GETPC());
6144}
6145
6146void helper_msa_fsaf_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6147 uint32_t ws, uint32_t wt)
6148{
6149 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6150 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6151 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6152 compare_af(env, pwd, pws, pwt, df, 0, GETPC());
6153}
6154
6155void helper_msa_fsun_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6156 uint32_t ws, uint32_t wt)
6157{
6158 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6159 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6160 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6161 compare_un(env, pwd, pws, pwt, df, 0, GETPC());
6162}
6163
6164void helper_msa_fseq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6165 uint32_t ws, uint32_t wt)
6166{
6167 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6168 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6169 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6170 compare_eq(env, pwd, pws, pwt, df, 0, GETPC());
6171}
6172
6173void helper_msa_fsueq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6174 uint32_t ws, uint32_t wt)
6175{
6176 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6177 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6178 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6179 compare_ueq(env, pwd, pws, pwt, df, 0, GETPC());
6180}
6181
6182void helper_msa_fslt_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6183 uint32_t ws, uint32_t wt)
6184{
6185 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6186 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6187 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6188 compare_lt(env, pwd, pws, pwt, df, 0, GETPC());
6189}
6190
6191void helper_msa_fsult_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6192 uint32_t ws, uint32_t wt)
6193{
6194 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6195 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6196 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6197 compare_ult(env, pwd, pws, pwt, df, 0, GETPC());
6198}
6199
6200void helper_msa_fsle_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6201 uint32_t ws, uint32_t wt)
6202{
6203 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6204 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6205 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6206 compare_le(env, pwd, pws, pwt, df, 0, GETPC());
6207}
6208
6209void helper_msa_fsule_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6210 uint32_t ws, uint32_t wt)
6211{
6212 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6213 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6214 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6215 compare_ule(env, pwd, pws, pwt, df, 0, GETPC());
6216}
6217
6218void helper_msa_fcor_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6219 uint32_t ws, uint32_t wt)
6220{
6221 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6222 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6223 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6224 compare_or(env, pwd, pws, pwt, df, 1, GETPC());
6225}
6226
6227void helper_msa_fcune_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6228 uint32_t ws, uint32_t wt)
6229{
6230 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6231 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6232 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6233 compare_une(env, pwd, pws, pwt, df, 1, GETPC());
6234}
6235
6236void helper_msa_fcne_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6237 uint32_t ws, uint32_t wt)
6238{
6239 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6240 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6241 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6242 compare_ne(env, pwd, pws, pwt, df, 1, GETPC());
6243}
6244
6245void helper_msa_fsor_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6246 uint32_t ws, uint32_t wt)
6247{
6248 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6249 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6250 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6251 compare_or(env, pwd, pws, pwt, df, 0, GETPC());
6252}
6253
6254void helper_msa_fsune_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6255 uint32_t ws, uint32_t wt)
6256{
6257 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6258 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6259 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6260 compare_une(env, pwd, pws, pwt, df, 0, GETPC());
6261}
6262
6263void helper_msa_fsne_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6264 uint32_t ws, uint32_t wt)
6265{
6266 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6267 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6268 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6269 compare_ne(env, pwd, pws, pwt, df, 0, GETPC());
6270}
6271
6272#define float16_is_zero(ARG) 0
6273#define float16_is_zero_or_denormal(ARG) 0
6274
6275#define IS_DENORMAL(ARG, BITS) \
6276 (!float ## BITS ## _is_zero(ARG) \
6277 && float ## BITS ## _is_zero_or_denormal(ARG))
6278
6279#define MSA_FLOAT_BINOP(DEST, OP, ARG1, ARG2, BITS) \
6280 do { \
6281 float_status *status = &env->active_tc.msa_fp_status; \
6282 int c; \
6283 \
6284 set_float_exception_flags(0, status); \
6285 DEST = float ## BITS ## _ ## OP(ARG1, ARG2, status); \
6286 c = update_msacsr(env, 0, IS_DENORMAL(DEST, BITS)); \
6287 \
6288 if (get_enabled_exceptions(env, c)) { \
6289 DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c; \
6290 } \
6291 } while (0)
6292
6293void helper_msa_fadd_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6294 uint32_t ws, uint32_t wt)
6295{
6296 wr_t wx, *pwx = &wx;
6297 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6298 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6299 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6300 uint32_t i;
6301
6302 clear_msacsr_cause(env);
6303
6304 switch (df) {
6305 case DF_WORD:
6306 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6307 MSA_FLOAT_BINOP(pwx->w[i], add, pws->w[i], pwt->w[i], 32);
6308 }
6309 break;
6310 case DF_DOUBLE:
6311 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6312 MSA_FLOAT_BINOP(pwx->d[i], add, pws->d[i], pwt->d[i], 64);
6313 }
6314 break;
6315 default:
6316 assert(0);
6317 }
6318
6319 check_msacsr_cause(env, GETPC());
6320 msa_move_v(pwd, pwx);
6321}
6322
6323void helper_msa_fsub_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6324 uint32_t ws, uint32_t wt)
6325{
6326 wr_t wx, *pwx = &wx;
6327 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6328 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6329 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6330 uint32_t i;
6331
6332 clear_msacsr_cause(env);
6333
6334 switch (df) {
6335 case DF_WORD:
6336 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6337 MSA_FLOAT_BINOP(pwx->w[i], sub, pws->w[i], pwt->w[i], 32);
6338 }
6339 break;
6340 case DF_DOUBLE:
6341 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6342 MSA_FLOAT_BINOP(pwx->d[i], sub, pws->d[i], pwt->d[i], 64);
6343 }
6344 break;
6345 default:
6346 assert(0);
6347 }
6348
6349 check_msacsr_cause(env, GETPC());
6350 msa_move_v(pwd, pwx);
6351}
6352
6353void helper_msa_fmul_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6354 uint32_t ws, uint32_t wt)
6355{
6356 wr_t wx, *pwx = &wx;
6357 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6358 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6359 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6360 uint32_t i;
6361
6362 clear_msacsr_cause(env);
6363
6364 switch (df) {
6365 case DF_WORD:
6366 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6367 MSA_FLOAT_BINOP(pwx->w[i], mul, pws->w[i], pwt->w[i], 32);
6368 }
6369 break;
6370 case DF_DOUBLE:
6371 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6372 MSA_FLOAT_BINOP(pwx->d[i], mul, pws->d[i], pwt->d[i], 64);
6373 }
6374 break;
6375 default:
6376 assert(0);
6377 }
6378
6379 check_msacsr_cause(env, GETPC());
6380
6381 msa_move_v(pwd, pwx);
6382}
6383
6384void helper_msa_fdiv_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6385 uint32_t ws, uint32_t wt)
6386{
6387 wr_t wx, *pwx = &wx;
6388 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6389 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6390 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6391 uint32_t i;
6392
6393 clear_msacsr_cause(env);
6394
6395 switch (df) {
6396 case DF_WORD:
6397 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6398 MSA_FLOAT_BINOP(pwx->w[i], div, pws->w[i], pwt->w[i], 32);
6399 }
6400 break;
6401 case DF_DOUBLE:
6402 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6403 MSA_FLOAT_BINOP(pwx->d[i], div, pws->d[i], pwt->d[i], 64);
6404 }
6405 break;
6406 default:
6407 assert(0);
6408 }
6409
6410 check_msacsr_cause(env, GETPC());
6411
6412 msa_move_v(pwd, pwx);
6413}
6414
6415#define MSA_FLOAT_MULADD(DEST, ARG1, ARG2, ARG3, NEGATE, BITS) \
6416 do { \
6417 float_status *status = &env->active_tc.msa_fp_status; \
6418 int c; \
6419 \
6420 set_float_exception_flags(0, status); \
6421 DEST = float ## BITS ## _muladd(ARG2, ARG3, ARG1, NEGATE, status); \
6422 c = update_msacsr(env, 0, IS_DENORMAL(DEST, BITS)); \
6423 \
6424 if (get_enabled_exceptions(env, c)) { \
6425 DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c; \
6426 } \
6427 } while (0)
6428
6429void helper_msa_fmadd_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6430 uint32_t ws, uint32_t wt)
6431{
6432 wr_t wx, *pwx = &wx;
6433 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6434 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6435 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6436 uint32_t i;
6437
6438 clear_msacsr_cause(env);
6439
6440 switch (df) {
6441 case DF_WORD:
6442 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6443 MSA_FLOAT_MULADD(pwx->w[i], pwd->w[i],
6444 pws->w[i], pwt->w[i], 0, 32);
6445 }
6446 break;
6447 case DF_DOUBLE:
6448 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6449 MSA_FLOAT_MULADD(pwx->d[i], pwd->d[i],
6450 pws->d[i], pwt->d[i], 0, 64);
6451 }
6452 break;
6453 default:
6454 assert(0);
6455 }
6456
6457 check_msacsr_cause(env, GETPC());
6458
6459 msa_move_v(pwd, pwx);
6460}
6461
6462void helper_msa_fmsub_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6463 uint32_t ws, uint32_t wt)
6464{
6465 wr_t wx, *pwx = &wx;
6466 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6467 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6468 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6469 uint32_t i;
6470
6471 clear_msacsr_cause(env);
6472
6473 switch (df) {
6474 case DF_WORD:
6475 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6476 MSA_FLOAT_MULADD(pwx->w[i], pwd->w[i],
6477 pws->w[i], pwt->w[i],
6478 float_muladd_negate_product, 32);
6479 }
6480 break;
6481 case DF_DOUBLE:
6482 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6483 MSA_FLOAT_MULADD(pwx->d[i], pwd->d[i],
6484 pws->d[i], pwt->d[i],
6485 float_muladd_negate_product, 64);
6486 }
6487 break;
6488 default:
6489 assert(0);
6490 }
6491
6492 check_msacsr_cause(env, GETPC());
6493
6494 msa_move_v(pwd, pwx);
6495}
6496
6497void helper_msa_fexp2_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6498 uint32_t ws, uint32_t wt)
6499{
6500 wr_t wx, *pwx = &wx;
6501 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6502 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6503 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6504 uint32_t i;
6505
6506 clear_msacsr_cause(env);
6507
6508 switch (df) {
6509 case DF_WORD:
6510 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6511 MSA_FLOAT_BINOP(pwx->w[i], scalbn, pws->w[i],
6512 pwt->w[i] > 0x200 ? 0x200 :
6513 pwt->w[i] < -0x200 ? -0x200 : pwt->w[i],
6514 32);
6515 }
6516 break;
6517 case DF_DOUBLE:
6518 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6519 MSA_FLOAT_BINOP(pwx->d[i], scalbn, pws->d[i],
6520 pwt->d[i] > 0x1000 ? 0x1000 :
6521 pwt->d[i] < -0x1000 ? -0x1000 : pwt->d[i],
6522 64);
6523 }
6524 break;
6525 default:
6526 assert(0);
6527 }
6528
6529 check_msacsr_cause(env, GETPC());
6530
6531 msa_move_v(pwd, pwx);
6532}
6533
6534#define MSA_FLOAT_UNOP(DEST, OP, ARG, BITS) \
6535 do { \
6536 float_status *status = &env->active_tc.msa_fp_status; \
6537 int c; \
6538 \
6539 set_float_exception_flags(0, status); \
6540 DEST = float ## BITS ## _ ## OP(ARG, status); \
6541 c = update_msacsr(env, 0, IS_DENORMAL(DEST, BITS)); \
6542 \
6543 if (get_enabled_exceptions(env, c)) { \
6544 DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c; \
6545 } \
6546 } while (0)
6547
6548void helper_msa_fexdo_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6549 uint32_t ws, uint32_t wt)
6550{
6551 wr_t wx, *pwx = &wx;
6552 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6553 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6554 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6555 uint32_t i;
6556
6557 clear_msacsr_cause(env);
6558
6559 switch (df) {
6560 case DF_WORD:
6561 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6562
6563
6564
6565
6566
6567 flag ieee = 1;
6568
6569 MSA_FLOAT_BINOP(Lh(pwx, i), from_float32, pws->w[i], ieee, 16);
6570 MSA_FLOAT_BINOP(Rh(pwx, i), from_float32, pwt->w[i], ieee, 16);
6571 }
6572 break;
6573 case DF_DOUBLE:
6574 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6575 MSA_FLOAT_UNOP(Lw(pwx, i), from_float64, pws->d[i], 32);
6576 MSA_FLOAT_UNOP(Rw(pwx, i), from_float64, pwt->d[i], 32);
6577 }
6578 break;
6579 default:
6580 assert(0);
6581 }
6582
6583 check_msacsr_cause(env, GETPC());
6584 msa_move_v(pwd, pwx);
6585}
6586
6587#define MSA_FLOAT_UNOP_XD(DEST, OP, ARG, BITS, XBITS) \
6588 do { \
6589 float_status *status = &env->active_tc.msa_fp_status; \
6590 int c; \
6591 \
6592 set_float_exception_flags(0, status); \
6593 DEST = float ## BITS ## _ ## OP(ARG, status); \
6594 c = update_msacsr(env, CLEAR_FS_UNDERFLOW, 0); \
6595 \
6596 if (get_enabled_exceptions(env, c)) { \
6597 DEST = ((FLOAT_SNAN ## XBITS(status) >> 6) << 6) | c; \
6598 } \
6599 } while (0)
6600
6601void helper_msa_ftq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6602 uint32_t ws, uint32_t wt)
6603{
6604 wr_t wx, *pwx = &wx;
6605 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6606 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6607 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6608 uint32_t i;
6609
6610 clear_msacsr_cause(env);
6611
6612 switch (df) {
6613 case DF_WORD:
6614 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6615 MSA_FLOAT_UNOP_XD(Lh(pwx, i), to_q16, pws->w[i], 32, 16);
6616 MSA_FLOAT_UNOP_XD(Rh(pwx, i), to_q16, pwt->w[i], 32, 16);
6617 }
6618 break;
6619 case DF_DOUBLE:
6620 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6621 MSA_FLOAT_UNOP_XD(Lw(pwx, i), to_q32, pws->d[i], 64, 32);
6622 MSA_FLOAT_UNOP_XD(Rw(pwx, i), to_q32, pwt->d[i], 64, 32);
6623 }
6624 break;
6625 default:
6626 assert(0);
6627 }
6628
6629 check_msacsr_cause(env, GETPC());
6630
6631 msa_move_v(pwd, pwx);
6632}
6633
6634#define NUMBER_QNAN_PAIR(ARG1, ARG2, BITS, STATUS) \
6635 !float ## BITS ## _is_any_nan(ARG1) \
6636 && float ## BITS ## _is_quiet_nan(ARG2, STATUS)
6637
6638#define MSA_FLOAT_MAXOP(DEST, OP, ARG1, ARG2, BITS) \
6639 do { \
6640 float_status *status = &env->active_tc.msa_fp_status; \
6641 int c; \
6642 \
6643 set_float_exception_flags(0, status); \
6644 DEST = float ## BITS ## _ ## OP(ARG1, ARG2, status); \
6645 c = update_msacsr(env, 0, 0); \
6646 \
6647 if (get_enabled_exceptions(env, c)) { \
6648 DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c; \
6649 } \
6650 } while (0)
6651
6652#define FMAXMIN_A(F, G, X, _S, _T, BITS, STATUS) \
6653 do { \
6654 uint## BITS ##_t S = _S, T = _T; \
6655 uint## BITS ##_t as, at, xs, xt, xd; \
6656 if (NUMBER_QNAN_PAIR(S, T, BITS, STATUS)) { \
6657 T = S; \
6658 } \
6659 else if (NUMBER_QNAN_PAIR(T, S, BITS, STATUS)) { \
6660 S = T; \
6661 } \
6662 as = float## BITS ##_abs(S); \
6663 at = float## BITS ##_abs(T); \
6664 MSA_FLOAT_MAXOP(xs, F, S, T, BITS); \
6665 MSA_FLOAT_MAXOP(xt, G, S, T, BITS); \
6666 MSA_FLOAT_MAXOP(xd, F, as, at, BITS); \
6667 X = (as == at || xd == float## BITS ##_abs(xs)) ? xs : xt; \
6668 } while (0)
6669
6670void helper_msa_fmin_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6671 uint32_t ws, uint32_t wt)
6672{
6673 float_status *status = &env->active_tc.msa_fp_status;
6674 wr_t wx, *pwx = &wx;
6675 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6676 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6677 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6678
6679 clear_msacsr_cause(env);
6680
6681 if (df == DF_WORD) {
6682
6683 if (NUMBER_QNAN_PAIR(pws->w[0], pwt->w[0], 32, status)) {
6684 MSA_FLOAT_MAXOP(pwx->w[0], min, pws->w[0], pws->w[0], 32);
6685 } else if (NUMBER_QNAN_PAIR(pwt->w[0], pws->w[0], 32, status)) {
6686 MSA_FLOAT_MAXOP(pwx->w[0], min, pwt->w[0], pwt->w[0], 32);
6687 } else {
6688 MSA_FLOAT_MAXOP(pwx->w[0], min, pws->w[0], pwt->w[0], 32);
6689 }
6690
6691 if (NUMBER_QNAN_PAIR(pws->w[1], pwt->w[1], 32, status)) {
6692 MSA_FLOAT_MAXOP(pwx->w[1], min, pws->w[1], pws->w[1], 32);
6693 } else if (NUMBER_QNAN_PAIR(pwt->w[1], pws->w[1], 32, status)) {
6694 MSA_FLOAT_MAXOP(pwx->w[1], min, pwt->w[1], pwt->w[1], 32);
6695 } else {
6696 MSA_FLOAT_MAXOP(pwx->w[1], min, pws->w[1], pwt->w[1], 32);
6697 }
6698
6699 if (NUMBER_QNAN_PAIR(pws->w[2], pwt->w[2], 32, status)) {
6700 MSA_FLOAT_MAXOP(pwx->w[2], min, pws->w[2], pws->w[2], 32);
6701 } else if (NUMBER_QNAN_PAIR(pwt->w[2], pws->w[2], 32, status)) {
6702 MSA_FLOAT_MAXOP(pwx->w[2], min, pwt->w[2], pwt->w[2], 32);
6703 } else {
6704 MSA_FLOAT_MAXOP(pwx->w[2], min, pws->w[2], pwt->w[2], 32);
6705 }
6706
6707 if (NUMBER_QNAN_PAIR(pws->w[3], pwt->w[3], 32, status)) {
6708 MSA_FLOAT_MAXOP(pwx->w[3], min, pws->w[3], pws->w[3], 32);
6709 } else if (NUMBER_QNAN_PAIR(pwt->w[3], pws->w[3], 32, status)) {
6710 MSA_FLOAT_MAXOP(pwx->w[3], min, pwt->w[3], pwt->w[3], 32);
6711 } else {
6712 MSA_FLOAT_MAXOP(pwx->w[3], min, pws->w[3], pwt->w[3], 32);
6713 }
6714
6715 } else if (df == DF_DOUBLE) {
6716
6717 if (NUMBER_QNAN_PAIR(pws->d[0], pwt->d[0], 64, status)) {
6718 MSA_FLOAT_MAXOP(pwx->d[0], min, pws->d[0], pws->d[0], 64);
6719 } else if (NUMBER_QNAN_PAIR(pwt->d[0], pws->d[0], 64, status)) {
6720 MSA_FLOAT_MAXOP(pwx->d[0], min, pwt->d[0], pwt->d[0], 64);
6721 } else {
6722 MSA_FLOAT_MAXOP(pwx->d[0], min, pws->d[0], pwt->d[0], 64);
6723 }
6724
6725 if (NUMBER_QNAN_PAIR(pws->d[1], pwt->d[1], 64, status)) {
6726 MSA_FLOAT_MAXOP(pwx->d[1], min, pws->d[1], pws->d[1], 64);
6727 } else if (NUMBER_QNAN_PAIR(pwt->d[1], pws->d[1], 64, status)) {
6728 MSA_FLOAT_MAXOP(pwx->d[1], min, pwt->d[1], pwt->d[1], 64);
6729 } else {
6730 MSA_FLOAT_MAXOP(pwx->d[1], min, pws->d[1], pwt->d[1], 64);
6731 }
6732
6733 } else {
6734
6735 assert(0);
6736
6737 }
6738
6739 check_msacsr_cause(env, GETPC());
6740
6741 msa_move_v(pwd, pwx);
6742}
6743
6744void helper_msa_fmin_a_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6745 uint32_t ws, uint32_t wt)
6746{
6747 float_status *status = &env->active_tc.msa_fp_status;
6748 wr_t wx, *pwx = &wx;
6749 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6750 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6751 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6752
6753 clear_msacsr_cause(env);
6754
6755 if (df == DF_WORD) {
6756 FMAXMIN_A(min, max, pwx->w[0], pws->w[0], pwt->w[0], 32, status);
6757 FMAXMIN_A(min, max, pwx->w[1], pws->w[1], pwt->w[1], 32, status);
6758 FMAXMIN_A(min, max, pwx->w[2], pws->w[2], pwt->w[2], 32, status);
6759 FMAXMIN_A(min, max, pwx->w[3], pws->w[3], pwt->w[3], 32, status);
6760 } else if (df == DF_DOUBLE) {
6761 FMAXMIN_A(min, max, pwx->d[0], pws->d[0], pwt->d[0], 64, status);
6762 FMAXMIN_A(min, max, pwx->d[1], pws->d[1], pwt->d[1], 64, status);
6763 } else {
6764 assert(0);
6765 }
6766
6767 check_msacsr_cause(env, GETPC());
6768
6769 msa_move_v(pwd, pwx);
6770}
6771
6772void helper_msa_fmax_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6773 uint32_t ws, uint32_t wt)
6774{
6775 float_status *status = &env->active_tc.msa_fp_status;
6776 wr_t wx, *pwx = &wx;
6777 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6778 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6779 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6780
6781 clear_msacsr_cause(env);
6782
6783 if (df == DF_WORD) {
6784
6785 if (NUMBER_QNAN_PAIR(pws->w[0], pwt->w[0], 32, status)) {
6786 MSA_FLOAT_MAXOP(pwx->w[0], max, pws->w[0], pws->w[0], 32);
6787 } else if (NUMBER_QNAN_PAIR(pwt->w[0], pws->w[0], 32, status)) {
6788 MSA_FLOAT_MAXOP(pwx->w[0], max, pwt->w[0], pwt->w[0], 32);
6789 } else {
6790 MSA_FLOAT_MAXOP(pwx->w[0], max, pws->w[0], pwt->w[0], 32);
6791 }
6792
6793 if (NUMBER_QNAN_PAIR(pws->w[1], pwt->w[1], 32, status)) {
6794 MSA_FLOAT_MAXOP(pwx->w[1], max, pws->w[1], pws->w[1], 32);
6795 } else if (NUMBER_QNAN_PAIR(pwt->w[1], pws->w[1], 32, status)) {
6796 MSA_FLOAT_MAXOP(pwx->w[1], max, pwt->w[1], pwt->w[1], 32);
6797 } else {
6798 MSA_FLOAT_MAXOP(pwx->w[1], max, pws->w[1], pwt->w[1], 32);
6799 }
6800
6801 if (NUMBER_QNAN_PAIR(pws->w[2], pwt->w[2], 32, status)) {
6802 MSA_FLOAT_MAXOP(pwx->w[2], max, pws->w[2], pws->w[2], 32);
6803 } else if (NUMBER_QNAN_PAIR(pwt->w[2], pws->w[2], 32, status)) {
6804 MSA_FLOAT_MAXOP(pwx->w[2], max, pwt->w[2], pwt->w[2], 32);
6805 } else {
6806 MSA_FLOAT_MAXOP(pwx->w[2], max, pws->w[2], pwt->w[2], 32);
6807 }
6808
6809 if (NUMBER_QNAN_PAIR(pws->w[3], pwt->w[3], 32, status)) {
6810 MSA_FLOAT_MAXOP(pwx->w[3], max, pws->w[3], pws->w[3], 32);
6811 } else if (NUMBER_QNAN_PAIR(pwt->w[3], pws->w[3], 32, status)) {
6812 MSA_FLOAT_MAXOP(pwx->w[3], max, pwt->w[3], pwt->w[3], 32);
6813 } else {
6814 MSA_FLOAT_MAXOP(pwx->w[3], max, pws->w[3], pwt->w[3], 32);
6815 }
6816
6817 } else if (df == DF_DOUBLE) {
6818
6819 if (NUMBER_QNAN_PAIR(pws->d[0], pwt->d[0], 64, status)) {
6820 MSA_FLOAT_MAXOP(pwx->d[0], max, pws->d[0], pws->d[0], 64);
6821 } else if (NUMBER_QNAN_PAIR(pwt->d[0], pws->d[0], 64, status)) {
6822 MSA_FLOAT_MAXOP(pwx->d[0], max, pwt->d[0], pwt->d[0], 64);
6823 } else {
6824 MSA_FLOAT_MAXOP(pwx->d[0], max, pws->d[0], pwt->d[0], 64);
6825 }
6826
6827 if (NUMBER_QNAN_PAIR(pws->d[1], pwt->d[1], 64, status)) {
6828 MSA_FLOAT_MAXOP(pwx->d[1], max, pws->d[1], pws->d[1], 64);
6829 } else if (NUMBER_QNAN_PAIR(pwt->d[1], pws->d[1], 64, status)) {
6830 MSA_FLOAT_MAXOP(pwx->d[1], max, pwt->d[1], pwt->d[1], 64);
6831 } else {
6832 MSA_FLOAT_MAXOP(pwx->d[1], max, pws->d[1], pwt->d[1], 64);
6833 }
6834
6835 } else {
6836
6837 assert(0);
6838
6839 }
6840
6841 check_msacsr_cause(env, GETPC());
6842
6843 msa_move_v(pwd, pwx);
6844}
6845
6846void helper_msa_fmax_a_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6847 uint32_t ws, uint32_t wt)
6848{
6849 float_status *status = &env->active_tc.msa_fp_status;
6850 wr_t wx, *pwx = &wx;
6851 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6852 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6853 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6854
6855 clear_msacsr_cause(env);
6856
6857 if (df == DF_WORD) {
6858 FMAXMIN_A(max, min, pwx->w[0], pws->w[0], pwt->w[0], 32, status);
6859 FMAXMIN_A(max, min, pwx->w[1], pws->w[1], pwt->w[1], 32, status);
6860 FMAXMIN_A(max, min, pwx->w[2], pws->w[2], pwt->w[2], 32, status);
6861 FMAXMIN_A(max, min, pwx->w[3], pws->w[3], pwt->w[3], 32, status);
6862 } else if (df == DF_DOUBLE) {
6863 FMAXMIN_A(max, min, pwx->d[0], pws->d[0], pwt->d[0], 64, status);
6864 FMAXMIN_A(max, min, pwx->d[1], pws->d[1], pwt->d[1], 64, status);
6865 } else {
6866 assert(0);
6867 }
6868
6869 check_msacsr_cause(env, GETPC());
6870
6871 msa_move_v(pwd, pwx);
6872}
6873
6874void helper_msa_fclass_df(CPUMIPSState *env, uint32_t df,
6875 uint32_t wd, uint32_t ws)
6876{
6877 float_status *status = &env->active_tc.msa_fp_status;
6878
6879 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6880 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6881 if (df == DF_WORD) {
6882 pwd->w[0] = float_class_s(pws->w[0], status);
6883 pwd->w[1] = float_class_s(pws->w[1], status);
6884 pwd->w[2] = float_class_s(pws->w[2], status);
6885 pwd->w[3] = float_class_s(pws->w[3], status);
6886 } else if (df == DF_DOUBLE) {
6887 pwd->d[0] = float_class_d(pws->d[0], status);
6888 pwd->d[1] = float_class_d(pws->d[1], status);
6889 } else {
6890 assert(0);
6891 }
6892}
6893
6894#define MSA_FLOAT_UNOP0(DEST, OP, ARG, BITS) \
6895 do { \
6896 float_status *status = &env->active_tc.msa_fp_status; \
6897 int c; \
6898 \
6899 set_float_exception_flags(0, status); \
6900 DEST = float ## BITS ## _ ## OP(ARG, status); \
6901 c = update_msacsr(env, CLEAR_FS_UNDERFLOW, 0); \
6902 \
6903 if (get_enabled_exceptions(env, c)) { \
6904 DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c; \
6905 } else if (float ## BITS ## _is_any_nan(ARG)) { \
6906 DEST = 0; \
6907 } \
6908 } while (0)
6909
6910void helper_msa_ftrunc_s_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6911 uint32_t ws)
6912{
6913 wr_t wx, *pwx = &wx;
6914 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6915 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6916 uint32_t i;
6917
6918 clear_msacsr_cause(env);
6919
6920 switch (df) {
6921 case DF_WORD:
6922 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6923 MSA_FLOAT_UNOP0(pwx->w[i], to_int32_round_to_zero, pws->w[i], 32);
6924 }
6925 break;
6926 case DF_DOUBLE:
6927 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6928 MSA_FLOAT_UNOP0(pwx->d[i], to_int64_round_to_zero, pws->d[i], 64);
6929 }
6930 break;
6931 default:
6932 assert(0);
6933 }
6934
6935 check_msacsr_cause(env, GETPC());
6936
6937 msa_move_v(pwd, pwx);
6938}
6939
6940void helper_msa_ftrunc_u_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6941 uint32_t ws)
6942{
6943 wr_t wx, *pwx = &wx;
6944 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6945 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6946 uint32_t i;
6947
6948 clear_msacsr_cause(env);
6949
6950 switch (df) {
6951 case DF_WORD:
6952 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6953 MSA_FLOAT_UNOP0(pwx->w[i], to_uint32_round_to_zero, pws->w[i], 32);
6954 }
6955 break;
6956 case DF_DOUBLE:
6957 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6958 MSA_FLOAT_UNOP0(pwx->d[i], to_uint64_round_to_zero, pws->d[i], 64);
6959 }
6960 break;
6961 default:
6962 assert(0);
6963 }
6964
6965 check_msacsr_cause(env, GETPC());
6966
6967 msa_move_v(pwd, pwx);
6968}
6969
6970void helper_msa_fsqrt_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6971 uint32_t ws)
6972{
6973 wr_t wx, *pwx = &wx;
6974 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6975 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6976 uint32_t i;
6977
6978 clear_msacsr_cause(env);
6979
6980 switch (df) {
6981 case DF_WORD:
6982 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6983 MSA_FLOAT_UNOP(pwx->w[i], sqrt, pws->w[i], 32);
6984 }
6985 break;
6986 case DF_DOUBLE:
6987 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6988 MSA_FLOAT_UNOP(pwx->d[i], sqrt, pws->d[i], 64);
6989 }
6990 break;
6991 default:
6992 assert(0);
6993 }
6994
6995 check_msacsr_cause(env, GETPC());
6996
6997 msa_move_v(pwd, pwx);
6998}
6999
7000#define MSA_FLOAT_RECIPROCAL(DEST, ARG, BITS) \
7001 do { \
7002 float_status *status = &env->active_tc.msa_fp_status; \
7003 int c; \
7004 \
7005 set_float_exception_flags(0, status); \
7006 DEST = float ## BITS ## _ ## div(FLOAT_ONE ## BITS, ARG, status); \
7007 c = update_msacsr(env, float ## BITS ## _is_infinity(ARG) || \
7008 float ## BITS ## _is_quiet_nan(DEST, status) ? \
7009 0 : RECIPROCAL_INEXACT, \
7010 IS_DENORMAL(DEST, BITS)); \
7011 \
7012 if (get_enabled_exceptions(env, c)) { \
7013 DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c; \
7014 } \
7015 } while (0)
7016
7017void helper_msa_frsqrt_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7018 uint32_t ws)
7019{
7020 wr_t wx, *pwx = &wx;
7021 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7022 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7023 uint32_t i;
7024
7025 clear_msacsr_cause(env);
7026
7027 switch (df) {
7028 case DF_WORD:
7029 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7030 MSA_FLOAT_RECIPROCAL(pwx->w[i], float32_sqrt(pws->w[i],
7031 &env->active_tc.msa_fp_status), 32);
7032 }
7033 break;
7034 case DF_DOUBLE:
7035 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7036 MSA_FLOAT_RECIPROCAL(pwx->d[i], float64_sqrt(pws->d[i],
7037 &env->active_tc.msa_fp_status), 64);
7038 }
7039 break;
7040 default:
7041 assert(0);
7042 }
7043
7044 check_msacsr_cause(env, GETPC());
7045
7046 msa_move_v(pwd, pwx);
7047}
7048
7049void helper_msa_frcp_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7050 uint32_t ws)
7051{
7052 wr_t wx, *pwx = &wx;
7053 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7054 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7055 uint32_t i;
7056
7057 clear_msacsr_cause(env);
7058
7059 switch (df) {
7060 case DF_WORD:
7061 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7062 MSA_FLOAT_RECIPROCAL(pwx->w[i], pws->w[i], 32);
7063 }
7064 break;
7065 case DF_DOUBLE:
7066 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7067 MSA_FLOAT_RECIPROCAL(pwx->d[i], pws->d[i], 64);
7068 }
7069 break;
7070 default:
7071 assert(0);
7072 }
7073
7074 check_msacsr_cause(env, GETPC());
7075
7076 msa_move_v(pwd, pwx);
7077}
7078
7079void helper_msa_frint_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7080 uint32_t ws)
7081{
7082 wr_t wx, *pwx = &wx;
7083 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7084 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7085 uint32_t i;
7086
7087 clear_msacsr_cause(env);
7088
7089 switch (df) {
7090 case DF_WORD:
7091 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7092 MSA_FLOAT_UNOP(pwx->w[i], round_to_int, pws->w[i], 32);
7093 }
7094 break;
7095 case DF_DOUBLE:
7096 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7097 MSA_FLOAT_UNOP(pwx->d[i], round_to_int, pws->d[i], 64);
7098 }
7099 break;
7100 default:
7101 assert(0);
7102 }
7103
7104 check_msacsr_cause(env, GETPC());
7105
7106 msa_move_v(pwd, pwx);
7107}
7108
7109#define MSA_FLOAT_LOGB(DEST, ARG, BITS) \
7110 do { \
7111 float_status *status = &env->active_tc.msa_fp_status; \
7112 int c; \
7113 \
7114 set_float_exception_flags(0, status); \
7115 set_float_rounding_mode(float_round_down, status); \
7116 DEST = float ## BITS ## _ ## log2(ARG, status); \
7117 DEST = float ## BITS ## _ ## round_to_int(DEST, status); \
7118 set_float_rounding_mode(ieee_rm[(env->active_tc.msacsr & \
7119 MSACSR_RM_MASK) >> MSACSR_RM], \
7120 status); \
7121 \
7122 set_float_exception_flags(get_float_exception_flags(status) & \
7123 (~float_flag_inexact), \
7124 status); \
7125 \
7126 c = update_msacsr(env, 0, IS_DENORMAL(DEST, BITS)); \
7127 \
7128 if (get_enabled_exceptions(env, c)) { \
7129 DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c; \
7130 } \
7131 } while (0)
7132
7133void helper_msa_flog2_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7134 uint32_t ws)
7135{
7136 wr_t wx, *pwx = &wx;
7137 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7138 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7139 uint32_t i;
7140
7141 clear_msacsr_cause(env);
7142
7143 switch (df) {
7144 case DF_WORD:
7145 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7146 MSA_FLOAT_LOGB(pwx->w[i], pws->w[i], 32);
7147 }
7148 break;
7149 case DF_DOUBLE:
7150 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7151 MSA_FLOAT_LOGB(pwx->d[i], pws->d[i], 64);
7152 }
7153 break;
7154 default:
7155 assert(0);
7156 }
7157
7158 check_msacsr_cause(env, GETPC());
7159
7160 msa_move_v(pwd, pwx);
7161}
7162
7163void helper_msa_fexupl_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7164 uint32_t ws)
7165{
7166 wr_t wx, *pwx = &wx;
7167 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7168 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7169 uint32_t i;
7170
7171 clear_msacsr_cause(env);
7172
7173 switch (df) {
7174 case DF_WORD:
7175 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7176
7177
7178
7179
7180
7181 flag ieee = 1;
7182
7183 MSA_FLOAT_BINOP(pwx->w[i], from_float16, Lh(pws, i), ieee, 32);
7184 }
7185 break;
7186 case DF_DOUBLE:
7187 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7188 MSA_FLOAT_UNOP(pwx->d[i], from_float32, Lw(pws, i), 64);
7189 }
7190 break;
7191 default:
7192 assert(0);
7193 }
7194
7195 check_msacsr_cause(env, GETPC());
7196 msa_move_v(pwd, pwx);
7197}
7198
7199void helper_msa_fexupr_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7200 uint32_t ws)
7201{
7202 wr_t wx, *pwx = &wx;
7203 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7204 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7205 uint32_t i;
7206
7207 clear_msacsr_cause(env);
7208
7209 switch (df) {
7210 case DF_WORD:
7211 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7212
7213
7214
7215
7216
7217 flag ieee = 1;
7218
7219 MSA_FLOAT_BINOP(pwx->w[i], from_float16, Rh(pws, i), ieee, 32);
7220 }
7221 break;
7222 case DF_DOUBLE:
7223 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7224 MSA_FLOAT_UNOP(pwx->d[i], from_float32, Rw(pws, i), 64);
7225 }
7226 break;
7227 default:
7228 assert(0);
7229 }
7230
7231 check_msacsr_cause(env, GETPC());
7232 msa_move_v(pwd, pwx);
7233}
7234
7235void helper_msa_ffql_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7236 uint32_t ws)
7237{
7238 wr_t wx, *pwx = &wx;
7239 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7240 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7241 uint32_t i;
7242
7243 switch (df) {
7244 case DF_WORD:
7245 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7246 MSA_FLOAT_UNOP(pwx->w[i], from_q16, Lh(pws, i), 32);
7247 }
7248 break;
7249 case DF_DOUBLE:
7250 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7251 MSA_FLOAT_UNOP(pwx->d[i], from_q32, Lw(pws, i), 64);
7252 }
7253 break;
7254 default:
7255 assert(0);
7256 }
7257
7258 msa_move_v(pwd, pwx);
7259}
7260
7261void helper_msa_ffqr_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7262 uint32_t ws)
7263{
7264 wr_t wx, *pwx = &wx;
7265 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7266 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7267 uint32_t i;
7268
7269 switch (df) {
7270 case DF_WORD:
7271 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7272 MSA_FLOAT_UNOP(pwx->w[i], from_q16, Rh(pws, i), 32);
7273 }
7274 break;
7275 case DF_DOUBLE:
7276 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7277 MSA_FLOAT_UNOP(pwx->d[i], from_q32, Rw(pws, i), 64);
7278 }
7279 break;
7280 default:
7281 assert(0);
7282 }
7283
7284 msa_move_v(pwd, pwx);
7285}
7286
7287void helper_msa_ftint_s_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7288 uint32_t ws)
7289{
7290 wr_t wx, *pwx = &wx;
7291 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7292 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7293 uint32_t i;
7294
7295 clear_msacsr_cause(env);
7296
7297 switch (df) {
7298 case DF_WORD:
7299 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7300 MSA_FLOAT_UNOP0(pwx->w[i], to_int32, pws->w[i], 32);
7301 }
7302 break;
7303 case DF_DOUBLE:
7304 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7305 MSA_FLOAT_UNOP0(pwx->d[i], to_int64, pws->d[i], 64);
7306 }
7307 break;
7308 default:
7309 assert(0);
7310 }
7311
7312 check_msacsr_cause(env, GETPC());
7313
7314 msa_move_v(pwd, pwx);
7315}
7316
7317void helper_msa_ftint_u_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7318 uint32_t ws)
7319{
7320 wr_t wx, *pwx = &wx;
7321 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7322 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7323 uint32_t i;
7324
7325 clear_msacsr_cause(env);
7326
7327 switch (df) {
7328 case DF_WORD:
7329 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7330 MSA_FLOAT_UNOP0(pwx->w[i], to_uint32, pws->w[i], 32);
7331 }
7332 break;
7333 case DF_DOUBLE:
7334 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7335 MSA_FLOAT_UNOP0(pwx->d[i], to_uint64, pws->d[i], 64);
7336 }
7337 break;
7338 default:
7339 assert(0);
7340 }
7341
7342 check_msacsr_cause(env, GETPC());
7343
7344 msa_move_v(pwd, pwx);
7345}
7346
7347#define float32_from_int32 int32_to_float32
7348#define float32_from_uint32 uint32_to_float32
7349
7350#define float64_from_int64 int64_to_float64
7351#define float64_from_uint64 uint64_to_float64
7352
7353void helper_msa_ffint_s_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7354 uint32_t ws)
7355{
7356 wr_t wx, *pwx = &wx;
7357 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7358 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7359 uint32_t i;
7360
7361 clear_msacsr_cause(env);
7362
7363 switch (df) {
7364 case DF_WORD:
7365 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7366 MSA_FLOAT_UNOP(pwx->w[i], from_int32, pws->w[i], 32);
7367 }
7368 break;
7369 case DF_DOUBLE:
7370 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7371 MSA_FLOAT_UNOP(pwx->d[i], from_int64, pws->d[i], 64);
7372 }
7373 break;
7374 default:
7375 assert(0);
7376 }
7377
7378 check_msacsr_cause(env, GETPC());
7379
7380 msa_move_v(pwd, pwx);
7381}
7382
7383void helper_msa_ffint_u_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7384 uint32_t ws)
7385{
7386 wr_t wx, *pwx = &wx;
7387 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7388 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7389 uint32_t i;
7390
7391 clear_msacsr_cause(env);
7392
7393 switch (df) {
7394 case DF_WORD:
7395 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7396 MSA_FLOAT_UNOP(pwx->w[i], from_uint32, pws->w[i], 32);
7397 }
7398 break;
7399 case DF_DOUBLE:
7400 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7401 MSA_FLOAT_UNOP(pwx->d[i], from_uint64, pws->d[i], 64);
7402 }
7403 break;
7404 default:
7405 assert(0);
7406 }
7407
7408 check_msacsr_cause(env, GETPC());
7409
7410 msa_move_v(pwd, pwx);
7411}
7412