Revision b8abbbe8 target-mips/dsp_helper.c
b/target-mips/dsp_helper.c | ||
---|---|---|
484 | 484 |
return (temp >> 1) & 0x00FF; |
485 | 485 |
} |
486 | 486 |
|
487 |
static inline int64_t mipsdsp_rashift_short_acc(int32_t ac, |
|
488 |
int32_t shift, |
|
489 |
CPUMIPSState *env) |
|
490 |
{ |
|
491 |
int32_t sign, temp31; |
|
492 |
int64_t temp, acc; |
|
493 |
|
|
494 |
sign = (env->active_tc.HI[ac] >> 31) & 0x01; |
|
495 |
acc = ((int64_t)env->active_tc.HI[ac] << 32) | |
|
496 |
((int64_t)env->active_tc.LO[ac] & 0xFFFFFFFF); |
|
497 |
if (shift == 0) { |
|
498 |
temp = acc; |
|
499 |
} else { |
|
500 |
if (sign == 0) { |
|
501 |
temp = (((int64_t)0x01 << (32 - shift + 1)) - 1) & (acc >> shift); |
|
502 |
} else { |
|
503 |
temp = ((((int64_t)0x01 << (shift + 1)) - 1) << (32 - shift)) | |
|
504 |
(acc >> shift); |
|
505 |
} |
|
506 |
} |
|
507 |
|
|
508 |
temp31 = (temp >> 31) & 0x01; |
|
509 |
if (sign != temp31) { |
|
510 |
set_DSPControl_overflow_flag(1, 23, env); |
|
511 |
} |
|
512 |
|
|
513 |
return temp; |
|
514 |
} |
|
515 |
|
|
516 | 487 |
/* 128 bits long. p[0] is LO, p[1] is HI. */ |
517 | 488 |
static inline void mipsdsp_rndrashift_short_acc(int64_t *p, |
518 | 489 |
int32_t ac, |
... | ... | |
3407 | 3378 |
int32_t tempI; |
3408 | 3379 |
int64_t tempDL[2]; |
3409 | 3380 |
|
3410 |
shift = shift & 0x0F;
|
|
3381 |
shift = shift & 0x1F;
|
|
3411 | 3382 |
|
3412 | 3383 |
mipsdsp_rndrashift_short_acc(tempDL, ac, shift, env); |
3413 | 3384 |
if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && |
... | ... | |
3435 | 3406 |
{ |
3436 | 3407 |
int64_t tempDL[2]; |
3437 | 3408 |
|
3438 |
shift = shift & 0x0F;
|
|
3409 |
shift = shift & 0x1F;
|
|
3439 | 3410 |
|
3440 | 3411 |
mipsdsp_rndrashift_short_acc(tempDL, ac, shift, env); |
3441 | 3412 |
if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && |
... | ... | |
3462 | 3433 |
int32_t tempI, temp64; |
3463 | 3434 |
int64_t tempDL[2]; |
3464 | 3435 |
|
3465 |
shift = shift & 0x0F;
|
|
3436 |
shift = shift & 0x1F;
|
|
3466 | 3437 |
|
3467 | 3438 |
mipsdsp_rndrashift_short_acc(tempDL, ac, shift, env); |
3468 | 3439 |
if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && |
... | ... | |
3645 | 3616 |
target_ulong helper_extr_s_h(target_ulong ac, target_ulong shift, |
3646 | 3617 |
CPUMIPSState *env) |
3647 | 3618 |
{ |
3648 |
int64_t temp; |
|
3619 |
int64_t temp, acc; |
|
3620 |
|
|
3621 |
shift = shift & 0x1F; |
|
3622 |
|
|
3623 |
acc = ((int64_t)env->active_tc.HI[ac] << 32) | |
|
3624 |
((int64_t)env->active_tc.LO[ac] & 0xFFFFFFFF); |
|
3649 | 3625 |
|
3650 |
shift = shift & 0x0F;
|
|
3626 |
temp = acc >> shift;
|
|
3651 | 3627 |
|
3652 |
temp = mipsdsp_rashift_short_acc(ac, shift, env); |
|
3653 | 3628 |
if (temp > (int64_t)0x7FFF) { |
3654 | 3629 |
temp = 0x00007FFF; |
3655 | 3630 |
set_DSPControl_overflow_flag(1, 23, env); |
Also available in: Unified diff