Revision 7d08d856 target-ppc/translate.c

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