Revision 8379bfdb

b/target-s390x/fpu_helper.c
577 577
    handle_exceptions(env, GETPC());
578 578
    return RET128(ret);
579 579
}
580

  
581
/* set fpc */
582
void HELPER(sfpc)(CPUS390XState *env, uint64_t fpc)
583
{
584
    static const int rnd[4] = {
585
        float_round_nearest_even,
586
        float_round_to_zero,
587
        float_round_up,
588
        float_round_down
589
    };
590

  
591
    /* Install everything in the main FPC.  */
592
    env->fpc = fpc;
593

  
594
    /* Install the rounding mode in the shadow fpu_status.  */
595
    set_float_rounding_mode(rnd[fpc & 3], &env->fpu_status);
596
}
b/target-s390x/helper.h
78 78
DEF_HELPER_4(tr, void, env, i32, i64, i64)
79 79
DEF_HELPER_3(cksm, void, env, i32, i32)
80 80
DEF_HELPER_FLAGS_5(calc_cc, TCG_CALL_NO_RWG_SE, i32, env, i32, i64, i64, i64)
81
DEF_HELPER_FLAGS_2(sfpc, TCG_CALL_NO_RWG, void, env, i64)
81 82

  
82 83
#ifndef CONFIG_USER_ONLY
83 84
DEF_HELPER_3(servc, i32, env, i32, i64)
b/target-s390x/insn-data.def
351 351
    C(0xb375, LZDR,    RRE,   Z,   0, 0, 0, f1, zero, 0)
352 352
    C(0xb376, LZXR,    RRE,   Z,   0, 0, 0, x1, zero2, 0)
353 353

  
354
/* LOAD FPC */
355
    C(0xb29d, LFPC,    S,     Z,   0, m2_32u, 0, 0, sfpc, 0)
356

  
354 357
/* LOAD LENGTHENED */
355 358
    C(0xb304, LDEBR,   RRE,   Z,   0, e2, f1, 0, ldeb, 0)
356 359
    C(0xb305, LXDBR,   RRE,   Z,   0, f2_o, x1, 0, lxdb, 0)
......
455 458
    C(0xeb1d, RLL,     RSY_a, Z,   r3_o, sh32, new, r1_32, rll32, 0)
456 459
    C(0xeb1c, RLLG,    RSY_a, Z,   r3_o, sh64, r1, 0, rll64, 0)
457 460

  
461
/* SET FPC */
462
    C(0xb384, SFPC,    RRE,   Z,   0, r1_o, 0, 0, sfpc, 0)
463

  
458 464
/* SHIFT LEFT SINGLE */
459 465
    D(0x8b00, SLA,     RS_a,  Z,   r1, sh32, new, r1_32, sla, 0, 31)
460 466
    D(0xebdd, SLAK,    RSY_a, DO,  r3, sh32, new, r1_32, sla, 0, 31)
b/target-s390x/translate.c
1337 1337
        tcg_temp_free_i32(tmp32_1);
1338 1338
        tcg_temp_free_i32(tmp32_2);
1339 1339
        break;
1340
    case 0x9d: /* LFPC      D2(B2)   [S] */
1341
        decode_rs(s, insn, &r1, &r3, &b2, &d2);
1342
        tmp = get_address(s, 0, b2, d2);
1343
        tmp2 = tcg_temp_new_i64();
1344
        tmp32_1 = tcg_temp_new_i32();
1345
        tcg_gen_qemu_ld32u(tmp2, tmp, get_mem_index(s));
1346
        tcg_gen_trunc_i64_i32(tmp32_1, tmp2);
1347
        tcg_gen_st_i32(tmp32_1, cpu_env, offsetof(CPUS390XState, fpc));
1348
        tcg_temp_free_i64(tmp);
1349
        tcg_temp_free_i64(tmp2);
1350
        tcg_temp_free_i32(tmp32_1);
1351
        break;
1352 1340
    case 0xb1: /* STFL     D2(B2)     [S] */
1353 1341
        /* Store Facility List (CPU features) at 200 */
1354 1342
        check_privileged(s);
......
1394 1382
    }
1395 1383
}
1396 1384

  
1397
static void disas_b3(CPUS390XState *env, DisasContext *s, int op, int m3,
1398
                     int r1, int r2)
1399
{
1400
    TCGv_i32 tmp32_1;
1401
    LOG_DISAS("disas_b3: op 0x%x m3 0x%x r1 %d r2 %d\n", op, m3, r1, r2);
1402
#define FP_HELPER(i) \
1403
    tmp32_1 = tcg_const_i32(r1); \
1404
    tmp32_2 = tcg_const_i32(r2); \
1405
    gen_helper_ ## i(cpu_env, tmp32_1, tmp32_2); \
1406
    tcg_temp_free_i32(tmp32_1); \
1407
    tcg_temp_free_i32(tmp32_2);
1408

  
1409
#define FP_HELPER_CC(i) \
1410
    tmp32_1 = tcg_const_i32(r1); \
1411
    tmp32_2 = tcg_const_i32(r2); \
1412
    gen_helper_ ## i(cc_op, cpu_env, tmp32_1, tmp32_2); \
1413
    set_cc_static(s); \
1414
    tcg_temp_free_i32(tmp32_1); \
1415
    tcg_temp_free_i32(tmp32_2);
1416

  
1417
    switch (op) {
1418
    case 0x84: /* SFPC        R1                [RRE] */
1419
        tmp32_1 = load_reg32(r1);
1420
        tcg_gen_st_i32(tmp32_1, cpu_env, offsetof(CPUS390XState, fpc));
1421
        tcg_temp_free_i32(tmp32_1);
1422
        break;
1423
    default:
1424
        LOG_DISAS("illegal b3 operation 0x%x\n", op);
1425
        gen_illegal_opcode(s);
1426
        break;
1427
    }
1428

  
1429
#undef FP_HELPER_CC
1430
#undef FP_HELPER
1431
}
1432

  
1433 1385
static void disas_s390_insn(CPUS390XState *env, DisasContext *s)
1434 1386
{
1435 1387
    unsigned char opc;
1436 1388
    uint64_t insn;
1437
    int op, r1, r2, r3;
1389
    int op;
1438 1390

  
1439 1391
    opc = cpu_ldub_code(env, s->pc);
1440 1392
    LOG_DISAS("opc 0x%x\n", opc);
......
1445 1397
        op = (insn >> 16) & 0xff;
1446 1398
        disas_b2(env, s, op, insn);
1447 1399
        break;
1448
    case 0xb3:
1449
        insn = ld_code4(env, s->pc);
1450
        op = (insn >> 16) & 0xff;
1451
        r3 = (insn >> 12) & 0xf; /* aka m3 */
1452
        r1 = (insn >> 4) & 0xf;
1453
        r2 = insn & 0xf;
1454
        disas_b3(env, s, op, r3, r1, r2);
1455
        break;
1456 1400
    default:
1457 1401
        qemu_log_mask(LOG_UNIMP, "unimplemented opcode 0x%x\n", opc);
1458 1402
        gen_illegal_opcode(s);
......
2981 2925
    return NO_EXIT;
2982 2926
}
2983 2927

  
2928
static ExitStatus op_sfpc(DisasContext *s, DisasOps *o)
2929
{
2930
    gen_helper_sfpc(cpu_env, o->in2);
2931
    return NO_EXIT;
2932
}
2933

  
2984 2934
#ifndef CONFIG_USER_ONLY
2985 2935
static ExitStatus op_ssm(DisasContext *s, DisasOps *o)
2986 2936
{

Also available in: Unified diff