2 * Copyright (c) 2007 MIPS Technologies, Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 * Authors: Brett Miller
31 #include "arch/mips/isa_traits.hh"
32 #include "arch/mips/dsp.hh"
33 #include "config/full_system.hh"
34 #include "cpu/static_inst.hh"
35 #include "sim/serialize.hh"
36 #include "base/bitfield.hh"
37 #include "base/misc.hh"
39 using namespace MipsISA
;
43 MipsISA::bitrev(int32_t value
)
48 for (int i
= 0; i
< 16; i
++) {
52 result
|= (value
& 1 << i
) << -shift
;
54 result
|= (value
& 1 << i
) >> shift
;
61 MipsISA::dspSaturate(uint64_t value
, int32_t fmt
, int32_t sign
,
64 int64_t svalue
= (int64_t)value
;
68 if (svalue
> (int64_t)FIXED_SMAX
[fmt
]) {
70 svalue
= (int64_t)FIXED_SMAX
[fmt
];
71 } else if (svalue
< (int64_t)FIXED_SMIN
[fmt
]) {
73 svalue
= (int64_t)FIXED_SMIN
[fmt
];
77 if (svalue
> (int64_t)FIXED_UMAX
[fmt
]) {
79 svalue
= FIXED_UMAX
[fmt
];
80 } else if (svalue
< (int64_t)FIXED_UMIN
[fmt
]) {
82 svalue
= FIXED_UMIN
[fmt
];
87 return (uint64_t)svalue
;
91 MipsISA::checkOverflow(uint64_t value
, int32_t fmt
, int32_t sign
,
94 int64_t svalue
= (int64_t)value
;
99 if (svalue
> (int64_t)FIXED_SMAX
[fmt
] ||
100 svalue
< (int64_t)FIXED_SMIN
[fmt
])
104 if (svalue
> (int64_t)FIXED_UMAX
[fmt
] ||
105 svalue
< (int64_t)FIXED_UMIN
[fmt
])
110 return (uint64_t)svalue
;
114 MipsISA::signExtend(uint64_t value
, int32_t fmt
)
116 int32_t signpos
= SIMD_NBITS
[fmt
];
117 uint64_t sign
= uint64_t(1) << (signpos
- 1);
118 uint64_t ones
= ~(0ULL);
121 value
|= (ones
<< signpos
); // extend with ones
123 value
&= (ones
>> (64 - signpos
)); // extend with zeros
129 MipsISA::addHalfLsb(uint64_t value
, int32_t lsbpos
)
131 return value
+= ULL(1) << (lsbpos
- 1);
135 MipsISA::dspAbs(int32_t a
, int32_t fmt
, uint32_t *dspctl
)
137 int nvals
= SIMD_NVALS
[fmt
];
141 uint64_t a_values
[SIMD_MAX_VALS
];
143 simdUnpack(a
, a_values
, fmt
, SIGNED
);
145 for (int i
= 0; i
< nvals
; i
++) {
146 svalue
= (int64_t)a_values
[i
];
148 if (a_values
[i
] == FIXED_SMIN
[fmt
]) {
149 a_values
[i
] = FIXED_SMAX
[fmt
];
151 } else if (svalue
< 0) {
152 a_values
[i
] = uint64_t(0 - svalue
);
156 simdPack(a_values
, &result
, fmt
);
159 writeDSPControl(dspctl
, (ouflag
<< 4) << DSP_CTL_POS
[DSP_OUFLAG
],
166 MipsISA::dspAdd(int32_t a
, int32_t b
, int32_t fmt
, int32_t saturate
,
167 int32_t sign
, uint32_t *dspctl
)
169 int nvals
= SIMD_NVALS
[fmt
];
172 uint64_t a_values
[SIMD_MAX_VALS
];
173 uint64_t b_values
[SIMD_MAX_VALS
];
175 simdUnpack(a
, a_values
, fmt
, sign
);
176 simdUnpack(b
, b_values
, fmt
, sign
);
178 for (int i
= 0; i
< nvals
; i
++)
181 a_values
[i
] = dspSaturate(a_values
[i
] + b_values
[i
], fmt
, sign
,
184 a_values
[i
] = checkOverflow(a_values
[i
] + b_values
[i
], fmt
, sign
,
188 simdPack(a_values
, &result
, fmt
);
191 writeDSPControl(dspctl
, (ouflag
<< 4) << DSP_CTL_POS
[DSP_OUFLAG
],
198 MipsISA::dspAddh(int32_t a
, int32_t b
, int32_t fmt
, int32_t round
,
201 int nvals
= SIMD_NVALS
[fmt
];
203 uint64_t a_values
[SIMD_MAX_VALS
];
204 uint64_t b_values
[SIMD_MAX_VALS
];
206 simdUnpack(a
, a_values
, fmt
, sign
);
207 simdUnpack(b
, b_values
, fmt
, sign
);
209 for (int i
= 0; i
< nvals
; i
++) {
211 a_values
[i
] = addHalfLsb(a_values
[i
] + b_values
[i
], 1) >> 1;
213 a_values
[i
] = (a_values
[i
] + b_values
[i
]) >> 1;
216 simdPack(a_values
, &result
, fmt
);
222 MipsISA::dspSub(int32_t a
, int32_t b
, int32_t fmt
, int32_t saturate
,
223 int32_t sign
, uint32_t *dspctl
)
225 int nvals
= SIMD_NVALS
[fmt
];
228 uint64_t a_values
[SIMD_MAX_VALS
];
229 uint64_t b_values
[SIMD_MAX_VALS
];
231 simdUnpack(a
, a_values
, fmt
, sign
);
232 simdUnpack(b
, b_values
, fmt
, sign
);
234 for (int i
= 0; i
< nvals
; i
++) {
236 a_values
[i
] = dspSaturate(a_values
[i
] - b_values
[i
], fmt
, sign
,
239 a_values
[i
] = checkOverflow(a_values
[i
] - b_values
[i
], fmt
, sign
,
243 simdPack(a_values
, &result
, fmt
);
246 writeDSPControl(dspctl
, (ouflag
<< 4) << DSP_CTL_POS
[DSP_OUFLAG
],
253 MipsISA::dspSubh(int32_t a
, int32_t b
, int32_t fmt
, int32_t round
,
256 int nvals
= SIMD_NVALS
[fmt
];
258 uint64_t a_values
[SIMD_MAX_VALS
];
259 uint64_t b_values
[SIMD_MAX_VALS
];
261 simdUnpack(a
, a_values
, fmt
, sign
);
262 simdUnpack(b
, b_values
, fmt
, sign
);
264 for (int i
= 0; i
< nvals
; i
++)
267 a_values
[i
] = addHalfLsb(a_values
[i
] - b_values
[i
], 1) >> 1;
269 a_values
[i
] = (a_values
[i
] - b_values
[i
]) >> 1;
272 simdPack(a_values
, &result
, fmt
);
278 MipsISA::dspShll(int32_t a
, uint32_t sa
, int32_t fmt
, int32_t saturate
,
279 int32_t sign
, uint32_t *dspctl
)
281 int nvals
= SIMD_NVALS
[fmt
];
284 uint64_t a_values
[SIMD_MAX_VALS
];
286 sa
= bits(sa
, SIMD_LOG2N
[fmt
] - 1, 0);
287 simdUnpack(a
, a_values
, fmt
, sign
);
289 for (int i
= 0; i
< nvals
; i
++)
292 a_values
[i
] = dspSaturate(a_values
[i
] << sa
, fmt
, sign
, &ouflag
);
294 a_values
[i
] = checkOverflow(a_values
[i
] << sa
, fmt
, sign
, &ouflag
);
297 simdPack(a_values
, &result
, fmt
);
300 writeDSPControl(dspctl
, (ouflag
<< 6) << DSP_CTL_POS
[DSP_OUFLAG
],
307 MipsISA::dspShrl(int32_t a
, uint32_t sa
, int32_t fmt
, int32_t sign
)
309 int nvals
= SIMD_NVALS
[fmt
];
311 uint64_t a_values
[SIMD_MAX_VALS
];
313 sa
= bits(sa
, SIMD_LOG2N
[fmt
] - 1, 0);
315 simdUnpack(a
, a_values
, fmt
, UNSIGNED
);
317 for (int i
= 0; i
< nvals
; i
++)
318 a_values
[i
] = a_values
[i
] >> sa
;
320 simdPack(a_values
, &result
, fmt
);
326 MipsISA::dspShra(int32_t a
, uint32_t sa
, int32_t fmt
, int32_t round
,
327 int32_t sign
, uint32_t *dspctl
)
329 int nvals
= SIMD_NVALS
[fmt
];
331 uint64_t a_values
[SIMD_MAX_VALS
];
333 sa
= bits(sa
, SIMD_LOG2N
[fmt
] - 1, 0);
335 simdUnpack(a
, a_values
, fmt
, SIGNED
);
337 for (int i
= 0; i
< nvals
; i
++) {
339 a_values
[i
] = addHalfLsb(a_values
[i
], sa
) >> sa
;
341 a_values
[i
] = a_values
[i
] >> sa
;
344 simdPack(a_values
, &result
, fmt
);
350 MipsISA::dspMulq(int32_t a
, int32_t b
, int32_t fmt
, int32_t saturate
,
351 int32_t round
, uint32_t *dspctl
)
353 int nvals
= SIMD_NVALS
[fmt
];
354 int sa
= SIMD_NBITS
[fmt
];
357 uint64_t a_values
[SIMD_MAX_VALS
];
358 uint64_t b_values
[SIMD_MAX_VALS
];
361 simdUnpack(a
, a_values
, fmt
, SIGNED
);
362 simdUnpack(b
, b_values
, fmt
, SIGNED
);
364 for (int i
= 0; i
< nvals
; i
++) {
367 (int64_t)addHalfLsb(a_values
[i
] * b_values
[i
] << 1, sa
) >> sa
;
369 temp
= (int64_t)(a_values
[i
] * b_values
[i
]) >> (sa
- 1);
371 if (a_values
[i
] == FIXED_SMIN
[fmt
] && b_values
[i
] == FIXED_SMIN
[fmt
]) {
375 temp
= FIXED_SMAX
[fmt
];
381 simdPack(a_values
, &result
, fmt
);
384 writeDSPControl(dspctl
, (ouflag
<< 5) << DSP_CTL_POS
[DSP_OUFLAG
],
391 MipsISA::dspMul(int32_t a
, int32_t b
, int32_t fmt
, int32_t saturate
,
394 int nvals
= SIMD_NVALS
[fmt
];
397 uint64_t a_values
[SIMD_MAX_VALS
];
398 uint64_t b_values
[SIMD_MAX_VALS
];
400 simdUnpack(a
, a_values
, fmt
, SIGNED
);
401 simdUnpack(b
, b_values
, fmt
, SIGNED
);
403 for (int i
= 0; i
< nvals
; i
++)
406 a_values
[i
] = dspSaturate(a_values
[i
] * b_values
[i
], fmt
, SIGNED
,
409 a_values
[i
] = checkOverflow(a_values
[i
] * b_values
[i
], fmt
, SIGNED
,
413 simdPack(a_values
, &result
, fmt
);
416 writeDSPControl(dspctl
, (ouflag
<< 5) << DSP_CTL_POS
[DSP_OUFLAG
],
423 MipsISA::dspMuleu(int32_t a
, int32_t b
, int32_t mode
, uint32_t *dspctl
)
425 int nvals
= SIMD_NVALS
[SIMD_FMT_PH
];
428 uint64_t a_values
[SIMD_MAX_VALS
];
429 uint64_t b_values
[SIMD_MAX_VALS
];
431 simdUnpack(a
, a_values
, SIMD_FMT_QB
, UNSIGNED
);
432 simdUnpack(b
, b_values
, SIMD_FMT_PH
, UNSIGNED
);
436 for (int i
= 0; i
< nvals
; i
++)
437 b_values
[i
] = dspSaturate(a_values
[i
+ 2] * b_values
[i
],
438 SIMD_FMT_PH
, UNSIGNED
, &ouflag
);
441 for (int i
= 0; i
< nvals
; i
++)
442 b_values
[i
] = dspSaturate(a_values
[i
] * b_values
[i
], SIMD_FMT_PH
,
447 simdPack(b_values
, &result
, SIMD_FMT_PH
);
450 writeDSPControl(dspctl
, (ouflag
<< 5) << DSP_CTL_POS
[DSP_OUFLAG
],
457 MipsISA::dspMuleq(int32_t a
, int32_t b
, int32_t mode
, uint32_t *dspctl
)
459 int nvals
= SIMD_NVALS
[SIMD_FMT_W
];
462 uint64_t a_values
[SIMD_MAX_VALS
];
463 uint64_t b_values
[SIMD_MAX_VALS
];
464 uint64_t c_values
[SIMD_MAX_VALS
];
466 simdUnpack(a
, a_values
, SIMD_FMT_PH
, SIGNED
);
467 simdUnpack(b
, b_values
, SIMD_FMT_PH
, SIGNED
);
471 for (int i
= 0; i
< nvals
; i
++)
472 c_values
[i
] = dspSaturate(a_values
[i
+ 1] * b_values
[i
+ 1] << 1,
473 SIMD_FMT_W
, SIGNED
, &ouflag
);
476 for (int i
= 0; i
< nvals
; i
++)
477 c_values
[i
] = dspSaturate(a_values
[i
] * b_values
[i
] << 1,
478 SIMD_FMT_W
, SIGNED
, &ouflag
);
482 simdPack(c_values
, &result
, SIMD_FMT_W
);
485 writeDSPControl(dspctl
, (ouflag
<< 5) << DSP_CTL_POS
[DSP_OUFLAG
],
492 MipsISA::dspDpaq(int64_t dspac
, int32_t a
, int32_t b
, int32_t ac
,
493 int32_t infmt
, int32_t outfmt
, int32_t postsat
, int32_t mode
,
496 int nvals
= SIMD_NVALS
[infmt
];
500 uint64_t a_values
[SIMD_MAX_VALS
];
501 uint64_t b_values
[SIMD_MAX_VALS
];
503 simdUnpack(a
, a_values
, infmt
, SIGNED
);
504 simdUnpack(b
, b_values
, infmt
, SIGNED
);
506 for (int i
= 0; i
< nvals
; i
++) {
509 if (a_values
[nvals
- 1 - i
] == FIXED_SMIN
[infmt
] &&
510 b_values
[i
] == FIXED_SMIN
[infmt
]) {
511 result
+= FIXED_SMAX
[outfmt
];
515 result
+= a_values
[nvals
- 1 - i
] * b_values
[i
] << 1;
518 if (a_values
[i
] == FIXED_SMIN
[infmt
] &&
519 b_values
[i
] == FIXED_SMIN
[infmt
]) {
520 result
+= FIXED_SMAX
[outfmt
];
523 result
+= a_values
[i
] * b_values
[i
] << 1;
530 if (outfmt
== SIMD_FMT_L
) {
531 int signa
= bits(dspac
, 63, 63);
532 int signb
= bits(result
, 63, 63);
534 temp
= dspac
+ result
;
536 if (signa
== signb
&& bits(temp
, 63, 63) != signa
) {
539 dspac
= FIXED_SMIN
[outfmt
];
541 dspac
= FIXED_SMAX
[outfmt
];
546 dspac
= dspSaturate(dspac
+ result
, outfmt
, SIGNED
, &ouflag
);
553 *dspctl
= insertBits(*dspctl
, 16 + ac
, 16 + ac
, 1);
559 MipsISA::dspDpsq(int64_t dspac
, int32_t a
, int32_t b
, int32_t ac
,
560 int32_t infmt
, int32_t outfmt
, int32_t postsat
, int32_t mode
,
563 int nvals
= SIMD_NVALS
[infmt
];
567 uint64_t a_values
[SIMD_MAX_VALS
];
568 uint64_t b_values
[SIMD_MAX_VALS
];
570 simdUnpack(a
, a_values
, infmt
, SIGNED
);
571 simdUnpack(b
, b_values
, infmt
, SIGNED
);
573 for (int i
= 0; i
< nvals
; i
++) {
576 if (a_values
[nvals
- 1 - i
] == FIXED_SMIN
[infmt
] &&
577 b_values
[i
] == FIXED_SMIN
[infmt
]) {
578 result
+= FIXED_SMAX
[outfmt
];
581 result
+= a_values
[nvals
- 1 - i
] * b_values
[i
] << 1;
585 if (a_values
[i
] == FIXED_SMIN
[infmt
] &&
586 b_values
[i
] == FIXED_SMIN
[infmt
]) {
587 result
+= FIXED_SMAX
[outfmt
];
590 result
+= a_values
[i
] * b_values
[i
] << 1;
597 if (outfmt
== SIMD_FMT_L
) {
598 int signa
= bits(dspac
, 63, 63);
599 int signb
= bits(-result
, 63, 63);
601 temp
= dspac
- result
;
603 if (signa
== signb
&& bits(temp
, 63, 63) != signa
) {
606 dspac
= FIXED_SMIN
[outfmt
];
608 dspac
= FIXED_SMAX
[outfmt
];
613 dspac
= dspSaturate(dspac
- result
, outfmt
, SIGNED
, &ouflag
);
620 *dspctl
= insertBits(*dspctl
, 16 + ac
, 16 + ac
, 1);
626 MipsISA::dspDpa(int64_t dspac
, int32_t a
, int32_t b
, int32_t ac
,
627 int32_t fmt
, int32_t sign
, int32_t mode
)
629 int nvals
= SIMD_NVALS
[fmt
];
630 uint64_t a_values
[SIMD_MAX_VALS
];
631 uint64_t b_values
[SIMD_MAX_VALS
];
633 simdUnpack(a
, a_values
, fmt
, sign
);
634 simdUnpack(b
, b_values
, fmt
, sign
);
636 for (int i
= 0; i
< 2; i
++) {
639 dspac
+= a_values
[nvals
- 1 - i
] * b_values
[nvals
- 1 - i
];
642 dspac
+= a_values
[nvals
- 3 - i
] * b_values
[nvals
- 3 - i
];
645 dspac
+= a_values
[nvals
- 1 - i
] * b_values
[i
];
654 MipsISA::dspDps(int64_t dspac
, int32_t a
, int32_t b
, int32_t ac
,
655 int32_t fmt
, int32_t sign
, int32_t mode
)
657 int nvals
= SIMD_NVALS
[fmt
];
658 uint64_t a_values
[SIMD_MAX_VALS
];
659 uint64_t b_values
[SIMD_MAX_VALS
];
661 simdUnpack(a
, a_values
, fmt
, sign
);
662 simdUnpack(b
, b_values
, fmt
, sign
);
664 for (int i
= 0; i
< 2; i
++) {
667 dspac
-= a_values
[nvals
- 1 - i
] * b_values
[nvals
- 1 - i
];
670 dspac
-= a_values
[nvals
- 3 - i
] * b_values
[nvals
- 3 - i
];
673 dspac
-= a_values
[nvals
- 1 - i
] * b_values
[i
];
682 MipsISA::dspMaq(int64_t dspac
, int32_t a
, int32_t b
, int32_t ac
,
683 int32_t fmt
, int32_t mode
, int32_t saturate
, uint32_t *dspctl
)
685 int nvals
= SIMD_NVALS
[fmt
- 1];
686 uint64_t a_values
[SIMD_MAX_VALS
];
687 uint64_t b_values
[SIMD_MAX_VALS
];
691 simdUnpack(a
, a_values
, fmt
, SIGNED
);
692 simdUnpack(b
, b_values
, fmt
, SIGNED
);
694 for (int i
= 0; i
< nvals
; i
++) {
697 temp
= a_values
[i
+ 1] * b_values
[i
+ 1] << 1;
698 if (a_values
[i
+ 1] == FIXED_SMIN
[fmt
] &&
699 b_values
[i
+ 1] == FIXED_SMIN
[fmt
]) {
700 temp
= (int64_t)FIXED_SMAX
[fmt
- 1];
705 temp
= a_values
[i
] * b_values
[i
] << 1;
706 if (a_values
[i
] == FIXED_SMIN
[fmt
] &&
707 b_values
[i
] == FIXED_SMIN
[fmt
]) {
708 temp
= (int64_t)FIXED_SMAX
[fmt
- 1];
717 temp
= dspSaturate(temp
, fmt
- 1, SIGNED
, &ouflag
);
719 *dspctl
= insertBits(*dspctl
, 16 + ac
, 16 + ac
, 1);
726 MipsISA::dspMulsa(int64_t dspac
, int32_t a
, int32_t b
, int32_t ac
, int32_t fmt
)
728 uint64_t a_values
[SIMD_MAX_VALS
];
729 uint64_t b_values
[SIMD_MAX_VALS
];
731 simdUnpack(a
, a_values
, fmt
, SIGNED
);
732 simdUnpack(b
, b_values
, fmt
, SIGNED
);
734 dspac
+= a_values
[1] * b_values
[1] - a_values
[0] * b_values
[0];
740 MipsISA::dspMulsaq(int64_t dspac
, int32_t a
, int32_t b
, int32_t ac
,
741 int32_t fmt
, uint32_t *dspctl
)
743 int nvals
= SIMD_NVALS
[fmt
];
744 uint64_t a_values
[SIMD_MAX_VALS
];
745 uint64_t b_values
[SIMD_MAX_VALS
];
749 simdUnpack(a
, a_values
, fmt
, SIGNED
);
750 simdUnpack(b
, b_values
, fmt
, SIGNED
);
752 for (int i
= nvals
- 1; i
> -1; i
--) {
753 temp
[i
] = a_values
[i
] * b_values
[i
] << 1;
754 if (a_values
[i
] == FIXED_SMIN
[fmt
] && b_values
[i
] == FIXED_SMIN
[fmt
]) {
755 temp
[i
] = FIXED_SMAX
[fmt
- 1];
760 dspac
+= temp
[1] - temp
[0];
763 *dspctl
= insertBits(*dspctl
, 16 + ac
, 16 + ac
, 1);
769 MipsISA::dspCmp(int32_t a
, int32_t b
, int32_t fmt
, int32_t sign
, int32_t op
,
772 int nvals
= SIMD_NVALS
[fmt
];
774 uint64_t a_values
[SIMD_MAX_VALS
];
775 uint64_t b_values
[SIMD_MAX_VALS
];
777 simdUnpack(a
, a_values
, fmt
, sign
);
778 simdUnpack(b
, b_values
, fmt
, sign
);
780 for (int i
= 0; i
< nvals
; i
++) {
785 cc
= (a_values
[i
] == b_values
[i
]);
788 cc
= (a_values
[i
] < b_values
[i
]);
791 cc
= (a_values
[i
] <= b_values
[i
]);
795 ccond
|= cc
<< (DSP_CTL_POS
[DSP_CCOND
] + i
);
798 writeDSPControl(dspctl
, ccond
, 1 << DSP_CCOND
);
802 MipsISA::dspCmpg(int32_t a
, int32_t b
, int32_t fmt
, int32_t sign
, int32_t op
)
804 int nvals
= SIMD_NVALS
[fmt
];
806 uint64_t a_values
[SIMD_MAX_VALS
];
807 uint64_t b_values
[SIMD_MAX_VALS
];
809 simdUnpack(a
, a_values
, fmt
, sign
);
810 simdUnpack(b
, b_values
, fmt
, sign
);
812 for (int i
= 0; i
< nvals
; i
++) {
817 cc
= (a_values
[i
] == b_values
[i
]);
820 cc
= (a_values
[i
] < b_values
[i
]);
823 cc
= (a_values
[i
] <= b_values
[i
]);
834 MipsISA::dspCmpgd(int32_t a
, int32_t b
, int32_t fmt
, int32_t sign
, int32_t op
,
837 int nvals
= SIMD_NVALS
[fmt
];
840 uint64_t a_values
[SIMD_MAX_VALS
];
841 uint64_t b_values
[SIMD_MAX_VALS
];
843 simdUnpack(a
, a_values
, fmt
, sign
);
844 simdUnpack(b
, b_values
, fmt
, sign
);
846 for (int i
= 0; i
< nvals
; i
++) {
851 cc
= (a_values
[i
] == b_values
[i
]);
854 cc
= (a_values
[i
] < b_values
[i
]);
857 cc
= (a_values
[i
] <= b_values
[i
]);
862 ccond
|= cc
<< (DSP_CTL_POS
[DSP_CCOND
] + i
);
865 writeDSPControl(dspctl
, ccond
, 1 << DSP_CCOND
);
871 MipsISA::dspPrece(int32_t a
, int32_t infmt
, int32_t insign
, int32_t outfmt
,
872 int32_t outsign
, int32_t mode
)
875 int ninvals
= SIMD_NVALS
[infmt
];
876 int noutvals
= SIMD_NVALS
[outfmt
];
878 uint64_t in_values
[SIMD_MAX_VALS
];
879 uint64_t out_values
[SIMD_MAX_VALS
];
881 if (insign
== SIGNED
&& outsign
== SIGNED
)
882 sa
= SIMD_NBITS
[infmt
];
883 else if (insign
== UNSIGNED
&& outsign
== SIGNED
)
884 sa
= SIMD_NBITS
[infmt
] - 1;
885 else if (insign
== UNSIGNED
&& outsign
== UNSIGNED
)
888 simdUnpack(a
, in_values
, infmt
, insign
);
890 for (int i
= 0; i
<noutvals
; i
++) {
893 out_values
[i
] = in_values
[i
+ (ninvals
>> 1)] << sa
;
896 out_values
[i
] = in_values
[i
] << sa
;
899 out_values
[i
] = in_values
[(i
<< 1) + 1] << sa
;
902 out_values
[i
] = in_values
[i
<< 1] << sa
;
907 simdPack(out_values
, &result
, outfmt
);
913 MipsISA::dspPrecrqu(int32_t a
, int32_t b
, uint32_t *dspctl
)
915 uint64_t a_values
[SIMD_MAX_VALS
];
916 uint64_t b_values
[SIMD_MAX_VALS
];
917 uint64_t r_values
[SIMD_MAX_VALS
];
921 simdUnpack(a
, a_values
, SIMD_FMT_PH
, SIGNED
);
922 simdUnpack(b
, b_values
, SIMD_FMT_PH
, SIGNED
);
924 for (int i
= 0; i
<2; i
++) {
926 dspSaturate((int64_t)b_values
[i
] >> SIMD_NBITS
[SIMD_FMT_QB
] - 1,
927 SIMD_FMT_QB
, UNSIGNED
, &ouflag
);
929 dspSaturate((int64_t)a_values
[i
] >> SIMD_NBITS
[SIMD_FMT_QB
] - 1,
930 SIMD_FMT_QB
, UNSIGNED
, &ouflag
);
933 simdPack(r_values
, &result
, SIMD_FMT_QB
);
936 *dspctl
= insertBits(*dspctl
, 22, 22, 1);
942 MipsISA::dspPrecrq(int32_t a
, int32_t b
, int32_t fmt
, uint32_t *dspctl
)
944 uint64_t a_values
[SIMD_MAX_VALS
];
945 uint64_t b_values
[SIMD_MAX_VALS
];
946 uint64_t r_values
[SIMD_MAX_VALS
];
950 simdUnpack(a
, a_values
, fmt
, SIGNED
);
951 simdUnpack(b
, b_values
, fmt
, SIGNED
);
953 r_values
[1] = dspSaturate((int64_t)addHalfLsb(a_values
[0], 16) >> 16,
954 fmt
+ 1, SIGNED
, &ouflag
);
955 r_values
[0] = dspSaturate((int64_t)addHalfLsb(b_values
[0], 16) >> 16,
956 fmt
+ 1, SIGNED
, &ouflag
);
958 simdPack(r_values
, &result
, fmt
+ 1);
961 *dspctl
= insertBits(*dspctl
, 22, 22, 1);
967 MipsISA::dspPrecrSra(int32_t a
, int32_t b
, int32_t sa
, int32_t fmt
,
970 int nvals
= SIMD_NVALS
[fmt
];
971 uint64_t a_values
[SIMD_MAX_VALS
];
972 uint64_t b_values
[SIMD_MAX_VALS
];
973 uint64_t c_values
[SIMD_MAX_VALS
];
976 simdUnpack(a
, a_values
, fmt
, SIGNED
);
977 simdUnpack(b
, b_values
, fmt
, SIGNED
);
979 for (int i
= 0; i
< nvals
; i
++) {
981 c_values
[i
] = addHalfLsb(b_values
[i
], sa
) >> sa
;
982 c_values
[i
+ 1] = addHalfLsb(a_values
[i
], sa
) >> sa
;
984 c_values
[i
] = b_values
[i
] >> sa
;
985 c_values
[i
+ 1] = a_values
[i
] >> sa
;
989 simdPack(c_values
, &result
, fmt
+ 1);
995 MipsISA::dspPick(int32_t a
, int32_t b
, int32_t fmt
, uint32_t *dspctl
)
997 int nvals
= SIMD_NVALS
[fmt
];
999 uint64_t a_values
[SIMD_MAX_VALS
];
1000 uint64_t b_values
[SIMD_MAX_VALS
];
1001 uint64_t c_values
[SIMD_MAX_VALS
];
1003 simdUnpack(a
, a_values
, fmt
, UNSIGNED
);
1004 simdUnpack(b
, b_values
, fmt
, UNSIGNED
);
1006 for (int i
= 0; i
< nvals
; i
++) {
1007 int condbit
= DSP_CTL_POS
[DSP_CCOND
] + i
;
1008 if (bits(*dspctl
, condbit
, condbit
) == 1)
1009 c_values
[i
] = a_values
[i
];
1011 c_values
[i
] = b_values
[i
];
1014 simdPack(c_values
, &result
, fmt
);
1020 MipsISA::dspPack(int32_t a
, int32_t b
, int32_t fmt
)
1023 uint64_t a_values
[SIMD_MAX_VALS
];
1024 uint64_t b_values
[SIMD_MAX_VALS
];
1025 uint64_t c_values
[SIMD_MAX_VALS
];
1027 simdUnpack(a
, a_values
, fmt
, UNSIGNED
);
1028 simdUnpack(b
, b_values
, fmt
, UNSIGNED
);
1030 c_values
[0] = b_values
[1];
1031 c_values
[1] = a_values
[0];
1033 simdPack(c_values
, &result
, fmt
);
1039 MipsISA::dspExtr(int64_t dspac
, int32_t fmt
, int32_t sa
, int32_t round
,
1040 int32_t saturate
, uint32_t *dspctl
)
1043 uint32_t ouflag
= 0;
1046 sa
= bits(sa
, 4, 0);
1050 temp
= (int64_t)addHalfLsb(dspac
, sa
);
1052 if (dspac
> 0 && temp
< 0) {
1055 temp
= FIXED_SMAX
[SIMD_FMT_L
];
1065 dspac
= checkOverflow(dspac
, fmt
, SIGNED
, &ouflag
);
1068 *dspctl
= insertBits(*dspctl
, 23, 23, ouflag
);
1071 result
= (int32_t)dspSaturate(temp
, fmt
, SIGNED
, &ouflag
);
1073 result
= (int32_t)temp
;
1075 result
= (int32_t)temp
;
1082 MipsISA::dspExtp(int64_t dspac
, int32_t size
, uint32_t *dspctl
)
1087 pos
= bits(*dspctl
, 5, 0);
1088 size
= bits(size
, 4, 0);
1090 if (pos
- (size
+ 1) >= -1) {
1091 result
= bits(dspac
, pos
, pos
- size
);
1092 *dspctl
= insertBits(*dspctl
, 14, 14, 0);
1095 *dspctl
= insertBits(*dspctl
, 14, 14, 1);
1102 MipsISA::dspExtpd(int64_t dspac
, int32_t size
, uint32_t *dspctl
)
1107 pos
= bits(*dspctl
, 5, 0);
1108 size
= bits(size
, 4, 0);
1110 if (pos
- (size
+ 1) >= -1) {
1111 result
= bits(dspac
, pos
, pos
- size
);
1112 *dspctl
= insertBits(*dspctl
, 14, 14, 0);
1113 if (pos
- (size
+ 1) >= 0)
1114 *dspctl
= insertBits(*dspctl
, 5, 0, pos
- (size
+ 1));
1115 else if ((pos
- (size
+ 1)) == -1)
1116 *dspctl
= insertBits(*dspctl
, 5, 0, 63);
1119 *dspctl
= insertBits(*dspctl
, 14, 14, 1);
1126 MipsISA::simdPack(uint64_t *values_ptr
, int32_t *reg
, int32_t fmt
)
1128 int nvals
= SIMD_NVALS
[fmt
];
1129 int nbits
= SIMD_NBITS
[fmt
];
1133 for (int i
= 0; i
< nvals
; i
++)
1134 *reg
|= (int32_t)bits(values_ptr
[i
], nbits
- 1, 0) << nbits
* i
;
1138 MipsISA::simdUnpack(int32_t reg
, uint64_t *values_ptr
, int32_t fmt
, int32_t sign
)
1140 int nvals
= SIMD_NVALS
[fmt
];
1141 int nbits
= SIMD_NBITS
[fmt
];
1145 for (int i
= 0; i
< nvals
; i
++) {
1146 uint64_t tmp
= (uint64_t)bits(reg
, nbits
* (i
+ 1) - 1, nbits
* i
);
1147 values_ptr
[i
] = signExtend(tmp
, fmt
);
1151 for (int i
= 0; i
< nvals
; i
++) {
1153 (uint64_t)bits(reg
, nbits
* (i
+ 1) - 1, nbits
* i
);
1160 MipsISA::writeDSPControl(uint32_t *dspctl
, uint32_t value
, uint32_t mask
)
1164 if (mask
& 0x01) fmask
|= DSP_CTL_MASK
[DSP_POS
];
1165 if (mask
& 0x02) fmask
|= DSP_CTL_MASK
[DSP_SCOUNT
];
1166 if (mask
& 0x04) fmask
|= DSP_CTL_MASK
[DSP_C
];
1167 if (mask
& 0x08) fmask
|= DSP_CTL_MASK
[DSP_OUFLAG
];
1168 if (mask
& 0x10) fmask
|= DSP_CTL_MASK
[DSP_CCOND
];
1169 if (mask
& 0x20) fmask
|= DSP_CTL_MASK
[DSP_EFI
];
1177 MipsISA::readDSPControl(uint32_t *dspctl
, uint32_t mask
)
1181 if (mask
& 0x01) fmask
|= DSP_CTL_MASK
[DSP_POS
];
1182 if (mask
& 0x02) fmask
|= DSP_CTL_MASK
[DSP_SCOUNT
];
1183 if (mask
& 0x04) fmask
|= DSP_CTL_MASK
[DSP_C
];
1184 if (mask
& 0x08) fmask
|= DSP_CTL_MASK
[DSP_OUFLAG
];
1185 if (mask
& 0x10) fmask
|= DSP_CTL_MASK
[DSP_CCOND
];
1186 if (mask
& 0x20) fmask
|= DSP_CTL_MASK
[DSP_EFI
];
1188 return *dspctl
& fmask
;