Signed-off-by: Richard Henderson <r...@twiddle.net> --- target-s390x/fpu_helper.c | 74 +++++++++++++--------------------------------- target-s390x/helper.h | 8 ++--- target-s390x/insn-data.def | 5 ++++ target-s390x/translate.c | 51 ++++++++++++-------------------- 4 files changed, 47 insertions(+), 91 deletions(-)
diff --git a/target-s390x/fpu_helper.c b/target-s390x/fpu_helper.c index c632366..4dac096 100644 --- a/target-s390x/fpu_helper.c +++ b/target-s390x/fpu_helper.c @@ -213,27 +213,31 @@ uint64_t HELPER(axb)(CPUS390XState *env, uint64_t ah, uint64_t al, return RET128(ret); } -/* 32-bit FP subtraction RR */ -uint32_t HELPER(sebr)(CPUS390XState *env, uint32_t f1, uint32_t f2) +/* 32-bit FP subtraction */ +uint64_t HELPER(seb)(CPUS390XState *env, uint64_t f1, uint64_t f2) { - env->fregs[f1].l.upper = float32_sub(env->fregs[f1].l.upper, - env->fregs[f2].l.upper, - &env->fpu_status); - HELPER_LOG("%s: adding 0x%d resulting in 0x%d in f%d\n", __func__, - env->fregs[f2].l.upper, env->fregs[f1].l.upper, f1); - - return set_cc_nz_f32(env->fregs[f1].l.upper); + float32 ret = float32_sub(f1, f2, &env->fpu_status); + handle_exceptions(env, GETPC()); + return ret; } -/* 64-bit FP subtraction RR */ -uint32_t HELPER(sdbr)(CPUS390XState *env, uint32_t f1, uint32_t f2) +/* 64-bit FP subtraction */ +uint64_t HELPER(sdb)(CPUS390XState *env, uint64_t f1, uint64_t f2) { - env->fregs[f1].d = float64_sub(env->fregs[f1].d, env->fregs[f2].d, - &env->fpu_status); - HELPER_LOG("%s: subtracting 0x%ld resulting in 0x%ld in f%d\n", - __func__, env->fregs[f2].d, env->fregs[f1].d, f1); + float64 ret = float64_sub(f1, f2, &env->fpu_status); + handle_exceptions(env, GETPC()); + return ret; +} - return set_cc_nz_f64(env->fregs[f1].d); +/* 128-bit FP subtraction */ +uint64_t HELPER(sxb)(CPUS390XState *env, uint64_t ah, uint64_t al, + uint64_t bh, uint64_t bl) +{ + float128 ret = float128_sub(make_float128(ah, al), + make_float128(bh, bl), + &env->fpu_status); + handle_exceptions(env, GETPC()); + return RET128(ret); } /* 32-bit FP division RR */ @@ -447,27 +451,6 @@ uint32_t HELPER(cxb)(CPUS390XState *env, uint64_t ah, uint64_t al, return float_comp_to_cc(env, cmp); } -/* 32-bit FP subtraction RM */ -void HELPER(seb)(CPUS390XState *env, uint32_t f1, uint32_t val) -{ - float32 v1 = env->fregs[f1].l.upper; - CPU_FloatU v2; - - v2.l = val; - env->fregs[f1].l.upper = float32_sub(v1, v2.f, &env->fpu_status); -} - -/* 64-bit FP subtraction RM */ -uint32_t HELPER(sdb)(CPUS390XState *env, uint32_t f1, uint64_t a2) -{ - float64 v1 = env->fregs[f1].d; - CPU_DoubleU v2; - - v2.ll = cpu_ldq_data(env, a2); - env->fregs[f1].d = v1 = float64_sub(v1, v2.d, &env->fpu_status); - return set_cc_nz_f64(v1); -} - /* 64-bit FP multiplication RM */ void HELPER(mdb)(CPUS390XState *env, uint32_t f1, uint64_t a2) { @@ -621,23 +604,6 @@ void HELPER(lzxr)(CPUS390XState *env, uint32_t f1) env->fregs[f1 + 1].ll = x.ll.lower; } -/* 128-bit FP subtraction RR */ -uint32_t HELPER(sxbr)(CPUS390XState *env, uint32_t f1, uint32_t f2) -{ - CPU_QuadU v1; - CPU_QuadU v2; - CPU_QuadU res; - - v1.ll.upper = env->fregs[f1].ll; - v1.ll.lower = env->fregs[f1 + 2].ll; - v2.ll.upper = env->fregs[f2].ll; - v2.ll.lower = env->fregs[f2 + 2].ll; - res.q = float128_sub(v1.q, v2.q, &env->fpu_status); - env->fregs[f1].ll = res.ll.upper; - env->fregs[f1 + 2].ll = res.ll.lower; - return set_cc_nz_f128(res.q); -} - /* 32-bit FP multiplication RR */ void HELPER(meebr)(CPUS390XState *env, uint32_t f1, uint32_t f2) { diff --git a/target-s390x/helper.h b/target-s390x/helper.h index 244c6ca..b3f5a40 100644 --- a/target-s390x/helper.h +++ b/target-s390x/helper.h @@ -50,8 +50,9 @@ DEF_HELPER_3(cxgbr, void, env, i32, s64) DEF_HELPER_3(aeb, i64, env, i64, i64) DEF_HELPER_3(adb, i64, env, i64, i64) DEF_HELPER_5(axb, i64, env, i64, i64, i64, i64) -DEF_HELPER_3(sebr, i32, env, i32, i32) -DEF_HELPER_3(sdbr, i32, env, i32, i32) +DEF_HELPER_3(seb, i64, env, i64, i64) +DEF_HELPER_3(sdb, i64, env, i64, i64) +DEF_HELPER_5(sxb, i64, env, i64, i64, i64, i64) DEF_HELPER_3(debr, void, env, i32, i32) DEF_HELPER_3(dxbr, void, env, i32, i32) DEF_HELPER_3(mdbr, void, env, i32, i32) @@ -70,8 +71,6 @@ DEF_HELPER_3(lcdbr, i32, env, i32, i32) DEF_HELPER_3(lcxbr, i32, env, i32, i32) DEF_HELPER_3(deb, void, env, i32, i32) DEF_HELPER_3(meeb, void, env, i32, i32) -DEF_HELPER_3(seb, void, env, i32, i32) -DEF_HELPER_3(sdb, i32, env, i32, i64) DEF_HELPER_3(mdb, void, env, i32, i64) DEF_HELPER_3(ddb, void, env, i32, i64) DEF_HELPER_FLAGS_3(ceb, TCG_CALL_PURE, i32, env, i64, i64) @@ -86,7 +85,6 @@ DEF_HELPER_2(lzxr, void, env, i32) DEF_HELPER_4(cfebr, i32, env, i32, i32, i32) DEF_HELPER_4(cfdbr, i32, env, i32, i32, i32) DEF_HELPER_4(cfxbr, i32, env, i32, i32, i32) -DEF_HELPER_3(sxbr, i32, env, i32, i32) DEF_HELPER_3(meebr, void, env, i32, i32) DEF_HELPER_3(ddbr, void, env, i32, i32) DEF_HELPER_4(madb, void, env, i32, i64, i32) diff --git a/target-s390x/insn-data.def b/target-s390x/insn-data.def index 1709cbf..9b02904 100644 --- a/target-s390x/insn-data.def +++ b/target-s390x/insn-data.def @@ -476,6 +476,11 @@ C(0xb9e9, SGRK, RRF_a, DO, r2, r3, r1, 0, sub, subs64) C(0xe309, SG, RXY_a, Z, r1, m2_64, r1, 0, sub, subs64) C(0xe319, SGF, RXY_a, Z, r1, m2_32s, r1, 0, sub, subs64) + C(0xb30b, SEBR, RRE, Z, e1, e2, new, e1, seb, f32) + C(0xb31b, SDBR, RRE, Z, f1_o, f2_o, f1, 0, sdb, f64) + C(0xb34b, SXBR, RRE, Z, 0, x2_o, x1, 0, sxb, f128) + C(0xed0b, SEB, RXE, Z, e1, m2_32u, new, e1, seb, f32) + C(0xed1b, SDB, RXE, Z, f1_o, m2_64, f1, 0, sdb, f64) /* SUBTRACT HALFWORD */ C(0x4b00, SH, RX_a, Z, r1, m2_16s, new, r1_32, sub, subs32) C(0xe37b, SHY, RXY_a, LD, r1, m2_16s, new, r1_32, sub, subs32) diff --git a/target-s390x/translate.c b/target-s390x/translate.c index 3d5668d..2ed8b2c 100644 --- a/target-s390x/translate.c +++ b/target-s390x/translate.c @@ -554,11 +554,6 @@ static inline void set_cc_s64(DisasContext *s, TCGv_i64 val) gen_op_update1_cc_i64(s, CC_OP_LTGT0_64, val); } -static void gen_set_cc_nz_f32(DisasContext *s, TCGv_i32 v1) -{ - gen_op_update1_cc_i32(s, CC_OP_NZ_F32, v1); -} - /* CC value is in env->cc_op */ static inline void set_cc_static(DisasContext *s) { @@ -998,19 +993,6 @@ static void disas_ed(DisasContext *s, int op, int r1, int x2, int b2, int d2, addr = get_address(s, x2, b2, d2); tmp_r1 = tcg_const_i32(r1); switch (op) { - case 0xb: /* SEB R1,D2(X2,B2) [RXE] */ - tmp = tcg_temp_new_i64(); - tmp32 = tcg_temp_new_i32(); - tcg_gen_qemu_ld32u(tmp, addr, get_mem_index(s)); - tcg_gen_trunc_i64_i32(tmp32, tmp); - gen_helper_seb(cpu_env, tmp_r1, tmp32); - tcg_temp_free_i64(tmp); - tcg_temp_free_i32(tmp32); - - tmp32 = load_freg32(r1); - gen_set_cc_nz_f32(s, tmp32); - tcg_temp_free_i32(tmp32); - break; case 0xd: /* DEB R1,D2(X2,B2) [RXE] */ tmp = tcg_temp_new_i64(); tmp32 = tcg_temp_new_i32(); @@ -1044,11 +1026,6 @@ static void disas_ed(DisasContext *s, int op, int r1, int x2, int b2, int d2, tcg_temp_free_i64(tmp); tcg_temp_free_i32(tmp32); break; - case 0x1b: /* SDB R1,D2(X2,B2) [RXE] */ - potential_page_fault(s); - gen_helper_sdb(cc_op, cpu_env, tmp_r1, addr); - set_cc_static(s); - break; case 0x1c: /* MDB R1,D2(X2,B2) [RXE] */ potential_page_fault(s); gen_helper_mdb(cpu_env, tmp_r1, addr); @@ -1475,9 +1452,6 @@ static void disas_b3(DisasContext *s, int op, int m3, int r1, int r2) case 0x3: /* LCEBR R1,R2 [RRE] */ FP_HELPER_CC(lcebr); break; - case 0xb: /* SEBR R1,R2 [RRE] */ - FP_HELPER_CC(sebr); - break; case 0xd: /* DEBR R1,R2 [RRE] */ FP_HELPER(debr); break; @@ -1493,9 +1467,6 @@ static void disas_b3(DisasContext *s, int op, int m3, int r1, int r2) case 0x17: /* MEEBR R1,R2 [RRE] */ FP_HELPER(meebr); break; - case 0x1b: /* SDBR R1,R2 [RRE] */ - FP_HELPER_CC(sdbr); - break; case 0x1c: /* MDBR R1,R2 [RRE] */ FP_HELPER(mdbr); break; @@ -1532,9 +1503,6 @@ static void disas_b3(DisasContext *s, int op, int m3, int r1, int r2) case 0x43: /* LCXBR R1,R2 [RRE] */ FP_HELPER_CC(lcxbr); break; - case 0x4b: /* SXBR R1,R2 [RRE] */ - FP_HELPER_CC(sxbr); - break; case 0x4c: /* MXBR R1,R2 [RRE] */ FP_HELPER(mxbr); break; @@ -2892,6 +2860,25 @@ static ExitStatus op_rll64(DisasContext *s, DisasOps *o) return NO_EXIT; } +static ExitStatus op_seb(DisasContext *s, DisasOps *o) +{ + gen_helper_seb(o->out, cpu_env, o->in1, o->in2); + return NO_EXIT; +} + +static ExitStatus op_sdb(DisasContext *s, DisasOps *o) +{ + gen_helper_sdb(o->out, cpu_env, o->in1, o->in2); + return NO_EXIT; +} + +static ExitStatus op_sxb(DisasContext *s, DisasOps *o) +{ + gen_helper_sxb(o->out, cpu_env, o->out, o->out2, o->in1, o->in2); + return_low128(o->out2); + return NO_EXIT; +} + #ifndef CONFIG_USER_ONLY static ExitStatus op_sigp(DisasContext *s, DisasOps *o) { -- 1.7.11.4