Revision 7d08d856

b/target-ppc/fpu_helper.c
430 430

  
431 431
void helper_store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask)
432 432
{
433
    /*
434
     * We use only the 32 LSB of the incoming fpr
435
     */
436
    uint32_t prev, new;
433
    target_ulong prev, new;
437 434
    int i;
438 435

  
439 436
    prev = env->fpscr;
440
    new = (uint32_t)arg;
441
    new &= ~0x60000000;
442
    new |= prev & 0x60000000;
443
    for (i = 0; i < 8; i++) {
437
    new = (target_ulong)arg;
438
    new &= ~0x60000000LL;
439
    new |= prev & 0x60000000LL;
440
    for (i = 0; i < sizeof(target_ulong) * 2; i++) {
444 441
        if (mask & (1 << i)) {
445
            env->fpscr &= ~(0xF << (4 * i));
446
            env->fpscr |= new & (0xF << (4 * i));
442
            env->fpscr &= ~(0xFLL << (4 * i));
443
            env->fpscr |= new & (0xFLL << (4 * i));
447 444
        }
448 445
    }
449 446
    /* Update VX and FEX */
b/target-ppc/translate.c
202 202
    int spe_enabled;
203 203
    ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
204 204
    int singlestep_enabled;
205
    uint64_t insns_flags;
206
    uint64_t insns_flags2;
205 207
} DisasContext;
206 208

  
207 209
/* True when active word size < size of target_long.  */
......
423 425
EXTRACT_HELPER(TO, 21, 5);
424 426

  
425 427
EXTRACT_HELPER(CRM, 12, 8);
426
EXTRACT_HELPER(FM, 17, 8);
427 428
EXTRACT_HELPER(SR, 16, 4);
429

  
430
/* mtfsf/mtfsfi */
431
EXTRACT_HELPER(FPBF, 19, 3);
428 432
EXTRACT_HELPER(FPIMM, 12, 4);
433
EXTRACT_HELPER(FPL, 21, 1);
434
EXTRACT_HELPER(FPFLM, 17, 8);
435
EXTRACT_HELPER(FPW, 16, 1);
429 436

  
430 437
/***                            Jump target decoding                       ***/
431 438
/* Displacement */
......
2360 2367
static void gen_mtfsf(DisasContext *ctx)
2361 2368
{
2362 2369
    TCGv_i32 t0;
2363
    int L = ctx->opcode & 0x02000000;
2370
    int flm, l, w;
2364 2371

  
2365 2372
    if (unlikely(!ctx->fpu_enabled)) {
2366 2373
        gen_exception(ctx, POWERPC_EXCP_FPU);
2367 2374
        return;
2368 2375
    }
2376
    flm = FPFLM(ctx->opcode);
2377
    l = FPL(ctx->opcode);
2378
    w = FPW(ctx->opcode);
2379
    if (unlikely(w & !(ctx->insns_flags2 & PPC2_ISA205))) {
2380
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2381
        return;
2382
    }
2369 2383
    /* NIP cannot be restored if the memory exception comes from an helper */
2370 2384
    gen_update_nip(ctx, ctx->nip - 4);
2371 2385
    gen_reset_fpstatus();
2372
    if (L)
2373
        t0 = tcg_const_i32(0xff);
2374
    else
2375
        t0 = tcg_const_i32(FM(ctx->opcode));
2386
    if (l) {
2387
        t0 = tcg_const_i32((ctx->insns_flags2 & PPC2_ISA205) ? 0xffff : 0xff);
2388
    } else {
2389
        t0 = tcg_const_i32(flm << (w * 8));
2390
    }
2376 2391
    gen_helper_store_fpscr(cpu_env, cpu_fpr[rB(ctx->opcode)], t0);
2377 2392
    tcg_temp_free_i32(t0);
2378 2393
    if (unlikely(Rc(ctx->opcode) != 0)) {
......
2386 2401
/* mtfsfi */
2387 2402
static void gen_mtfsfi(DisasContext *ctx)
2388 2403
{
2389
    int bf, sh;
2404
    int bf, sh, w;
2390 2405
    TCGv_i64 t0;
2391 2406
    TCGv_i32 t1;
2392 2407

  
......
2394 2409
        gen_exception(ctx, POWERPC_EXCP_FPU);
2395 2410
        return;
2396 2411
    }
2397
    bf = crbD(ctx->opcode) >> 2;
2398
    sh = 7 - bf;
2412
    w = FPW(ctx->opcode);
2413
    bf = FPBF(ctx->opcode);
2414
    if (unlikely(w & !(ctx->insns_flags2 & PPC2_ISA205))) {
2415
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2416
        return;
2417
    }
2418
    sh = (8 * w) + 7 - bf;
2399 2419
    /* NIP cannot be restored if the memory exception comes from an helper */
2400 2420
    gen_update_nip(ctx, ctx->nip - 4);
2401 2421
    gen_reset_fpstatus();
2402
    t0 = tcg_const_i64(FPIMM(ctx->opcode) << (4 * sh));
2422
    t0 = tcg_const_i64(((uint64_t)FPIMM(ctx->opcode)) << (4 * sh));
2403 2423
    t1 = tcg_const_i32(1 << sh);
2404 2424
    gen_helper_store_fpscr(cpu_env, t0, t1);
2405 2425
    tcg_temp_free_i64(t0);
......
8689 8709
GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT),
8690 8710
GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT),
8691 8711
GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT),
8692
GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x00010000, PPC_FLOAT),
8693
GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT),
8712
GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x00000000, PPC_FLOAT),
8713
GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006e0800, PPC_FLOAT),
8694 8714
#if defined(TARGET_PPC64)
8695 8715
GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B),
8696 8716
GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX),
......
9728 9748
    ctx.exception = POWERPC_EXCP_NONE;
9729 9749
    ctx.spr_cb = env->spr_cb;
9730 9750
    ctx.mem_idx = env->mmu_idx;
9751
    ctx.insns_flags = env->insns_flags;
9752
    ctx.insns_flags2 = env->insns_flags2;
9731 9753
    ctx.access_type = -1;
9732 9754
    ctx.le_mode = env->hflags & (1 << MSR_LE) ? 1 : 0;
9733 9755
#if defined(TARGET_PPC64)

Also available in: Unified diff