target-mips: Add ASE DSP arithmetic instructions
[sdk/emulator/qemu.git] / target-mips / dsp_helper.c
1 /*
2  * MIPS ASE DSP Instruction emulation helpers for QEMU.
3  *
4  * Copyright (c) 2012  Jia Liu <proljc@gmail.com>
5  *                     Dongxue Zhang <elat.era@gmail.com>
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include "cpu.h"
21 #include "helper.h"
22
23 /*** MIPS DSP internal functions begin ***/
24 #define MIPSDSP_ABS(x) (((x) >= 0) ? x : -x)
25 #define MIPSDSP_OVERFLOW(a, b, c, d) (!(!((a ^ b ^ -1) & (a ^ c) & d)))
26
27 static inline void set_DSPControl_overflow_flag(uint32_t flag, int position,
28                                                 CPUMIPSState *env)
29 {
30     env->active_tc.DSPControl |= (target_ulong)flag << position;
31 }
32
33 static inline void set_DSPControl_carryflag(uint32_t flag, CPUMIPSState *env)
34 {
35     env->active_tc.DSPControl |= (target_ulong)flag << 13;
36 }
37
38 static inline uint32_t get_DSPControl_carryflag(CPUMIPSState *env)
39 {
40     return (env->active_tc.DSPControl >> 13) & 0x01;
41 }
42
43 static inline void set_DSPControl_24(uint32_t flag, int len, CPUMIPSState *env)
44 {
45   uint32_t filter;
46
47   filter = ((0x01 << len) - 1) << 24;
48   filter = ~filter;
49
50   env->active_tc.DSPControl &= filter;
51   env->active_tc.DSPControl |= (target_ulong)flag << 24;
52 }
53
54 static inline uint32_t get_DSPControl_24(int len, CPUMIPSState *env)
55 {
56   uint32_t filter;
57
58   filter = (0x01 << len) - 1;
59
60   return (env->active_tc.DSPControl >> 24) & filter;
61 }
62
63 static inline void set_DSPControl_pos(uint32_t pos, CPUMIPSState *env)
64 {
65     target_ulong dspc;
66
67     dspc = env->active_tc.DSPControl;
68 #ifndef TARGET_MIPS64
69     dspc = dspc & 0xFFFFFFC0;
70     dspc |= pos;
71 #else
72     dspc = dspc & 0xFFFFFF80;
73     dspc |= pos;
74 #endif
75     env->active_tc.DSPControl = dspc;
76 }
77
78 static inline uint32_t get_DSPControl_pos(CPUMIPSState *env)
79 {
80     target_ulong dspc;
81     uint32_t pos;
82
83     dspc = env->active_tc.DSPControl;
84
85 #ifndef TARGET_MIPS64
86     pos = dspc & 0x3F;
87 #else
88     pos = dspc & 0x7F;
89 #endif
90
91     return pos;
92 }
93
94 static inline void set_DSPControl_efi(uint32_t flag, CPUMIPSState *env)
95 {
96     env->active_tc.DSPControl &= 0xFFFFBFFF;
97     env->active_tc.DSPControl |= (target_ulong)flag << 14;
98 }
99
100 #define DO_MIPS_SAT_ABS(size)                                          \
101 static inline int##size##_t mipsdsp_sat_abs##size(int##size##_t a,         \
102                                                   CPUMIPSState *env)   \
103 {                                                                      \
104     if (a == INT##size##_MIN) {                                        \
105         set_DSPControl_overflow_flag(1, 20, env);                      \
106         return INT##size##_MAX;                                        \
107     } else {                                                           \
108         return MIPSDSP_ABS(a);                                         \
109     }                                                                  \
110 }
111 DO_MIPS_SAT_ABS(8)
112 DO_MIPS_SAT_ABS(16)
113 DO_MIPS_SAT_ABS(32)
114 #undef DO_MIPS_SAT_ABS
115
116 /* get sum value */
117 static inline int16_t mipsdsp_add_i16(int16_t a, int16_t b, CPUMIPSState *env)
118 {
119     int16_t tempI;
120
121     tempI = a + b;
122
123     if (MIPSDSP_OVERFLOW(a, b, tempI, 0x8000)) {
124         set_DSPControl_overflow_flag(1, 20, env);
125     }
126
127     return tempI;
128 }
129
130 static inline int16_t mipsdsp_sat_add_i16(int16_t a, int16_t b,
131                                           CPUMIPSState *env)
132 {
133     int16_t tempS;
134
135     tempS = a + b;
136
137     if (MIPSDSP_OVERFLOW(a, b, tempS, 0x8000)) {
138         if (a > 0) {
139             tempS = 0x7FFF;
140         } else {
141             tempS = 0x8000;
142         }
143         set_DSPControl_overflow_flag(1, 20, env);
144     }
145
146     return tempS;
147 }
148
149 static inline int32_t mipsdsp_sat_add_i32(int32_t a, int32_t b,
150                                           CPUMIPSState *env)
151 {
152     int32_t tempI;
153
154     tempI = a + b;
155
156     if (MIPSDSP_OVERFLOW(a, b, tempI, 0x80000000)) {
157         if (a > 0) {
158             tempI = 0x7FFFFFFF;
159         } else {
160             tempI = 0x80000000;
161         }
162         set_DSPControl_overflow_flag(1, 20, env);
163     }
164
165     return tempI;
166 }
167
168 static inline uint8_t mipsdsp_add_u8(uint8_t a, uint8_t b, CPUMIPSState *env)
169 {
170     uint16_t temp;
171
172     temp = (uint16_t)a + (uint16_t)b;
173
174     if (temp & 0x0100) {
175         set_DSPControl_overflow_flag(1, 20, env);
176     }
177
178     return temp & 0xFF;
179 }
180
181 static inline uint16_t mipsdsp_add_u16(uint16_t a, uint16_t b,
182                                        CPUMIPSState *env)
183 {
184     uint32_t temp;
185
186     temp = (uint32_t)a + (uint32_t)b;
187
188     if (temp & 0x00010000) {
189         set_DSPControl_overflow_flag(1, 20, env);
190     }
191
192     return temp & 0xFFFF;
193 }
194
195 static inline uint8_t mipsdsp_sat_add_u8(uint8_t a, uint8_t b,
196                                          CPUMIPSState *env)
197 {
198     uint8_t  result;
199     uint16_t temp;
200
201     temp = (uint16_t)a + (uint16_t)b;
202     result = temp & 0xFF;
203
204     if (0x0100 & temp) {
205         result = 0xFF;
206         set_DSPControl_overflow_flag(1, 20, env);
207     }
208
209     return result;
210 }
211
212 static inline uint16_t mipsdsp_sat_add_u16(uint16_t a, uint16_t b,
213                                            CPUMIPSState *env)
214 {
215     uint16_t result;
216     uint32_t temp;
217
218     temp = (uint32_t)a + (uint32_t)b;
219     result = temp & 0xFFFF;
220
221     if (0x00010000 & temp) {
222         result = 0xFFFF;
223         set_DSPControl_overflow_flag(1, 20, env);
224     }
225
226     return result;
227 }
228
229 static inline int32_t mipsdsp_sat32_acc_q31(int32_t acc, int32_t a,
230                                             CPUMIPSState *env)
231 {
232     int64_t temp;
233     int32_t temp32, temp31, result;
234     int64_t temp_sum;
235
236 #ifndef TARGET_MIPS64
237     temp = ((uint64_t)env->active_tc.HI[acc] << 32) |
238            (uint64_t)env->active_tc.LO[acc];
239 #else
240     temp = (uint64_t)env->active_tc.LO[acc];
241 #endif
242
243     temp_sum = (int64_t)a + temp;
244
245     temp32 = (temp_sum >> 32) & 0x01;
246     temp31 = (temp_sum >> 31) & 0x01;
247     result = temp_sum & 0xFFFFFFFF;
248
249     /* FIXME
250        This sat function may wrong, because user manual wrote:
251        temp127..0 ← temp + ( (signA) || a31..0
252        if ( temp32 ≠ temp31 ) then
253            if ( temp32 = 0 ) then
254                temp31..0 ← 0x80000000
255            else
256                 temp31..0 ← 0x7FFFFFFF
257            endif
258            DSPControlouflag:16+acc ← 1
259        endif
260      */
261     if (temp32 != temp31) {
262         if (temp32 == 0) {
263             result = 0x7FFFFFFF;
264         } else {
265             result = 0x80000000;
266         }
267         set_DSPControl_overflow_flag(1, 16 + acc, env);
268     }
269
270     return result;
271 }
272
273 /* a[0] is LO, a[1] is HI. */
274 static inline void mipsdsp_sat64_acc_add_q63(int64_t *ret,
275                                              int32_t ac,
276                                              int64_t *a,
277                                              CPUMIPSState *env)
278 {
279     bool temp64;
280
281     ret[0] = env->active_tc.LO[ac] + a[0];
282     ret[1] = env->active_tc.HI[ac] + a[1];
283
284     if (((uint64_t)ret[0] < (uint64_t)env->active_tc.LO[ac]) &&
285         ((uint64_t)ret[0] < (uint64_t)a[0])) {
286         ret[1] += 1;
287     }
288     temp64 = ret[1] & 1;
289     if (temp64 != ((ret[0] >> 63) & 0x01)) {
290         if (temp64) {
291             ret[0] = (0x01ull << 63);
292             ret[1] = ~0ull;
293         } else {
294             ret[0] = (0x01ull << 63) - 1;
295             ret[1] = 0x00;
296         }
297         set_DSPControl_overflow_flag(1, 16 + ac, env);
298     }
299 }
300
301 static inline void mipsdsp_sat64_acc_sub_q63(int64_t *ret,
302                                              int32_t ac,
303                                              int64_t *a,
304                                              CPUMIPSState *env)
305 {
306     bool temp64;
307
308     ret[0] = env->active_tc.LO[ac] - a[0];
309     ret[1] = env->active_tc.HI[ac] - a[1];
310
311     if ((uint64_t)ret[0] > (uint64_t)env->active_tc.LO[ac]) {
312         ret[1] -= 1;
313     }
314     temp64 = ret[1] & 1;
315     if (temp64 != ((ret[0] >> 63) & 0x01)) {
316         if (temp64) {
317             ret[0] = (0x01ull << 63);
318             ret[1] = ~0ull;
319         } else {
320             ret[0] = (0x01ull << 63) - 1;
321             ret[1] = 0x00;
322         }
323         set_DSPControl_overflow_flag(1, 16 + ac, env);
324     }
325 }
326
327 static inline int32_t mipsdsp_mul_i16_i16(int16_t a, int16_t b,
328                                           CPUMIPSState *env)
329 {
330     int32_t temp;
331
332     temp = (int32_t)a * (int32_t)b;
333
334     if ((temp > (int)0x7FFF) || (temp < (int)0xFFFF8000)) {
335         set_DSPControl_overflow_flag(1, 21, env);
336     }
337     temp &= 0x0000FFFF;
338
339     return temp;
340 }
341
342 static inline int32_t mipsdsp_mul_u16_u16(int32_t a, int32_t b)
343 {
344     return a * b;
345 }
346
347 static inline int32_t mipsdsp_mul_i32_i32(int32_t a, int32_t b)
348 {
349     return a * b;
350 }
351
352 static inline int32_t mipsdsp_sat16_mul_i16_i16(int16_t a, int16_t b,
353                                                 CPUMIPSState *env)
354 {
355     int32_t temp;
356
357     temp = (int32_t)a * (int32_t)b;
358
359     if (temp > (int)0x7FFF) {
360         temp = 0x00007FFF;
361         set_DSPControl_overflow_flag(1, 21, env);
362     } else if (temp < (int)0xffff8000) {
363         temp = 0xFFFF8000;
364         set_DSPControl_overflow_flag(1, 21, env);
365     }
366     temp &= 0x0000FFFF;
367
368     return temp;
369 }
370
371 static inline int32_t mipsdsp_mul_q15_q15_overflowflag21(uint16_t a, uint16_t b,
372                                                          CPUMIPSState *env)
373 {
374     int32_t temp;
375
376     if ((a == 0x8000) && (b == 0x8000)) {
377         temp = 0x7FFFFFFF;
378         set_DSPControl_overflow_flag(1, 21, env);
379     } else {
380         temp = ((int32_t)(int16_t)a * (int32_t)(int16_t)b) << 1;
381     }
382
383     return temp;
384 }
385
386 /* right shift */
387 static inline uint8_t mipsdsp_rshift_u8(uint8_t a, target_ulong mov)
388 {
389     return a >> mov;
390 }
391
392 static inline uint16_t mipsdsp_rshift_u16(uint16_t a, target_ulong mov)
393 {
394     return a >> mov;
395 }
396
397 static inline int8_t mipsdsp_rashift8(int8_t a, target_ulong mov)
398 {
399     return a >> mov;
400 }
401
402 static inline int16_t mipsdsp_rashift16(int16_t a, target_ulong mov)
403 {
404     return a >> mov;
405 }
406
407 static inline int32_t mipsdsp_rashift32(int32_t a, target_ulong mov)
408 {
409     return a >> mov;
410 }
411
412 static inline int16_t mipsdsp_rshift1_add_q16(int16_t a, int16_t b)
413 {
414     int32_t temp;
415
416     temp = (int32_t)a + (int32_t)b;
417
418     return (temp >> 1) & 0xFFFF;
419 }
420
421 /* round right shift */
422 static inline int16_t mipsdsp_rrshift1_add_q16(int16_t a, int16_t b)
423 {
424     int32_t temp;
425
426     temp = (int32_t)a + (int32_t)b;
427     temp += 1;
428
429     return (temp >> 1) & 0xFFFF;
430 }
431
432 static inline int32_t mipsdsp_rshift1_add_q32(int32_t a, int32_t b)
433 {
434     int64_t temp;
435
436     temp = (int64_t)a + (int64_t)b;
437
438     return (temp >> 1) & 0xFFFFFFFF;
439 }
440
441 static inline int32_t mipsdsp_rrshift1_add_q32(int32_t a, int32_t b)
442 {
443     int64_t temp;
444
445     temp = (int64_t)a + (int64_t)b;
446     temp += 1;
447
448     return (temp >> 1) & 0xFFFFFFFF;
449 }
450
451 static inline uint8_t mipsdsp_rshift1_add_u8(uint8_t a, uint8_t b)
452 {
453     uint16_t temp;
454
455     temp = (uint16_t)a + (uint16_t)b;
456
457     return (temp >> 1) & 0x00FF;
458 }
459
460 static inline uint8_t mipsdsp_rrshift1_add_u8(uint8_t a, uint8_t b)
461 {
462     uint16_t temp;
463
464     temp = (uint16_t)a + (uint16_t)b + 1;
465
466     return (temp >> 1) & 0x00FF;
467 }
468
469 static inline uint8_t mipsdsp_rshift1_sub_u8(uint8_t a, uint8_t b)
470 {
471     uint16_t temp;
472
473     temp = (uint16_t)a - (uint16_t)b;
474
475     return (temp >> 1) & 0x00FF;
476 }
477
478 static inline uint8_t mipsdsp_rrshift1_sub_u8(uint8_t a, uint8_t b)
479 {
480     uint16_t temp;
481
482     temp = (uint16_t)a - (uint16_t)b + 1;
483
484     return (temp >> 1) & 0x00FF;
485 }
486
487 static inline int64_t mipsdsp_rashift_short_acc(int32_t ac,
488                                                 int32_t shift,
489                                                 CPUMIPSState *env)
490 {
491     int32_t sign, temp31;
492     int64_t temp, acc;
493
494     sign = (env->active_tc.HI[ac] >> 31) & 0x01;
495     acc = ((int64_t)env->active_tc.HI[ac] << 32) |
496           ((int64_t)env->active_tc.LO[ac] & 0xFFFFFFFF);
497     if (shift == 0) {
498         temp = acc;
499     } else {
500         if (sign == 0) {
501             temp = (((int64_t)0x01 << (32 - shift + 1)) - 1) & (acc >> shift);
502         } else {
503             temp = ((((int64_t)0x01 << (shift + 1)) - 1) << (32 - shift)) |
504                    (acc >> shift);
505         }
506     }
507
508     temp31 = (temp >> 31) & 0x01;
509     if (sign != temp31) {
510         set_DSPControl_overflow_flag(1, 23, env);
511     }
512
513     return temp;
514 }
515
516 /*  128 bits long. p[0] is LO, p[1] is HI. */
517 static inline void mipsdsp_rndrashift_short_acc(int64_t *p,
518                                                 int32_t ac,
519                                                 int32_t shift,
520                                                 CPUMIPSState *env)
521 {
522     int64_t acc;
523
524     acc = ((int64_t)env->active_tc.HI[ac] << 32) |
525           ((int64_t)env->active_tc.LO[ac] & 0xFFFFFFFF);
526     if (shift == 0) {
527         p[0] = acc << 1;
528         p[1] = (acc >> 63) & 0x01;
529     } else {
530         p[0] = acc >> (shift - 1);
531         p[1] = 0;
532     }
533 }
534
535 /* 128 bits long. p[0] is LO, p[1] is HI */
536 static inline void mipsdsp_rashift_acc(uint64_t *p,
537                                        uint32_t ac,
538                                        uint32_t shift,
539                                        CPUMIPSState *env)
540 {
541     uint64_t tempB, tempA;
542
543     tempB = env->active_tc.HI[ac];
544     tempA = env->active_tc.LO[ac];
545     shift = shift & 0x1F;
546
547     if (shift == 0) {
548         p[1] = tempB;
549         p[0] = tempA;
550     } else {
551         p[0] = (tempB << (64 - shift)) | (tempA >> shift);
552         p[1] = (int64_t)tempB >> shift;
553     }
554 }
555
556 /* 128 bits long. p[0] is LO, p[1] is HI , p[2] is sign of HI.*/
557 static inline void mipsdsp_rndrashift_acc(uint64_t *p,
558                                           uint32_t ac,
559                                           uint32_t shift,
560                                           CPUMIPSState *env)
561 {
562     int64_t tempB, tempA;
563
564     tempB = env->active_tc.HI[ac];
565     tempA = env->active_tc.LO[ac];
566     shift = shift & 0x3F;
567
568     if (shift == 0) {
569         p[2] = tempB >> 63;
570         p[1] = (tempB << 1) | (tempA >> 63);
571         p[0] = tempA << 1;
572     } else {
573         p[0] = (tempB << (65 - shift)) | (tempA >> (shift - 1));
574         p[1] = (int64_t)tempB >> (shift - 1);
575         if (tempB >= 0) {
576             p[2] = 0x0;
577         } else {
578             p[2] = ~0ull;
579         }
580     }
581 }
582
583 static inline int32_t mipsdsp_mul_q15_q15(int32_t ac, uint16_t a, uint16_t b,
584                                           CPUMIPSState *env)
585 {
586     int32_t temp;
587
588     if ((a == 0x8000) && (b == 0x8000)) {
589         temp = 0x7FFFFFFF;
590         set_DSPControl_overflow_flag(1, 16 + ac, env);
591     } else {
592         temp = ((uint32_t)a * (uint32_t)b) << 1;
593     }
594
595     return temp;
596 }
597
598 static inline int64_t mipsdsp_mul_q31_q31(int32_t ac, uint32_t a, uint32_t b,
599                                           CPUMIPSState *env)
600 {
601     uint64_t temp;
602
603     if ((a == 0x80000000) && (b == 0x80000000)) {
604         temp = (0x01ull << 63) - 1;
605         set_DSPControl_overflow_flag(1, 16 + ac, env);
606     } else {
607         temp = ((uint64_t)a * (uint64_t)b) << 1;
608     }
609
610     return temp;
611 }
612
613 static inline uint16_t mipsdsp_mul_u8_u8(uint8_t a, uint8_t b)
614 {
615     return (uint16_t)a * (uint16_t)b;
616 }
617
618 static inline uint16_t mipsdsp_mul_u8_u16(uint8_t a, uint16_t b,
619                                           CPUMIPSState *env)
620 {
621     uint32_t tempI;
622
623     tempI = (uint32_t)a * (uint32_t)b;
624     if (tempI > 0x0000FFFF) {
625         tempI = 0x0000FFFF;
626         set_DSPControl_overflow_flag(1, 21, env);
627     }
628
629     return tempI & 0x0000FFFF;
630 }
631
632 static inline uint64_t mipsdsp_mul_u32_u32(uint32_t a, uint32_t b)
633 {
634     return (uint64_t)a * (uint64_t)b;
635 }
636
637 static inline int16_t mipsdsp_rndq15_mul_q15_q15(uint16_t a, uint16_t b,
638                                                  CPUMIPSState *env)
639 {
640     uint32_t temp;
641
642     if ((a == 0x8000) && (b == 0x8000)) {
643         temp = 0x7FFF0000;
644         set_DSPControl_overflow_flag(1, 21, env);
645     } else {
646         temp = (a * b) << 1;
647         temp = temp + 0x00008000;
648     }
649
650     return (temp & 0xFFFF0000) >> 16;
651 }
652
653 static inline int32_t mipsdsp_sat16_mul_q15_q15(uint16_t a, uint16_t b,
654                                                 CPUMIPSState *env)
655 {
656     int32_t temp;
657
658     if ((a == 0x8000) && (b == 0x8000)) {
659         temp = 0x7FFF0000;
660         set_DSPControl_overflow_flag(1, 21, env);
661     } else {
662         temp = ((uint32_t)a * (uint32_t)b);
663         temp = temp << 1;
664     }
665
666     return (temp >> 16) & 0x0000FFFF;
667 }
668
669 static inline uint16_t mipsdsp_trunc16_sat16_round(int32_t a,
670                                                    CPUMIPSState *env)
671 {
672     int64_t temp;
673
674     temp = (int32_t)a + 0x00008000;
675
676     if (a > (int)0x7fff8000) {
677         temp = 0x7FFFFFFF;
678         set_DSPControl_overflow_flag(1, 22, env);
679     }
680
681     return (temp >> 16) & 0xFFFF;
682 }
683
684 static inline uint8_t mipsdsp_sat8_reduce_precision(uint16_t a,
685                                                     CPUMIPSState *env)
686 {
687     uint16_t mag;
688     uint32_t sign;
689
690     sign = (a >> 15) & 0x01;
691     mag = a & 0x7FFF;
692
693     if (sign == 0) {
694         if (mag > 0x7F80) {
695             set_DSPControl_overflow_flag(1, 22, env);
696             return 0xFF;
697         } else {
698             return (mag >> 7) & 0xFFFF;
699         }
700     } else {
701         set_DSPControl_overflow_flag(1, 22, env);
702         return 0x00;
703     }
704 }
705
706 static inline uint8_t mipsdsp_lshift8(uint8_t a, uint8_t s, CPUMIPSState *env)
707 {
708     uint8_t sign;
709     uint8_t discard;
710
711     if (s == 0) {
712         return a;
713     } else {
714         sign = (a >> 7) & 0x01;
715         if (sign != 0) {
716             discard = (((0x01 << (8 - s)) - 1) << s) |
717                       ((a >> (6 - (s - 1))) & ((0x01 << s) - 1));
718         } else {
719             discard = a >> (6 - (s - 1));
720         }
721
722         if (discard != 0x00) {
723             set_DSPControl_overflow_flag(1, 22, env);
724         }
725         return a << s;
726     }
727 }
728
729 static inline uint16_t mipsdsp_lshift16(uint16_t a, uint8_t s,
730                                         CPUMIPSState *env)
731 {
732     uint8_t  sign;
733     uint16_t discard;
734
735     if (s == 0) {
736         return a;
737     } else {
738         sign = (a >> 15) & 0x01;
739         if (sign != 0) {
740             discard = (((0x01 << (16 - s)) - 1) << s) |
741                       ((a >> (14 - (s - 1))) & ((0x01 << s) - 1));
742         } else {
743             discard = a >> (14 - (s - 1));
744         }
745
746         if ((discard != 0x0000) && (discard != 0xFFFF)) {
747             set_DSPControl_overflow_flag(1, 22, env);
748         }
749         return a << s;
750     }
751 }
752
753
754 static inline uint32_t mipsdsp_lshift32(uint32_t a, uint8_t s,
755                                         CPUMIPSState *env)
756 {
757     uint32_t discard;
758
759     if (s == 0) {
760         return a;
761     } else {
762         discard = (int32_t)a >> (31 - (s - 1));
763
764         if ((discard != 0x00000000) && (discard != 0xFFFFFFFF)) {
765             set_DSPControl_overflow_flag(1, 22, env);
766         }
767         return a << s;
768     }
769 }
770
771 static inline uint16_t mipsdsp_sat16_lshift(uint16_t a, uint8_t s,
772                                             CPUMIPSState *env)
773 {
774     uint8_t  sign;
775     uint16_t discard;
776
777     if (s == 0) {
778         return a;
779     } else {
780         sign = (a >> 15) & 0x01;
781         if (sign != 0) {
782             discard = (((0x01 << (16 - s)) - 1) << s) |
783                       ((a >> (14 - (s - 1))) & ((0x01 << s) - 1));
784         } else {
785             discard = a >> (14 - (s - 1));
786         }
787
788         if ((discard != 0x0000) && (discard != 0xFFFF)) {
789             set_DSPControl_overflow_flag(1, 22, env);
790             return (sign == 0) ? 0x7FFF : 0x8000;
791         } else {
792             return a << s;
793         }
794     }
795 }
796
797 static inline uint32_t mipsdsp_sat32_lshift(uint32_t a, uint8_t s,
798                                             CPUMIPSState *env)
799 {
800     uint8_t  sign;
801     uint32_t discard;
802
803     if (s == 0) {
804         return a;
805     } else {
806         sign = (a >> 31) & 0x01;
807         if (sign != 0) {
808             discard = (((0x01 << (32 - s)) - 1) << s) |
809                       ((a >> (30 - (s - 1))) & ((0x01 << s) - 1));
810         } else {
811             discard = a >> (30 - (s - 1));
812         }
813
814         if ((discard != 0x00000000) && (discard != 0xFFFFFFFF)) {
815             set_DSPControl_overflow_flag(1, 22, env);
816             return (sign == 0) ? 0x7FFFFFFF : 0x80000000;
817         } else {
818             return a << s;
819         }
820     }
821 }
822
823 static inline uint8_t mipsdsp_rnd8_rashift(uint8_t a, uint8_t s)
824 {
825     uint32_t temp;
826
827     if (s == 0) {
828         temp = (uint32_t)a << 1;
829     } else {
830         temp = (int32_t)(int8_t)a >> (s - 1);
831     }
832
833     return (temp + 1) >> 1;
834 }
835
836 static inline uint16_t mipsdsp_rnd16_rashift(uint16_t a, uint8_t s)
837 {
838     uint32_t temp;
839
840     if (s == 0) {
841         temp = (uint32_t)a << 1;
842     } else {
843         temp = (int32_t)(int16_t)a >> (s - 1);
844     }
845
846     return (temp + 1) >> 1;
847 }
848
849 static inline uint32_t mipsdsp_rnd32_rashift(uint32_t a, uint8_t s)
850 {
851     int64_t temp;
852
853     if (s == 0) {
854         temp = (uint64_t)a << 1;
855     } else {
856         temp = (int64_t)(int32_t)a >> (s - 1);
857     }
858     temp += 1;
859
860     return (temp >> 1) & 0xFFFFFFFFull;
861 }
862
863 static inline uint16_t mipsdsp_sub_i16(int16_t a, int16_t b, CPUMIPSState *env)
864 {
865     int16_t  temp;
866
867     temp = a - b;
868     if (MIPSDSP_OVERFLOW(a, -b, temp, 0x8000)) {
869         set_DSPControl_overflow_flag(1, 20, env);
870     }
871
872     return temp;
873 }
874
875 static inline uint16_t mipsdsp_sat16_sub(int16_t a, int16_t b,
876                                          CPUMIPSState *env)
877 {
878     int16_t  temp;
879
880     temp = a - b;
881     if (MIPSDSP_OVERFLOW(a, -b, temp, 0x8000)) {
882         if (a > 0) {
883             temp = 0x7FFF;
884         } else {
885             temp = 0x8000;
886         }
887         set_DSPControl_overflow_flag(1, 20, env);
888     }
889
890     return temp;
891 }
892
893 static inline uint32_t mipsdsp_sat32_sub(int32_t a, int32_t b,
894                                          CPUMIPSState *env)
895 {
896     int32_t  temp;
897
898     temp = a - b;
899     if (MIPSDSP_OVERFLOW(a, -b, temp, 0x80000000)) {
900         if (a > 0) {
901             temp = 0x7FFFFFFF;
902         } else {
903             temp = 0x80000000;
904         }
905         set_DSPControl_overflow_flag(1, 20, env);
906     }
907
908     return temp & 0xFFFFFFFFull;
909 }
910
911 static inline uint16_t mipsdsp_rshift1_sub_q16(int16_t a, int16_t b)
912 {
913     int32_t  temp;
914
915     temp = (int32_t)a - (int32_t)b;
916
917     return (temp >> 1) & 0x0000FFFF;
918 }
919
920 static inline uint16_t mipsdsp_rrshift1_sub_q16(int16_t a, int16_t b)
921 {
922     int32_t  temp;
923
924     temp = (int32_t)a - (int32_t)b;
925     temp += 1;
926
927     return (temp >> 1) & 0x0000FFFF;
928 }
929
930 static inline uint32_t mipsdsp_rshift1_sub_q32(int32_t a, int32_t b)
931 {
932     int64_t  temp;
933
934     temp = (int64_t)a - (int64_t)b;
935
936     return (temp >> 1) & 0xFFFFFFFFull;
937 }
938
939 static inline uint32_t mipsdsp_rrshift1_sub_q32(int32_t a, int32_t b)
940 {
941     int64_t  temp;
942
943     temp = (int64_t)a - (int64_t)b;
944     temp += 1;
945
946     return (temp >> 1) & 0xFFFFFFFFull;
947 }
948
949 static inline uint16_t mipsdsp_sub_u16_u16(uint16_t a, uint16_t b,
950                                            CPUMIPSState *env)
951 {
952     uint8_t  temp16;
953     uint32_t temp;
954
955     temp = (uint32_t)a - (uint32_t)b;
956     temp16 = (temp >> 16) & 0x01;
957     if (temp16 == 1) {
958         set_DSPControl_overflow_flag(1, 20, env);
959     }
960     return temp & 0x0000FFFF;
961 }
962
963 static inline uint16_t mipsdsp_satu16_sub_u16_u16(uint16_t a, uint16_t b,
964                                                   CPUMIPSState *env)
965 {
966     uint8_t  temp16;
967     uint32_t temp;
968
969     temp   = (uint32_t)a - (uint32_t)b;
970     temp16 = (temp >> 16) & 0x01;
971
972     if (temp16 == 1) {
973         temp = 0x0000;
974         set_DSPControl_overflow_flag(1, 20, env);
975     }
976
977     return temp & 0x0000FFFF;
978 }
979
980 static inline uint8_t mipsdsp_sub_u8(uint8_t a, uint8_t b, CPUMIPSState *env)
981 {
982     uint8_t  temp8;
983     uint16_t temp;
984
985     temp = (uint16_t)a - (uint16_t)b;
986     temp8 = (temp >> 8) & 0x01;
987     if (temp8 == 1) {
988         set_DSPControl_overflow_flag(1, 20, env);
989     }
990
991     return temp & 0x00FF;
992 }
993
994 static inline uint8_t mipsdsp_satu8_sub(uint8_t a, uint8_t b, CPUMIPSState *env)
995 {
996     uint8_t  temp8;
997     uint16_t temp;
998
999     temp = (uint16_t)a - (uint16_t)b;
1000     temp8 = (temp >> 8) & 0x01;
1001     if (temp8 == 1) {
1002         temp = 0x00;
1003         set_DSPControl_overflow_flag(1, 20, env);
1004     }
1005
1006     return temp & 0x00FF;
1007 }
1008
1009 static inline uint32_t mipsdsp_sub32(int32_t a, int32_t b, CPUMIPSState *env)
1010 {
1011     int32_t temp;
1012
1013     temp = a - b;
1014     if (MIPSDSP_OVERFLOW(a, -b, temp, 0x80000000)) {
1015         set_DSPControl_overflow_flag(1, 20, env);
1016     }
1017
1018     return temp;
1019 }
1020
1021 static inline int32_t mipsdsp_add_i32(int32_t a, int32_t b, CPUMIPSState *env)
1022 {
1023     int32_t temp;
1024
1025     temp = a + b;
1026
1027     if (MIPSDSP_OVERFLOW(a, b, temp, 0x80000000)) {
1028         set_DSPControl_overflow_flag(1, 20, env);
1029     }
1030
1031     return temp;
1032 }
1033
1034 static inline int32_t mipsdsp_cmp_eq(int32_t a, int32_t b)
1035 {
1036     return a == b;
1037 }
1038
1039 static inline int32_t mipsdsp_cmp_le(int32_t a, int32_t b)
1040 {
1041     return a <= b;
1042 }
1043
1044 static inline int32_t mipsdsp_cmp_lt(int32_t a, int32_t b)
1045 {
1046     return a < b;
1047 }
1048
1049 static inline int32_t mipsdsp_cmpu_eq(uint32_t a, uint32_t b)
1050 {
1051     return a == b;
1052 }
1053
1054 static inline int32_t mipsdsp_cmpu_le(uint32_t a, uint32_t b)
1055 {
1056     return a <= b;
1057 }
1058
1059 static inline int32_t mipsdsp_cmpu_lt(uint32_t a, uint32_t b)
1060 {
1061     return a < b;
1062 }
1063 /*** MIPS DSP internal functions end ***/
1064
1065 #define MIPSDSP_LHI 0xFFFFFFFF00000000ull
1066 #define MIPSDSP_LLO 0x00000000FFFFFFFFull
1067 #define MIPSDSP_HI  0xFFFF0000
1068 #define MIPSDSP_LO  0x0000FFFF
1069 #define MIPSDSP_Q3  0xFF000000
1070 #define MIPSDSP_Q2  0x00FF0000
1071 #define MIPSDSP_Q1  0x0000FF00
1072 #define MIPSDSP_Q0  0x000000FF
1073
1074 #define MIPSDSP_SPLIT32_8(num, a, b, c, d)  \
1075     do {                                    \
1076         a = (num >> 24) & MIPSDSP_Q0;       \
1077         b = (num >> 16) & MIPSDSP_Q0;       \
1078         c = (num >> 8) & MIPSDSP_Q0;        \
1079         d = num & MIPSDSP_Q0;               \
1080     } while (0)
1081
1082 #define MIPSDSP_SPLIT32_16(num, a, b)       \
1083     do {                                    \
1084         a = (num >> 16) & MIPSDSP_LO;       \
1085         b = num & MIPSDSP_LO;               \
1086     } while (0)
1087
1088 #define MIPSDSP_RETURN32(a)             ((target_long)(int32_t)a)
1089 #define MIPSDSP_RETURN32_8(a, b, c, d)  ((target_long)(int32_t) \
1090                                          (((uint32_t)a << 24) | \
1091                                          (((uint32_t)b << 16) | \
1092                                          (((uint32_t)c << 8) |  \
1093                                           ((uint32_t)d & 0xFF)))))
1094 #define MIPSDSP_RETURN32_16(a, b)       ((target_long)(int32_t) \
1095                                          (((uint32_t)a << 16) | \
1096                                           ((uint32_t)b & 0xFFFF)))
1097
1098 #ifdef TARGET_MIPS64
1099 #define MIPSDSP_SPLIT64_16(num, a, b, c, d)  \
1100     do {                                     \
1101         a = (num >> 48) & MIPSDSP_LO;        \
1102         b = (num >> 32) & MIPSDSP_LO;        \
1103         c = (num >> 16) & MIPSDSP_LO;        \
1104         d = num & MIPSDSP_LO;                \
1105     } while (0)
1106
1107 #define MIPSDSP_SPLIT64_32(num, a, b)       \
1108     do {                                    \
1109         a = (num >> 32) & MIPSDSP_LLO;      \
1110         b = num & MIPSDSP_LLO;              \
1111     } while (0)
1112
1113 #define MIPSDSP_RETURN64_16(a, b, c, d) (((uint64_t)a << 48) | \
1114                                          ((uint64_t)b << 32) | \
1115                                          ((uint64_t)c << 16) | \
1116                                          (uint64_t)d)
1117 #define MIPSDSP_RETURN64_32(a, b)       (((uint64_t)a << 32) | (uint64_t)b)
1118 #endif
1119
1120 /** DSP Arithmetic Sub-class insns **/
1121 #define ARITH_PH(name, func)                                      \
1122 target_ulong helper_##name##_ph(target_ulong rs, target_ulong rt) \
1123 {                                                                 \
1124     uint16_t  rsh, rsl, rth, rtl, temph, templ;                   \
1125                                                                   \
1126     MIPSDSP_SPLIT32_16(rs, rsh, rsl);                             \
1127     MIPSDSP_SPLIT32_16(rt, rth, rtl);                             \
1128                                                                   \
1129     temph = mipsdsp_##func(rsh, rth);                             \
1130     templ = mipsdsp_##func(rsl, rtl);                             \
1131                                                                   \
1132     return MIPSDSP_RETURN32_16(temph, templ);                     \
1133 }
1134
1135 #define ARITH_PH_ENV(name, func)                                  \
1136 target_ulong helper_##name##_ph(target_ulong rs, target_ulong rt, \
1137                                 CPUMIPSState *env)                \
1138 {                                                                 \
1139     uint16_t  rsh, rsl, rth, rtl, temph, templ;                   \
1140                                                                   \
1141     MIPSDSP_SPLIT32_16(rs, rsh, rsl);                             \
1142     MIPSDSP_SPLIT32_16(rt, rth, rtl);                             \
1143                                                                   \
1144     temph = mipsdsp_##func(rsh, rth, env);                        \
1145     templ = mipsdsp_##func(rsl, rtl, env);                        \
1146                                                                   \
1147     return MIPSDSP_RETURN32_16(temph, templ);                     \
1148 }
1149
1150
1151 ARITH_PH_ENV(addq, add_i16);
1152 ARITH_PH_ENV(addq_s, sat_add_i16);
1153 ARITH_PH_ENV(addu, add_u16);
1154 ARITH_PH_ENV(addu_s, sat_add_u16);
1155
1156 ARITH_PH(addqh, rshift1_add_q16);
1157 ARITH_PH(addqh_r, rrshift1_add_q16);
1158
1159 ARITH_PH_ENV(subq, sub_i16);
1160 ARITH_PH_ENV(subq_s, sat16_sub);
1161 ARITH_PH_ENV(subu, sub_u16_u16);
1162 ARITH_PH_ENV(subu_s, satu16_sub_u16_u16);
1163
1164 ARITH_PH(subqh, rshift1_sub_q16);
1165 ARITH_PH(subqh_r, rrshift1_sub_q16);
1166
1167 #undef ARITH_PH
1168 #undef ARITH_PH_ENV
1169
1170 #ifdef TARGET_MIPS64
1171 #define ARITH_QH_ENV(name, func) \
1172 target_ulong helper_##name##_qh(target_ulong rs, target_ulong rt, \
1173                                 CPUMIPSState *env)           \
1174 {                                                            \
1175     uint16_t rs3, rs2, rs1, rs0;                             \
1176     uint16_t rt3, rt2, rt1, rt0;                             \
1177     uint16_t tempD, tempC, tempB, tempA;                     \
1178                                                              \
1179     MIPSDSP_SPLIT64_16(rs, rs3, rs2, rs1, rs0);              \
1180     MIPSDSP_SPLIT64_16(rt, rt3, rt2, rt1, rt0);              \
1181                                                              \
1182     tempD = mipsdsp_##func(rs3, rt3, env);                   \
1183     tempC = mipsdsp_##func(rs2, rt2, env);                   \
1184     tempB = mipsdsp_##func(rs1, rt1, env);                   \
1185     tempA = mipsdsp_##func(rs0, rt0, env);                   \
1186                                                              \
1187     return MIPSDSP_RETURN64_16(tempD, tempC, tempB, tempA);  \
1188 }
1189
1190 ARITH_QH_ENV(addq, add_i16);
1191 ARITH_QH_ENV(addq_s, sat_add_i16);
1192 ARITH_QH_ENV(addu, add_u16);
1193 ARITH_QH_ENV(addu_s, sat_add_u16);
1194
1195 ARITH_QH_ENV(subq, sub_i16);
1196 ARITH_QH_ENV(subq_s, sat16_sub);
1197 ARITH_QH_ENV(subu, sub_u16_u16);
1198 ARITH_QH_ENV(subu_s, satu16_sub_u16_u16);
1199
1200 #undef ARITH_QH_ENV
1201
1202 #endif
1203
1204 #define ARITH_W(name, func) \
1205 target_ulong helper_##name##_w(target_ulong rs, target_ulong rt) \
1206 {                                                                \
1207     uint32_t rd;                                                 \
1208     rd = mipsdsp_##func(rs, rt);                                 \
1209     return MIPSDSP_RETURN32(rd);                                 \
1210 }
1211
1212 #define ARITH_W_ENV(name, func) \
1213 target_ulong helper_##name##_w(target_ulong rs, target_ulong rt, \
1214                                CPUMIPSState *env)                \
1215 {                                                                \
1216     uint32_t rd;                                                 \
1217     rd = mipsdsp_##func(rs, rt, env);                            \
1218     return MIPSDSP_RETURN32(rd);                                 \
1219 }
1220
1221 ARITH_W_ENV(addq_s, sat_add_i32);
1222
1223 ARITH_W(addqh, rshift1_add_q32);
1224 ARITH_W(addqh_r, rrshift1_add_q32);
1225
1226 ARITH_W_ENV(subq_s, sat32_sub);
1227
1228 ARITH_W(subqh, rshift1_sub_q32);
1229 ARITH_W(subqh_r, rrshift1_sub_q32);
1230
1231 #undef ARITH_W
1232 #undef ARITH_W_ENV
1233
1234 target_ulong helper_absq_s_w(target_ulong rt, CPUMIPSState *env)
1235 {
1236     uint32_t rd;
1237
1238     rd = mipsdsp_sat_abs32(rt, env);
1239
1240     return (target_ulong)rd;
1241 }
1242
1243
1244 #if defined(TARGET_MIPS64)
1245
1246 #define ARITH_PW_ENV(name, func) \
1247 target_ulong helper_##name##_pw(target_ulong rs, target_ulong rt, \
1248                                 CPUMIPSState *env)                \
1249 {                                                                 \
1250     uint32_t rs1, rs0;                                            \
1251     uint32_t rt1, rt0;                                            \
1252     uint32_t tempB, tempA;                                        \
1253                                                                   \
1254     MIPSDSP_SPLIT64_32(rs, rs1, rs0);                             \
1255     MIPSDSP_SPLIT64_32(rt, rt1, rt0);                             \
1256                                                                   \
1257     tempB = mipsdsp_##func(rs1, rt1, env);                        \
1258     tempA = mipsdsp_##func(rs0, rt0, env);                        \
1259                                                                   \
1260     return MIPSDSP_RETURN64_32(tempB, tempA);                     \
1261 }
1262
1263 ARITH_PW_ENV(addq, add_i32);
1264 ARITH_PW_ENV(addq_s, sat_add_i32);
1265 ARITH_PW_ENV(subq, sub32);
1266 ARITH_PW_ENV(subq_s, sat32_sub);
1267
1268 #undef ARITH_PW_ENV
1269
1270 #endif
1271
1272 #define ARITH_QB(name, func) \
1273 target_ulong helper_##name##_qb(target_ulong rs, target_ulong rt) \
1274 {                                                                 \
1275     uint8_t  rs0, rs1, rs2, rs3;                                  \
1276     uint8_t  rt0, rt1, rt2, rt3;                                  \
1277     uint8_t  temp0, temp1, temp2, temp3;                          \
1278                                                                   \
1279     MIPSDSP_SPLIT32_8(rs, rs3, rs2, rs1, rs0);                    \
1280     MIPSDSP_SPLIT32_8(rt, rt3, rt2, rt1, rt0);                    \
1281                                                                   \
1282     temp0 = mipsdsp_##func(rs0, rt0);                             \
1283     temp1 = mipsdsp_##func(rs1, rt1);                             \
1284     temp2 = mipsdsp_##func(rs2, rt2);                             \
1285     temp3 = mipsdsp_##func(rs3, rt3);                             \
1286                                                                   \
1287     return MIPSDSP_RETURN32_8(temp3, temp2, temp1, temp0);        \
1288 }
1289
1290 #define ARITH_QB_ENV(name, func) \
1291 target_ulong helper_##name##_qb(target_ulong rs, target_ulong rt, \
1292                                 CPUMIPSState *env)          \
1293 {                                                           \
1294     uint8_t  rs0, rs1, rs2, rs3;                            \
1295     uint8_t  rt0, rt1, rt2, rt3;                            \
1296     uint8_t  temp0, temp1, temp2, temp3;                    \
1297                                                             \
1298     MIPSDSP_SPLIT32_8(rs, rs3, rs2, rs1, rs0);              \
1299     MIPSDSP_SPLIT32_8(rt, rt3, rt2, rt1, rt0);              \
1300                                                             \
1301     temp0 = mipsdsp_##func(rs0, rt0, env);                  \
1302     temp1 = mipsdsp_##func(rs1, rt1, env);                  \
1303     temp2 = mipsdsp_##func(rs2, rt2, env);                  \
1304     temp3 = mipsdsp_##func(rs3, rt3, env);                  \
1305                                                             \
1306     return MIPSDSP_RETURN32_8(temp3, temp2, temp1, temp0);  \
1307 }
1308
1309 ARITH_QB(adduh, rshift1_add_u8);
1310 ARITH_QB(adduh_r, rrshift1_add_u8);
1311
1312 ARITH_QB_ENV(addu, add_u8);
1313 ARITH_QB_ENV(addu_s, sat_add_u8);
1314
1315 #undef ADDU_QB
1316 #undef ADDU_QB_ENV
1317
1318 #if defined(TARGET_MIPS64)
1319 #define ARITH_OB(name, func) \
1320 target_ulong helper_##name##_ob(target_ulong rs, target_ulong rt) \
1321 {                                                                 \
1322     int i;                                                        \
1323     uint8_t rs_t[8], rt_t[8];                                     \
1324     uint8_t temp[8];                                              \
1325     uint64_t result;                                              \
1326                                                                   \
1327     result = 0;                                                   \
1328                                                                   \
1329     for (i = 0; i < 8; i++) {                                     \
1330         rs_t[i] = (rs >> (8 * i)) & MIPSDSP_Q0;                   \
1331         rt_t[i] = (rt >> (8 * i)) & MIPSDSP_Q0;                   \
1332         temp[i] = mipsdsp_##func(rs_t[i], rt_t[i]);               \
1333         result |= (uint64_t)temp[i] << (8 * i);                   \
1334     }                                                             \
1335                                                                   \
1336     return result;                                                \
1337 }
1338
1339 #define ARITH_OB_ENV(name, func) \
1340 target_ulong helper_##name##_ob(target_ulong rs, target_ulong rt, \
1341                                 CPUMIPSState *env)                \
1342 {                                                                 \
1343     int i;                                                        \
1344     uint8_t rs_t[8], rt_t[8];                                     \
1345     uint8_t temp[8];                                              \
1346     uint64_t result;                                              \
1347                                                                   \
1348     result = 0;                                                   \
1349                                                                   \
1350     for (i = 0; i < 8; i++) {                                     \
1351         rs_t[i] = (rs >> (8 * i)) & MIPSDSP_Q0;                   \
1352         rt_t[i] = (rt >> (8 * i)) & MIPSDSP_Q0;                   \
1353         temp[i] = mipsdsp_##func(rs_t[i], rt_t[i], env);          \
1354         result |= (uint64_t)temp[i] << (8 * i);                   \
1355     }                                                             \
1356                                                                   \
1357     return result;                                                \
1358 }
1359
1360 ARITH_OB_ENV(addu, add_u8);
1361 ARITH_OB_ENV(addu_s, sat_add_u8);
1362
1363 ARITH_OB(adduh, rshift1_add_u8);
1364 ARITH_OB(adduh_r, rrshift1_add_u8);
1365
1366 ARITH_OB_ENV(subu, sub_u8);
1367 ARITH_OB_ENV(subu_s, satu8_sub);
1368
1369 ARITH_OB(subuh, rshift1_sub_u8);
1370 ARITH_OB(subuh_r, rrshift1_sub_u8);
1371
1372 #undef ARITH_OB
1373 #undef ARITH_OB_ENV
1374
1375 #endif
1376
1377 #define SUBU_QB(name, func) \
1378 target_ulong helper_##name##_qb(target_ulong rs,               \
1379                                 target_ulong rt,               \
1380                                 CPUMIPSState *env)             \
1381 {                                                              \
1382     uint8_t rs3, rs2, rs1, rs0;                                \
1383     uint8_t rt3, rt2, rt1, rt0;                                \
1384     uint8_t tempD, tempC, tempB, tempA;                        \
1385                                                                \
1386     MIPSDSP_SPLIT32_8(rs, rs3, rs2, rs1, rs0);                 \
1387     MIPSDSP_SPLIT32_8(rt, rt3, rt2, rt1, rt0);                 \
1388                                                                \
1389     tempD = mipsdsp_##func(rs3, rt3, env);                     \
1390     tempC = mipsdsp_##func(rs2, rt2, env);                     \
1391     tempB = mipsdsp_##func(rs1, rt1, env);                     \
1392     tempA = mipsdsp_##func(rs0, rt0, env);                     \
1393                                                                \
1394     return MIPSDSP_RETURN32_8(tempD, tempC, tempB, tempA);     \
1395 }
1396
1397 SUBU_QB(subu, sub_u8);
1398 SUBU_QB(subu_s, satu8_sub);
1399
1400 #undef SUBU_QB
1401
1402 #define SUBUH_QB(name, var) \
1403 target_ulong helper_##name##_qb(target_ulong rs, target_ulong rt) \
1404 {                                                                 \
1405     uint8_t rs3, rs2, rs1, rs0;                                   \
1406     uint8_t rt3, rt2, rt1, rt0;                                   \
1407     uint8_t tempD, tempC, tempB, tempA;                           \
1408                                                                   \
1409     MIPSDSP_SPLIT32_8(rs, rs3, rs2, rs1, rs0);                    \
1410     MIPSDSP_SPLIT32_8(rt, rt3, rt2, rt1, rt0);                    \
1411                                                                   \
1412     tempD = ((uint16_t)rs3 - (uint16_t)rt3 + var) >> 1;           \
1413     tempC = ((uint16_t)rs2 - (uint16_t)rt2 + var) >> 1;           \
1414     tempB = ((uint16_t)rs1 - (uint16_t)rt1 + var) >> 1;           \
1415     tempA = ((uint16_t)rs0 - (uint16_t)rt0 + var) >> 1;           \
1416                                                                   \
1417     return ((uint32_t)tempD << 24) | ((uint32_t)tempC << 16) |    \
1418         ((uint32_t)tempB << 8) | ((uint32_t)tempA);               \
1419 }
1420
1421 SUBUH_QB(subuh, 0);
1422 SUBUH_QB(subuh_r, 1);
1423
1424 #undef SUBUH_QB
1425
1426 target_ulong helper_addsc(target_ulong rs, target_ulong rt, CPUMIPSState *env)
1427 {
1428     uint64_t temp, tempRs, tempRt;
1429     int32_t flag;
1430
1431     tempRs = (uint64_t)rs & MIPSDSP_LLO;
1432     tempRt = (uint64_t)rt & MIPSDSP_LLO;
1433
1434     temp = tempRs + tempRt;
1435     flag = (temp & 0x0100000000ull) >> 32;
1436     set_DSPControl_carryflag(flag, env);
1437
1438     return (target_long)(int32_t)(temp & MIPSDSP_LLO);
1439 }
1440
1441 target_ulong helper_addwc(target_ulong rs, target_ulong rt, CPUMIPSState *env)
1442 {
1443     uint32_t rd;
1444     int32_t temp32, temp31;
1445     int64_t tempL;
1446
1447     tempL = (int64_t)(int32_t)rs + (int64_t)(int32_t)rt +
1448         get_DSPControl_carryflag(env);
1449     temp31 = (tempL >> 31) & 0x01;
1450     temp32 = (tempL >> 32) & 0x01;
1451
1452     if (temp31 != temp32) {
1453         set_DSPControl_overflow_flag(1, 20, env);
1454     }
1455
1456     rd = tempL & MIPSDSP_LLO;
1457
1458     return (target_long)(int32_t)rd;
1459 }
1460
1461 target_ulong helper_modsub(target_ulong rs, target_ulong rt)
1462 {
1463     int32_t decr;
1464     uint16_t lastindex;
1465     target_ulong rd;
1466
1467     decr = rt & MIPSDSP_Q0;
1468     lastindex = (rt >> 8) & MIPSDSP_LO;
1469
1470     if ((rs & MIPSDSP_LLO) == 0x00000000) {
1471         rd = (target_ulong)lastindex;
1472     } else {
1473         rd = rs - decr;
1474     }
1475
1476     return rd;
1477 }
1478
1479 target_ulong helper_raddu_w_qb(target_ulong rs)
1480 {
1481     uint8_t  rs3, rs2, rs1, rs0;
1482     uint16_t temp;
1483
1484     MIPSDSP_SPLIT32_8(rs, rs3, rs2, rs1, rs0);
1485
1486     temp = (uint16_t)rs3 + (uint16_t)rs2 + (uint16_t)rs1 + (uint16_t)rs0;
1487
1488     return (target_ulong)temp;
1489 }
1490
1491 #if defined(TARGET_MIPS64)
1492 target_ulong helper_raddu_l_ob(target_ulong rs)
1493 {
1494     int i;
1495     uint16_t rs_t[8];
1496     uint64_t temp;
1497
1498     temp = 0;
1499
1500     for (i = 0; i < 8; i++) {
1501         rs_t[i] = (rs >> (8 * i)) & MIPSDSP_Q0;
1502         temp += (uint64_t)rs_t[i];
1503     }
1504
1505     return temp;
1506 }
1507 #endif
1508
1509 target_ulong helper_absq_s_qb(target_ulong rt, CPUMIPSState *env)
1510 {
1511     uint8_t tempD, tempC, tempB, tempA;
1512
1513     MIPSDSP_SPLIT32_8(rt, tempD, tempC, tempB, tempA);
1514
1515     tempD = mipsdsp_sat_abs8(tempD, env);
1516     tempC = mipsdsp_sat_abs8(tempC, env);
1517     tempB = mipsdsp_sat_abs8(tempB, env);
1518     tempA = mipsdsp_sat_abs8(tempA, env);
1519
1520     return MIPSDSP_RETURN32_8(tempD, tempC, tempB, tempA);
1521 }
1522
1523 target_ulong helper_absq_s_ph(target_ulong rt, CPUMIPSState *env)
1524 {
1525     uint16_t tempB, tempA;
1526
1527     MIPSDSP_SPLIT32_16(rt, tempB, tempA);
1528
1529     tempB = mipsdsp_sat_abs16 (tempB, env);
1530     tempA = mipsdsp_sat_abs16 (tempA, env);
1531
1532     return MIPSDSP_RETURN32_16(tempB, tempA);
1533 }
1534
1535 #if defined(TARGET_MIPS64)
1536 target_ulong helper_absq_s_ob(target_ulong rt, CPUMIPSState *env)
1537 {
1538     int i;
1539     int8_t temp[8];
1540     uint64_t result;
1541
1542     for (i = 0; i < 8; i++) {
1543         temp[i] = (rt >> (8 * i)) & MIPSDSP_Q0;
1544         temp[i] = mipsdsp_sat_abs8(temp[i], env);
1545     }
1546
1547     for (i = 0; i < 8; i++) {
1548         result = (uint64_t)(uint8_t)temp[i] << (8 * i);
1549     }
1550
1551     return result;
1552 }
1553
1554 target_ulong helper_absq_s_qh(target_ulong rt, CPUMIPSState *env)
1555 {
1556     int16_t tempD, tempC, tempB, tempA;
1557
1558     MIPSDSP_SPLIT64_16(rt, tempD, tempC, tempB, tempA);
1559
1560     tempD = mipsdsp_sat_abs16(tempD, env);
1561     tempC = mipsdsp_sat_abs16(tempC, env);
1562     tempB = mipsdsp_sat_abs16(tempB, env);
1563     tempA = mipsdsp_sat_abs16(tempA, env);
1564
1565     return MIPSDSP_RETURN64_16(tempD, tempC, tempB, tempA);
1566 }
1567
1568 target_ulong helper_absq_s_pw(target_ulong rt, CPUMIPSState *env)
1569 {
1570     int32_t tempB, tempA;
1571
1572     MIPSDSP_SPLIT64_32(rt, tempB, tempA);
1573
1574     tempB = mipsdsp_sat_abs32(tempB, env);
1575     tempA = mipsdsp_sat_abs32(tempA, env);
1576
1577     return MIPSDSP_RETURN64_32(tempB, tempA);
1578 }
1579 #endif
1580
1581 #define PRECR_QB_PH(name, a, b)\
1582 target_ulong helper_##name##_qb_ph(target_ulong rs, target_ulong rt) \
1583 {                                                                    \
1584     uint8_t tempD, tempC, tempB, tempA;                              \
1585                                                                      \
1586     tempD = (rs >> a) & MIPSDSP_Q0;                                  \
1587     tempC = (rs >> b) & MIPSDSP_Q0;                                  \
1588     tempB = (rt >> a) & MIPSDSP_Q0;                                  \
1589     tempA = (rt >> b) & MIPSDSP_Q0;                                  \
1590                                                                      \
1591     return MIPSDSP_RETURN32_8(tempD, tempC, tempB, tempA);           \
1592 }
1593
1594 PRECR_QB_PH(precr, 16, 0);
1595 PRECR_QB_PH(precrq, 24, 8);
1596
1597 #undef PRECR_QB_OH
1598
1599 target_ulong helper_precr_sra_ph_w(uint32_t sa, target_ulong rs,
1600                                    target_ulong rt)
1601 {
1602     uint16_t tempB, tempA;
1603
1604     tempB = ((int32_t)rt >> sa) & MIPSDSP_LO;
1605     tempA = ((int32_t)rs >> sa) & MIPSDSP_LO;
1606
1607     return MIPSDSP_RETURN32_16(tempB, tempA);
1608 }
1609
1610 target_ulong helper_precr_sra_r_ph_w(uint32_t sa,
1611                                      target_ulong rs, target_ulong rt)
1612 {
1613     uint64_t tempB, tempA;
1614
1615     /* If sa = 0, then (sa - 1) = -1 will case shift error, so we need else. */
1616     if (sa == 0) {
1617         tempB = (rt & MIPSDSP_LO) << 1;
1618         tempA = (rs & MIPSDSP_LO) << 1;
1619     } else {
1620         tempB = ((int32_t)rt >> (sa - 1)) + 1;
1621         tempA = ((int32_t)rs >> (sa - 1)) + 1;
1622     }
1623     rt = (((tempB >> 1) & MIPSDSP_LO) << 16) | ((tempA >> 1) & MIPSDSP_LO);
1624
1625     return (target_long)(int32_t)rt;
1626 }
1627
1628 target_ulong helper_precrq_ph_w(target_ulong rs, target_ulong rt)
1629 {
1630     uint16_t tempB, tempA;
1631
1632     tempB = (rs & MIPSDSP_HI) >> 16;
1633     tempA = (rt & MIPSDSP_HI) >> 16;
1634
1635     return MIPSDSP_RETURN32_16(tempB, tempA);
1636 }
1637
1638 target_ulong helper_precrq_rs_ph_w(target_ulong rs, target_ulong rt,
1639                                    CPUMIPSState *env)
1640 {
1641     uint16_t tempB, tempA;
1642
1643     tempB = mipsdsp_trunc16_sat16_round(rs, env);
1644     tempA = mipsdsp_trunc16_sat16_round(rt, env);
1645
1646     return MIPSDSP_RETURN32_16(tempB, tempA);
1647 }
1648
1649 #if defined(TARGET_MIPS64)
1650 target_ulong helper_precr_ob_qh(target_ulong rs, target_ulong rt)
1651 {
1652     uint8_t rs6, rs4, rs2, rs0;
1653     uint8_t rt6, rt4, rt2, rt0;
1654     uint64_t temp;
1655
1656     rs6 = (rs >> 48) & MIPSDSP_Q0;
1657     rs4 = (rs >> 32) & MIPSDSP_Q0;
1658     rs2 = (rs >> 16) & MIPSDSP_Q0;
1659     rs0 = rs & MIPSDSP_Q0;
1660     rt6 = (rt >> 48) & MIPSDSP_Q0;
1661     rt4 = (rt >> 32) & MIPSDSP_Q0;
1662     rt2 = (rt >> 16) & MIPSDSP_Q0;
1663     rt0 = rt & MIPSDSP_Q0;
1664
1665     temp = ((uint64_t)rs6 << 56) | ((uint64_t)rs4 << 48) |
1666            ((uint64_t)rs2 << 40) | ((uint64_t)rs0 << 32) |
1667            ((uint64_t)rt6 << 24) | ((uint64_t)rt4 << 16) |
1668            ((uint64_t)rt2 << 8) | (uint64_t)rt0;
1669
1670     return temp;
1671 }
1672
1673 #define PRECR_QH_PW(name, var) \
1674 target_ulong helper_precr_##name##_qh_pw(target_ulong rs, target_ulong rt, \
1675                                     uint32_t sa)                      \
1676 {                                                                     \
1677     uint16_t rs3, rs2, rs1, rs0;                                      \
1678     uint16_t rt3, rt2, rt1, rt0;                                      \
1679     uint16_t tempD, tempC, tempB, tempA;                              \
1680                                                                       \
1681     MIPSDSP_SPLIT64_16(rs, rs3, rs2, rs1, rs0);                       \
1682     MIPSDSP_SPLIT64_16(rt, rt3, rt2, rt1, rt0);                       \
1683                                                                       \
1684     /* When sa = 0, we use rt2, rt0, rs2, rs0;                        \
1685      * when sa != 0, we use rt3, rt1, rs3, rs1. */                    \
1686     if (sa == 0) {                                                    \
1687         tempD = rt2 << var;                                           \
1688         tempC = rt0 << var;                                           \
1689         tempB = rs2 << var;                                           \
1690         tempA = rs0 << var;                                           \
1691     } else {                                                          \
1692         tempD = (((int16_t)rt3 >> sa) + var) >> var;                  \
1693         tempC = (((int16_t)rt1 >> sa) + var) >> var;                  \
1694         tempB = (((int16_t)rs3 >> sa) + var) >> var;                  \
1695         tempA = (((int16_t)rs1 >> sa) + var) >> var;                  \
1696     }                                                                 \
1697                                                                       \
1698     return MIPSDSP_RETURN64_16(tempD, tempC, tempB, tempA);           \
1699 }
1700
1701 PRECR_QH_PW(sra, 0);
1702 PRECR_QH_PW(sra_r, 1);
1703
1704 #undef PRECR_QH_PW
1705
1706 target_ulong helper_precrq_ob_qh(target_ulong rs, target_ulong rt)
1707 {
1708     uint8_t rs6, rs4, rs2, rs0;
1709     uint8_t rt6, rt4, rt2, rt0;
1710     uint64_t temp;
1711
1712     rs6 = (rs >> 56) & MIPSDSP_Q0;
1713     rs4 = (rs >> 40) & MIPSDSP_Q0;
1714     rs2 = (rs >> 24) & MIPSDSP_Q0;
1715     rs0 = (rs >> 8) & MIPSDSP_Q0;
1716     rt6 = (rt >> 56) & MIPSDSP_Q0;
1717     rt4 = (rt >> 40) & MIPSDSP_Q0;
1718     rt2 = (rt >> 24) & MIPSDSP_Q0;
1719     rt0 = (rt >> 8) & MIPSDSP_Q0;
1720
1721     temp = ((uint64_t)rs6 << 56) | ((uint64_t)rs4 << 48) |
1722            ((uint64_t)rs2 << 40) | ((uint64_t)rs0 << 32) |
1723            ((uint64_t)rt6 << 24) | ((uint64_t)rt4 << 16) |
1724            ((uint64_t)rt2 << 8) | (uint64_t)rt0;
1725
1726     return temp;
1727 }
1728
1729 target_ulong helper_precrq_qh_pw(target_ulong rs, target_ulong rt)
1730 {
1731     uint16_t tempD, tempC, tempB, tempA;
1732
1733     tempD = (rs >> 48) & MIPSDSP_LO;
1734     tempC = (rs >> 16) & MIPSDSP_LO;
1735     tempB = (rt >> 48) & MIPSDSP_LO;
1736     tempA = (rt >> 16) & MIPSDSP_LO;
1737
1738     return MIPSDSP_RETURN64_16(tempD, tempC, tempB, tempA);
1739 }
1740
1741 target_ulong helper_precrq_rs_qh_pw(target_ulong rs, target_ulong rt,
1742                                     CPUMIPSState *env)
1743 {
1744     uint32_t rs2, rs0;
1745     uint32_t rt2, rt0;
1746     uint16_t tempD, tempC, tempB, tempA;
1747
1748     rs2 = (rs >> 32) & MIPSDSP_LLO;
1749     rs0 = rs & MIPSDSP_LLO;
1750     rt2 = (rt >> 32) & MIPSDSP_LLO;
1751     rt0 = rt & MIPSDSP_LLO;
1752
1753     tempD = mipsdsp_trunc16_sat16_round(rs2, env);
1754     tempC = mipsdsp_trunc16_sat16_round(rs0, env);
1755     tempB = mipsdsp_trunc16_sat16_round(rt2, env);
1756     tempA = mipsdsp_trunc16_sat16_round(rt0, env);
1757
1758     return MIPSDSP_RETURN64_16(tempD, tempC, tempB, tempA);
1759 }
1760
1761 target_ulong helper_precrq_pw_l(target_ulong rs, target_ulong rt)
1762 {
1763     uint32_t tempB, tempA;
1764
1765     tempB = (rs >> 32) & MIPSDSP_LLO;
1766     tempA = (rt >> 32) & MIPSDSP_LLO;
1767
1768     return MIPSDSP_RETURN64_32(tempB, tempA);
1769 }
1770 #endif
1771
1772 target_ulong helper_precrqu_s_qb_ph(target_ulong rs, target_ulong rt,
1773                                     CPUMIPSState *env)
1774 {
1775     uint8_t  tempD, tempC, tempB, tempA;
1776     uint16_t rsh, rsl, rth, rtl;
1777
1778     rsh = (rs & MIPSDSP_HI) >> 16;
1779     rsl =  rs & MIPSDSP_LO;
1780     rth = (rt & MIPSDSP_HI) >> 16;
1781     rtl =  rt & MIPSDSP_LO;
1782
1783     tempD = mipsdsp_sat8_reduce_precision(rsh, env);
1784     tempC = mipsdsp_sat8_reduce_precision(rsl, env);
1785     tempB = mipsdsp_sat8_reduce_precision(rth, env);
1786     tempA = mipsdsp_sat8_reduce_precision(rtl, env);
1787
1788     return MIPSDSP_RETURN32_8(tempD, tempC, tempB, tempA);
1789 }
1790
1791 #if defined(TARGET_MIPS64)
1792 target_ulong helper_precrqu_s_ob_qh(target_ulong rs, target_ulong rt,
1793                                     CPUMIPSState *env)
1794 {
1795     int i;
1796     uint16_t rs3, rs2, rs1, rs0;
1797     uint16_t rt3, rt2, rt1, rt0;
1798     uint8_t temp[8];
1799     uint64_t result;
1800
1801     result = 0;
1802
1803     MIPSDSP_SPLIT64_16(rs, rs3, rs2, rs1, rs0);
1804     MIPSDSP_SPLIT64_16(rt, rt3, rt2, rt1, rt0);
1805
1806     temp[7] = mipsdsp_sat8_reduce_precision(rs3, env);
1807     temp[6] = mipsdsp_sat8_reduce_precision(rs2, env);
1808     temp[5] = mipsdsp_sat8_reduce_precision(rs1, env);
1809     temp[4] = mipsdsp_sat8_reduce_precision(rs0, env);
1810     temp[3] = mipsdsp_sat8_reduce_precision(rt3, env);
1811     temp[2] = mipsdsp_sat8_reduce_precision(rt2, env);
1812     temp[1] = mipsdsp_sat8_reduce_precision(rt1, env);
1813     temp[0] = mipsdsp_sat8_reduce_precision(rt0, env);
1814
1815     for (i = 0; i < 8; i++) {
1816         result |= (uint64_t)temp[i] << (8 * i);
1817     }
1818
1819     return result;
1820 }
1821
1822 #define PRECEQ_PW(name, a, b) \
1823 target_ulong helper_preceq_pw_##name(target_ulong rt) \
1824 {                                                       \
1825     uint16_t tempB, tempA;                              \
1826     uint32_t tempBI, tempAI;                            \
1827                                                         \
1828     tempB = (rt >> a) & MIPSDSP_LO;                     \
1829     tempA = (rt >> b) & MIPSDSP_LO;                     \
1830                                                         \
1831     tempBI = (uint32_t)tempB << 16;                     \
1832     tempAI = (uint32_t)tempA << 16;                     \
1833                                                         \
1834     return MIPSDSP_RETURN64_32(tempBI, tempAI);         \
1835 }
1836
1837 PRECEQ_PW(qhl, 48, 32);
1838 PRECEQ_PW(qhr, 16, 0);
1839 PRECEQ_PW(qhla, 48, 16);
1840 PRECEQ_PW(qhra, 32, 0);
1841
1842 #undef PRECEQ_PW
1843
1844 #endif
1845
1846 #define PRECEQU_PH(name, a, b) \
1847 target_ulong helper_precequ_ph_##name(target_ulong rt) \
1848 {                                                        \
1849     uint16_t tempB, tempA;                               \
1850                                                          \
1851     tempB = (rt >> a) & MIPSDSP_Q0;                      \
1852     tempA = (rt >> b) & MIPSDSP_Q0;                      \
1853                                                          \
1854     tempB = tempB << 7;                                  \
1855     tempA = tempA << 7;                                  \
1856                                                          \
1857     return MIPSDSP_RETURN32_16(tempB, tempA);            \
1858 }
1859
1860 PRECEQU_PH(qbl, 24, 16);
1861 PRECEQU_PH(qbr, 8, 0);
1862 PRECEQU_PH(qbla, 24, 8);
1863 PRECEQU_PH(qbra, 16, 0);
1864
1865 #undef PRECEQU_PH
1866
1867 #if defined(TARGET_MIPS64)
1868 #define PRECEQU_QH(name, a, b, c, d) \
1869 target_ulong helper_precequ_qh_##name(target_ulong rt)       \
1870 {                                                            \
1871     uint16_t tempD, tempC, tempB, tempA;                     \
1872                                                              \
1873     tempD = (rt >> a) & MIPSDSP_Q0;                          \
1874     tempC = (rt >> b) & MIPSDSP_Q0;                          \
1875     tempB = (rt >> c) & MIPSDSP_Q0;                          \
1876     tempA = (rt >> d) & MIPSDSP_Q0;                          \
1877                                                              \
1878     tempD = tempD << 7;                                      \
1879     tempC = tempC << 7;                                      \
1880     tempB = tempB << 7;                                      \
1881     tempA = tempA << 7;                                      \
1882                                                              \
1883     return MIPSDSP_RETURN64_16(tempD, tempC, tempB, tempA);  \
1884 }
1885
1886 PRECEQU_QH(obl, 56, 48, 40, 32);
1887 PRECEQU_QH(obr, 24, 16, 8, 0);
1888 PRECEQU_QH(obla, 56, 40, 24, 8);
1889 PRECEQU_QH(obra, 48, 32, 16, 0);
1890
1891 #undef PRECEQU_QH
1892
1893 #endif
1894
1895 #define PRECEU_PH(name, a, b) \
1896 target_ulong helper_preceu_ph_##name(target_ulong rt) \
1897 {                                                     \
1898     uint16_t tempB, tempA;                            \
1899                                                       \
1900     tempB = (rt >> a) & MIPSDSP_Q0;                   \
1901     tempA = (rt >> b) & MIPSDSP_Q0;                   \
1902                                                       \
1903     return MIPSDSP_RETURN32_16(tempB, tempA);         \
1904 }
1905
1906 PRECEU_PH(qbl, 24, 16);
1907 PRECEU_PH(qbr, 8, 0);
1908 PRECEU_PH(qbla, 24, 8);
1909 PRECEU_PH(qbra, 16, 0);
1910
1911 #undef PRECEU_PH
1912
1913 #if defined(TARGET_MIPS64)
1914 #define PRECEU_QH(name, a, b, c, d) \
1915 target_ulong helper_preceu_qh_##name(target_ulong rt)        \
1916 {                                                            \
1917     uint16_t tempD, tempC, tempB, tempA;                     \
1918                                                              \
1919     tempD = (rt >> a) & MIPSDSP_Q0;                          \
1920     tempC = (rt >> b) & MIPSDSP_Q0;                          \
1921     tempB = (rt >> c) & MIPSDSP_Q0;                          \
1922     tempA = (rt >> d) & MIPSDSP_Q0;                          \
1923                                                              \
1924     return MIPSDSP_RETURN64_16(tempD, tempC, tempB, tempA);  \
1925 }
1926
1927 PRECEU_QH(obl, 56, 48, 40, 32);
1928 PRECEU_QH(obr, 24, 16, 8, 0);
1929 PRECEU_QH(obla, 56, 40, 24, 8);
1930 PRECEU_QH(obra, 48, 32, 16, 0);
1931
1932 #undef PRECEU_QH
1933
1934 #endif
1935
1936 #undef MIPSDSP_LHI
1937 #undef MIPSDSP_LLO
1938 #undef MIPSDSP_HI
1939 #undef MIPSDSP_LO
1940 #undef MIPSDSP_Q3
1941 #undef MIPSDSP_Q2
1942 #undef MIPSDSP_Q1
1943 #undef MIPSDSP_Q0
1944
1945 #undef MIPSDSP_SPLIT32_8
1946 #undef MIPSDSP_SPLIT32_16
1947
1948 #undef MIPSDSP_RETURN32
1949 #undef MIPSDSP_RETURN32_8
1950 #undef MIPSDSP_RETURN32_16
1951
1952 #ifdef TARGET_MIPS64
1953 #undef MIPSDSP_SPLIT64_16
1954 #undef MIPSDSP_SPLIT64_32
1955 #undef MIPSDSP_RETURN64_16
1956 #undef MIPSDSP_RETURN64_32
1957 #endif