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