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/dsp.hh"
32 #include "arch/mips/isa_traits.hh"
33 #include "base/bitfield.hh"
34 #include "base/misc.hh"
35 #include "cpu/static_inst.hh"
36 #include "sim/serialize.hh"
38 using namespace MipsISA
;
42 MipsISA::bitrev(int32_t value
)
47 for (int i
= 0; i
< 16; i
++) {
51 result
|= (value
& 1 << i
) << -shift
;
53 result
|= (value
& 1 << i
) >> shift
;
60 MipsISA::dspSaturate(uint64_t value
, int32_t fmt
, int32_t sign
,
63 int64_t svalue
= (int64_t)value
;
67 if (svalue
> (int64_t)FIXED_SMAX
[fmt
]) {
69 svalue
= (int64_t)FIXED_SMAX
[fmt
];
70 } else if (svalue
< (int64_t)FIXED_SMIN
[fmt
]) {
72 svalue
= (int64_t)FIXED_SMIN
[fmt
];
76 if (svalue
> (int64_t)FIXED_UMAX
[fmt
]) {
78 svalue
= FIXED_UMAX
[fmt
];
79 } else if (svalue
< (int64_t)FIXED_UMIN
[fmt
]) {
81 svalue
= FIXED_UMIN
[fmt
];
86 return (uint64_t)svalue
;
90 MipsISA::checkOverflow(uint64_t value
, int32_t fmt
, int32_t sign
,
93 int64_t svalue
= (int64_t)value
;
98 if (svalue
> (int64_t)FIXED_SMAX
[fmt
] ||
99 svalue
< (int64_t)FIXED_SMIN
[fmt
])
103 if (svalue
> (int64_t)FIXED_UMAX
[fmt
] ||
104 svalue
< (int64_t)FIXED_UMIN
[fmt
])
109 return (uint64_t)svalue
;
113 MipsISA::signExtend(uint64_t value
, int32_t fmt
)
115 int32_t signpos
= SIMD_NBITS
[fmt
];
116 uint64_t sign
= uint64_t(1) << (signpos
- 1);
117 uint64_t ones
= ~(0ULL);
120 value
|= (ones
<< signpos
); // extend with ones
122 value
&= (ones
>> (64 - signpos
)); // extend with zeros
128 MipsISA::addHalfLsb(uint64_t value
, int32_t lsbpos
)
130 return value
+= ULL(1) << (lsbpos
- 1);
134 MipsISA::dspAbs(int32_t a
, int32_t fmt
, uint32_t *dspctl
)
136 int nvals
= SIMD_NVALS
[fmt
];
140 uint64_t a_values
[SIMD_MAX_VALS
];
142 simdUnpack(a
, a_values
, fmt
, SIGNED
);
144 for (int i
= 0; i
< nvals
; i
++) {
145 svalue
= (int64_t)a_values
[i
];
147 if (a_values
[i
] == FIXED_SMIN
[fmt
]) {
148 a_values
[i
] = FIXED_SMAX
[fmt
];
150 } else if (svalue
< 0) {
151 a_values
[i
] = uint64_t(0 - svalue
);
155 simdPack(a_values
, &result
, fmt
);
158 writeDSPControl(dspctl
, (ouflag
<< 4) << DSP_CTL_POS
[DSP_OUFLAG
],
165 MipsISA::dspAdd(int32_t a
, int32_t b
, int32_t fmt
, int32_t saturate
,
166 int32_t sign
, uint32_t *dspctl
)
168 int nvals
= SIMD_NVALS
[fmt
];
171 uint64_t a_values
[SIMD_MAX_VALS
];
172 uint64_t b_values
[SIMD_MAX_VALS
];
174 simdUnpack(a
, a_values
, fmt
, sign
);
175 simdUnpack(b
, b_values
, fmt
, sign
);
177 for (int i
= 0; i
< nvals
; i
++)
180 a_values
[i
] = dspSaturate(a_values
[i
] + b_values
[i
], fmt
, sign
,
183 a_values
[i
] = checkOverflow(a_values
[i
] + b_values
[i
], fmt
, sign
,
187 simdPack(a_values
, &result
, fmt
);
190 writeDSPControl(dspctl
, (ouflag
<< 4) << DSP_CTL_POS
[DSP_OUFLAG
],
197 MipsISA::dspAddh(int32_t a
, int32_t b
, int32_t fmt
, int32_t round
,
200 int nvals
= SIMD_NVALS
[fmt
];
202 uint64_t a_values
[SIMD_MAX_VALS
];
203 uint64_t b_values
[SIMD_MAX_VALS
];
205 simdUnpack(a
, a_values
, fmt
, sign
);
206 simdUnpack(b
, b_values
, fmt
, sign
);
208 for (int i
= 0; i
< nvals
; i
++) {
210 a_values
[i
] = addHalfLsb(a_values
[i
] + b_values
[i
], 1) >> 1;
212 a_values
[i
] = (a_values
[i
] + b_values
[i
]) >> 1;
215 simdPack(a_values
, &result
, fmt
);
221 MipsISA::dspSub(int32_t a
, int32_t b
, int32_t fmt
, int32_t saturate
,
222 int32_t sign
, uint32_t *dspctl
)
224 int nvals
= SIMD_NVALS
[fmt
];
227 uint64_t a_values
[SIMD_MAX_VALS
];
228 uint64_t b_values
[SIMD_MAX_VALS
];
230 simdUnpack(a
, a_values
, fmt
, sign
);
231 simdUnpack(b
, b_values
, fmt
, sign
);
233 for (int i
= 0; i
< nvals
; i
++) {
235 a_values
[i
] = dspSaturate(a_values
[i
] - b_values
[i
], fmt
, sign
,
238 a_values
[i
] = checkOverflow(a_values
[i
] - b_values
[i
], fmt
, sign
,
242 simdPack(a_values
, &result
, fmt
);
245 writeDSPControl(dspctl
, (ouflag
<< 4) << DSP_CTL_POS
[DSP_OUFLAG
],
252 MipsISA::dspSubh(int32_t a
, int32_t b
, int32_t fmt
, int32_t round
,
255 int nvals
= SIMD_NVALS
[fmt
];
257 uint64_t a_values
[SIMD_MAX_VALS
];
258 uint64_t b_values
[SIMD_MAX_VALS
];
260 simdUnpack(a
, a_values
, fmt
, sign
);
261 simdUnpack(b
, b_values
, fmt
, sign
);
263 for (int i
= 0; i
< nvals
; i
++)
266 a_values
[i
] = addHalfLsb(a_values
[i
] - b_values
[i
], 1) >> 1;
268 a_values
[i
] = (a_values
[i
] - b_values
[i
]) >> 1;
271 simdPack(a_values
, &result
, fmt
);
277 MipsISA::dspShll(int32_t a
, uint32_t sa
, int32_t fmt
, int32_t saturate
,
278 int32_t sign
, uint32_t *dspctl
)
280 int nvals
= SIMD_NVALS
[fmt
];
283 uint64_t a_values
[SIMD_MAX_VALS
];
285 sa
= bits(sa
, SIMD_LOG2N
[fmt
] - 1, 0);
286 simdUnpack(a
, a_values
, fmt
, sign
);
288 for (int i
= 0; i
< nvals
; i
++)
291 a_values
[i
] = dspSaturate(a_values
[i
] << sa
, fmt
, sign
, &ouflag
);
293 a_values
[i
] = checkOverflow(a_values
[i
] << sa
, fmt
, sign
, &ouflag
);
296 simdPack(a_values
, &result
, fmt
);
299 writeDSPControl(dspctl
, (ouflag
<< 6) << DSP_CTL_POS
[DSP_OUFLAG
],
306 MipsISA::dspShrl(int32_t a
, uint32_t sa
, int32_t fmt
, int32_t sign
)
308 int nvals
= SIMD_NVALS
[fmt
];
310 uint64_t a_values
[SIMD_MAX_VALS
];
312 sa
= bits(sa
, SIMD_LOG2N
[fmt
] - 1, 0);
314 simdUnpack(a
, a_values
, fmt
, UNSIGNED
);
316 for (int i
= 0; i
< nvals
; i
++)
317 a_values
[i
] = a_values
[i
] >> sa
;
319 simdPack(a_values
, &result
, fmt
);
325 MipsISA::dspShra(int32_t a
, uint32_t sa
, int32_t fmt
, int32_t round
,
326 int32_t sign
, uint32_t *dspctl
)
328 int nvals
= SIMD_NVALS
[fmt
];
330 uint64_t a_values
[SIMD_MAX_VALS
];
332 sa
= bits(sa
, SIMD_LOG2N
[fmt
] - 1, 0);
334 simdUnpack(a
, a_values
, fmt
, SIGNED
);
336 for (int i
= 0; i
< nvals
; i
++) {
338 a_values
[i
] = addHalfLsb(a_values
[i
], sa
) >> sa
;
340 a_values
[i
] = a_values
[i
] >> sa
;
343 simdPack(a_values
, &result
, fmt
);
349 MipsISA::dspMulq(int32_t a
, int32_t b
, int32_t fmt
, int32_t saturate
,
350 int32_t round
, uint32_t *dspctl
)
352 int nvals
= SIMD_NVALS
[fmt
];
353 int sa
= SIMD_NBITS
[fmt
];
356 uint64_t a_values
[SIMD_MAX_VALS
];
357 uint64_t b_values
[SIMD_MAX_VALS
];
360 simdUnpack(a
, a_values
, fmt
, SIGNED
);
361 simdUnpack(b
, b_values
, fmt
, SIGNED
);
363 for (int i
= 0; i
< nvals
; i
++) {
366 (int64_t)addHalfLsb(a_values
[i
] * b_values
[i
] << 1, sa
) >> sa
;
368 temp
= (int64_t)(a_values
[i
] * b_values
[i
]) >> (sa
- 1);
370 if (a_values
[i
] == FIXED_SMIN
[fmt
] && b_values
[i
] == FIXED_SMIN
[fmt
]) {
374 temp
= FIXED_SMAX
[fmt
];
380 simdPack(a_values
, &result
, fmt
);
383 writeDSPControl(dspctl
, (ouflag
<< 5) << DSP_CTL_POS
[DSP_OUFLAG
],
390 MipsISA::dspMul(int32_t a
, int32_t b
, int32_t fmt
, int32_t saturate
,
393 int nvals
= SIMD_NVALS
[fmt
];
396 uint64_t a_values
[SIMD_MAX_VALS
];
397 uint64_t b_values
[SIMD_MAX_VALS
];
399 simdUnpack(a
, a_values
, fmt
, SIGNED
);
400 simdUnpack(b
, b_values
, fmt
, SIGNED
);
402 for (int i
= 0; i
< nvals
; i
++)
405 a_values
[i
] = dspSaturate(a_values
[i
] * b_values
[i
], fmt
, SIGNED
,
408 a_values
[i
] = checkOverflow(a_values
[i
] * b_values
[i
], fmt
, SIGNED
,
412 simdPack(a_values
, &result
, fmt
);
415 writeDSPControl(dspctl
, (ouflag
<< 5) << DSP_CTL_POS
[DSP_OUFLAG
],
422 MipsISA::dspMuleu(int32_t a
, int32_t b
, int32_t mode
, uint32_t *dspctl
)
424 int nvals
= SIMD_NVALS
[SIMD_FMT_PH
];
427 uint64_t a_values
[SIMD_MAX_VALS
];
428 uint64_t b_values
[SIMD_MAX_VALS
];
430 simdUnpack(a
, a_values
, SIMD_FMT_QB
, UNSIGNED
);
431 simdUnpack(b
, b_values
, SIMD_FMT_PH
, UNSIGNED
);
435 for (int i
= 0; i
< nvals
; i
++)
436 b_values
[i
] = dspSaturate(a_values
[i
+ 2] * b_values
[i
],
437 SIMD_FMT_PH
, UNSIGNED
, &ouflag
);
440 for (int i
= 0; i
< nvals
; i
++)
441 b_values
[i
] = dspSaturate(a_values
[i
] * b_values
[i
], SIMD_FMT_PH
,
446 simdPack(b_values
, &result
, SIMD_FMT_PH
);
449 writeDSPControl(dspctl
, (ouflag
<< 5) << DSP_CTL_POS
[DSP_OUFLAG
],
456 MipsISA::dspMuleq(int32_t a
, int32_t b
, int32_t mode
, uint32_t *dspctl
)
458 int nvals
= SIMD_NVALS
[SIMD_FMT_W
];
461 uint64_t a_values
[SIMD_MAX_VALS
];
462 uint64_t b_values
[SIMD_MAX_VALS
];
463 uint64_t c_values
[SIMD_MAX_VALS
];
465 memset(c_values
, 0, sizeof(c_values
));
467 simdUnpack(a
, a_values
, SIMD_FMT_PH
, SIGNED
);
468 simdUnpack(b
, b_values
, SIMD_FMT_PH
, SIGNED
);
472 for (int i
= 0; i
< nvals
; i
++)
473 c_values
[i
] = dspSaturate(a_values
[i
+ 1] * b_values
[i
+ 1] << 1,
474 SIMD_FMT_W
, SIGNED
, &ouflag
);
477 for (int i
= 0; i
< nvals
; i
++)
478 c_values
[i
] = dspSaturate(a_values
[i
] * b_values
[i
] << 1,
479 SIMD_FMT_W
, SIGNED
, &ouflag
);
483 simdPack(c_values
, &result
, SIMD_FMT_W
);
486 writeDSPControl(dspctl
, (ouflag
<< 5) << DSP_CTL_POS
[DSP_OUFLAG
],
493 MipsISA::dspDpaq(int64_t dspac
, int32_t a
, int32_t b
, int32_t ac
,
494 int32_t infmt
, int32_t outfmt
, int32_t postsat
, int32_t mode
,
497 int nvals
= SIMD_NVALS
[infmt
];
501 uint64_t a_values
[SIMD_MAX_VALS
];
502 uint64_t b_values
[SIMD_MAX_VALS
];
504 simdUnpack(a
, a_values
, infmt
, SIGNED
);
505 simdUnpack(b
, b_values
, infmt
, SIGNED
);
507 for (int i
= 0; i
< nvals
; i
++) {
510 if (a_values
[nvals
- 1 - i
] == FIXED_SMIN
[infmt
] &&
511 b_values
[i
] == FIXED_SMIN
[infmt
]) {
512 result
+= FIXED_SMAX
[outfmt
];
516 result
+= a_values
[nvals
- 1 - i
] * b_values
[i
] << 1;
519 if (a_values
[i
] == FIXED_SMIN
[infmt
] &&
520 b_values
[i
] == FIXED_SMIN
[infmt
]) {
521 result
+= FIXED_SMAX
[outfmt
];
524 result
+= a_values
[i
] * b_values
[i
] << 1;
531 if (outfmt
== SIMD_FMT_L
) {
532 int signa
= bits(dspac
, 63, 63);
533 int signb
= bits(result
, 63, 63);
535 temp
= dspac
+ result
;
537 if (signa
== signb
&& bits(temp
, 63, 63) != signa
) {
540 dspac
= FIXED_SMIN
[outfmt
];
542 dspac
= FIXED_SMAX
[outfmt
];
547 dspac
= dspSaturate(dspac
+ result
, outfmt
, SIGNED
, &ouflag
);
554 *dspctl
= insertBits(*dspctl
, 16 + ac
, 16 + ac
, 1);
560 MipsISA::dspDpsq(int64_t dspac
, int32_t a
, int32_t b
, int32_t ac
,
561 int32_t infmt
, int32_t outfmt
, int32_t postsat
, int32_t mode
,
564 int nvals
= SIMD_NVALS
[infmt
];
568 uint64_t a_values
[SIMD_MAX_VALS
];
569 uint64_t b_values
[SIMD_MAX_VALS
];
571 simdUnpack(a
, a_values
, infmt
, SIGNED
);
572 simdUnpack(b
, b_values
, infmt
, SIGNED
);
574 for (int i
= 0; i
< nvals
; i
++) {
577 if (a_values
[nvals
- 1 - i
] == FIXED_SMIN
[infmt
] &&
578 b_values
[i
] == FIXED_SMIN
[infmt
]) {
579 result
+= FIXED_SMAX
[outfmt
];
582 result
+= a_values
[nvals
- 1 - i
] * b_values
[i
] << 1;
586 if (a_values
[i
] == FIXED_SMIN
[infmt
] &&
587 b_values
[i
] == FIXED_SMIN
[infmt
]) {
588 result
+= FIXED_SMAX
[outfmt
];
591 result
+= a_values
[i
] * b_values
[i
] << 1;
598 if (outfmt
== SIMD_FMT_L
) {
599 int signa
= bits(dspac
, 63, 63);
600 int signb
= bits(-result
, 63, 63);
602 temp
= dspac
- result
;
604 if (signa
== signb
&& bits(temp
, 63, 63) != signa
) {
607 dspac
= FIXED_SMIN
[outfmt
];
609 dspac
= FIXED_SMAX
[outfmt
];
614 dspac
= dspSaturate(dspac
- result
, outfmt
, SIGNED
, &ouflag
);
621 *dspctl
= insertBits(*dspctl
, 16 + ac
, 16 + ac
, 1);
627 MipsISA::dspDpa(int64_t dspac
, int32_t a
, int32_t b
, int32_t ac
,
628 int32_t fmt
, int32_t sign
, int32_t mode
)
630 int nvals
= SIMD_NVALS
[fmt
];
631 uint64_t a_values
[SIMD_MAX_VALS
];
632 uint64_t b_values
[SIMD_MAX_VALS
];
634 simdUnpack(a
, a_values
, fmt
, sign
);
635 simdUnpack(b
, b_values
, fmt
, sign
);
637 for (int i
= 0; i
< 2; i
++) {
640 dspac
+= a_values
[nvals
- 1 - i
] * b_values
[nvals
- 1 - i
];
643 dspac
+= a_values
[nvals
- 3 - i
] * b_values
[nvals
- 3 - i
];
646 dspac
+= a_values
[nvals
- 1 - i
] * b_values
[i
];
655 MipsISA::dspDps(int64_t dspac
, int32_t a
, int32_t b
, int32_t ac
,
656 int32_t fmt
, int32_t sign
, int32_t mode
)
658 int nvals
= SIMD_NVALS
[fmt
];
659 uint64_t a_values
[SIMD_MAX_VALS
];
660 uint64_t b_values
[SIMD_MAX_VALS
];
662 simdUnpack(a
, a_values
, fmt
, sign
);
663 simdUnpack(b
, b_values
, fmt
, sign
);
665 for (int i
= 0; i
< 2; i
++) {
668 dspac
-= a_values
[nvals
- 1 - i
] * b_values
[nvals
- 1 - i
];
671 dspac
-= a_values
[nvals
- 3 - i
] * b_values
[nvals
- 3 - i
];
674 dspac
-= a_values
[nvals
- 1 - i
] * b_values
[i
];
683 MipsISA::dspMaq(int64_t dspac
, int32_t a
, int32_t b
, int32_t ac
,
684 int32_t fmt
, int32_t mode
, int32_t saturate
, uint32_t *dspctl
)
686 int nvals
= SIMD_NVALS
[fmt
- 1];
687 uint64_t a_values
[SIMD_MAX_VALS
];
688 uint64_t b_values
[SIMD_MAX_VALS
];
692 simdUnpack(a
, a_values
, fmt
, SIGNED
);
693 simdUnpack(b
, b_values
, fmt
, SIGNED
);
695 for (int i
= 0; i
< nvals
; i
++) {
698 temp
= a_values
[i
+ 1] * b_values
[i
+ 1] << 1;
699 if (a_values
[i
+ 1] == FIXED_SMIN
[fmt
] &&
700 b_values
[i
+ 1] == FIXED_SMIN
[fmt
]) {
701 temp
= (int64_t)FIXED_SMAX
[fmt
- 1];
706 temp
= a_values
[i
] * b_values
[i
] << 1;
707 if (a_values
[i
] == FIXED_SMIN
[fmt
] &&
708 b_values
[i
] == FIXED_SMIN
[fmt
]) {
709 temp
= (int64_t)FIXED_SMAX
[fmt
- 1];
718 temp
= dspSaturate(temp
, fmt
- 1, SIGNED
, &ouflag
);
720 *dspctl
= insertBits(*dspctl
, 16 + ac
, 16 + ac
, 1);
727 MipsISA::dspMulsa(int64_t dspac
, int32_t a
, int32_t b
, int32_t ac
, int32_t fmt
)
729 uint64_t a_values
[SIMD_MAX_VALS
];
730 uint64_t b_values
[SIMD_MAX_VALS
];
732 simdUnpack(a
, a_values
, fmt
, SIGNED
);
733 simdUnpack(b
, b_values
, fmt
, SIGNED
);
735 dspac
+= a_values
[1] * b_values
[1] - a_values
[0] * b_values
[0];
741 MipsISA::dspMulsaq(int64_t dspac
, int32_t a
, int32_t b
, int32_t ac
,
742 int32_t fmt
, uint32_t *dspctl
)
744 int nvals
= SIMD_NVALS
[fmt
];
745 uint64_t a_values
[SIMD_MAX_VALS
];
746 uint64_t b_values
[SIMD_MAX_VALS
];
747 int64_t temp
[2] = {0, 0};
750 simdUnpack(a
, a_values
, fmt
, SIGNED
);
751 simdUnpack(b
, b_values
, fmt
, SIGNED
);
753 for (int i
= nvals
- 1; i
> -1; i
--) {
754 temp
[i
] = a_values
[i
] * b_values
[i
] << 1;
755 if (a_values
[i
] == FIXED_SMIN
[fmt
] && b_values
[i
] == FIXED_SMIN
[fmt
]) {
756 temp
[i
] = FIXED_SMAX
[fmt
- 1];
761 dspac
+= temp
[1] - temp
[0];
764 *dspctl
= insertBits(*dspctl
, 16 + ac
, 16 + ac
, 1);
770 MipsISA::dspCmp(int32_t a
, int32_t b
, int32_t fmt
, int32_t sign
, int32_t op
,
773 int nvals
= SIMD_NVALS
[fmt
];
775 uint64_t a_values
[SIMD_MAX_VALS
];
776 uint64_t b_values
[SIMD_MAX_VALS
];
778 simdUnpack(a
, a_values
, fmt
, sign
);
779 simdUnpack(b
, b_values
, fmt
, sign
);
781 for (int i
= 0; i
< nvals
; i
++) {
786 cc
= (a_values
[i
] == b_values
[i
]);
789 cc
= (a_values
[i
] < b_values
[i
]);
792 cc
= (a_values
[i
] <= b_values
[i
]);
796 ccond
|= cc
<< (DSP_CTL_POS
[DSP_CCOND
] + i
);
799 writeDSPControl(dspctl
, ccond
, 1 << DSP_CCOND
);
803 MipsISA::dspCmpg(int32_t a
, int32_t b
, int32_t fmt
, int32_t sign
, int32_t op
)
805 int nvals
= SIMD_NVALS
[fmt
];
807 uint64_t a_values
[SIMD_MAX_VALS
];
808 uint64_t b_values
[SIMD_MAX_VALS
];
810 simdUnpack(a
, a_values
, fmt
, sign
);
811 simdUnpack(b
, b_values
, fmt
, sign
);
813 for (int i
= 0; i
< nvals
; i
++) {
818 cc
= (a_values
[i
] == b_values
[i
]);
821 cc
= (a_values
[i
] < b_values
[i
]);
824 cc
= (a_values
[i
] <= b_values
[i
]);
835 MipsISA::dspCmpgd(int32_t a
, int32_t b
, int32_t fmt
, int32_t sign
, int32_t op
,
838 int nvals
= SIMD_NVALS
[fmt
];
841 uint64_t a_values
[SIMD_MAX_VALS
];
842 uint64_t b_values
[SIMD_MAX_VALS
];
844 simdUnpack(a
, a_values
, fmt
, sign
);
845 simdUnpack(b
, b_values
, fmt
, sign
);
847 for (int i
= 0; i
< nvals
; i
++) {
852 cc
= (a_values
[i
] == b_values
[i
]);
855 cc
= (a_values
[i
] < b_values
[i
]);
858 cc
= (a_values
[i
] <= b_values
[i
]);
863 ccond
|= cc
<< (DSP_CTL_POS
[DSP_CCOND
] + i
);
866 writeDSPControl(dspctl
, ccond
, 1 << DSP_CCOND
);
872 MipsISA::dspPrece(int32_t a
, int32_t infmt
, int32_t insign
, int32_t outfmt
,
873 int32_t outsign
, int32_t mode
)
876 int ninvals
= SIMD_NVALS
[infmt
];
877 int noutvals
= SIMD_NVALS
[outfmt
];
879 uint64_t in_values
[SIMD_MAX_VALS
];
880 uint64_t out_values
[SIMD_MAX_VALS
];
882 if (insign
== SIGNED
&& outsign
== SIGNED
)
883 sa
= SIMD_NBITS
[infmt
];
884 else if (insign
== UNSIGNED
&& outsign
== SIGNED
)
885 sa
= SIMD_NBITS
[infmt
] - 1;
886 else if (insign
== UNSIGNED
&& outsign
== UNSIGNED
)
889 simdUnpack(a
, in_values
, infmt
, insign
);
891 for (int i
= 0; i
<noutvals
; i
++) {
894 out_values
[i
] = in_values
[i
+ (ninvals
>> 1)] << sa
;
897 out_values
[i
] = in_values
[i
] << sa
;
900 out_values
[i
] = in_values
[(i
<< 1) + 1] << sa
;
903 out_values
[i
] = in_values
[i
<< 1] << sa
;
908 simdPack(out_values
, &result
, outfmt
);
914 MipsISA::dspPrecrqu(int32_t a
, int32_t b
, uint32_t *dspctl
)
916 uint64_t a_values
[SIMD_MAX_VALS
];
917 uint64_t b_values
[SIMD_MAX_VALS
];
918 uint64_t r_values
[SIMD_MAX_VALS
];
922 simdUnpack(a
, a_values
, SIMD_FMT_PH
, SIGNED
);
923 simdUnpack(b
, b_values
, SIMD_FMT_PH
, SIGNED
);
925 for (int i
= 0; i
<2; i
++) {
927 dspSaturate((int64_t)b_values
[i
] >> (SIMD_NBITS
[SIMD_FMT_QB
] - 1),
928 SIMD_FMT_QB
, UNSIGNED
, &ouflag
);
930 dspSaturate((int64_t)a_values
[i
] >> (SIMD_NBITS
[SIMD_FMT_QB
] - 1),
931 SIMD_FMT_QB
, UNSIGNED
, &ouflag
);
934 simdPack(r_values
, &result
, SIMD_FMT_QB
);
937 *dspctl
= insertBits(*dspctl
, 22, 22, 1);
943 MipsISA::dspPrecrq(int32_t a
, int32_t b
, int32_t fmt
, uint32_t *dspctl
)
945 uint64_t a_values
[SIMD_MAX_VALS
];
946 uint64_t b_values
[SIMD_MAX_VALS
];
947 uint64_t r_values
[SIMD_MAX_VALS
];
951 simdUnpack(a
, a_values
, fmt
, SIGNED
);
952 simdUnpack(b
, b_values
, fmt
, SIGNED
);
954 r_values
[1] = dspSaturate((int64_t)addHalfLsb(a_values
[0], 16) >> 16,
955 fmt
+ 1, SIGNED
, &ouflag
);
956 r_values
[0] = dspSaturate((int64_t)addHalfLsb(b_values
[0], 16) >> 16,
957 fmt
+ 1, SIGNED
, &ouflag
);
959 simdPack(r_values
, &result
, fmt
+ 1);
962 *dspctl
= insertBits(*dspctl
, 22, 22, 1);
968 MipsISA::dspPrecrSra(int32_t a
, int32_t b
, int32_t sa
, int32_t fmt
,
971 int nvals
= SIMD_NVALS
[fmt
];
972 uint64_t a_values
[SIMD_MAX_VALS
];
973 uint64_t b_values
[SIMD_MAX_VALS
];
974 uint64_t c_values
[SIMD_MAX_VALS
];
977 simdUnpack(a
, a_values
, fmt
, SIGNED
);
978 simdUnpack(b
, b_values
, fmt
, SIGNED
);
980 for (int i
= 0; i
< nvals
; i
++) {
982 c_values
[i
] = addHalfLsb(b_values
[i
], sa
) >> sa
;
983 c_values
[i
+ 1] = addHalfLsb(a_values
[i
], sa
) >> sa
;
985 c_values
[i
] = b_values
[i
] >> sa
;
986 c_values
[i
+ 1] = a_values
[i
] >> sa
;
990 simdPack(c_values
, &result
, fmt
+ 1);
996 MipsISA::dspPick(int32_t a
, int32_t b
, int32_t fmt
, uint32_t *dspctl
)
998 int nvals
= SIMD_NVALS
[fmt
];
1000 uint64_t a_values
[SIMD_MAX_VALS
];
1001 uint64_t b_values
[SIMD_MAX_VALS
];
1002 uint64_t c_values
[SIMD_MAX_VALS
];
1004 simdUnpack(a
, a_values
, fmt
, UNSIGNED
);
1005 simdUnpack(b
, b_values
, fmt
, UNSIGNED
);
1007 for (int i
= 0; i
< nvals
; i
++) {
1008 int condbit
= DSP_CTL_POS
[DSP_CCOND
] + i
;
1009 if (bits(*dspctl
, condbit
, condbit
) == 1)
1010 c_values
[i
] = a_values
[i
];
1012 c_values
[i
] = b_values
[i
];
1015 simdPack(c_values
, &result
, fmt
);
1021 MipsISA::dspPack(int32_t a
, int32_t b
, int32_t fmt
)
1024 uint64_t a_values
[SIMD_MAX_VALS
];
1025 uint64_t b_values
[SIMD_MAX_VALS
];
1026 uint64_t c_values
[SIMD_MAX_VALS
];
1028 simdUnpack(a
, a_values
, fmt
, UNSIGNED
);
1029 simdUnpack(b
, b_values
, fmt
, UNSIGNED
);
1031 c_values
[0] = b_values
[1];
1032 c_values
[1] = a_values
[0];
1034 simdPack(c_values
, &result
, fmt
);
1040 MipsISA::dspExtr(int64_t dspac
, int32_t fmt
, int32_t sa
, int32_t round
,
1041 int32_t saturate
, uint32_t *dspctl
)
1044 uint32_t ouflag
= 0;
1047 sa
= bits(sa
, 4, 0);
1051 temp
= (int64_t)addHalfLsb(dspac
, sa
);
1053 if (dspac
> 0 && temp
< 0) {
1056 temp
= FIXED_SMAX
[SIMD_FMT_L
];
1066 dspac
= checkOverflow(dspac
, fmt
, SIGNED
, &ouflag
);
1069 *dspctl
= insertBits(*dspctl
, 23, 23, ouflag
);
1072 result
= (int32_t)dspSaturate(temp
, fmt
, SIGNED
, &ouflag
);
1074 result
= (int32_t)temp
;
1076 result
= (int32_t)temp
;
1083 MipsISA::dspExtp(int64_t dspac
, int32_t size
, uint32_t *dspctl
)
1088 pos
= bits(*dspctl
, 5, 0);
1089 size
= bits(size
, 4, 0);
1091 if (pos
- (size
+ 1) >= -1) {
1092 result
= bits(dspac
, pos
, pos
- size
);
1093 *dspctl
= insertBits(*dspctl
, 14, 14, 0);
1096 *dspctl
= insertBits(*dspctl
, 14, 14, 1);
1103 MipsISA::dspExtpd(int64_t dspac
, int32_t size
, uint32_t *dspctl
)
1108 pos
= bits(*dspctl
, 5, 0);
1109 size
= bits(size
, 4, 0);
1111 if (pos
- (size
+ 1) >= -1) {
1112 result
= bits(dspac
, pos
, pos
- size
);
1113 *dspctl
= insertBits(*dspctl
, 14, 14, 0);
1114 if (pos
- (size
+ 1) >= 0)
1115 *dspctl
= insertBits(*dspctl
, 5, 0, pos
- (size
+ 1));
1116 else if ((pos
- (size
+ 1)) == -1)
1117 *dspctl
= insertBits(*dspctl
, 5, 0, 63);
1120 *dspctl
= insertBits(*dspctl
, 14, 14, 1);
1127 MipsISA::simdPack(uint64_t *values_ptr
, int32_t *reg
, int32_t fmt
)
1129 int nvals
= SIMD_NVALS
[fmt
];
1130 int nbits
= SIMD_NBITS
[fmt
];
1134 for (int i
= 0; i
< nvals
; i
++)
1135 *reg
|= (int32_t)bits(values_ptr
[i
], nbits
- 1, 0) << nbits
* i
;
1139 MipsISA::simdUnpack(int32_t reg
, uint64_t *values_ptr
, int32_t fmt
, int32_t sign
)
1141 int nvals
= SIMD_NVALS
[fmt
];
1142 int nbits
= SIMD_NBITS
[fmt
];
1146 for (int i
= 0; i
< nvals
; i
++) {
1147 uint64_t tmp
= (uint64_t)bits(reg
, nbits
* (i
+ 1) - 1, nbits
* i
);
1148 values_ptr
[i
] = signExtend(tmp
, fmt
);
1152 for (int i
= 0; i
< nvals
; i
++) {
1154 (uint64_t)bits(reg
, nbits
* (i
+ 1) - 1, nbits
* i
);
1161 MipsISA::writeDSPControl(uint32_t *dspctl
, uint32_t value
, uint32_t mask
)
1165 if (mask
& 0x01) fmask
|= DSP_CTL_MASK
[DSP_POS
];
1166 if (mask
& 0x02) fmask
|= DSP_CTL_MASK
[DSP_SCOUNT
];
1167 if (mask
& 0x04) fmask
|= DSP_CTL_MASK
[DSP_C
];
1168 if (mask
& 0x08) fmask
|= DSP_CTL_MASK
[DSP_OUFLAG
];
1169 if (mask
& 0x10) fmask
|= DSP_CTL_MASK
[DSP_CCOND
];
1170 if (mask
& 0x20) fmask
|= DSP_CTL_MASK
[DSP_EFI
];
1178 MipsISA::readDSPControl(uint32_t *dspctl
, uint32_t mask
)
1182 if (mask
& 0x01) fmask
|= DSP_CTL_MASK
[DSP_POS
];
1183 if (mask
& 0x02) fmask
|= DSP_CTL_MASK
[DSP_SCOUNT
];
1184 if (mask
& 0x04) fmask
|= DSP_CTL_MASK
[DSP_C
];
1185 if (mask
& 0x08) fmask
|= DSP_CTL_MASK
[DSP_OUFLAG
];
1186 if (mask
& 0x10) fmask
|= DSP_CTL_MASK
[DSP_CCOND
];
1187 if (mask
& 0x20) fmask
|= DSP_CTL_MASK
[DSP_EFI
];
1189 return *dspctl
& fmask
;