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.
29 #include "arch/mips/dsp.hh"
31 #include "arch/mips/isa_traits.hh"
32 #include "base/bitfield.hh"
33 #include "base/logging.hh"
34 #include "cpu/static_inst.hh"
35 #include "sim/serialize.hh"
37 using namespace MipsISA
;
41 MipsISA::bitrev(int32_t value
)
46 for (int i
= 0; i
< 16; i
++) {
50 result
|= (value
& 1 << i
) << -shift
;
52 result
|= (value
& 1 << i
) >> shift
;
59 MipsISA::dspSaturate(uint64_t value
, int32_t fmt
, int32_t sign
,
62 int64_t svalue
= (int64_t)value
;
66 if (svalue
> (int64_t)FIXED_SMAX
[fmt
]) {
68 svalue
= (int64_t)FIXED_SMAX
[fmt
];
69 } else if (svalue
< (int64_t)FIXED_SMIN
[fmt
]) {
71 svalue
= (int64_t)FIXED_SMIN
[fmt
];
75 if (svalue
> (int64_t)FIXED_UMAX
[fmt
]) {
77 svalue
= FIXED_UMAX
[fmt
];
78 } else if (svalue
< (int64_t)FIXED_UMIN
[fmt
]) {
80 svalue
= FIXED_UMIN
[fmt
];
85 return (uint64_t)svalue
;
89 MipsISA::checkOverflow(uint64_t value
, int32_t fmt
, int32_t sign
,
92 int64_t svalue
= (int64_t)value
;
97 if (svalue
> (int64_t)FIXED_SMAX
[fmt
] ||
98 svalue
< (int64_t)FIXED_SMIN
[fmt
])
102 if (svalue
> (int64_t)FIXED_UMAX
[fmt
] ||
103 svalue
< (int64_t)FIXED_UMIN
[fmt
])
108 return (uint64_t)svalue
;
112 MipsISA::signExtend(uint64_t value
, int32_t fmt
)
114 int32_t signpos
= SIMD_NBITS
[fmt
];
115 uint64_t sign
= uint64_t(1) << (signpos
- 1);
116 uint64_t ones
= ~(0ULL);
119 value
|= (ones
<< signpos
); // extend with ones
121 value
&= (ones
>> (64 - signpos
)); // extend with zeros
127 MipsISA::addHalfLsb(uint64_t value
, int32_t lsbpos
)
129 return value
+= ULL(1) << (lsbpos
- 1);
133 MipsISA::dspAbs(int32_t a
, int32_t fmt
, uint32_t *dspctl
)
135 int nvals
= SIMD_NVALS
[fmt
];
139 uint64_t a_values
[SIMD_MAX_VALS
];
141 simdUnpack(a
, a_values
, fmt
, SIGNED
);
143 for (int i
= 0; i
< nvals
; i
++) {
144 svalue
= (int64_t)a_values
[i
];
146 if (a_values
[i
] == FIXED_SMIN
[fmt
]) {
147 a_values
[i
] = FIXED_SMAX
[fmt
];
149 } else if (svalue
< 0) {
150 a_values
[i
] = uint64_t(0 - svalue
);
154 simdPack(a_values
, &result
, fmt
);
157 writeDSPControl(dspctl
, (ouflag
<< 4) << DSP_CTL_POS
[DSP_OUFLAG
],
164 MipsISA::dspAdd(int32_t a
, int32_t b
, int32_t fmt
, int32_t saturate
,
165 int32_t sign
, uint32_t *dspctl
)
167 int nvals
= SIMD_NVALS
[fmt
];
170 uint64_t a_values
[SIMD_MAX_VALS
];
171 uint64_t b_values
[SIMD_MAX_VALS
];
173 simdUnpack(a
, a_values
, fmt
, sign
);
174 simdUnpack(b
, b_values
, fmt
, sign
);
176 for (int i
= 0; i
< nvals
; i
++)
179 a_values
[i
] = dspSaturate(a_values
[i
] + b_values
[i
], fmt
, sign
,
182 a_values
[i
] = checkOverflow(a_values
[i
] + b_values
[i
], fmt
, sign
,
186 simdPack(a_values
, &result
, fmt
);
189 writeDSPControl(dspctl
, (ouflag
<< 4) << DSP_CTL_POS
[DSP_OUFLAG
],
196 MipsISA::dspAddh(int32_t a
, int32_t b
, int32_t fmt
, int32_t round
,
199 int nvals
= SIMD_NVALS
[fmt
];
201 uint64_t a_values
[SIMD_MAX_VALS
];
202 uint64_t b_values
[SIMD_MAX_VALS
];
204 simdUnpack(a
, a_values
, fmt
, sign
);
205 simdUnpack(b
, b_values
, fmt
, sign
);
207 for (int i
= 0; i
< nvals
; i
++) {
209 a_values
[i
] = addHalfLsb(a_values
[i
] + b_values
[i
], 1) >> 1;
211 a_values
[i
] = (a_values
[i
] + b_values
[i
]) >> 1;
214 simdPack(a_values
, &result
, fmt
);
220 MipsISA::dspSub(int32_t a
, int32_t b
, int32_t fmt
, int32_t saturate
,
221 int32_t sign
, uint32_t *dspctl
)
223 int nvals
= SIMD_NVALS
[fmt
];
226 uint64_t a_values
[SIMD_MAX_VALS
];
227 uint64_t b_values
[SIMD_MAX_VALS
];
229 simdUnpack(a
, a_values
, fmt
, sign
);
230 simdUnpack(b
, b_values
, fmt
, sign
);
232 for (int i
= 0; i
< nvals
; i
++) {
234 a_values
[i
] = dspSaturate(a_values
[i
] - b_values
[i
], fmt
, sign
,
237 a_values
[i
] = checkOverflow(a_values
[i
] - b_values
[i
], fmt
, sign
,
241 simdPack(a_values
, &result
, fmt
);
244 writeDSPControl(dspctl
, (ouflag
<< 4) << DSP_CTL_POS
[DSP_OUFLAG
],
251 MipsISA::dspSubh(int32_t a
, int32_t b
, int32_t fmt
, int32_t round
,
254 int nvals
= SIMD_NVALS
[fmt
];
256 uint64_t a_values
[SIMD_MAX_VALS
];
257 uint64_t b_values
[SIMD_MAX_VALS
];
259 simdUnpack(a
, a_values
, fmt
, sign
);
260 simdUnpack(b
, b_values
, fmt
, sign
);
262 for (int i
= 0; i
< nvals
; i
++)
265 a_values
[i
] = addHalfLsb(a_values
[i
] - b_values
[i
], 1) >> 1;
267 a_values
[i
] = (a_values
[i
] - b_values
[i
]) >> 1;
270 simdPack(a_values
, &result
, fmt
);
276 MipsISA::dspShll(int32_t a
, uint32_t sa
, int32_t fmt
, int32_t saturate
,
277 int32_t sign
, uint32_t *dspctl
)
279 int nvals
= SIMD_NVALS
[fmt
];
282 uint64_t a_values
[SIMD_MAX_VALS
];
284 sa
= bits(sa
, SIMD_LOG2N
[fmt
] - 1, 0);
285 simdUnpack(a
, a_values
, fmt
, sign
);
287 for (int i
= 0; i
< nvals
; i
++)
290 a_values
[i
] = dspSaturate(a_values
[i
] << sa
, fmt
, sign
, &ouflag
);
292 a_values
[i
] = checkOverflow(a_values
[i
] << sa
, fmt
, sign
, &ouflag
);
295 simdPack(a_values
, &result
, fmt
);
298 writeDSPControl(dspctl
, (ouflag
<< 6) << DSP_CTL_POS
[DSP_OUFLAG
],
305 MipsISA::dspShrl(int32_t a
, uint32_t sa
, int32_t fmt
, int32_t sign
)
307 int nvals
= SIMD_NVALS
[fmt
];
309 uint64_t a_values
[SIMD_MAX_VALS
];
311 sa
= bits(sa
, SIMD_LOG2N
[fmt
] - 1, 0);
313 simdUnpack(a
, a_values
, fmt
, UNSIGNED
);
315 for (int i
= 0; i
< nvals
; i
++)
316 a_values
[i
] = a_values
[i
] >> sa
;
318 simdPack(a_values
, &result
, fmt
);
324 MipsISA::dspShra(int32_t a
, uint32_t sa
, int32_t fmt
, int32_t round
,
325 int32_t sign
, uint32_t *dspctl
)
327 int nvals
= SIMD_NVALS
[fmt
];
329 uint64_t a_values
[SIMD_MAX_VALS
];
331 sa
= bits(sa
, SIMD_LOG2N
[fmt
] - 1, 0);
333 simdUnpack(a
, a_values
, fmt
, SIGNED
);
335 for (int i
= 0; i
< nvals
; i
++) {
337 a_values
[i
] = addHalfLsb(a_values
[i
], sa
) >> sa
;
339 a_values
[i
] = a_values
[i
] >> sa
;
342 simdPack(a_values
, &result
, fmt
);
348 MipsISA::dspMulq(int32_t a
, int32_t b
, int32_t fmt
, int32_t saturate
,
349 int32_t round
, uint32_t *dspctl
)
351 int nvals
= SIMD_NVALS
[fmt
];
352 int sa
= SIMD_NBITS
[fmt
];
355 uint64_t a_values
[SIMD_MAX_VALS
];
356 uint64_t b_values
[SIMD_MAX_VALS
];
359 simdUnpack(a
, a_values
, fmt
, SIGNED
);
360 simdUnpack(b
, b_values
, fmt
, SIGNED
);
362 for (int i
= 0; i
< nvals
; i
++) {
365 (int64_t)addHalfLsb(a_values
[i
] * b_values
[i
] << 1, sa
) >> sa
;
367 temp
= (int64_t)(a_values
[i
] * b_values
[i
]) >> (sa
- 1);
369 if (a_values
[i
] == FIXED_SMIN
[fmt
] && b_values
[i
] == FIXED_SMIN
[fmt
]) {
373 temp
= FIXED_SMAX
[fmt
];
379 simdPack(a_values
, &result
, fmt
);
382 writeDSPControl(dspctl
, (ouflag
<< 5) << DSP_CTL_POS
[DSP_OUFLAG
],
389 MipsISA::dspMul(int32_t a
, int32_t b
, int32_t fmt
, int32_t saturate
,
392 int nvals
= SIMD_NVALS
[fmt
];
395 uint64_t a_values
[SIMD_MAX_VALS
];
396 uint64_t b_values
[SIMD_MAX_VALS
];
398 simdUnpack(a
, a_values
, fmt
, SIGNED
);
399 simdUnpack(b
, b_values
, fmt
, SIGNED
);
401 for (int i
= 0; i
< nvals
; i
++)
404 a_values
[i
] = dspSaturate(a_values
[i
] * b_values
[i
], fmt
, SIGNED
,
407 a_values
[i
] = checkOverflow(a_values
[i
] * b_values
[i
], fmt
, SIGNED
,
411 simdPack(a_values
, &result
, fmt
);
414 writeDSPControl(dspctl
, (ouflag
<< 5) << DSP_CTL_POS
[DSP_OUFLAG
],
421 MipsISA::dspMuleu(int32_t a
, int32_t b
, int32_t mode
, uint32_t *dspctl
)
423 int nvals
= SIMD_NVALS
[SIMD_FMT_PH
];
426 uint64_t a_values
[SIMD_MAX_VALS
];
427 uint64_t b_values
[SIMD_MAX_VALS
];
429 simdUnpack(a
, a_values
, SIMD_FMT_QB
, UNSIGNED
);
430 simdUnpack(b
, b_values
, SIMD_FMT_PH
, UNSIGNED
);
434 for (int i
= 0; i
< nvals
; i
++)
435 b_values
[i
] = dspSaturate(a_values
[i
+ 2] * b_values
[i
],
436 SIMD_FMT_PH
, UNSIGNED
, &ouflag
);
439 for (int i
= 0; i
< nvals
; i
++)
440 b_values
[i
] = dspSaturate(a_values
[i
] * b_values
[i
], SIMD_FMT_PH
,
445 simdPack(b_values
, &result
, SIMD_FMT_PH
);
448 writeDSPControl(dspctl
, (ouflag
<< 5) << DSP_CTL_POS
[DSP_OUFLAG
],
455 MipsISA::dspMuleq(int32_t a
, int32_t b
, int32_t mode
, uint32_t *dspctl
)
457 int nvals
= SIMD_NVALS
[SIMD_FMT_W
];
460 uint64_t a_values
[SIMD_MAX_VALS
];
461 uint64_t b_values
[SIMD_MAX_VALS
];
462 uint64_t c_values
[SIMD_MAX_VALS
];
464 memset(c_values
, 0, sizeof(c_values
));
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
];
746 int64_t temp
[2] = {0, 0};
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
;