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