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} |