aboutsummaryrefslogtreecommitdiff
path: root/target/s390x/translate.c
diff options
context:
space:
mode:
authorDavid Hildenbrand <david@redhat.com>2019-02-18 13:27:04 +0100
committerCornelia Huck <cohuck@redhat.com>2019-03-04 11:49:31 +0100
commitb9c737f58e82bf89efaa4a04ab3f730342c06a3a (patch)
treef559054f7e61040886ecc11497414c75989e0924 /target/s390x/translate.c
parent2aea83c6728f5006e07e4f148c2798441683fe86 (diff)
s390x/tcg: Check for exceptions in SET BFP ROUNDING MODE
Let's split handling of BFP/DFP rounding mode configuration. Also, let's not reuse the sfpc handler, use a separate handler so we can properly check for specification exceptions for SRNMB. Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: David Hildenbrand <david@redhat.com> Message-Id: <20190218122710.23639-10-david@redhat.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
Diffstat (limited to 'target/s390x/translate.c')
-rw-r--r--target/s390x/translate.c56
1 files changed, 24 insertions, 32 deletions
diff --git a/target/s390x/translate.c b/target/s390x/translate.c
index d9a89625c6..80952a30f9 100644
--- a/target/s390x/translate.c
+++ b/target/s390x/translate.c
@@ -3996,41 +3996,33 @@ static DisasJumpType op_sfas(DisasContext *s, DisasOps *o)
static DisasJumpType op_srnm(DisasContext *s, DisasOps *o)
{
- int b2 = get_field(s->fields, b2);
- int d2 = get_field(s->fields, d2);
- TCGv_i64 t1 = tcg_temp_new_i64();
- TCGv_i64 t2 = tcg_temp_new_i64();
- int mask, pos, len;
+ /* Bits other than 62 and 63 are ignored. Bit 29 is set to zero. */
+ tcg_gen_andi_i64(o->addr1, o->addr1, 0x3ull);
+ gen_helper_srnm(cpu_env, o->addr1);
+ return DISAS_NEXT;
+}
- switch (s->fields->op2) {
- case 0x99: /* SRNM */
- pos = 0, len = 2;
- break;
- case 0xb8: /* SRNMB */
- pos = 0, len = 3;
- break;
- case 0xb9: /* SRNMT */
- pos = 4, len = 3;
- break;
- default:
- tcg_abort();
- }
- mask = (1 << len) - 1;
+static DisasJumpType op_srnmb(DisasContext *s, DisasOps *o)
+{
+ /* Bits 0-55 are are ignored. */
+ tcg_gen_andi_i64(o->addr1, o->addr1, 0xffull);
+ gen_helper_srnm(cpu_env, o->addr1);
+ return DISAS_NEXT;
+}
- /* Insert the value into the appropriate field of the FPC. */
- if (b2 == 0) {
- tcg_gen_movi_i64(t1, d2 & mask);
- } else {
- tcg_gen_addi_i64(t1, regs[b2], d2);
- tcg_gen_andi_i64(t1, t1, mask);
- }
- tcg_gen_ld32u_i64(t2, cpu_env, offsetof(CPUS390XState, fpc));
- tcg_gen_deposit_i64(t2, t2, t1, pos, len);
- tcg_temp_free_i64(t1);
+static DisasJumpType op_srnmt(DisasContext *s, DisasOps *o)
+{
+ TCGv_i64 tmp = tcg_temp_new_i64();
- /* Then install the new FPC to set the rounding mode in fpu_status. */
- gen_helper_sfpc(cpu_env, t2);
- tcg_temp_free_i64(t2);
+ /* Bits other than 61-63 are ignored. */
+ tcg_gen_andi_i64(o->addr1, o->addr1, 0x7ull);
+
+ /* No need to call a helper, we don't implement dfp */
+ tcg_gen_ld32u_i64(tmp, cpu_env, offsetof(CPUS390XState, fpc));
+ tcg_gen_deposit_i64(tmp, tmp, o->addr1, 4, 3);
+ tcg_gen_st32_i64(tmp, cpu_env, offsetof(CPUS390XState, fpc));
+
+ tcg_temp_free_i64(tmp);
return DISAS_NEXT;
}