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 "config/full_system.hh"
36 #include "cpu/static_inst.hh"
37 #include "sim/serialize.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 memset(c_values
, 0, sizeof(c_values
));
468 simdUnpack(a
, a_values
, SIMD_FMT_PH
, SIGNED
);
469 simdUnpack(b
, b_values
, SIMD_FMT_PH
, SIGNED
);
473 for (int i
= 0; i
< nvals
; i
++)
474 c_values
[i
] = dspSaturate(a_values
[i
+ 1] * b_values
[i
+ 1] << 1,
475 SIMD_FMT_W
, SIGNED
, &ouflag
);
478 for (int i
= 0; i
< nvals
; i
++)
479 c_values
[i
] = dspSaturate(a_values
[i
] * b_values
[i
] << 1,
480 SIMD_FMT_W
, SIGNED
, &ouflag
);
484 simdPack(c_values
, &result
, SIMD_FMT_W
);
487 writeDSPControl(dspctl
, (ouflag
<< 5) << DSP_CTL_POS
[DSP_OUFLAG
],
494 MipsISA::dspDpaq(int64_t dspac
, int32_t a
, int32_t b
, int32_t ac
,
495 int32_t infmt
, int32_t outfmt
, int32_t postsat
, int32_t mode
,
498 int nvals
= SIMD_NVALS
[infmt
];
502 uint64_t a_values
[SIMD_MAX_VALS
];
503 uint64_t b_values
[SIMD_MAX_VALS
];
505 simdUnpack(a
, a_values
, infmt
, SIGNED
);
506 simdUnpack(b
, b_values
, infmt
, SIGNED
);
508 for (int i
= 0; i
< nvals
; i
++) {
511 if (a_values
[nvals
- 1 - i
] == FIXED_SMIN
[infmt
] &&
512 b_values
[i
] == FIXED_SMIN
[infmt
]) {
513 result
+= FIXED_SMAX
[outfmt
];
517 result
+= a_values
[nvals
- 1 - i
] * b_values
[i
] << 1;
520 if (a_values
[i
] == FIXED_SMIN
[infmt
] &&
521 b_values
[i
] == FIXED_SMIN
[infmt
]) {
522 result
+= FIXED_SMAX
[outfmt
];
525 result
+= a_values
[i
] * b_values
[i
] << 1;
532 if (outfmt
== SIMD_FMT_L
) {
533 int signa
= bits(dspac
, 63, 63);
534 int signb
= bits(result
, 63, 63);
536 temp
= dspac
+ result
;
538 if (signa
== signb
&& bits(temp
, 63, 63) != signa
) {
541 dspac
= FIXED_SMIN
[outfmt
];
543 dspac
= FIXED_SMAX
[outfmt
];
548 dspac
= dspSaturate(dspac
+ result
, outfmt
, SIGNED
, &ouflag
);
555 *dspctl
= insertBits(*dspctl
, 16 + ac
, 16 + ac
, 1);
561 MipsISA::dspDpsq(int64_t dspac
, int32_t a
, int32_t b
, int32_t ac
,
562 int32_t infmt
, int32_t outfmt
, int32_t postsat
, int32_t mode
,
565 int nvals
= SIMD_NVALS
[infmt
];
569 uint64_t a_values
[SIMD_MAX_VALS
];
570 uint64_t b_values
[SIMD_MAX_VALS
];
572 simdUnpack(a
, a_values
, infmt
, SIGNED
);
573 simdUnpack(b
, b_values
, infmt
, SIGNED
);
575 for (int i
= 0; i
< nvals
; i
++) {
578 if (a_values
[nvals
- 1 - i
] == FIXED_SMIN
[infmt
] &&
579 b_values
[i
] == FIXED_SMIN
[infmt
]) {
580 result
+= FIXED_SMAX
[outfmt
];
583 result
+= a_values
[nvals
- 1 - i
] * b_values
[i
] << 1;
587 if (a_values
[i
] == FIXED_SMIN
[infmt
] &&
588 b_values
[i
] == FIXED_SMIN
[infmt
]) {
589 result
+= FIXED_SMAX
[outfmt
];
592 result
+= a_values
[i
] * b_values
[i
] << 1;
599 if (outfmt
== SIMD_FMT_L
) {
600 int signa
= bits(dspac
, 63, 63);
601 int signb
= bits(-result
, 63, 63);
603 temp
= dspac
- result
;
605 if (signa
== signb
&& bits(temp
, 63, 63) != signa
) {
608 dspac
= FIXED_SMIN
[outfmt
];
610 dspac
= FIXED_SMAX
[outfmt
];
615 dspac
= dspSaturate(dspac
- result
, outfmt
, SIGNED
, &ouflag
);
622 *dspctl
= insertBits(*dspctl
, 16 + ac
, 16 + ac
, 1);
628 MipsISA::dspDpa(int64_t dspac
, int32_t a
, int32_t b
, int32_t ac
,
629 int32_t fmt
, int32_t sign
, int32_t mode
)
631 int nvals
= SIMD_NVALS
[fmt
];
632 uint64_t a_values
[SIMD_MAX_VALS
];
633 uint64_t b_values
[SIMD_MAX_VALS
];
635 simdUnpack(a
, a_values
, fmt
, sign
);
636 simdUnpack(b
, b_values
, fmt
, sign
);
638 for (int i
= 0; i
< 2; i
++) {
641 dspac
+= a_values
[nvals
- 1 - i
] * b_values
[nvals
- 1 - i
];
644 dspac
+= a_values
[nvals
- 3 - i
] * b_values
[nvals
- 3 - i
];
647 dspac
+= a_values
[nvals
- 1 - i
] * b_values
[i
];
656 MipsISA::dspDps(int64_t dspac
, int32_t a
, int32_t b
, int32_t ac
,
657 int32_t fmt
, int32_t sign
, int32_t mode
)
659 int nvals
= SIMD_NVALS
[fmt
];
660 uint64_t a_values
[SIMD_MAX_VALS
];
661 uint64_t b_values
[SIMD_MAX_VALS
];
663 simdUnpack(a
, a_values
, fmt
, sign
);
664 simdUnpack(b
, b_values
, fmt
, sign
);
666 for (int i
= 0; i
< 2; i
++) {
669 dspac
-= a_values
[nvals
- 1 - i
] * b_values
[nvals
- 1 - i
];
672 dspac
-= a_values
[nvals
- 3 - i
] * b_values
[nvals
- 3 - i
];
675 dspac
-= a_values
[nvals
- 1 - i
] * b_values
[i
];
684 MipsISA::dspMaq(int64_t dspac
, int32_t a
, int32_t b
, int32_t ac
,
685 int32_t fmt
, int32_t mode
, int32_t saturate
, uint32_t *dspctl
)
687 int nvals
= SIMD_NVALS
[fmt
- 1];
688 uint64_t a_values
[SIMD_MAX_VALS
];
689 uint64_t b_values
[SIMD_MAX_VALS
];
693 simdUnpack(a
, a_values
, fmt
, SIGNED
);
694 simdUnpack(b
, b_values
, fmt
, SIGNED
);
696 for (int i
= 0; i
< nvals
; i
++) {
699 temp
= a_values
[i
+ 1] * b_values
[i
+ 1] << 1;
700 if (a_values
[i
+ 1] == FIXED_SMIN
[fmt
] &&
701 b_values
[i
+ 1] == FIXED_SMIN
[fmt
]) {
702 temp
= (int64_t)FIXED_SMAX
[fmt
- 1];
707 temp
= a_values
[i
] * b_values
[i
] << 1;
708 if (a_values
[i
] == FIXED_SMIN
[fmt
] &&
709 b_values
[i
] == FIXED_SMIN
[fmt
]) {
710 temp
= (int64_t)FIXED_SMAX
[fmt
- 1];
719 temp
= dspSaturate(temp
, fmt
- 1, SIGNED
, &ouflag
);
721 *dspctl
= insertBits(*dspctl
, 16 + ac
, 16 + ac
, 1);
728 MipsISA::dspMulsa(int64_t dspac
, int32_t a
, int32_t b
, int32_t ac
, int32_t fmt
)
730 uint64_t a_values
[SIMD_MAX_VALS
];
731 uint64_t b_values
[SIMD_MAX_VALS
];
733 simdUnpack(a
, a_values
, fmt
, SIGNED
);
734 simdUnpack(b
, b_values
, fmt
, SIGNED
);
736 dspac
+= a_values
[1] * b_values
[1] - a_values
[0] * b_values
[0];
742 MipsISA::dspMulsaq(int64_t dspac
, int32_t a
, int32_t b
, int32_t ac
,
743 int32_t fmt
, uint32_t *dspctl
)
745 int nvals
= SIMD_NVALS
[fmt
];
746 uint64_t a_values
[SIMD_MAX_VALS
];
747 uint64_t b_values
[SIMD_MAX_VALS
];
748 int64_t temp
[2] = {0, 0};
751 simdUnpack(a
, a_values
, fmt
, SIGNED
);
752 simdUnpack(b
, b_values
, fmt
, SIGNED
);
754 for (int i
= nvals
- 1; i
> -1; i
--) {
755 temp
[i
] = a_values
[i
] * b_values
[i
] << 1;
756 if (a_values
[i
] == FIXED_SMIN
[fmt
] && b_values
[i
] == FIXED_SMIN
[fmt
]) {
757 temp
[i
] = FIXED_SMAX
[fmt
- 1];
762 dspac
+= temp
[1] - temp
[0];
765 *dspctl
= insertBits(*dspctl
, 16 + ac
, 16 + ac
, 1);
771 MipsISA::dspCmp(int32_t a
, int32_t b
, int32_t fmt
, int32_t sign
, int32_t op
,
774 int nvals
= SIMD_NVALS
[fmt
];
776 uint64_t a_values
[SIMD_MAX_VALS
];
777 uint64_t b_values
[SIMD_MAX_VALS
];
779 simdUnpack(a
, a_values
, fmt
, sign
);
780 simdUnpack(b
, b_values
, fmt
, sign
);
782 for (int i
= 0; i
< nvals
; i
++) {
787 cc
= (a_values
[i
] == b_values
[i
]);
790 cc
= (a_values
[i
] < b_values
[i
]);
793 cc
= (a_values
[i
] <= b_values
[i
]);
797 ccond
|= cc
<< (DSP_CTL_POS
[DSP_CCOND
] + i
);
800 writeDSPControl(dspctl
, ccond
, 1 << DSP_CCOND
);
804 MipsISA::dspCmpg(int32_t a
, int32_t b
, int32_t fmt
, int32_t sign
, int32_t op
)
806 int nvals
= SIMD_NVALS
[fmt
];
808 uint64_t a_values
[SIMD_MAX_VALS
];
809 uint64_t b_values
[SIMD_MAX_VALS
];
811 simdUnpack(a
, a_values
, fmt
, sign
);
812 simdUnpack(b
, b_values
, fmt
, sign
);
814 for (int i
= 0; i
< nvals
; i
++) {
819 cc
= (a_values
[i
] == b_values
[i
]);
822 cc
= (a_values
[i
] < b_values
[i
]);
825 cc
= (a_values
[i
] <= b_values
[i
]);
836 MipsISA::dspCmpgd(int32_t a
, int32_t b
, int32_t fmt
, int32_t sign
, int32_t op
,
839 int nvals
= SIMD_NVALS
[fmt
];
842 uint64_t a_values
[SIMD_MAX_VALS
];
843 uint64_t b_values
[SIMD_MAX_VALS
];
845 simdUnpack(a
, a_values
, fmt
, sign
);
846 simdUnpack(b
, b_values
, fmt
, sign
);
848 for (int i
= 0; i
< nvals
; i
++) {
853 cc
= (a_values
[i
] == b_values
[i
]);
856 cc
= (a_values
[i
] < b_values
[i
]);
859 cc
= (a_values
[i
] <= b_values
[i
]);
864 ccond
|= cc
<< (DSP_CTL_POS
[DSP_CCOND
] + i
);
867 writeDSPControl(dspctl
, ccond
, 1 << DSP_CCOND
);
873 MipsISA::dspPrece(int32_t a
, int32_t infmt
, int32_t insign
, int32_t outfmt
,
874 int32_t outsign
, int32_t mode
)
877 int ninvals
= SIMD_NVALS
[infmt
];
878 int noutvals
= SIMD_NVALS
[outfmt
];
880 uint64_t in_values
[SIMD_MAX_VALS
];
881 uint64_t out_values
[SIMD_MAX_VALS
];
883 if (insign
== SIGNED
&& outsign
== SIGNED
)
884 sa
= SIMD_NBITS
[infmt
];
885 else if (insign
== UNSIGNED
&& outsign
== SIGNED
)
886 sa
= SIMD_NBITS
[infmt
] - 1;
887 else if (insign
== UNSIGNED
&& outsign
== UNSIGNED
)
890 simdUnpack(a
, in_values
, infmt
, insign
);
892 for (int i
= 0; i
<noutvals
; i
++) {
895 out_values
[i
] = in_values
[i
+ (ninvals
>> 1)] << sa
;
898 out_values
[i
] = in_values
[i
] << sa
;
901 out_values
[i
] = in_values
[(i
<< 1) + 1] << sa
;
904 out_values
[i
] = in_values
[i
<< 1] << sa
;
909 simdPack(out_values
, &result
, outfmt
);
915 MipsISA::dspPrecrqu(int32_t a
, int32_t b
, uint32_t *dspctl
)
917 uint64_t a_values
[SIMD_MAX_VALS
];
918 uint64_t b_values
[SIMD_MAX_VALS
];
919 uint64_t r_values
[SIMD_MAX_VALS
];
923 simdUnpack(a
, a_values
, SIMD_FMT_PH
, SIGNED
);
924 simdUnpack(b
, b_values
, SIMD_FMT_PH
, SIGNED
);
926 for (int i
= 0; i
<2; i
++) {
928 dspSaturate((int64_t)b_values
[i
] >> (SIMD_NBITS
[SIMD_FMT_QB
] - 1),
929 SIMD_FMT_QB
, UNSIGNED
, &ouflag
);
931 dspSaturate((int64_t)a_values
[i
] >> (SIMD_NBITS
[SIMD_FMT_QB
] - 1),
932 SIMD_FMT_QB
, UNSIGNED
, &ouflag
);
935 simdPack(r_values
, &result
, SIMD_FMT_QB
);
938 *dspctl
= insertBits(*dspctl
, 22, 22, 1);
944 MipsISA::dspPrecrq(int32_t a
, int32_t b
, int32_t fmt
, uint32_t *dspctl
)
946 uint64_t a_values
[SIMD_MAX_VALS
];
947 uint64_t b_values
[SIMD_MAX_VALS
];
948 uint64_t r_values
[SIMD_MAX_VALS
];
952 simdUnpack(a
, a_values
, fmt
, SIGNED
);
953 simdUnpack(b
, b_values
, fmt
, SIGNED
);
955 r_values
[1] = dspSaturate((int64_t)addHalfLsb(a_values
[0], 16) >> 16,
956 fmt
+ 1, SIGNED
, &ouflag
);
957 r_values
[0] = dspSaturate((int64_t)addHalfLsb(b_values
[0], 16) >> 16,
958 fmt
+ 1, SIGNED
, &ouflag
);
960 simdPack(r_values
, &result
, fmt
+ 1);
963 *dspctl
= insertBits(*dspctl
, 22, 22, 1);
969 MipsISA::dspPrecrSra(int32_t a
, int32_t b
, int32_t sa
, int32_t fmt
,
972 int nvals
= SIMD_NVALS
[fmt
];
973 uint64_t a_values
[SIMD_MAX_VALS
];
974 uint64_t b_values
[SIMD_MAX_VALS
];
975 uint64_t c_values
[SIMD_MAX_VALS
];
978 simdUnpack(a
, a_values
, fmt
, SIGNED
);
979 simdUnpack(b
, b_values
, fmt
, SIGNED
);
981 for (int i
= 0; i
< nvals
; i
++) {
983 c_values
[i
] = addHalfLsb(b_values
[i
], sa
) >> sa
;
984 c_values
[i
+ 1] = addHalfLsb(a_values
[i
], sa
) >> sa
;
986 c_values
[i
] = b_values
[i
] >> sa
;
987 c_values
[i
+ 1] = a_values
[i
] >> sa
;
991 simdPack(c_values
, &result
, fmt
+ 1);
997 MipsISA::dspPick(int32_t a
, int32_t b
, int32_t fmt
, uint32_t *dspctl
)
999 int nvals
= SIMD_NVALS
[fmt
];
1001 uint64_t a_values
[SIMD_MAX_VALS
];
1002 uint64_t b_values
[SIMD_MAX_VALS
];
1003 uint64_t c_values
[SIMD_MAX_VALS
];
1005 simdUnpack(a
, a_values
, fmt
, UNSIGNED
);
1006 simdUnpack(b
, b_values
, fmt
, UNSIGNED
);
1008 for (int i
= 0; i
< nvals
; i
++) {
1009 int condbit
= DSP_CTL_POS
[DSP_CCOND
] + i
;
1010 if (bits(*dspctl
, condbit
, condbit
) == 1)
1011 c_values
[i
] = a_values
[i
];
1013 c_values
[i
] = b_values
[i
];
1016 simdPack(c_values
, &result
, fmt
);
1022 MipsISA::dspPack(int32_t a
, int32_t b
, int32_t fmt
)
1025 uint64_t a_values
[SIMD_MAX_VALS
];
1026 uint64_t b_values
[SIMD_MAX_VALS
];
1027 uint64_t c_values
[SIMD_MAX_VALS
];
1029 simdUnpack(a
, a_values
, fmt
, UNSIGNED
);
1030 simdUnpack(b
, b_values
, fmt
, UNSIGNED
);
1032 c_values
[0] = b_values
[1];
1033 c_values
[1] = a_values
[0];
1035 simdPack(c_values
, &result
, fmt
);
1041 MipsISA::dspExtr(int64_t dspac
, int32_t fmt
, int32_t sa
, int32_t round
,
1042 int32_t saturate
, uint32_t *dspctl
)
1045 uint32_t ouflag
= 0;
1048 sa
= bits(sa
, 4, 0);
1052 temp
= (int64_t)addHalfLsb(dspac
, sa
);
1054 if (dspac
> 0 && temp
< 0) {
1057 temp
= FIXED_SMAX
[SIMD_FMT_L
];
1067 dspac
= checkOverflow(dspac
, fmt
, SIGNED
, &ouflag
);
1070 *dspctl
= insertBits(*dspctl
, 23, 23, ouflag
);
1073 result
= (int32_t)dspSaturate(temp
, fmt
, SIGNED
, &ouflag
);
1075 result
= (int32_t)temp
;
1077 result
= (int32_t)temp
;
1084 MipsISA::dspExtp(int64_t dspac
, int32_t size
, uint32_t *dspctl
)
1089 pos
= bits(*dspctl
, 5, 0);
1090 size
= bits(size
, 4, 0);
1092 if (pos
- (size
+ 1) >= -1) {
1093 result
= bits(dspac
, pos
, pos
- size
);
1094 *dspctl
= insertBits(*dspctl
, 14, 14, 0);
1097 *dspctl
= insertBits(*dspctl
, 14, 14, 1);
1104 MipsISA::dspExtpd(int64_t dspac
, int32_t size
, uint32_t *dspctl
)
1109 pos
= bits(*dspctl
, 5, 0);
1110 size
= bits(size
, 4, 0);
1112 if (pos
- (size
+ 1) >= -1) {
1113 result
= bits(dspac
, pos
, pos
- size
);
1114 *dspctl
= insertBits(*dspctl
, 14, 14, 0);
1115 if (pos
- (size
+ 1) >= 0)
1116 *dspctl
= insertBits(*dspctl
, 5, 0, pos
- (size
+ 1));
1117 else if ((pos
- (size
+ 1)) == -1)
1118 *dspctl
= insertBits(*dspctl
, 5, 0, 63);
1121 *dspctl
= insertBits(*dspctl
, 14, 14, 1);
1128 MipsISA::simdPack(uint64_t *values_ptr
, int32_t *reg
, int32_t fmt
)
1130 int nvals
= SIMD_NVALS
[fmt
];
1131 int nbits
= SIMD_NBITS
[fmt
];
1135 for (int i
= 0; i
< nvals
; i
++)
1136 *reg
|= (int32_t)bits(values_ptr
[i
], nbits
- 1, 0) << nbits
* i
;
1140 MipsISA::simdUnpack(int32_t reg
, uint64_t *values_ptr
, int32_t fmt
, int32_t sign
)
1142 int nvals
= SIMD_NVALS
[fmt
];
1143 int nbits
= SIMD_NBITS
[fmt
];
1147 for (int i
= 0; i
< nvals
; i
++) {
1148 uint64_t tmp
= (uint64_t)bits(reg
, nbits
* (i
+ 1) - 1, nbits
* i
);
1149 values_ptr
[i
] = signExtend(tmp
, fmt
);
1153 for (int i
= 0; i
< nvals
; i
++) {
1155 (uint64_t)bits(reg
, nbits
* (i
+ 1) - 1, nbits
* i
);
1162 MipsISA::writeDSPControl(uint32_t *dspctl
, uint32_t value
, uint32_t mask
)
1166 if (mask
& 0x01) fmask
|= DSP_CTL_MASK
[DSP_POS
];
1167 if (mask
& 0x02) fmask
|= DSP_CTL_MASK
[DSP_SCOUNT
];
1168 if (mask
& 0x04) fmask
|= DSP_CTL_MASK
[DSP_C
];
1169 if (mask
& 0x08) fmask
|= DSP_CTL_MASK
[DSP_OUFLAG
];
1170 if (mask
& 0x10) fmask
|= DSP_CTL_MASK
[DSP_CCOND
];
1171 if (mask
& 0x20) fmask
|= DSP_CTL_MASK
[DSP_EFI
];
1179 MipsISA::readDSPControl(uint32_t *dspctl
, uint32_t mask
)
1183 if (mask
& 0x01) fmask
|= DSP_CTL_MASK
[DSP_POS
];
1184 if (mask
& 0x02) fmask
|= DSP_CTL_MASK
[DSP_SCOUNT
];
1185 if (mask
& 0x04) fmask
|= DSP_CTL_MASK
[DSP_C
];
1186 if (mask
& 0x08) fmask
|= DSP_CTL_MASK
[DSP_OUFLAG
];
1187 if (mask
& 0x10) fmask
|= DSP_CTL_MASK
[DSP_CCOND
];
1188 if (mask
& 0x20) fmask
|= DSP_CTL_MASK
[DSP_EFI
];
1190 return *dspctl
& fmask
;