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
)
53 result
|= (value
& 1L<<i
) << -shift
;
55 result
|= (value
& 1L<<i
) >> shift
;
62 MipsISA::dspSaturate( uint64_t value
, int32_t fmt
, int32_t sign
, uint32_t *overflow
)
66 svalue
= (int64_t)value
;
71 if( svalue
> (int64_t)FIXED_SMAX
[fmt
] )
74 svalue
= (int64_t)FIXED_SMAX
[fmt
];
76 else if( svalue
< (int64_t)FIXED_SMIN
[fmt
] )
79 svalue
= (int64_t)FIXED_SMIN
[fmt
];
83 if( svalue
> (int64_t)FIXED_UMAX
[fmt
] )
86 svalue
= FIXED_UMAX
[fmt
];
88 else if( svalue
< (int64_t)FIXED_UMIN
[fmt
] )
91 svalue
= FIXED_UMIN
[fmt
];
96 return( (uint64_t)svalue
);
100 MipsISA::checkOverflow( uint64_t value
, int32_t fmt
, int32_t sign
, uint32_t *overflow
)
104 svalue
= (int64_t)value
;
109 if( svalue
> (int64_t)FIXED_SMAX
[fmt
] || svalue
< (int64_t)FIXED_SMIN
[fmt
] )
113 if( svalue
> (int64_t)FIXED_UMAX
[fmt
] || svalue
< (int64_t)FIXED_UMIN
[fmt
] )
118 return( (uint64_t)svalue
);
122 MipsISA::signExtend( uint64_t value
, int32_t fmt
)
124 int32_t signpos
= SIMD_NBITS
[fmt
];
125 uint64_t sign
= uint64_t(1)<<(signpos
-1);
126 uint64_t ones
= ~(0ULL);
129 value
|= (ones
<< signpos
); // extend with ones
131 value
&= (ones
>> (64 - signpos
)); // extend with zeros
137 MipsISA::addHalfLsb( uint64_t value
, int32_t lsbpos
)
139 return( value
+= ULL(1) << (lsbpos
-1) );
143 MipsISA::dspAbs( int32_t a
, int32_t fmt
, uint32_t *dspctl
)
146 int nvals
= SIMD_NVALS
[fmt
];
150 uint64_t a_values
[SIMD_MAX_VALS
];
152 simdUnpack( a
, a_values
, fmt
, SIGNED
);
154 for( i
=0; i
<nvals
; i
++ )
156 svalue
= (int64_t)a_values
[i
];
158 if( a_values
[i
] == FIXED_SMIN
[fmt
] )
160 a_values
[i
] = FIXED_SMAX
[fmt
];
163 else if( svalue
< 0 )
165 a_values
[i
] = uint64_t( 0 - svalue
);
169 simdPack( a_values
, &result
, fmt
);
172 writeDSPControl( dspctl
, (ouflag
<<4)<<DSP_CTL_POS
[DSP_OUFLAG
], 1<<DSP_OUFLAG
);
178 MipsISA::dspAdd( int32_t a
, int32_t b
, int32_t fmt
, int32_t saturate
, int32_t sign
, uint32_t *dspctl
)
181 int nvals
= SIMD_NVALS
[fmt
];
184 uint64_t a_values
[SIMD_MAX_VALS
];
185 uint64_t b_values
[SIMD_MAX_VALS
];
187 simdUnpack( a
, a_values
, fmt
, sign
);
188 simdUnpack( b
, b_values
, fmt
, sign
);
190 for( i
=0; i
<nvals
; i
++ )
193 a_values
[i
] = dspSaturate( a_values
[i
] + b_values
[i
], fmt
, sign
, &ouflag
);
195 a_values
[i
] = checkOverflow( a_values
[i
] + b_values
[i
], fmt
, sign
, &ouflag
);
198 simdPack( a_values
, &result
, fmt
);
201 writeDSPControl( dspctl
, (ouflag
<<4)<<DSP_CTL_POS
[DSP_OUFLAG
], 1<<DSP_OUFLAG
);
207 MipsISA::dspAddh( int32_t a
, int32_t b
, int32_t fmt
, int32_t round
, int32_t sign
)
210 int nvals
= SIMD_NVALS
[fmt
];
212 uint64_t a_values
[SIMD_MAX_VALS
];
213 uint64_t b_values
[SIMD_MAX_VALS
];
215 simdUnpack( a
, a_values
, fmt
, sign
);
216 simdUnpack( b
, b_values
, fmt
, sign
);
218 for( i
=0; i
<nvals
; i
++ )
221 a_values
[i
] = addHalfLsb( a_values
[i
] + b_values
[i
], 1 ) >> 1;
223 a_values
[i
] = ( a_values
[i
] + b_values
[i
] ) >> 1;
226 simdPack( a_values
, &result
, fmt
);
232 MipsISA::dspSub( int32_t a
, int32_t b
, int32_t fmt
, int32_t saturate
, int32_t sign
, uint32_t *dspctl
)
235 int nvals
= SIMD_NVALS
[fmt
];
238 uint64_t a_values
[SIMD_MAX_VALS
];
239 uint64_t b_values
[SIMD_MAX_VALS
];
241 simdUnpack( a
, a_values
, fmt
, sign
);
242 simdUnpack( b
, b_values
, fmt
, sign
);
244 for( i
=0; i
<nvals
; i
++ )
247 a_values
[i
] = dspSaturate( a_values
[i
] - b_values
[i
], fmt
, sign
, &ouflag
);
249 a_values
[i
] = checkOverflow( a_values
[i
] - b_values
[i
], fmt
, sign
, &ouflag
);
252 simdPack( a_values
, &result
, fmt
);
255 writeDSPControl( dspctl
, (ouflag
<<4)<<DSP_CTL_POS
[DSP_OUFLAG
], 1<<DSP_OUFLAG
);
261 MipsISA::dspSubh( int32_t a
, int32_t b
, int32_t fmt
, int32_t round
, int32_t sign
)
264 int nvals
= SIMD_NVALS
[fmt
];
266 uint64_t a_values
[SIMD_MAX_VALS
];
267 uint64_t b_values
[SIMD_MAX_VALS
];
269 simdUnpack( a
, a_values
, fmt
, sign
);
270 simdUnpack( b
, b_values
, fmt
, sign
);
272 for( i
=0; i
<nvals
; i
++ )
275 a_values
[i
] = addHalfLsb( a_values
[i
] - b_values
[i
], 1 ) >> 1;
277 a_values
[i
] = ( a_values
[i
] - b_values
[i
] ) >> 1;
280 simdPack( a_values
, &result
, fmt
);
286 MipsISA::dspShll( int32_t a
, uint32_t sa
, int32_t fmt
, int32_t saturate
, int32_t sign
, uint32_t *dspctl
)
289 int nvals
= SIMD_NVALS
[fmt
];
292 uint64_t a_values
[SIMD_MAX_VALS
];
294 sa
= bits( sa
, SIMD_LOG2N
[fmt
]-1, 0 );
295 simdUnpack( a
, a_values
, fmt
, sign
);
297 for( i
=0; i
<nvals
; i
++ )
300 a_values
[i
] = dspSaturate( a_values
[i
] << sa
, fmt
, sign
, &ouflag
);
302 a_values
[i
] = checkOverflow( a_values
[i
] << sa
, fmt
, sign
, &ouflag
);
305 simdPack( a_values
, &result
, fmt
);
308 writeDSPControl( dspctl
, (ouflag
<<6)<<DSP_CTL_POS
[DSP_OUFLAG
], 1<<DSP_OUFLAG
);
314 MipsISA::dspShrl( int32_t a
, uint32_t sa
, int32_t fmt
, int32_t sign
)
317 int nvals
= SIMD_NVALS
[fmt
];
319 uint64_t a_values
[SIMD_MAX_VALS
];
321 sa
= bits( sa
, SIMD_LOG2N
[fmt
]-1, 0 );
323 simdUnpack( a
, a_values
, fmt
, UNSIGNED
);
325 for( i
=0; i
<nvals
; i
++ )
326 a_values
[i
] = a_values
[i
] >> sa
;
328 simdPack( a_values
, &result
, fmt
);
334 MipsISA::dspShra( int32_t a
, uint32_t sa
, int32_t fmt
, int32_t round
, int32_t sign
, uint32_t *dspctl
)
337 int nvals
= SIMD_NVALS
[fmt
];
339 uint64_t a_values
[SIMD_MAX_VALS
];
341 sa
= bits( sa
, SIMD_LOG2N
[fmt
]-1, 0 );
343 simdUnpack( a
, a_values
, fmt
, SIGNED
);
345 for( i
=0; i
<nvals
; i
++ )
348 a_values
[i
] = addHalfLsb( a_values
[i
], sa
) >> sa
;
350 a_values
[i
] = a_values
[i
] >> sa
;
353 simdPack( a_values
, &result
, fmt
);
359 MipsISA::dspMulq( int32_t a
, int32_t b
, int32_t fmt
, int32_t saturate
, int32_t round
, uint32_t *dspctl
)
362 int nvals
= SIMD_NVALS
[fmt
];
363 int sa
= SIMD_NBITS
[fmt
];
366 uint64_t a_values
[SIMD_MAX_VALS
];
367 uint64_t b_values
[SIMD_MAX_VALS
];
370 simdUnpack( a
, a_values
, fmt
, SIGNED
);
371 simdUnpack( b
, b_values
, fmt
, SIGNED
);
373 for( i
=0; i
<nvals
; i
++ )
376 temp
= (int64_t)addHalfLsb( a_values
[i
] * b_values
[i
] << 1, sa
) >> sa
;
378 temp
= (int64_t)(a_values
[i
] * b_values
[i
]) >> (sa
- 1);
380 if( a_values
[i
] == FIXED_SMIN
[fmt
] &&
381 b_values
[i
] == FIXED_SMIN
[fmt
] )
386 temp
= FIXED_SMAX
[fmt
];
392 simdPack( a_values
, &result
, fmt
);
395 writeDSPControl( dspctl
, (ouflag
<<5)<<DSP_CTL_POS
[DSP_OUFLAG
], 1<<DSP_OUFLAG
);
401 MipsISA::dspMul( int32_t a
, int32_t b
, int32_t fmt
, int32_t saturate
, uint32_t *dspctl
)
404 int nvals
= SIMD_NVALS
[fmt
];
407 uint64_t a_values
[SIMD_MAX_VALS
];
408 uint64_t b_values
[SIMD_MAX_VALS
];
410 simdUnpack( a
, a_values
, fmt
, SIGNED
);
411 simdUnpack( b
, b_values
, fmt
, SIGNED
);
413 for( i
=0; i
<nvals
; i
++ )
416 a_values
[i
] = dspSaturate( a_values
[i
] * b_values
[i
], fmt
, SIGNED
, &ouflag
);
418 a_values
[i
] = checkOverflow( a_values
[i
] * b_values
[i
], fmt
, SIGNED
, &ouflag
);
421 simdPack( a_values
, &result
, fmt
);
424 writeDSPControl( dspctl
, (ouflag
<<5)<<DSP_CTL_POS
[DSP_OUFLAG
], 1<<DSP_OUFLAG
);
430 MipsISA::dspMuleu( int32_t a
, int32_t b
, int32_t mode
, uint32_t *dspctl
)
433 int nvals
= SIMD_NVALS
[SIMD_FMT_PH
];
436 uint64_t a_values
[SIMD_MAX_VALS
];
437 uint64_t b_values
[SIMD_MAX_VALS
];
439 simdUnpack( a
, a_values
, SIMD_FMT_QB
, UNSIGNED
);
440 simdUnpack( b
, b_values
, SIMD_FMT_PH
, UNSIGNED
);
445 for( i
=0; i
<nvals
; i
++ )
446 b_values
[i
] = dspSaturate( a_values
[i
+2] * b_values
[i
], SIMD_FMT_PH
, UNSIGNED
, &ouflag
);
449 for( i
=0; i
<nvals
; i
++ )
450 b_values
[i
] = dspSaturate( a_values
[i
] * b_values
[i
], SIMD_FMT_PH
, UNSIGNED
, &ouflag
);
454 simdPack( b_values
, &result
, SIMD_FMT_PH
);
457 writeDSPControl( dspctl
, (ouflag
<<5)<<DSP_CTL_POS
[DSP_OUFLAG
], 1<<DSP_OUFLAG
);
463 MipsISA::dspMuleq( int32_t a
, int32_t b
, int32_t mode
, uint32_t *dspctl
)
466 int nvals
= SIMD_NVALS
[SIMD_FMT_W
];
469 uint64_t a_values
[SIMD_MAX_VALS
];
470 uint64_t b_values
[SIMD_MAX_VALS
];
471 uint64_t c_values
[SIMD_MAX_VALS
];
473 simdUnpack( a
, a_values
, SIMD_FMT_PH
, SIGNED
);
474 simdUnpack( b
, b_values
, SIMD_FMT_PH
, SIGNED
);
479 for( i
=0; i
<nvals
; i
++ )
480 c_values
[i
] = dspSaturate( a_values
[i
+1] * b_values
[i
+1] << 1,
481 SIMD_FMT_W
, SIGNED
, &ouflag
);
484 for( i
=0; i
<nvals
; i
++ )
485 c_values
[i
] = dspSaturate( a_values
[i
] * b_values
[i
] << 1,
486 SIMD_FMT_W
, SIGNED
, &ouflag
);
490 simdPack( c_values
, &result
, SIMD_FMT_W
);
493 writeDSPControl( dspctl
, (ouflag
<<5)<<DSP_CTL_POS
[DSP_OUFLAG
], 1<<DSP_OUFLAG
);
499 MipsISA::dspDpaq( int64_t dspac
, int32_t a
, int32_t b
, int32_t ac
, int32_t infmt
,
500 int32_t outfmt
, int32_t postsat
, int32_t mode
, uint32_t *dspctl
)
503 int nvals
= SIMD_NVALS
[infmt
];
507 uint64_t a_values
[SIMD_MAX_VALS
];
508 uint64_t b_values
[SIMD_MAX_VALS
];
510 simdUnpack( a
, a_values
, infmt
, SIGNED
);
511 simdUnpack( b
, b_values
, infmt
, SIGNED
);
513 for( i
=0; i
<nvals
; i
++ )
518 if( a_values
[nvals
-1-i
] == FIXED_SMIN
[infmt
] &&
519 b_values
[i
] == FIXED_SMIN
[infmt
] )
521 result
+= FIXED_SMAX
[outfmt
];
525 result
+= a_values
[nvals
-1-i
] * b_values
[i
] << 1;
528 if( a_values
[i
] == FIXED_SMIN
[infmt
] &&
529 b_values
[i
] == FIXED_SMIN
[infmt
] )
531 result
+= FIXED_SMAX
[outfmt
];
535 result
+= a_values
[i
] * b_values
[i
] << 1;
542 if( outfmt
== SIMD_FMT_L
)
544 int signa
= bits( dspac
, 63, 63 );
545 int signb
= bits( result
, 63, 63 );
547 temp
= dspac
+ result
;
549 if( ( signa
== signb
) &&
550 ( bits( temp
, 63, 63 ) != signa
) )
554 dspac
= FIXED_SMIN
[outfmt
];
556 dspac
= FIXED_SMAX
[outfmt
];
562 dspac
= dspSaturate( dspac
+ result
, outfmt
, SIGNED
, &ouflag
);
568 *dspctl
= insertBits( *dspctl
, 16+ac
, 16+ac
, 1 );
574 MipsISA::dspDpsq( int64_t dspac
, int32_t a
, int32_t b
, int32_t ac
, int32_t infmt
,
575 int32_t outfmt
, int32_t postsat
, int32_t mode
, uint32_t *dspctl
)
578 int nvals
= SIMD_NVALS
[infmt
];
582 uint64_t a_values
[SIMD_MAX_VALS
];
583 uint64_t b_values
[SIMD_MAX_VALS
];
585 simdUnpack( a
, a_values
, infmt
, SIGNED
);
586 simdUnpack( b
, b_values
, infmt
, SIGNED
);
588 for( i
=0; i
<nvals
; i
++ )
593 if( a_values
[nvals
-1-i
] == FIXED_SMIN
[infmt
] &&
594 b_values
[i
] == FIXED_SMIN
[infmt
] )
596 result
+= FIXED_SMAX
[outfmt
];
600 result
+= a_values
[nvals
-1-i
] * b_values
[i
] << 1;
603 if( a_values
[i
] == FIXED_SMIN
[infmt
] &&
604 b_values
[i
] == FIXED_SMIN
[infmt
] )
606 result
+= FIXED_SMAX
[outfmt
];
610 result
+= a_values
[i
] * b_values
[i
] << 1;
617 if( outfmt
== SIMD_FMT_L
)
619 int signa
= bits( dspac
, 63, 63 );
620 int signb
= bits( -result
, 63, 63 );
622 temp
= dspac
- result
;
624 if( ( signa
== signb
) &&
625 ( bits( temp
, 63, 63 ) != signa
) )
629 dspac
= FIXED_SMIN
[outfmt
];
631 dspac
= FIXED_SMAX
[outfmt
];
637 dspac
= dspSaturate( dspac
- result
, outfmt
, SIGNED
, &ouflag
);
643 *dspctl
= insertBits( *dspctl
, 16+ac
, 16+ac
, 1 );
649 MipsISA::dspDpa( int64_t dspac
, int32_t a
, int32_t b
, int32_t ac
,
650 int32_t fmt
, int32_t sign
, int32_t mode
)
653 int nvals
= SIMD_NVALS
[fmt
];
654 uint64_t a_values
[SIMD_MAX_VALS
];
655 uint64_t b_values
[SIMD_MAX_VALS
];
657 simdUnpack( a
, a_values
, fmt
, sign
);
658 simdUnpack( b
, b_values
, fmt
, sign
);
665 dspac
+= a_values
[nvals
-1-i
] * b_values
[nvals
-1-i
];
668 dspac
+= a_values
[nvals
-3-i
] * b_values
[nvals
-3-i
];
671 dspac
+= a_values
[nvals
-1-i
] * b_values
[i
];
680 MipsISA::dspDps( int64_t dspac
, int32_t a
, int32_t b
, int32_t ac
,
681 int32_t fmt
, int32_t sign
, int32_t mode
)
684 int nvals
= SIMD_NVALS
[fmt
];
685 uint64_t a_values
[SIMD_MAX_VALS
];
686 uint64_t b_values
[SIMD_MAX_VALS
];
688 simdUnpack( a
, a_values
, fmt
, sign
);
689 simdUnpack( b
, b_values
, fmt
, sign
);
696 dspac
-= a_values
[nvals
-1-i
] * b_values
[nvals
-1-i
];
699 dspac
-= a_values
[nvals
-3-i
] * b_values
[nvals
-3-i
];
702 dspac
-= a_values
[nvals
-1-i
] * b_values
[i
];
711 MipsISA::dspMaq( int64_t dspac
, int32_t a
, int32_t b
, int32_t ac
,
712 int32_t fmt
, int32_t mode
, int32_t saturate
, uint32_t *dspctl
)
715 int nvals
= SIMD_NVALS
[fmt
-1];
716 uint64_t a_values
[SIMD_MAX_VALS
];
717 uint64_t b_values
[SIMD_MAX_VALS
];
721 simdUnpack( a
, a_values
, fmt
, SIGNED
);
722 simdUnpack( b
, b_values
, fmt
, SIGNED
);
724 for( i
=0; i
<nvals
; i
++ )
729 temp
= a_values
[i
+1] * b_values
[i
+1] << 1;
730 if( a_values
[i
+1] == FIXED_SMIN
[fmt
] && b_values
[i
+1] == FIXED_SMIN
[fmt
] )
732 temp
= (int64_t)FIXED_SMAX
[fmt
-1];
737 temp
= a_values
[i
] * b_values
[i
] << 1;
738 if( a_values
[i
] == FIXED_SMIN
[fmt
] && b_values
[i
] == FIXED_SMIN
[fmt
] )
740 temp
= (int64_t)FIXED_SMAX
[fmt
-1];
749 temp
= dspSaturate( temp
, fmt
-1, SIGNED
, &ouflag
);
751 *dspctl
= insertBits( *dspctl
, 16+ac
, 16+ac
, 1 );
758 MipsISA::dspMulsa( int64_t dspac
, int32_t a
, int32_t b
, int32_t ac
, int32_t fmt
)
760 uint64_t a_values
[SIMD_MAX_VALS
];
761 uint64_t b_values
[SIMD_MAX_VALS
];
763 simdUnpack( a
, a_values
, fmt
, SIGNED
);
764 simdUnpack( b
, b_values
, fmt
, SIGNED
);
766 dspac
+= a_values
[1] * b_values
[1] - a_values
[0] * b_values
[0];
772 MipsISA::dspMulsaq( int64_t dspac
, int32_t a
, int32_t b
, int32_t ac
, int32_t fmt
, uint32_t *dspctl
)
775 int nvals
= SIMD_NVALS
[fmt
];
776 uint64_t a_values
[SIMD_MAX_VALS
];
777 uint64_t b_values
[SIMD_MAX_VALS
];
781 simdUnpack( a
, a_values
, fmt
, SIGNED
);
782 simdUnpack( b
, b_values
, fmt
, SIGNED
);
784 for( i
=nvals
-1; i
>-1; i
-- )
786 temp
[i
] = a_values
[i
] * b_values
[i
] << 1;
787 if( a_values
[i
] == FIXED_SMIN
[fmt
] &&
788 b_values
[i
] == FIXED_SMIN
[fmt
] )
790 temp
[i
] = FIXED_SMAX
[fmt
-1];
795 dspac
+= temp
[1] - temp
[0];
798 *dspctl
= insertBits( *dspctl
, 16+ac
, 16+ac
, 1 );
804 MipsISA::dspCmp( int32_t a
, int32_t b
, int32_t fmt
, int32_t sign
, int32_t op
, uint32_t *dspctl
)
807 int nvals
= SIMD_NVALS
[fmt
];
809 uint64_t a_values
[SIMD_MAX_VALS
];
810 uint64_t b_values
[SIMD_MAX_VALS
];
812 simdUnpack( a
, a_values
, fmt
, sign
);
813 simdUnpack( b
, b_values
, fmt
, sign
);
815 for( i
=0; i
<nvals
; i
++ )
821 case CMP_EQ
: cc
= ( a_values
[i
] == b_values
[i
] ); break;
822 case CMP_LT
: cc
= ( a_values
[i
] < b_values
[i
] ); break;
823 case CMP_LE
: cc
= ( a_values
[i
] <= b_values
[i
] ); break;
826 ccond
|= cc
<< ( DSP_CTL_POS
[DSP_CCOND
] + i
);
829 writeDSPControl( dspctl
, ccond
, 1<<DSP_CCOND
);
833 MipsISA::dspCmpg( int32_t a
, int32_t b
, int32_t fmt
, int32_t sign
, int32_t op
)
836 int nvals
= SIMD_NVALS
[fmt
];
838 uint64_t a_values
[SIMD_MAX_VALS
];
839 uint64_t b_values
[SIMD_MAX_VALS
];
841 simdUnpack( a
, a_values
, fmt
, sign
);
842 simdUnpack( b
, b_values
, fmt
, sign
);
844 for( i
=0; i
<nvals
; i
++ )
850 case CMP_EQ
: cc
= ( a_values
[i
] == b_values
[i
] ); break;
851 case CMP_LT
: cc
= ( a_values
[i
] < b_values
[i
] ); break;
852 case CMP_LE
: cc
= ( a_values
[i
] <= b_values
[i
] ); break;
862 MipsISA::dspCmpgd( int32_t a
, int32_t b
, int32_t fmt
, int32_t sign
, int32_t op
, uint32_t *dspctl
)
865 int nvals
= SIMD_NVALS
[fmt
];
868 uint64_t a_values
[SIMD_MAX_VALS
];
869 uint64_t b_values
[SIMD_MAX_VALS
];
871 simdUnpack( a
, a_values
, fmt
, sign
);
872 simdUnpack( b
, b_values
, fmt
, sign
);
874 for( i
=0; i
<nvals
; i
++ )
880 case CMP_EQ
: cc
= ( a_values
[i
] == b_values
[i
] ); break;
881 case CMP_LT
: cc
= ( a_values
[i
] < b_values
[i
] ); break;
882 case CMP_LE
: cc
= ( a_values
[i
] <= b_values
[i
] ); break;
886 ccond
|= cc
<< ( DSP_CTL_POS
[DSP_CCOND
] + i
);
889 writeDSPControl( dspctl
, ccond
, 1<<DSP_CCOND
);
895 MipsISA::dspPrece( int32_t a
, int32_t infmt
, int32_t insign
, int32_t outfmt
, int32_t outsign
, int32_t mode
)
899 int ninvals
= SIMD_NVALS
[infmt
];
900 int noutvals
= SIMD_NVALS
[outfmt
];
902 uint64_t in_values
[SIMD_MAX_VALS
];
903 uint64_t out_values
[SIMD_MAX_VALS
];
905 if( insign
== SIGNED
&& outsign
== SIGNED
)
906 sa
= SIMD_NBITS
[infmt
];
907 else if( insign
== UNSIGNED
&& outsign
== SIGNED
)
908 sa
= SIMD_NBITS
[infmt
] - 1;
909 else if( insign
== UNSIGNED
&& outsign
== UNSIGNED
)
912 simdUnpack( a
, in_values
, infmt
, insign
);
914 for( i
=0; i
<noutvals
; i
++ )
918 case MODE_L
: out_values
[i
] = in_values
[i
+(ninvals
>>1)] << sa
; break;
919 case MODE_R
: out_values
[i
] = in_values
[i
] << sa
; break;
920 case MODE_LA
: out_values
[i
] = in_values
[(i
<<1)+1] << sa
; break;
921 case MODE_RA
: out_values
[i
] = in_values
[i
<<1] << sa
; break;
925 simdPack( out_values
, &result
, outfmt
);
931 MipsISA::dspPrecrqu( int32_t a
, int32_t b
, uint32_t *dspctl
)
934 uint64_t a_values
[SIMD_MAX_VALS
];
935 uint64_t b_values
[SIMD_MAX_VALS
];
936 uint64_t r_values
[SIMD_MAX_VALS
];
940 simdUnpack( a
, a_values
, SIMD_FMT_PH
, SIGNED
);
941 simdUnpack( b
, b_values
, SIMD_FMT_PH
, SIGNED
);
945 r_values
[i
] = dspSaturate( (int64_t)b_values
[i
] >> SIMD_NBITS
[SIMD_FMT_QB
] - 1,
946 SIMD_FMT_QB
, UNSIGNED
, &ouflag
);
947 r_values
[i
+2] = dspSaturate( (int64_t)a_values
[i
] >> SIMD_NBITS
[SIMD_FMT_QB
] - 1,
948 SIMD_FMT_QB
, UNSIGNED
, &ouflag
);
951 simdPack( r_values
, &result
, SIMD_FMT_QB
);
954 *dspctl
= insertBits( *dspctl
, 22, 22, 1 );
960 MipsISA::dspPrecrq( int32_t a
, int32_t b
, int32_t fmt
, uint32_t *dspctl
)
962 uint64_t a_values
[SIMD_MAX_VALS
];
963 uint64_t b_values
[SIMD_MAX_VALS
];
964 uint64_t r_values
[SIMD_MAX_VALS
];
968 simdUnpack( a
, a_values
, fmt
, SIGNED
);
969 simdUnpack( b
, b_values
, fmt
, SIGNED
);
971 r_values
[1] = dspSaturate( (int64_t)addHalfLsb( a_values
[0], 16 ) >> 16,
972 fmt
+1, SIGNED
, &ouflag
);
973 r_values
[0] = dspSaturate( (int64_t)addHalfLsb( b_values
[0], 16 ) >> 16,
974 fmt
+1, SIGNED
, &ouflag
);
976 simdPack( r_values
, &result
, fmt
+1 );
979 *dspctl
= insertBits( *dspctl
, 22, 22, 1 );
985 MipsISA::dspPrecrSra( int32_t a
, int32_t b
, int32_t sa
, int32_t fmt
, int32_t round
)
988 int nvals
= SIMD_NVALS
[fmt
];
989 uint64_t a_values
[SIMD_MAX_VALS
];
990 uint64_t b_values
[SIMD_MAX_VALS
];
991 uint64_t c_values
[SIMD_MAX_VALS
];
994 simdUnpack( a
, a_values
, fmt
, SIGNED
);
995 simdUnpack( b
, b_values
, fmt
, SIGNED
);
997 for( i
=0; i
<nvals
; i
++ )
1001 c_values
[i
] = addHalfLsb( b_values
[i
], sa
) >> sa
;
1002 c_values
[i
+1] = addHalfLsb( a_values
[i
], sa
) >> sa
;
1006 c_values
[i
] = b_values
[i
] >> sa
;
1007 c_values
[i
+1] = a_values
[i
] >> sa
;
1011 simdPack( c_values
, &result
, fmt
+1 );
1017 MipsISA::dspPick( int32_t a
, int32_t b
, int32_t fmt
, uint32_t *dspctl
)
1020 int nvals
= SIMD_NVALS
[fmt
];
1022 uint64_t a_values
[SIMD_MAX_VALS
];
1023 uint64_t b_values
[SIMD_MAX_VALS
];
1024 uint64_t c_values
[SIMD_MAX_VALS
];
1026 simdUnpack( a
, a_values
, fmt
, UNSIGNED
);
1027 simdUnpack( b
, b_values
, fmt
, UNSIGNED
);
1029 for( i
=0; i
<nvals
; i
++ )
1031 int condbit
= DSP_CTL_POS
[DSP_CCOND
] + i
;
1032 if( bits( *dspctl
, condbit
, condbit
) == 1 )
1033 c_values
[i
] = a_values
[i
];
1035 c_values
[i
] = b_values
[i
];
1038 simdPack( c_values
, &result
, fmt
);
1044 MipsISA::dspPack( int32_t a
, int32_t b
, int32_t fmt
)
1047 uint64_t a_values
[SIMD_MAX_VALS
];
1048 uint64_t b_values
[SIMD_MAX_VALS
];
1049 uint64_t c_values
[SIMD_MAX_VALS
];
1051 simdUnpack( a
, a_values
, fmt
, UNSIGNED
);
1052 simdUnpack( b
, b_values
, fmt
, UNSIGNED
);
1054 c_values
[0] = b_values
[1];
1055 c_values
[1] = a_values
[0];
1057 simdPack( c_values
, &result
, fmt
);
1063 MipsISA::dspExtr( int64_t dspac
, int32_t fmt
, int32_t sa
, int32_t round
, int32_t saturate
, uint32_t *dspctl
)
1066 uint32_t ouflag
= 0;
1069 sa
= bits( sa
, 4, 0 );
1075 temp
= (int64_t)addHalfLsb( dspac
, sa
);
1077 if( dspac
> 0 && temp
< 0 )
1081 temp
= FIXED_SMAX
[SIMD_FMT_L
];
1091 dspac
= checkOverflow( dspac
, fmt
, SIGNED
, &ouflag
);
1095 *dspctl
= insertBits( *dspctl
, 23, 23, ouflag
);
1098 result
= (int32_t)dspSaturate( temp
, fmt
, SIGNED
, &ouflag
);
1100 result
= (int32_t)temp
;
1103 result
= (int32_t)temp
;
1109 MipsISA::dspExtp( int64_t dspac
, int32_t size
, uint32_t *dspctl
)
1114 pos
= bits( *dspctl
, 5, 0 );
1115 size
= bits( size
, 4, 0 );
1117 if( pos
- (size
+1) >= -1 )
1119 result
= bits( dspac
, pos
, pos
-size
);
1120 *dspctl
= insertBits( *dspctl
, 14, 14, 0 );
1125 *dspctl
= insertBits( *dspctl
, 14, 14, 1 );
1132 MipsISA::dspExtpd( int64_t dspac
, int32_t size
, uint32_t *dspctl
)
1137 pos
= bits( *dspctl
, 5, 0 );
1138 size
= bits( size
, 4, 0 );
1140 if( pos
- (size
+1) >= -1 )
1142 result
= bits( dspac
, pos
, pos
-size
);
1143 *dspctl
= insertBits( *dspctl
, 14, 14, 0 );
1144 if( pos
- (size
+1) >= 0 )
1145 *dspctl
= insertBits( *dspctl
, 5, 0, pos
- (size
+1) );
1146 else if( (pos
- (size
+1)) == -1 )
1147 *dspctl
= insertBits( *dspctl
, 5, 0, 63 );
1152 *dspctl
= insertBits( *dspctl
, 14, 14, 1 );
1159 MipsISA::simdPack( uint64_t *values_ptr
, int32_t *reg
, int32_t fmt
)
1162 int nvals
= SIMD_NVALS
[fmt
];
1163 int nbits
= SIMD_NBITS
[fmt
];
1167 for( i
=0; i
<nvals
; i
++ )
1168 *reg
|= (int32_t)bits( values_ptr
[i
], nbits
-1, 0 ) << nbits
*i
;
1172 MipsISA::simdUnpack( int32_t reg
, uint64_t *values_ptr
, int32_t fmt
, int32_t sign
)
1175 int nvals
= SIMD_NVALS
[fmt
];
1176 int nbits
= SIMD_NBITS
[fmt
];
1181 for( i
=0; i
<nvals
; i
++ )
1183 values_ptr
[i
] = (uint64_t)bits( reg
, nbits
*(i
+1)-1, nbits
*i
);
1184 values_ptr
[i
] = signExtend( values_ptr
[i
], fmt
);
1188 for( i
=0; i
<nvals
; i
++ )
1190 values_ptr
[i
] = (uint64_t)bits( reg
, nbits
*(i
+1)-1, nbits
*i
);
1197 MipsISA::writeDSPControl( uint32_t *dspctl
, uint32_t value
, uint32_t mask
)
1201 if( mask
& 0x01 ) fmask
|= DSP_CTL_MASK
[DSP_POS
];
1202 if( mask
& 0x02 ) fmask
|= DSP_CTL_MASK
[DSP_SCOUNT
];
1203 if( mask
& 0x04 ) fmask
|= DSP_CTL_MASK
[DSP_C
];
1204 if( mask
& 0x08 ) fmask
|= DSP_CTL_MASK
[DSP_OUFLAG
];
1205 if( mask
& 0x10 ) fmask
|= DSP_CTL_MASK
[DSP_CCOND
];
1206 if( mask
& 0x20 ) fmask
|= DSP_CTL_MASK
[DSP_EFI
];
1214 MipsISA::readDSPControl( uint32_t *dspctl
, uint32_t mask
)
1218 if( mask
& 0x01 ) fmask
|= DSP_CTL_MASK
[DSP_POS
];
1219 if( mask
& 0x02 ) fmask
|= DSP_CTL_MASK
[DSP_SCOUNT
];
1220 if( mask
& 0x04 ) fmask
|= DSP_CTL_MASK
[DSP_C
];
1221 if( mask
& 0x08 ) fmask
|= DSP_CTL_MASK
[DSP_OUFLAG
];
1222 if( mask
& 0x10 ) fmask
|= DSP_CTL_MASK
[DSP_CCOND
];
1223 if( mask
& 0x20 ) fmask
|= DSP_CTL_MASK
[DSP_EFI
];
1225 return( *dspctl
& fmask
);