dsp.cc (5222:bb733a878f85) dsp.cc (5558:cb98f0fcc6c6)
1/*
2 * Copyright (c) 2007 MIPS Technologies, Inc.
3 * All rights reserved.
4 *
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;

--- 26 unchanged lines hidden (view full) ---

35#include "sim/serialize.hh"
36#include "base/bitfield.hh"
37#include "base/misc.hh"
38
39using namespace MipsISA;
40using namespace std;
41
42int32_t
1/*
2 * Copyright (c) 2007 MIPS Technologies, Inc.
3 * All rights reserved.
4 *
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;

--- 26 unchanged lines hidden (view full) ---

35#include "sim/serialize.hh"
36#include "base/bitfield.hh"
37#include "base/misc.hh"
38
39using namespace MipsISA;
40using namespace std;
41
42int32_t
43MipsISA::bitrev( int32_t value )
43MipsISA::bitrev(int32_t value)
44{
45 int32_t result = 0;
44{
45 int32_t result = 0;
46 int i, shift;
46 int shift;
47
47
48 for( i=0; i<16; i++ )
49 {
50 shift = 2*i - 15;
48 for (int i = 0; i < 16; i++) {
49 shift = 2 * i - 15;
51
50
52 if( shift < 0 )
53 result |= (value & 1L<<i) << -shift;
51 if (shift < 0)
52 result |= (value & 1 << i) << -shift;
54 else
53 else
55 result |= (value & 1L<<i) >> shift;
54 result |= (value & 1 << i) >> shift;
56 }
57
58 return result;
59}
60
61uint64_t
55 }
56
57 return result;
58}
59
60uint64_t
62MipsISA::dspSaturate( uint64_t value, int32_t fmt, int32_t sign, uint32_t *overflow )
61MipsISA::dspSaturate(uint64_t value, int32_t fmt, int32_t sign,
62 uint32_t *overflow)
63{
63{
64 int64_t svalue;
64 int64_t svalue = (int64_t)value;
65
65
66 svalue = (int64_t)value;
67
68 switch( sign )
69 {
66 switch(sign) {
70 case SIGNED:
67 case SIGNED:
71 if( svalue > (int64_t)FIXED_SMAX[fmt] )
72 {
68 if (svalue > (int64_t)FIXED_SMAX[fmt]) {
73 *overflow = 1;
74 svalue = (int64_t)FIXED_SMAX[fmt];
69 *overflow = 1;
70 svalue = (int64_t)FIXED_SMAX[fmt];
75 }
76 else if( svalue < (int64_t)FIXED_SMIN[fmt] )
77 {
71 } else if (svalue < (int64_t)FIXED_SMIN[fmt]) {
78 *overflow = 1;
79 svalue = (int64_t)FIXED_SMIN[fmt];
80 }
81 break;
82 case UNSIGNED:
72 *overflow = 1;
73 svalue = (int64_t)FIXED_SMIN[fmt];
74 }
75 break;
76 case UNSIGNED:
83 if( svalue > (int64_t)FIXED_UMAX[fmt] )
84 {
77 if (svalue > (int64_t)FIXED_UMAX[fmt]) {
85 *overflow = 1;
86 svalue = FIXED_UMAX[fmt];
78 *overflow = 1;
79 svalue = FIXED_UMAX[fmt];
87 }
88 else if( svalue < (int64_t)FIXED_UMIN[fmt] )
89 {
80 } else if (svalue < (int64_t)FIXED_UMIN[fmt]) {
90 *overflow = 1;
91 svalue = FIXED_UMIN[fmt];
92 }
93 break;
94 }
95
81 *overflow = 1;
82 svalue = FIXED_UMIN[fmt];
83 }
84 break;
85 }
86
96 return( (uint64_t)svalue );
87 return (uint64_t)svalue;
97}
98
99uint64_t
88}
89
90uint64_t
100MipsISA::checkOverflow( uint64_t value, int32_t fmt, int32_t sign, uint32_t *overflow )
91MipsISA::checkOverflow(uint64_t value, int32_t fmt, int32_t sign,
92 uint32_t *overflow)
101{
93{
102 int64_t svalue;
94 int64_t svalue = (int64_t)value;
103
95
104 svalue = (int64_t)value;
105
106 switch( sign )
96 switch(sign)
107 {
108 case SIGNED:
97 {
98 case SIGNED:
109 if( svalue > (int64_t)FIXED_SMAX[fmt] || svalue < (int64_t)FIXED_SMIN[fmt] )
99 if (svalue > (int64_t)FIXED_SMAX[fmt] ||
100 svalue < (int64_t)FIXED_SMIN[fmt])
110 *overflow = 1;
111 break;
112 case UNSIGNED:
101 *overflow = 1;
102 break;
103 case UNSIGNED:
113 if( svalue > (int64_t)FIXED_UMAX[fmt] || svalue < (int64_t)FIXED_UMIN[fmt] )
104 if (svalue > (int64_t)FIXED_UMAX[fmt] ||
105 svalue < (int64_t)FIXED_UMIN[fmt])
114 *overflow = 1;
115 break;
116 }
117
106 *overflow = 1;
107 break;
108 }
109
118 return( (uint64_t)svalue );
110 return (uint64_t)svalue;
119}
120
121uint64_t
111}
112
113uint64_t
122MipsISA::signExtend( uint64_t value, int32_t fmt )
114MipsISA::signExtend(uint64_t value, int32_t fmt)
123{
124 int32_t signpos = SIMD_NBITS[fmt];
115{
116 int32_t signpos = SIMD_NBITS[fmt];
125 uint64_t sign = uint64_t(1)<<(signpos-1);
117 uint64_t sign = uint64_t(1) << (signpos - 1);
126 uint64_t ones = ~(0ULL);
127
118 uint64_t ones = ~(0ULL);
119
128 if( value & sign )
120 if (value & sign)
129 value |= (ones << signpos); // extend with ones
130 else
131 value &= (ones >> (64 - signpos)); // extend with zeros
132
133 return value;
134}
135
136uint64_t
121 value |= (ones << signpos); // extend with ones
122 else
123 value &= (ones >> (64 - signpos)); // extend with zeros
124
125 return value;
126}
127
128uint64_t
137MipsISA::addHalfLsb( uint64_t value, int32_t lsbpos )
129MipsISA::addHalfLsb(uint64_t value, int32_t lsbpos)
138{
130{
139 return( value += ULL(1) << (lsbpos-1) );
131 return value += ULL(1) << (lsbpos - 1);
140}
141
142int32_t
132}
133
134int32_t
143MipsISA::dspAbs( int32_t a, int32_t fmt, uint32_t *dspctl )
135MipsISA::dspAbs(int32_t a, int32_t fmt, uint32_t *dspctl)
144{
136{
145 int i = 0;
146 int nvals = SIMD_NVALS[fmt];
147 int32_t result;
148 int64_t svalue;
149 uint32_t ouflag = 0;
150 uint64_t a_values[SIMD_MAX_VALS];
151
137 int nvals = SIMD_NVALS[fmt];
138 int32_t result;
139 int64_t svalue;
140 uint32_t ouflag = 0;
141 uint64_t a_values[SIMD_MAX_VALS];
142
152 simdUnpack( a, a_values, fmt, SIGNED );
143 simdUnpack(a, a_values, fmt, SIGNED);
153
144
154 for( i=0; i<nvals; i++ )
155 {
145 for (int i = 0; i < nvals; i++) {
156 svalue = (int64_t)a_values[i];
157
146 svalue = (int64_t)a_values[i];
147
158 if( a_values[i] == FIXED_SMIN[fmt] )
159 {
148 if (a_values[i] == FIXED_SMIN[fmt]) {
160 a_values[i] = FIXED_SMAX[fmt];
161 ouflag = 1;
149 a_values[i] = FIXED_SMAX[fmt];
150 ouflag = 1;
151 } else if (svalue < 0) {
152 a_values[i] = uint64_t(0 - svalue);
162 }
153 }
163 else if( svalue < 0 )
164 {
165 a_values[i] = uint64_t( 0 - svalue );
166 }
167 }
168
154 }
155
169 simdPack( a_values, &result, fmt );
156 simdPack(a_values, &result, fmt);
170
157
171 if( ouflag )
172 writeDSPControl( dspctl, (ouflag<<4)<<DSP_CTL_POS[DSP_OUFLAG], 1<<DSP_OUFLAG);
158 if (ouflag)
159 writeDSPControl(dspctl, (ouflag << 4) << DSP_CTL_POS[DSP_OUFLAG],
160 1 << DSP_OUFLAG);
173
161
174 return( result );
162 return result;
175}
176
177int32_t
163}
164
165int32_t
178MipsISA::dspAdd( int32_t a, int32_t b, int32_t fmt, int32_t saturate, int32_t sign, uint32_t *dspctl )
166MipsISA::dspAdd(int32_t a, int32_t b, int32_t fmt, int32_t saturate,
167 int32_t sign, uint32_t *dspctl)
179{
168{
180 int i = 0;
181 int nvals = SIMD_NVALS[fmt];
182 int32_t result;
183 uint32_t ouflag = 0;
184 uint64_t a_values[SIMD_MAX_VALS];
185 uint64_t b_values[SIMD_MAX_VALS];
186
169 int nvals = SIMD_NVALS[fmt];
170 int32_t result;
171 uint32_t ouflag = 0;
172 uint64_t a_values[SIMD_MAX_VALS];
173 uint64_t b_values[SIMD_MAX_VALS];
174
187 simdUnpack( a, a_values, fmt, sign );
188 simdUnpack( b, b_values, fmt, sign );
175 simdUnpack(a, a_values, fmt, sign);
176 simdUnpack(b, b_values, fmt, sign);
189
177
190 for( i=0; i<nvals; i++ )
178 for (int i = 0; i < nvals; i++)
191 {
179 {
192 if( saturate )
193 a_values[i] = dspSaturate( a_values[i] + b_values[i], fmt, sign, &ouflag );
180 if (saturate)
181 a_values[i] = dspSaturate(a_values[i] + b_values[i], fmt, sign,
182 &ouflag);
194 else
183 else
195 a_values[i] = checkOverflow( a_values[i] + b_values[i], fmt, sign, &ouflag );
184 a_values[i] = checkOverflow(a_values[i] + b_values[i], fmt, sign,
185 &ouflag);
196 }
197
186 }
187
198 simdPack( a_values, &result, fmt );
188 simdPack(a_values, &result, fmt);
199
189
200 if( ouflag )
201 writeDSPControl( dspctl, (ouflag<<4)<<DSP_CTL_POS[DSP_OUFLAG], 1<<DSP_OUFLAG);
190 if (ouflag)
191 writeDSPControl(dspctl, (ouflag << 4) << DSP_CTL_POS[DSP_OUFLAG],
192 1 << DSP_OUFLAG);
202
193
203 return( result );
194 return result;
204}
205
206int32_t
195}
196
197int32_t
207MipsISA::dspAddh( int32_t a, int32_t b, int32_t fmt, int32_t round, int32_t sign )
198MipsISA::dspAddh(int32_t a, int32_t b, int32_t fmt, int32_t round,
199 int32_t sign)
208{
200{
209 int i = 0;
210 int nvals = SIMD_NVALS[fmt];
211 int32_t result;
212 uint64_t a_values[SIMD_MAX_VALS];
213 uint64_t b_values[SIMD_MAX_VALS];
214
201 int nvals = SIMD_NVALS[fmt];
202 int32_t result;
203 uint64_t a_values[SIMD_MAX_VALS];
204 uint64_t b_values[SIMD_MAX_VALS];
205
215 simdUnpack( a, a_values, fmt, sign );
216 simdUnpack( b, b_values, fmt, sign );
206 simdUnpack(a, a_values, fmt, sign);
207 simdUnpack(b, b_values, fmt, sign);
217
208
218 for( i=0; i<nvals; i++ )
219 {
220 if( round )
221 a_values[i] = addHalfLsb( a_values[i] + b_values[i], 1 ) >> 1;
209 for (int i = 0; i < nvals; i++) {
210 if (round)
211 a_values[i] = addHalfLsb(a_values[i] + b_values[i], 1) >> 1;
222 else
212 else
223 a_values[i] = ( a_values[i] + b_values[i] ) >> 1;
213 a_values[i] = (a_values[i] + b_values[i]) >> 1;
224 }
225
214 }
215
226 simdPack( a_values, &result, fmt );
216 simdPack(a_values, &result, fmt);
227
217
228 return( result );
218 return result;
229}
230
231int32_t
219}
220
221int32_t
232MipsISA::dspSub( int32_t a, int32_t b, int32_t fmt, int32_t saturate, int32_t sign, uint32_t *dspctl )
222MipsISA::dspSub(int32_t a, int32_t b, int32_t fmt, int32_t saturate,
223 int32_t sign, uint32_t *dspctl)
233{
224{
234 int i = 0;
235 int nvals = SIMD_NVALS[fmt];
236 int32_t result;
237 uint32_t ouflag = 0;
238 uint64_t a_values[SIMD_MAX_VALS];
239 uint64_t b_values[SIMD_MAX_VALS];
240
225 int nvals = SIMD_NVALS[fmt];
226 int32_t result;
227 uint32_t ouflag = 0;
228 uint64_t a_values[SIMD_MAX_VALS];
229 uint64_t b_values[SIMD_MAX_VALS];
230
241 simdUnpack( a, a_values, fmt, sign );
242 simdUnpack( b, b_values, fmt, sign );
231 simdUnpack(a, a_values, fmt, sign);
232 simdUnpack(b, b_values, fmt, sign);
243
233
244 for( i=0; i<nvals; i++ )
245 {
246 if( saturate )
247 a_values[i] = dspSaturate( a_values[i] - b_values[i], fmt, sign, &ouflag );
234 for (int i = 0; i < nvals; i++) {
235 if (saturate)
236 a_values[i] = dspSaturate(a_values[i] - b_values[i], fmt, sign,
237 &ouflag);
248 else
238 else
249 a_values[i] = checkOverflow( a_values[i] - b_values[i], fmt, sign, &ouflag );
239 a_values[i] = checkOverflow(a_values[i] - b_values[i], fmt, sign,
240 &ouflag);
250 }
251
241 }
242
252 simdPack( a_values, &result, fmt );
243 simdPack(a_values, &result, fmt);
253
244
254 if( ouflag )
255 writeDSPControl( dspctl, (ouflag<<4)<<DSP_CTL_POS[DSP_OUFLAG], 1<<DSP_OUFLAG);
245 if (ouflag)
246 writeDSPControl(dspctl, (ouflag << 4) << DSP_CTL_POS[DSP_OUFLAG],
247 1 << DSP_OUFLAG);
256
248
257 return( result );
249 return result;
258}
259
260int32_t
250}
251
252int32_t
261MipsISA::dspSubh( int32_t a, int32_t b, int32_t fmt, int32_t round, int32_t sign )
253MipsISA::dspSubh(int32_t a, int32_t b, int32_t fmt, int32_t round,
254 int32_t sign)
262{
255{
263 int i = 0;
264 int nvals = SIMD_NVALS[fmt];
265 int32_t result;
266 uint64_t a_values[SIMD_MAX_VALS];
267 uint64_t b_values[SIMD_MAX_VALS];
268
256 int nvals = SIMD_NVALS[fmt];
257 int32_t result;
258 uint64_t a_values[SIMD_MAX_VALS];
259 uint64_t b_values[SIMD_MAX_VALS];
260
269 simdUnpack( a, a_values, fmt, sign );
270 simdUnpack( b, b_values, fmt, sign );
261 simdUnpack(a, a_values, fmt, sign);
262 simdUnpack(b, b_values, fmt, sign);
271
263
272 for( i=0; i<nvals; i++ )
264 for (int i = 0; i < nvals; i++)
273 {
265 {
274 if( round )
275 a_values[i] = addHalfLsb( a_values[i] - b_values[i], 1 ) >> 1;
266 if (round)
267 a_values[i] = addHalfLsb(a_values[i] - b_values[i], 1) >> 1;
276 else
268 else
277 a_values[i] = ( a_values[i] - b_values[i] ) >> 1;
269 a_values[i] = (a_values[i] - b_values[i]) >> 1;
278 }
279
270 }
271
280 simdPack( a_values, &result, fmt );
272 simdPack(a_values, &result, fmt);
281
273
282 return( result );
274 return result;
283}
284
285int32_t
275}
276
277int32_t
286MipsISA::dspShll( int32_t a, uint32_t sa, int32_t fmt, int32_t saturate, int32_t sign, uint32_t *dspctl )
278MipsISA::dspShll(int32_t a, uint32_t sa, int32_t fmt, int32_t saturate,
279 int32_t sign, uint32_t *dspctl)
287{
280{
288 int i = 0;
289 int nvals = SIMD_NVALS[fmt];
290 int32_t result;
291 uint32_t ouflag = 0;
292 uint64_t a_values[SIMD_MAX_VALS];
293
281 int nvals = SIMD_NVALS[fmt];
282 int32_t result;
283 uint32_t ouflag = 0;
284 uint64_t a_values[SIMD_MAX_VALS];
285
294 sa = bits( sa, SIMD_LOG2N[fmt]-1, 0 );
295 simdUnpack( a, a_values, fmt, sign );
286 sa = bits(sa, SIMD_LOG2N[fmt] - 1, 0);
287 simdUnpack(a, a_values, fmt, sign);
296
288
297 for( i=0; i<nvals; i++ )
289 for (int i = 0; i < nvals; i++)
298 {
290 {
299 if( saturate )
300 a_values[i] = dspSaturate( a_values[i] << sa, fmt, sign, &ouflag );
291 if (saturate)
292 a_values[i] = dspSaturate(a_values[i] << sa, fmt, sign, &ouflag);
301 else
293 else
302 a_values[i] = checkOverflow( a_values[i] << sa, fmt, sign, &ouflag );
294 a_values[i] = checkOverflow(a_values[i] << sa, fmt, sign, &ouflag);
303 }
304
295 }
296
305 simdPack( a_values, &result, fmt );
297 simdPack(a_values, &result, fmt);
306
298
307 if( ouflag )
308 writeDSPControl( dspctl, (ouflag<<6)<<DSP_CTL_POS[DSP_OUFLAG], 1<<DSP_OUFLAG);
299 if (ouflag)
300 writeDSPControl(dspctl, (ouflag << 6) << DSP_CTL_POS[DSP_OUFLAG],
301 1 << DSP_OUFLAG);
309
302
310 return( result );
303 return result;
311}
312
313int32_t
304}
305
306int32_t
314MipsISA::dspShrl( int32_t a, uint32_t sa, int32_t fmt, int32_t sign )
307MipsISA::dspShrl(int32_t a, uint32_t sa, int32_t fmt, int32_t sign)
315{
308{
316 int i = 0;
317 int nvals = SIMD_NVALS[fmt];
318 int32_t result;
319 uint64_t a_values[SIMD_MAX_VALS];
320
309 int nvals = SIMD_NVALS[fmt];
310 int32_t result;
311 uint64_t a_values[SIMD_MAX_VALS];
312
321 sa = bits( sa, SIMD_LOG2N[fmt]-1, 0 );
313 sa = bits(sa, SIMD_LOG2N[fmt] - 1, 0);
322
314
323 simdUnpack( a, a_values, fmt, UNSIGNED );
315 simdUnpack(a, a_values, fmt, UNSIGNED);
324
316
325 for( i=0; i<nvals; i++ )
317 for (int i = 0; i < nvals; i++)
326 a_values[i] = a_values[i] >> sa;
327
318 a_values[i] = a_values[i] >> sa;
319
328 simdPack( a_values, &result, fmt );
320 simdPack(a_values, &result, fmt);
329
321
330 return( result );
322 return result;
331}
332
333int32_t
323}
324
325int32_t
334MipsISA::dspShra( int32_t a, uint32_t sa, int32_t fmt, int32_t round, int32_t sign, uint32_t *dspctl )
326MipsISA::dspShra(int32_t a, uint32_t sa, int32_t fmt, int32_t round,
327 int32_t sign, uint32_t *dspctl)
335{
328{
336 int i = 0;
337 int nvals = SIMD_NVALS[fmt];
338 int32_t result;
339 uint64_t a_values[SIMD_MAX_VALS];
340
329 int nvals = SIMD_NVALS[fmt];
330 int32_t result;
331 uint64_t a_values[SIMD_MAX_VALS];
332
341 sa = bits( sa, SIMD_LOG2N[fmt]-1, 0 );
333 sa = bits(sa, SIMD_LOG2N[fmt] - 1, 0);
342
334
343 simdUnpack( a, a_values, fmt, SIGNED );
335 simdUnpack(a, a_values, fmt, SIGNED);
344
336
345 for( i=0; i<nvals; i++ )
346 {
347 if( round )
348 a_values[i] = addHalfLsb( a_values[i], sa ) >> sa;
337 for (int i = 0; i < nvals; i++) {
338 if (round)
339 a_values[i] = addHalfLsb(a_values[i], sa) >> sa;
349 else
350 a_values[i] = a_values[i] >> sa;
351 }
352
340 else
341 a_values[i] = a_values[i] >> sa;
342 }
343
353 simdPack( a_values, &result, fmt );
344 simdPack(a_values, &result, fmt);
354
345
355 return( result );
346 return result;
356}
357
358int32_t
347}
348
349int32_t
359MipsISA::dspMulq( int32_t a, int32_t b, int32_t fmt, int32_t saturate, int32_t round, uint32_t *dspctl )
350MipsISA::dspMulq(int32_t a, int32_t b, int32_t fmt, int32_t saturate,
351 int32_t round, uint32_t *dspctl)
360{
352{
361 int i = 0;
362 int nvals = SIMD_NVALS[fmt];
363 int sa = SIMD_NBITS[fmt];
364 int32_t result;
365 uint32_t ouflag = 0;
366 uint64_t a_values[SIMD_MAX_VALS];
367 uint64_t b_values[SIMD_MAX_VALS];
368 int64_t temp;
369
353 int nvals = SIMD_NVALS[fmt];
354 int sa = SIMD_NBITS[fmt];
355 int32_t result;
356 uint32_t ouflag = 0;
357 uint64_t a_values[SIMD_MAX_VALS];
358 uint64_t b_values[SIMD_MAX_VALS];
359 int64_t temp;
360
370 simdUnpack( a, a_values, fmt, SIGNED );
371 simdUnpack( b, b_values, fmt, SIGNED );
361 simdUnpack(a, a_values, fmt, SIGNED);
362 simdUnpack(b, b_values, fmt, SIGNED);
372
363
373 for( i=0; i<nvals; i++ )
374 {
375 if( round )
376 temp = (int64_t)addHalfLsb( a_values[i] * b_values[i] << 1, sa ) >> sa;
364 for (int i = 0; i < nvals; i++) {
365 if (round)
366 temp =
367 (int64_t)addHalfLsb(a_values[i] * b_values[i] << 1, sa) >> sa;
377 else
378 temp = (int64_t)(a_values[i] * b_values[i]) >> (sa - 1);
379
368 else
369 temp = (int64_t)(a_values[i] * b_values[i]) >> (sa - 1);
370
380 if( a_values[i] == FIXED_SMIN[fmt] &&
381 b_values[i] == FIXED_SMIN[fmt] )
382 {
371 if (a_values[i] == FIXED_SMIN[fmt] && b_values[i] == FIXED_SMIN[fmt]) {
383 ouflag = 1;
384
372 ouflag = 1;
373
385 if( saturate )
374 if (saturate)
386 temp = FIXED_SMAX[fmt];
387 }
388
389 a_values[i] = temp;
390 }
391
375 temp = FIXED_SMAX[fmt];
376 }
377
378 a_values[i] = temp;
379 }
380
392 simdPack( a_values, &result, fmt );
381 simdPack(a_values, &result, fmt);
393
382
394 if( ouflag )
395 writeDSPControl( dspctl, (ouflag<<5)<<DSP_CTL_POS[DSP_OUFLAG], 1<<DSP_OUFLAG);
383 if (ouflag)
384 writeDSPControl(dspctl, (ouflag << 5) << DSP_CTL_POS[DSP_OUFLAG],
385 1 << DSP_OUFLAG);
396
386
397 return( result );
387 return result;
398}
399
400int32_t
388}
389
390int32_t
401MipsISA::dspMul( int32_t a, int32_t b, int32_t fmt, int32_t saturate, uint32_t *dspctl )
391MipsISA::dspMul(int32_t a, int32_t b, int32_t fmt, int32_t saturate,
392 uint32_t *dspctl)
402{
393{
403 int i = 0;
404 int nvals = SIMD_NVALS[fmt];
405 int32_t result;
406 uint32_t ouflag = 0;
407 uint64_t a_values[SIMD_MAX_VALS];
408 uint64_t b_values[SIMD_MAX_VALS];
409
394 int nvals = SIMD_NVALS[fmt];
395 int32_t result;
396 uint32_t ouflag = 0;
397 uint64_t a_values[SIMD_MAX_VALS];
398 uint64_t b_values[SIMD_MAX_VALS];
399
410 simdUnpack( a, a_values, fmt, SIGNED );
411 simdUnpack( b, b_values, fmt, SIGNED );
400 simdUnpack(a, a_values, fmt, SIGNED);
401 simdUnpack(b, b_values, fmt, SIGNED);
412
402
413 for( i=0; i<nvals; i++ )
403 for (int i = 0; i < nvals; i++)
414 {
404 {
415 if( saturate )
416 a_values[i] = dspSaturate( a_values[i] * b_values[i], fmt, SIGNED, &ouflag );
405 if (saturate)
406 a_values[i] = dspSaturate(a_values[i] * b_values[i], fmt, SIGNED,
407 &ouflag);
417 else
408 else
418 a_values[i] = checkOverflow( a_values[i] * b_values[i], fmt, SIGNED, &ouflag );
409 a_values[i] = checkOverflow(a_values[i] * b_values[i], fmt, SIGNED,
410 &ouflag);
419 }
420
411 }
412
421 simdPack( a_values, &result, fmt );
413 simdPack(a_values, &result, fmt);
422
414
423 if( ouflag )
424 writeDSPControl( dspctl, (ouflag<<5)<<DSP_CTL_POS[DSP_OUFLAG], 1<<DSP_OUFLAG);
415 if (ouflag)
416 writeDSPControl(dspctl, (ouflag << 5) << DSP_CTL_POS[DSP_OUFLAG],
417 1 << DSP_OUFLAG);
425
418
426 return( result );
419 return result;
427}
428
429int32_t
420}
421
422int32_t
430MipsISA::dspMuleu( int32_t a, int32_t b, int32_t mode, uint32_t *dspctl )
423MipsISA::dspMuleu(int32_t a, int32_t b, int32_t mode, uint32_t *dspctl)
431{
424{
432 int i = 0;
433 int nvals = SIMD_NVALS[SIMD_FMT_PH];
434 int32_t result;
435 uint32_t ouflag = 0;
436 uint64_t a_values[SIMD_MAX_VALS];
437 uint64_t b_values[SIMD_MAX_VALS];
438
425 int nvals = SIMD_NVALS[SIMD_FMT_PH];
426 int32_t result;
427 uint32_t ouflag = 0;
428 uint64_t a_values[SIMD_MAX_VALS];
429 uint64_t b_values[SIMD_MAX_VALS];
430
439 simdUnpack( a, a_values, SIMD_FMT_QB, UNSIGNED );
440 simdUnpack( b, b_values, SIMD_FMT_PH, UNSIGNED );
431 simdUnpack(a, a_values, SIMD_FMT_QB, UNSIGNED);
432 simdUnpack(b, b_values, SIMD_FMT_PH, UNSIGNED);
441
433
442 switch( mode )
443 {
434 switch(mode) {
444 case MODE_L:
435 case MODE_L:
445 for( i=0; i<nvals; i++ )
446 b_values[i] = dspSaturate( a_values[i+2] * b_values[i], SIMD_FMT_PH, UNSIGNED, &ouflag );
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);
447 break;
448 case MODE_R:
439 break;
440 case MODE_R:
449 for( i=0; i<nvals; i++ )
450 b_values[i] = dspSaturate( a_values[i] * b_values[i], 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,
443 UNSIGNED, &ouflag);
451 break;
452 }
453
444 break;
445 }
446
454 simdPack( b_values, &result, SIMD_FMT_PH );
447 simdPack(b_values, &result, SIMD_FMT_PH);
455
448
456 if( ouflag )
457 writeDSPControl( dspctl, (ouflag<<5)<<DSP_CTL_POS[DSP_OUFLAG], 1<<DSP_OUFLAG);
449 if (ouflag)
450 writeDSPControl(dspctl, (ouflag << 5) << DSP_CTL_POS[DSP_OUFLAG],
451 1 << DSP_OUFLAG);
458
452
459 return( result );
453 return result;
460}
461
462int32_t
454}
455
456int32_t
463MipsISA::dspMuleq( int32_t a, int32_t b, int32_t mode, uint32_t *dspctl )
457MipsISA::dspMuleq(int32_t a, int32_t b, int32_t mode, uint32_t *dspctl)
464{
458{
465 int i = 0;
466 int nvals = SIMD_NVALS[SIMD_FMT_W];
467 int32_t result;
468 uint32_t ouflag = 0;
469 uint64_t a_values[SIMD_MAX_VALS];
470 uint64_t b_values[SIMD_MAX_VALS];
471 uint64_t c_values[SIMD_MAX_VALS];
472
459 int nvals = SIMD_NVALS[SIMD_FMT_W];
460 int32_t result;
461 uint32_t ouflag = 0;
462 uint64_t a_values[SIMD_MAX_VALS];
463 uint64_t b_values[SIMD_MAX_VALS];
464 uint64_t c_values[SIMD_MAX_VALS];
465
473 simdUnpack( a, a_values, SIMD_FMT_PH, SIGNED );
474 simdUnpack( b, b_values, SIMD_FMT_PH, SIGNED );
466 simdUnpack(a, a_values, SIMD_FMT_PH, SIGNED);
467 simdUnpack(b, b_values, SIMD_FMT_PH, SIGNED);
475
468
476 switch( mode )
477 {
469 switch(mode) {
478 case MODE_L:
470 case MODE_L:
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 );
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);
482 break;
483 case MODE_R:
474 break;
475 case MODE_R:
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 );
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);
487 break;
488 }
489
479 break;
480 }
481
490 simdPack( c_values, &result, SIMD_FMT_W );
482 simdPack(c_values, &result, SIMD_FMT_W);
491
483
492 if( ouflag )
493 writeDSPControl( dspctl, (ouflag<<5)<<DSP_CTL_POS[DSP_OUFLAG], 1<<DSP_OUFLAG);
484 if (ouflag)
485 writeDSPControl(dspctl, (ouflag << 5) << DSP_CTL_POS[DSP_OUFLAG],
486 1 << DSP_OUFLAG);
494
487
495 return( result );
488 return result;
496}
497
498int64_t
489}
490
491int64_t
499MipsISA::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 )
492MipsISA::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,
494 uint32_t *dspctl)
501{
495{
502 int i = 0;
503 int nvals = SIMD_NVALS[infmt];
504 int64_t result = 0;
505 int64_t temp = 0;
506 uint32_t ouflag = 0;
507 uint64_t a_values[SIMD_MAX_VALS];
508 uint64_t b_values[SIMD_MAX_VALS];
509
496 int nvals = SIMD_NVALS[infmt];
497 int64_t result = 0;
498 int64_t temp = 0;
499 uint32_t ouflag = 0;
500 uint64_t a_values[SIMD_MAX_VALS];
501 uint64_t b_values[SIMD_MAX_VALS];
502
510 simdUnpack( a, a_values, infmt, SIGNED );
511 simdUnpack( b, b_values, infmt, SIGNED );
503 simdUnpack(a, a_values, infmt, SIGNED);
504 simdUnpack(b, b_values, infmt, SIGNED);
512
505
513 for( i=0; i<nvals; i++ )
514 {
515 switch( mode )
516 {
506 for (int i = 0; i < nvals; i++) {
507 switch(mode) {
517 case MODE_X:
508 case MODE_X:
518 if( a_values[nvals-1-i] == FIXED_SMIN[infmt] &&
519 b_values[i] == FIXED_SMIN[infmt] )
520 {
509 if (a_values[nvals - 1 - i] == FIXED_SMIN[infmt] &&
510 b_values[i] == FIXED_SMIN[infmt]) {
521 result += FIXED_SMAX[outfmt];
522 ouflag = 1;
523 }
524 else
511 result += FIXED_SMAX[outfmt];
512 ouflag = 1;
513 }
514 else
525 result += a_values[nvals-1-i] * b_values[i] << 1;
515 result += a_values[nvals - 1 - i] * b_values[i] << 1;
526 break;
527 default:
516 break;
517 default:
528 if( a_values[i] == FIXED_SMIN[infmt] &&
529 b_values[i] == FIXED_SMIN[infmt] )
530 {
518 if (a_values[i] == FIXED_SMIN[infmt] &&
519 b_values[i] == FIXED_SMIN[infmt]) {
531 result += FIXED_SMAX[outfmt];
532 ouflag = 1;
520 result += FIXED_SMAX[outfmt];
521 ouflag = 1;
533 }
534 else
522 } else {
535 result += a_values[i] * b_values[i] << 1;
523 result += a_values[i] * b_values[i] << 1;
524 }
536 break;
537 }
538 }
539
525 break;
526 }
527 }
528
540 if( postsat )
541 {
542 if( outfmt == SIMD_FMT_L )
543 {
544 int signa = bits( dspac, 63, 63 );
545 int signb = bits( result, 63, 63 );
529 if (postsat) {
530 if (outfmt == SIMD_FMT_L) {
531 int signa = bits(dspac, 63, 63);
532 int signb = bits(result, 63, 63);
546
547 temp = dspac + result;
548
533
534 temp = dspac + result;
535
549 if( ( signa == signb ) &&
550 ( bits( temp, 63, 63 ) != signa ) )
551 {
536 if (signa == signb && bits(temp, 63, 63) != signa) {
552 ouflag = 1;
537 ouflag = 1;
553 if( signa )
538 if (signa)
554 dspac = FIXED_SMIN[outfmt];
555 else
556 dspac = FIXED_SMAX[outfmt];
539 dspac = FIXED_SMIN[outfmt];
540 else
541 dspac = FIXED_SMAX[outfmt];
557 }
558 else
542 } else {
559 dspac = temp;
543 dspac = temp;
544 }
545 } else {
546 dspac = dspSaturate(dspac + result, outfmt, SIGNED, &ouflag);
560 }
547 }
561 else
562 dspac = dspSaturate( dspac + result, outfmt, SIGNED, &ouflag );
563 }
564 else
548 } else {
565 dspac += result;
549 dspac += result;
550 }
566
551
567 if( ouflag )
568 *dspctl = insertBits( *dspctl, 16+ac, 16+ac, 1 );
552 if (ouflag)
553 *dspctl = insertBits(*dspctl, 16 + ac, 16 + ac, 1);
569
554
570 return( dspac );
555 return dspac;
571}
572
573int64_t
556}
557
558int64_t
574MipsISA::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 )
559MipsISA::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,
561 uint32_t *dspctl)
576{
562{
577 int i = 0;
578 int nvals = SIMD_NVALS[infmt];
579 int64_t result = 0;
580 int64_t temp = 0;
581 uint32_t ouflag = 0;
582 uint64_t a_values[SIMD_MAX_VALS];
583 uint64_t b_values[SIMD_MAX_VALS];
584
563 int nvals = SIMD_NVALS[infmt];
564 int64_t result = 0;
565 int64_t temp = 0;
566 uint32_t ouflag = 0;
567 uint64_t a_values[SIMD_MAX_VALS];
568 uint64_t b_values[SIMD_MAX_VALS];
569
585 simdUnpack( a, a_values, infmt, SIGNED );
586 simdUnpack( b, b_values, infmt, SIGNED );
570 simdUnpack(a, a_values, infmt, SIGNED);
571 simdUnpack(b, b_values, infmt, SIGNED);
587
572
588 for( i=0; i<nvals; i++ )
589 {
590 switch( mode )
591 {
573 for (int i = 0; i < nvals; i++) {
574 switch(mode) {
592 case MODE_X:
575 case MODE_X:
593 if( a_values[nvals-1-i] == FIXED_SMIN[infmt] &&
594 b_values[i] == FIXED_SMIN[infmt] )
595 {
576 if (a_values[nvals - 1 - i] == FIXED_SMIN[infmt] &&
577 b_values[i] == FIXED_SMIN[infmt]) {
596 result += FIXED_SMAX[outfmt];
597 ouflag = 1;
578 result += FIXED_SMAX[outfmt];
579 ouflag = 1;
580 } else {
581 result += a_values[nvals - 1 - i] * b_values[i] << 1;
598 }
582 }
599 else
600 result += a_values[nvals-1-i] * b_values[i] << 1;
601 break;
602 default:
583 break;
584 default:
603 if( a_values[i] == FIXED_SMIN[infmt] &&
604 b_values[i] == FIXED_SMIN[infmt] )
605 {
585 if (a_values[i] == FIXED_SMIN[infmt] &&
586 b_values[i] == FIXED_SMIN[infmt]) {
606 result += FIXED_SMAX[outfmt];
607 ouflag = 1;
587 result += FIXED_SMAX[outfmt];
588 ouflag = 1;
608 }
609 else
589 } else {
610 result += a_values[i] * b_values[i] << 1;
590 result += a_values[i] * b_values[i] << 1;
591 }
611 break;
612 }
613 }
614
592 break;
593 }
594 }
595
615 if( postsat )
616 {
617 if( outfmt == SIMD_FMT_L )
618 {
619 int signa = bits( dspac, 63, 63 );
620 int signb = bits( -result, 63, 63 );
596 if (postsat) {
597 if (outfmt == SIMD_FMT_L) {
598 int signa = bits(dspac, 63, 63);
599 int signb = bits(-result, 63, 63);
621
622 temp = dspac - result;
623
600
601 temp = dspac - result;
602
624 if( ( signa == signb ) &&
625 ( bits( temp, 63, 63 ) != signa ) )
626 {
603 if (signa == signb && bits(temp, 63, 63) != signa) {
627 ouflag = 1;
604 ouflag = 1;
628 if( signa )
605 if (signa)
629 dspac = FIXED_SMIN[outfmt];
630 else
631 dspac = FIXED_SMAX[outfmt];
606 dspac = FIXED_SMIN[outfmt];
607 else
608 dspac = FIXED_SMAX[outfmt];
632 }
633 else
609 } else {
634 dspac = temp;
610 dspac = temp;
611 }
612 } else {
613 dspac = dspSaturate(dspac - result, outfmt, SIGNED, &ouflag);
635 }
614 }
636 else
637 dspac = dspSaturate( dspac - result, outfmt, SIGNED, &ouflag );
638 }
639 else
615 } else {
640 dspac -= result;
616 dspac -= result;
617 }
641
618
642 if( ouflag )
643 *dspctl = insertBits( *dspctl, 16+ac, 16+ac, 1 );
619 if (ouflag)
620 *dspctl = insertBits(*dspctl, 16 + ac, 16 + ac, 1);
644
621
645 return( dspac );
622 return dspac;
646}
647
648int64_t
623}
624
625int64_t
649MipsISA::dspDpa( int64_t dspac, int32_t a, int32_t b, int32_t ac,
650 int32_t fmt, int32_t sign, int32_t mode )
626MipsISA::dspDpa(int64_t dspac, int32_t a, int32_t b, int32_t ac,
627 int32_t fmt, int32_t sign, int32_t mode)
651{
628{
652 int i = 0;
653 int nvals = SIMD_NVALS[fmt];
654 uint64_t a_values[SIMD_MAX_VALS];
655 uint64_t b_values[SIMD_MAX_VALS];
656
629 int nvals = SIMD_NVALS[fmt];
630 uint64_t a_values[SIMD_MAX_VALS];
631 uint64_t b_values[SIMD_MAX_VALS];
632
657 simdUnpack( a, a_values, fmt, sign );
658 simdUnpack( b, b_values, fmt, sign );
633 simdUnpack(a, a_values, fmt, sign);
634 simdUnpack(b, b_values, fmt, sign);
659
635
660 for( i=0; i<2; i++ )
661 {
662 switch( mode )
663 {
636 for (int i = 0; i < 2; i++) {
637 switch(mode) {
664 case MODE_L:
638 case MODE_L:
665 dspac += a_values[nvals-1-i] * b_values[nvals-1-i];
639 dspac += a_values[nvals - 1 - i] * b_values[nvals - 1 - i];
666 break;
667 case MODE_R:
640 break;
641 case MODE_R:
668 dspac += a_values[nvals-3-i] * b_values[nvals-3-i];
642 dspac += a_values[nvals - 3 - i] * b_values[nvals - 3 - i];
669 break;
670 case MODE_X:
643 break;
644 case MODE_X:
671 dspac += a_values[nvals-1-i] * b_values[i];
645 dspac += a_values[nvals - 1 - i] * b_values[i];
672 break;
673 }
674 }
675
676 return dspac;
677}
678
679int64_t
646 break;
647 }
648 }
649
650 return dspac;
651}
652
653int64_t
680MipsISA::dspDps( int64_t dspac, int32_t a, int32_t b, int32_t ac,
681 int32_t fmt, int32_t sign, int32_t mode )
654MipsISA::dspDps(int64_t dspac, int32_t a, int32_t b, int32_t ac,
655 int32_t fmt, int32_t sign, int32_t mode)
682{
656{
683 int i = 0;
684 int nvals = SIMD_NVALS[fmt];
685 uint64_t a_values[SIMD_MAX_VALS];
686 uint64_t b_values[SIMD_MAX_VALS];
687
657 int nvals = SIMD_NVALS[fmt];
658 uint64_t a_values[SIMD_MAX_VALS];
659 uint64_t b_values[SIMD_MAX_VALS];
660
688 simdUnpack( a, a_values, fmt, sign );
689 simdUnpack( b, b_values, fmt, sign );
661 simdUnpack(a, a_values, fmt, sign);
662 simdUnpack(b, b_values, fmt, sign);
690
663
691 for( i=0; i<2; i++ )
692 {
693 switch( mode )
694 {
664 for (int i = 0; i < 2; i++) {
665 switch(mode) {
695 case MODE_L:
666 case MODE_L:
696 dspac -= a_values[nvals-1-i] * b_values[nvals-1-i];
667 dspac -= a_values[nvals - 1 - i] * b_values[nvals - 1 - i];
697 break;
698 case MODE_R:
668 break;
669 case MODE_R:
699 dspac -= a_values[nvals-3-i] * b_values[nvals-3-i];
670 dspac -= a_values[nvals - 3 - i] * b_values[nvals - 3 - i];
700 break;
701 case MODE_X:
671 break;
672 case MODE_X:
702 dspac -= a_values[nvals-1-i] * b_values[i];
673 dspac -= a_values[nvals - 1 - i] * b_values[i];
703 break;
704 }
705 }
706
707 return dspac;
708}
709
710int64_t
674 break;
675 }
676 }
677
678 return dspac;
679}
680
681int64_t
711MipsISA::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 )
682MipsISA::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)
713{
684{
714 int i = 0;
715 int nvals = SIMD_NVALS[fmt-1];
685 int nvals = SIMD_NVALS[fmt - 1];
716 uint64_t a_values[SIMD_MAX_VALS];
717 uint64_t b_values[SIMD_MAX_VALS];
718 int64_t temp = 0;
719 uint32_t ouflag = 0;
720
686 uint64_t a_values[SIMD_MAX_VALS];
687 uint64_t b_values[SIMD_MAX_VALS];
688 int64_t temp = 0;
689 uint32_t ouflag = 0;
690
721 simdUnpack( a, a_values, fmt, SIGNED );
722 simdUnpack( b, b_values, fmt, SIGNED );
691 simdUnpack(a, a_values, fmt, SIGNED);
692 simdUnpack(b, b_values, fmt, SIGNED);
723
693
724 for( i=0; i<nvals; i++ )
725 {
726 switch( mode )
727 {
694 for (int i = 0; i < nvals; i++) {
695 switch(mode) {
728 case MODE_L:
696 case MODE_L:
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] )
731 {
732 temp = (int64_t)FIXED_SMAX[fmt-1];
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];
733 ouflag = 1;
734 }
735 break;
736 case MODE_R:
737 temp = a_values[i] * b_values[i] << 1;
701 ouflag = 1;
702 }
703 break;
704 case MODE_R:
705 temp = a_values[i] * b_values[i] << 1;
738 if( a_values[i] == FIXED_SMIN[fmt] && b_values[i] == FIXED_SMIN[fmt] )
739 {
740 temp = (int64_t)FIXED_SMAX[fmt-1];
706 if (a_values[i] == FIXED_SMIN[fmt] &&
707 b_values[i] == FIXED_SMIN[fmt]) {
708 temp = (int64_t)FIXED_SMAX[fmt - 1];
741 ouflag = 1;
742 }
743 break;
744 }
745
746 temp += dspac;
747
709 ouflag = 1;
710 }
711 break;
712 }
713
714 temp += dspac;
715
748 if( saturate )
749 temp = dspSaturate( temp, fmt-1, SIGNED, &ouflag );
750 if( ouflag )
751 *dspctl = insertBits( *dspctl, 16+ac, 16+ac, 1 );
716 if (saturate)
717 temp = dspSaturate(temp, fmt - 1, SIGNED, &ouflag);
718 if (ouflag)
719 *dspctl = insertBits(*dspctl, 16 + ac, 16 + ac, 1);
752 }
753
754 return temp;
755}
756
757int64_t
720 }
721
722 return temp;
723}
724
725int64_t
758MipsISA::dspMulsa( int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t fmt )
726MipsISA::dspMulsa(int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t fmt)
759{
760 uint64_t a_values[SIMD_MAX_VALS];
761 uint64_t b_values[SIMD_MAX_VALS];
762
727{
728 uint64_t a_values[SIMD_MAX_VALS];
729 uint64_t b_values[SIMD_MAX_VALS];
730
763 simdUnpack( a, a_values, fmt, SIGNED );
764 simdUnpack( b, b_values, fmt, SIGNED );
731 simdUnpack(a, a_values, fmt, SIGNED);
732 simdUnpack(b, b_values, fmt, SIGNED);
765
766 dspac += a_values[1] * b_values[1] - a_values[0] * b_values[0];
767
768 return dspac;
769}
770
771int64_t
733
734 dspac += a_values[1] * b_values[1] - a_values[0] * b_values[0];
735
736 return dspac;
737}
738
739int64_t
772MipsISA::dspMulsaq( int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t fmt, uint32_t *dspctl )
740MipsISA::dspMulsaq(int64_t dspac, int32_t a, int32_t b, int32_t ac,
741 int32_t fmt, uint32_t *dspctl)
773{
742{
774 int i = 0;
775 int nvals = SIMD_NVALS[fmt];
776 uint64_t a_values[SIMD_MAX_VALS];
777 uint64_t b_values[SIMD_MAX_VALS];
778 int64_t temp[2];
779 uint32_t ouflag = 0;
780
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];
747 uint32_t ouflag = 0;
748
781 simdUnpack( a, a_values, fmt, SIGNED );
782 simdUnpack( b, b_values, fmt, SIGNED );
749 simdUnpack(a, a_values, fmt, SIGNED);
750 simdUnpack(b, b_values, fmt, SIGNED);
783
751
784 for( i=nvals-1; i>-1; i-- )
785 {
752 for (int i = nvals - 1; i > -1; i--) {
786 temp[i] = a_values[i] * b_values[i] << 1;
753 temp[i] = a_values[i] * b_values[i] << 1;
787 if( a_values[i] == FIXED_SMIN[fmt] &&
788 b_values[i] == FIXED_SMIN[fmt] )
789 {
790 temp[i] = FIXED_SMAX[fmt-1];
754 if (a_values[i] == FIXED_SMIN[fmt] && b_values[i] == FIXED_SMIN[fmt]) {
755 temp[i] = FIXED_SMAX[fmt - 1];
791 ouflag = 1;
792 }
793 }
794
795 dspac += temp[1] - temp[0];
796
756 ouflag = 1;
757 }
758 }
759
760 dspac += temp[1] - temp[0];
761
797 if( ouflag )
798 *dspctl = insertBits( *dspctl, 16+ac, 16+ac, 1 );
762 if (ouflag)
763 *dspctl = insertBits(*dspctl, 16 + ac, 16 + ac, 1);
799
800 return dspac;
801}
802
803void
764
765 return dspac;
766}
767
768void
804MipsISA::dspCmp( int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op, uint32_t *dspctl )
769MipsISA::dspCmp(int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op,
770 uint32_t *dspctl)
805{
771{
806 int i = 0;
807 int nvals = SIMD_NVALS[fmt];
808 int ccond = 0;
809 uint64_t a_values[SIMD_MAX_VALS];
810 uint64_t b_values[SIMD_MAX_VALS];
811
772 int nvals = SIMD_NVALS[fmt];
773 int ccond = 0;
774 uint64_t a_values[SIMD_MAX_VALS];
775 uint64_t b_values[SIMD_MAX_VALS];
776
812 simdUnpack( a, a_values, fmt, sign );
813 simdUnpack( b, b_values, fmt, sign );
777 simdUnpack(a, a_values, fmt, sign);
778 simdUnpack(b, b_values, fmt, sign);
814
779
815 for( i=0; i<nvals; i++ )
816 {
780 for (int i = 0; i < nvals; i++) {
817 int cc = 0;
818
781 int cc = 0;
782
819 switch( op )
820 {
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;
783 switch(op) {
784 case CMP_EQ:
785 cc = (a_values[i] == b_values[i]);
786 break;
787 case CMP_LT:
788 cc = (a_values[i] < b_values[i]);
789 break;
790 case CMP_LE:
791 cc = (a_values[i] <= b_values[i]);
792 break;
824 }
825
793 }
794
826 ccond |= cc << ( DSP_CTL_POS[DSP_CCOND] + i );
795 ccond |= cc << (DSP_CTL_POS[DSP_CCOND] + i);
827 }
828
796 }
797
829 writeDSPControl( dspctl, ccond, 1<<DSP_CCOND );
798 writeDSPControl(dspctl, ccond, 1 << DSP_CCOND);
830}
831
832int32_t
799}
800
801int32_t
833MipsISA::dspCmpg( int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op )
802MipsISA::dspCmpg(int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op)
834{
803{
835 int i = 0;
836 int nvals = SIMD_NVALS[fmt];
837 int32_t result = 0;
838 uint64_t a_values[SIMD_MAX_VALS];
839 uint64_t b_values[SIMD_MAX_VALS];
840
804 int nvals = SIMD_NVALS[fmt];
805 int32_t result = 0;
806 uint64_t a_values[SIMD_MAX_VALS];
807 uint64_t b_values[SIMD_MAX_VALS];
808
841 simdUnpack( a, a_values, fmt, sign );
842 simdUnpack( b, b_values, fmt, sign );
809 simdUnpack(a, a_values, fmt, sign);
810 simdUnpack(b, b_values, fmt, sign);
843
811
844 for( i=0; i<nvals; i++ )
845 {
812 for (int i = 0; i < nvals; i++) {
846 int cc = 0;
847
813 int cc = 0;
814
848 switch( op )
849 {
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;
815 switch(op) {
816 case CMP_EQ:
817 cc = (a_values[i] == b_values[i]);
818 break;
819 case CMP_LT:
820 cc = (a_values[i] < b_values[i]);
821 break;
822 case CMP_LE:
823 cc = (a_values[i] <= b_values[i]);
824 break;
853 }
854
855 result |= cc << i;
856 }
857
825 }
826
827 result |= cc << i;
828 }
829
858 return( result );
830 return result;
859}
860
861int32_t
831}
832
833int32_t
862MipsISA::dspCmpgd( int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op, uint32_t *dspctl )
834MipsISA::dspCmpgd(int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op,
835 uint32_t *dspctl)
863{
836{
864 int i = 0;;
865 int nvals = SIMD_NVALS[fmt];
866 int32_t result = 0;
867 int ccond = 0;
868 uint64_t a_values[SIMD_MAX_VALS];
869 uint64_t b_values[SIMD_MAX_VALS];
870
837 int nvals = SIMD_NVALS[fmt];
838 int32_t result = 0;
839 int ccond = 0;
840 uint64_t a_values[SIMD_MAX_VALS];
841 uint64_t b_values[SIMD_MAX_VALS];
842
871 simdUnpack( a, a_values, fmt, sign );
872 simdUnpack( b, b_values, fmt, sign );
843 simdUnpack(a, a_values, fmt, sign);
844 simdUnpack(b, b_values, fmt, sign);
873
845
874 for( i=0; i<nvals; i++ )
875 {
876 int cc = 0;;
846 for (int i = 0; i < nvals; i++) {
847 int cc = 0;
877
848
878 switch( op )
879 {
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;
849 switch(op) {
850 case CMP_EQ:
851 cc = (a_values[i] == b_values[i]);
852 break;
853 case CMP_LT:
854 cc = (a_values[i] < b_values[i]);
855 break;
856 case CMP_LE:
857 cc = (a_values[i] <= b_values[i]);
858 break;
883 }
884
885 result |= cc << i;
859 }
860
861 result |= cc << i;
886 ccond |= cc << ( DSP_CTL_POS[DSP_CCOND] + i );
862 ccond |= cc << (DSP_CTL_POS[DSP_CCOND] + i);
887 }
888
863 }
864
889 writeDSPControl( dspctl, ccond, 1<<DSP_CCOND );
865 writeDSPControl(dspctl, ccond, 1 << DSP_CCOND);
890
866
891 return( result );
867 return result;
892}
893
894int32_t
868}
869
870int32_t
895MipsISA::dspPrece( int32_t a, int32_t infmt, int32_t insign, int32_t outfmt, int32_t outsign, int32_t mode )
871MipsISA::dspPrece(int32_t a, int32_t infmt, int32_t insign, int32_t outfmt,
872 int32_t outsign, int32_t mode)
896{
873{
897 int i = 0;
898 int sa = 0;
899 int ninvals = SIMD_NVALS[infmt];
900 int noutvals = SIMD_NVALS[outfmt];
901 int32_t result;
902 uint64_t in_values[SIMD_MAX_VALS];
903 uint64_t out_values[SIMD_MAX_VALS];
904
874 int sa = 0;
875 int ninvals = SIMD_NVALS[infmt];
876 int noutvals = SIMD_NVALS[outfmt];
877 int32_t result;
878 uint64_t in_values[SIMD_MAX_VALS];
879 uint64_t out_values[SIMD_MAX_VALS];
880
905 if( insign == SIGNED && outsign == SIGNED )
881 if (insign == SIGNED && outsign == SIGNED)
906 sa = SIMD_NBITS[infmt];
882 sa = SIMD_NBITS[infmt];
907 else if( insign == UNSIGNED && outsign == SIGNED )
883 else if (insign == UNSIGNED && outsign == SIGNED)
908 sa = SIMD_NBITS[infmt] - 1;
884 sa = SIMD_NBITS[infmt] - 1;
909 else if( insign == UNSIGNED && outsign == UNSIGNED )
885 else if (insign == UNSIGNED && outsign == UNSIGNED)
910 sa = 0;
911
886 sa = 0;
887
912 simdUnpack( a, in_values, infmt, insign );
888 simdUnpack(a, in_values, infmt, insign);
913
889
914 for( i=0; i<noutvals; i++ )
915 {
916 switch( mode )
917 {
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;
890 for (int i = 0; i<noutvals; i++) {
891 switch(mode) {
892 case MODE_L:
893 out_values[i] = in_values[i + (ninvals >> 1)] << sa;
894 break;
895 case MODE_R:
896 out_values[i] = in_values[i] << sa;
897 break;
898 case MODE_LA:
899 out_values[i] = in_values[(i << 1) + 1] << sa;
900 break;
901 case MODE_RA:
902 out_values[i] = in_values[i << 1] << sa;
903 break;
922 }
923 }
924
904 }
905 }
906
925 simdPack( out_values, &result, outfmt );
907 simdPack(out_values, &result, outfmt);
926
908
927 return( result );
909 return result;
928}
929
930int32_t
910}
911
912int32_t
931MipsISA::dspPrecrqu( int32_t a, int32_t b, uint32_t *dspctl )
913MipsISA::dspPrecrqu(int32_t a, int32_t b, uint32_t *dspctl)
932{
914{
933 int i = 0;
934 uint64_t a_values[SIMD_MAX_VALS];
935 uint64_t b_values[SIMD_MAX_VALS];
936 uint64_t r_values[SIMD_MAX_VALS];
937 uint32_t ouflag = 0;
938 int32_t result = 0;
939
915 uint64_t a_values[SIMD_MAX_VALS];
916 uint64_t b_values[SIMD_MAX_VALS];
917 uint64_t r_values[SIMD_MAX_VALS];
918 uint32_t ouflag = 0;
919 int32_t result = 0;
920
940 simdUnpack( a, a_values, SIMD_FMT_PH, SIGNED );
941 simdUnpack( b, b_values, SIMD_FMT_PH, SIGNED );
921 simdUnpack(a, a_values, SIMD_FMT_PH, SIGNED);
922 simdUnpack(b, b_values, SIMD_FMT_PH, SIGNED);
942
923
943 for( i=0; i<2; i++ )
944 {
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 );
924 for (int i = 0; i<2; i++) {
925 r_values[i] =
926 dspSaturate((int64_t)b_values[i] >> SIMD_NBITS[SIMD_FMT_QB] - 1,
927 SIMD_FMT_QB, UNSIGNED, &ouflag);
928 r_values[i + 2] =
929 dspSaturate((int64_t)a_values[i] >> SIMD_NBITS[SIMD_FMT_QB] - 1,
930 SIMD_FMT_QB, UNSIGNED, &ouflag);
949 }
950
931 }
932
951 simdPack( r_values, &result, SIMD_FMT_QB );
933 simdPack(r_values, &result, SIMD_FMT_QB);
952
934
953 if( ouflag )
954 *dspctl = insertBits( *dspctl, 22, 22, 1 );
935 if (ouflag)
936 *dspctl = insertBits(*dspctl, 22, 22, 1);
955
956 return result;
957}
958
959int32_t
937
938 return result;
939}
940
941int32_t
960MipsISA::dspPrecrq( int32_t a, int32_t b, int32_t fmt, uint32_t *dspctl )
942MipsISA::dspPrecrq(int32_t a, int32_t b, int32_t fmt, uint32_t *dspctl)
961{
962 uint64_t a_values[SIMD_MAX_VALS];
963 uint64_t b_values[SIMD_MAX_VALS];
964 uint64_t r_values[SIMD_MAX_VALS];
965 uint32_t ouflag = 0;
966 int32_t result;
967
943{
944 uint64_t a_values[SIMD_MAX_VALS];
945 uint64_t b_values[SIMD_MAX_VALS];
946 uint64_t r_values[SIMD_MAX_VALS];
947 uint32_t ouflag = 0;
948 int32_t result;
949
968 simdUnpack( a, a_values, fmt, SIGNED );
969 simdUnpack( b, b_values, fmt, SIGNED );
950 simdUnpack(a, a_values, fmt, SIGNED);
951 simdUnpack(b, b_values, fmt, SIGNED);
970
952
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 );
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);
975
957
976 simdPack( r_values, &result, fmt+1 );
958 simdPack(r_values, &result, fmt + 1);
977
959
978 if( ouflag )
979 *dspctl = insertBits( *dspctl, 22, 22, 1 );
960 if (ouflag)
961 *dspctl = insertBits(*dspctl, 22, 22, 1);
980
981 return result;
982}
983
984int32_t
962
963 return result;
964}
965
966int32_t
985MipsISA::dspPrecrSra( int32_t a, int32_t b, int32_t sa, int32_t fmt, int32_t round )
967MipsISA::dspPrecrSra(int32_t a, int32_t b, int32_t sa, int32_t fmt,
968 int32_t round)
986{
969{
987 int i = 0;
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];
992 int32_t result = 0;
993
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];
974 int32_t result = 0;
975
994 simdUnpack( a, a_values, fmt, SIGNED );
995 simdUnpack( b, b_values, fmt, SIGNED );
976 simdUnpack(a, a_values, fmt, SIGNED);
977 simdUnpack(b, b_values, fmt, SIGNED);
996
978
997 for( i=0; i<nvals; i++ )
998 {
999 if( round )
1000 {
1001 c_values[i] = addHalfLsb( b_values[i], sa ) >> sa;
1002 c_values[i+1] = addHalfLsb( a_values[i], sa ) >> sa;
1003 }
1004 else
1005 {
979 for (int i = 0; i < nvals; i++) {
980 if (round) {
981 c_values[i] = addHalfLsb(b_values[i], sa) >> sa;
982 c_values[i + 1] = addHalfLsb(a_values[i], sa) >> sa;
983 } else {
1006 c_values[i] = b_values[i] >> sa;
984 c_values[i] = b_values[i] >> sa;
1007 c_values[i+1] = a_values[i] >> sa;
985 c_values[i + 1] = a_values[i] >> sa;
1008 }
1009 }
1010
986 }
987 }
988
1011 simdPack( c_values, &result, fmt+1 );
989 simdPack(c_values, &result, fmt + 1);
1012
1013 return result;
1014}
1015
1016int32_t
990
991 return result;
992}
993
994int32_t
1017MipsISA::dspPick( int32_t a, int32_t b, int32_t fmt, uint32_t *dspctl )
995MipsISA::dspPick(int32_t a, int32_t b, int32_t fmt, uint32_t *dspctl)
1018{
996{
1019 int i = 0;
1020 int nvals = SIMD_NVALS[fmt];
1021 int32_t result;
1022 uint64_t a_values[SIMD_MAX_VALS];
1023 uint64_t b_values[SIMD_MAX_VALS];
1024 uint64_t c_values[SIMD_MAX_VALS];
1025
997 int nvals = SIMD_NVALS[fmt];
998 int32_t result;
999 uint64_t a_values[SIMD_MAX_VALS];
1000 uint64_t b_values[SIMD_MAX_VALS];
1001 uint64_t c_values[SIMD_MAX_VALS];
1002
1026 simdUnpack( a, a_values, fmt, UNSIGNED );
1027 simdUnpack( b, b_values, fmt, UNSIGNED );
1003 simdUnpack(a, a_values, fmt, UNSIGNED);
1004 simdUnpack(b, b_values, fmt, UNSIGNED);
1028
1005
1029 for( i=0; i<nvals; i++ )
1030 {
1006 for (int i = 0; i < nvals; i++) {
1031 int condbit = DSP_CTL_POS[DSP_CCOND] + i;
1007 int condbit = DSP_CTL_POS[DSP_CCOND] + i;
1032 if( bits( *dspctl, condbit, condbit ) == 1 )
1008 if (bits(*dspctl, condbit, condbit) == 1)
1033 c_values[i] = a_values[i];
1034 else
1035 c_values[i] = b_values[i];
1036 }
1037
1009 c_values[i] = a_values[i];
1010 else
1011 c_values[i] = b_values[i];
1012 }
1013
1038 simdPack( c_values, &result, fmt );
1014 simdPack(c_values, &result, fmt);
1039
1015
1040 return( result );
1016 return result;
1041}
1042
1043int32_t
1017}
1018
1019int32_t
1044MipsISA::dspPack( int32_t a, int32_t b, int32_t fmt )
1020MipsISA::dspPack(int32_t a, int32_t b, int32_t fmt)
1045{
1046 int32_t result;
1047 uint64_t a_values[SIMD_MAX_VALS];
1048 uint64_t b_values[SIMD_MAX_VALS];
1049 uint64_t c_values[SIMD_MAX_VALS];
1050
1021{
1022 int32_t result;
1023 uint64_t a_values[SIMD_MAX_VALS];
1024 uint64_t b_values[SIMD_MAX_VALS];
1025 uint64_t c_values[SIMD_MAX_VALS];
1026
1051 simdUnpack( a, a_values, fmt, UNSIGNED );
1052 simdUnpack( b, b_values, fmt, UNSIGNED );
1027 simdUnpack(a, a_values, fmt, UNSIGNED);
1028 simdUnpack(b, b_values, fmt, UNSIGNED);
1053
1054 c_values[0] = b_values[1];
1055 c_values[1] = a_values[0];
1056
1029
1030 c_values[0] = b_values[1];
1031 c_values[1] = a_values[0];
1032
1057 simdPack( c_values, &result, fmt );
1033 simdPack(c_values, &result, fmt);
1058
1034
1059 return( result );
1035 return result;
1060}
1061
1062int32_t
1036}
1037
1038int32_t
1063MipsISA::dspExtr( int64_t dspac, int32_t fmt, int32_t sa, int32_t round, int32_t saturate, uint32_t *dspctl )
1039MipsISA::dspExtr(int64_t dspac, int32_t fmt, int32_t sa, int32_t round,
1040 int32_t saturate, uint32_t *dspctl)
1064{
1065 int32_t result = 0;
1066 uint32_t ouflag = 0;
1067 int64_t temp = 0;
1068
1041{
1042 int32_t result = 0;
1043 uint32_t ouflag = 0;
1044 int64_t temp = 0;
1045
1069 sa = bits( sa, 4, 0 );
1046 sa = bits(sa, 4, 0);
1070
1047
1071 if( sa > 0 )
1072 {
1073 if( round )
1074 {
1075 temp = (int64_t)addHalfLsb( dspac, sa );
1048 if (sa > 0) {
1049 if (round) {
1050 temp = (int64_t)addHalfLsb(dspac, sa);
1076
1051
1077 if( dspac > 0 && temp < 0 )
1078 {
1052 if (dspac > 0 && temp < 0) {
1079 ouflag = 1;
1053 ouflag = 1;
1080 if( saturate )
1054 if (saturate)
1081 temp = FIXED_SMAX[SIMD_FMT_L];
1082 }
1083 temp = temp >> sa;
1055 temp = FIXED_SMAX[SIMD_FMT_L];
1056 }
1057 temp = temp >> sa;
1084 }
1085 else
1058 } else {
1086 temp = dspac >> sa;
1059 temp = dspac >> sa;
1087 }
1088 else
1060 }
1061 } else {
1089 temp = dspac;
1062 temp = dspac;
1063 }
1090
1064
1091 dspac = checkOverflow( dspac, fmt, SIGNED, &ouflag );
1065 dspac = checkOverflow(dspac, fmt, SIGNED, &ouflag);
1092
1066
1093 if( ouflag )
1094 {
1095 *dspctl = insertBits( *dspctl, 23, 23, ouflag );
1067 if (ouflag) {
1068 *dspctl = insertBits(*dspctl, 23, 23, ouflag);
1096
1069
1097 if( saturate )
1098 result = (int32_t)dspSaturate( temp, fmt, SIGNED, &ouflag );
1070 if (saturate)
1071 result = (int32_t)dspSaturate(temp, fmt, SIGNED, &ouflag);
1099 else
1100 result = (int32_t)temp;
1072 else
1073 result = (int32_t)temp;
1101 }
1102 else
1074 } else {
1103 result = (int32_t)temp;
1075 result = (int32_t)temp;
1076 }
1104
1077
1105 return( result );
1078 return result;
1106}
1107
1108int32_t
1079}
1080
1081int32_t
1109MipsISA::dspExtp( int64_t dspac, int32_t size, uint32_t *dspctl )
1082MipsISA::dspExtp(int64_t dspac, int32_t size, uint32_t *dspctl)
1110{
1111 int32_t pos = 0;
1112 int32_t result = 0;
1113
1083{
1084 int32_t pos = 0;
1085 int32_t result = 0;
1086
1114 pos = bits( *dspctl, 5, 0 );
1115 size = bits( size, 4, 0 );
1087 pos = bits(*dspctl, 5, 0);
1088 size = bits(size, 4, 0);
1116
1089
1117 if( pos - (size+1) >= -1 )
1118 {
1119 result = bits( dspac, pos, pos-size );
1120 *dspctl = insertBits( *dspctl, 14, 14, 0 );
1121 }
1122 else
1123 {
1090 if (pos - (size + 1) >= -1) {
1091 result = bits(dspac, pos, pos - size);
1092 *dspctl = insertBits(*dspctl, 14, 14, 0);
1093 } else {
1124 result = 0;
1094 result = 0;
1125 *dspctl = insertBits( *dspctl, 14, 14, 1 );
1095 *dspctl = insertBits(*dspctl, 14, 14, 1);
1126 }
1127
1096 }
1097
1128 return( result );
1098 return result;
1129}
1130
1131int32_t
1099}
1100
1101int32_t
1132MipsISA::dspExtpd( int64_t dspac, int32_t size, uint32_t *dspctl )
1102MipsISA::dspExtpd(int64_t dspac, int32_t size, uint32_t *dspctl)
1133{
1134 int32_t pos = 0;
1135 int32_t result = 0;
1136
1103{
1104 int32_t pos = 0;
1105 int32_t result = 0;
1106
1137 pos = bits( *dspctl, 5, 0 );
1138 size = bits( size, 4, 0 );
1107 pos = bits(*dspctl, 5, 0);
1108 size = bits(size, 4, 0);
1139
1109
1140 if( pos - (size+1) >= -1 )
1141 {
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 );
1148 }
1149 else
1150 {
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);
1117 } else {
1151 result = 0;
1118 result = 0;
1152 *dspctl = insertBits( *dspctl, 14, 14, 1 );
1119 *dspctl = insertBits(*dspctl, 14, 14, 1);
1153 }
1154
1120 }
1121
1155 return( result );
1122 return result;
1156}
1157
1158void
1123}
1124
1125void
1159MipsISA::simdPack( uint64_t *values_ptr, int32_t *reg, int32_t fmt )
1126MipsISA::simdPack(uint64_t *values_ptr, int32_t *reg, int32_t fmt)
1160{
1127{
1161 int i = 0;
1162 int nvals = SIMD_NVALS[fmt];
1163 int nbits = SIMD_NBITS[fmt];
1164
1165 *reg = 0;
1166
1128 int nvals = SIMD_NVALS[fmt];
1129 int nbits = SIMD_NBITS[fmt];
1130
1131 *reg = 0;
1132
1167 for( i=0; i<nvals; i++ )
1168 *reg |= (int32_t)bits( values_ptr[i], nbits-1, 0 ) << nbits*i;
1133 for (int i = 0; i < nvals; i++)
1134 *reg |= (int32_t)bits(values_ptr[i], nbits - 1, 0) << nbits * i;
1169}
1170
1171void
1135}
1136
1137void
1172MipsISA::simdUnpack( int32_t reg, uint64_t *values_ptr, int32_t fmt, int32_t sign )
1138MipsISA::simdUnpack(int32_t reg, uint64_t *values_ptr, int32_t fmt, int32_t sign)
1173{
1139{
1174 int i = 0;
1175 int nvals = SIMD_NVALS[fmt];
1176 int nbits = SIMD_NBITS[fmt];
1177
1140 int nvals = SIMD_NVALS[fmt];
1141 int nbits = SIMD_NBITS[fmt];
1142
1178 switch( sign )
1179 {
1180 case SIGNED:
1181 for( i=0; i<nvals; i++ )
1182 {
1183 values_ptr[i] = (uint64_t)bits( reg, nbits*(i+1)-1, nbits*i );
1184 values_ptr[i] = signExtend( values_ptr[i], fmt );
1143 switch(sign) {
1144 case SIGNED:
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);
1185 }
1186 break;
1148 }
1149 break;
1187 case UNSIGNED:
1188 for( i=0; i<nvals; i++ )
1189 {
1190 values_ptr[i] = (uint64_t)bits( reg, nbits*(i+1)-1, nbits*i );
1150 case UNSIGNED:
1151 for (int i = 0; i < nvals; i++) {
1152 values_ptr[i] =
1153 (uint64_t)bits(reg, nbits * (i + 1) - 1, nbits * i);
1191 }
1192 break;
1193 }
1194}
1195
1196void
1154 }
1155 break;
1156 }
1157}
1158
1159void
1197MipsISA::writeDSPControl( uint32_t *dspctl, uint32_t value, uint32_t mask )
1160MipsISA::writeDSPControl(uint32_t *dspctl, uint32_t value, uint32_t mask)
1198{
1199 uint32_t fmask = 0;
1200
1161{
1162 uint32_t fmask = 0;
1163
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];
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];
1207
1208 *dspctl &= ~fmask;
1209 value &= fmask;
1210 *dspctl |= value;
1211}
1212
1213uint32_t
1170
1171 *dspctl &= ~fmask;
1172 value &= fmask;
1173 *dspctl |= value;
1174}
1175
1176uint32_t
1214MipsISA::readDSPControl( uint32_t *dspctl, uint32_t mask )
1177MipsISA::readDSPControl(uint32_t *dspctl, uint32_t mask)
1215{
1216 uint32_t fmask = 0;
1217
1178{
1179 uint32_t fmask = 0;
1180
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];
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];
1224
1187
1225 return( *dspctl & fmask );
1188 return *dspctl & fmask;
1226}
1189}