[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[qemu-s390x] [PATCH v1 12/15] s390x/tcg: Implement XxC and checks for mo
From: |
David Hildenbrand |
Subject: |
[qemu-s390x] [PATCH v1 12/15] s390x/tcg: Implement XxC and checks for most FP instructions |
Date: |
Tue, 12 Feb 2019 12:03:05 +0100 |
With the floating-point extension facility
- CONVERT FROM LOGICAL
- CONVERT TO LOGICAL
- CONVERT TO FIXED
- CONVERT FROM FIXED
- LOAD FP INTEGER
have both, a rounding mode specification and the inexact-exception control
(XxC). Other instructions will be handled separatly.
Check for valid rounding modes and forward also the XxC. To avoid a lot
of boilerplate code and changes to the helpers, combine both, the m3 and
m4 field in a combined 32 bit TCG variable. Mangle/unmangle on a 8bit
basis, so this can be reused for other fields later on.
Signed-off-by: David Hildenbrand <address@hidden>
---
target/s390x/fpu_helper.c | 126 +++++++++----------
target/s390x/internal.h | 6 +
target/s390x/translate.c | 254 ++++++++++++++++++++++++++++----------
3 files changed, 260 insertions(+), 126 deletions(-)
diff --git a/target/s390x/fpu_helper.c b/target/s390x/fpu_helper.c
index 5136147da6..a0501b9ee5 100644
--- a/target/s390x/fpu_helper.c
+++ b/target/s390x/fpu_helper.c
@@ -407,239 +407,239 @@ void s390_restore_bfp_rounding_mode(CPUS390XState *env,
int old_mode)
}
/* convert 64-bit int to 32-bit float */
-uint64_t HELPER(cegb)(CPUS390XState *env, int64_t v2, uint32_t m3)
+uint64_t HELPER(cegb)(CPUS390XState *env, int64_t v2, uint32_t m)
{
- int old_mode = s390_swap_bfp_rounding_mode(env, m3);
+ int old_mode = s390_swap_bfp_rounding_mode(env, m & 0xf);
float32 ret = int64_to_float32(v2, &env->fpu_status);
s390_restore_bfp_rounding_mode(env, old_mode);
- handle_exceptions(env, false, GETPC());
+ handle_exceptions(env, (m >> 8) & 1, GETPC());
return ret;
}
/* convert 64-bit int to 64-bit float */
-uint64_t HELPER(cdgb)(CPUS390XState *env, int64_t v2, uint32_t m3)
+uint64_t HELPER(cdgb)(CPUS390XState *env, int64_t v2, uint32_t m)
{
- int old_mode = s390_swap_bfp_rounding_mode(env, m3);
+ int old_mode = s390_swap_bfp_rounding_mode(env, m & 0xf);
float64 ret = int64_to_float64(v2, &env->fpu_status);
s390_restore_bfp_rounding_mode(env, old_mode);
- handle_exceptions(env, false, GETPC());
+ handle_exceptions(env, (m >> 8) & 1, GETPC());
return ret;
}
/* convert 64-bit int to 128-bit float */
-uint64_t HELPER(cxgb)(CPUS390XState *env, int64_t v2, uint32_t m3)
+uint64_t HELPER(cxgb)(CPUS390XState *env, int64_t v2, uint32_t m)
{
- int old_mode = s390_swap_bfp_rounding_mode(env, m3);
+ int old_mode = s390_swap_bfp_rounding_mode(env, m & 0xf);
float128 ret = int64_to_float128(v2, &env->fpu_status);
s390_restore_bfp_rounding_mode(env, old_mode);
- handle_exceptions(env, false, GETPC());
+ handle_exceptions(env, (m >> 8) & 1, GETPC());
return RET128(ret);
}
/* convert 64-bit uint to 32-bit float */
-uint64_t HELPER(celgb)(CPUS390XState *env, uint64_t v2, uint32_t m3)
+uint64_t HELPER(celgb)(CPUS390XState *env, uint64_t v2, uint32_t m)
{
- int old_mode = s390_swap_bfp_rounding_mode(env, m3);
+ int old_mode = s390_swap_bfp_rounding_mode(env, m & 0xf);
float32 ret = uint64_to_float32(v2, &env->fpu_status);
s390_restore_bfp_rounding_mode(env, old_mode);
- handle_exceptions(env, false, GETPC());
+ handle_exceptions(env, (m >> 8) & 1, GETPC());
return ret;
}
/* convert 64-bit uint to 64-bit float */
-uint64_t HELPER(cdlgb)(CPUS390XState *env, uint64_t v2, uint32_t m3)
+uint64_t HELPER(cdlgb)(CPUS390XState *env, uint64_t v2, uint32_t m)
{
- int old_mode = s390_swap_bfp_rounding_mode(env, m3);
+ int old_mode = s390_swap_bfp_rounding_mode(env, m & 0xf);
float64 ret = uint64_to_float64(v2, &env->fpu_status);
s390_restore_bfp_rounding_mode(env, old_mode);
- handle_exceptions(env, false, GETPC());
+ handle_exceptions(env, (m >> 8) & 1, GETPC());
return ret;
}
/* convert 64-bit uint to 128-bit float */
-uint64_t HELPER(cxlgb)(CPUS390XState *env, uint64_t v2, uint32_t m3)
+uint64_t HELPER(cxlgb)(CPUS390XState *env, uint64_t v2, uint32_t m)
{
- int old_mode = s390_swap_bfp_rounding_mode(env, m3);
+ int old_mode = s390_swap_bfp_rounding_mode(env, m & 0xf);
float128 ret = uint64_to_float128(v2, &env->fpu_status);
s390_restore_bfp_rounding_mode(env, old_mode);
- handle_exceptions(env, false, GETPC());
+ handle_exceptions(env, (m >> 8) & 1, GETPC());
return RET128(ret);
}
/* convert 32-bit float to 64-bit int */
-uint64_t HELPER(cgeb)(CPUS390XState *env, uint64_t v2, uint32_t m3)
+uint64_t HELPER(cgeb)(CPUS390XState *env, uint64_t v2, uint32_t m)
{
- int old_mode = s390_swap_bfp_rounding_mode(env, m3);
+ int old_mode = s390_swap_bfp_rounding_mode(env, m & 0xf);
int64_t ret = float32_to_int64(v2, &env->fpu_status);
s390_restore_bfp_rounding_mode(env, old_mode);
- handle_exceptions(env, false, GETPC());
+ handle_exceptions(env, (m >> 8) & 1, GETPC());
return ret;
}
/* convert 64-bit float to 64-bit int */
-uint64_t HELPER(cgdb)(CPUS390XState *env, uint64_t v2, uint32_t m3)
+uint64_t HELPER(cgdb)(CPUS390XState *env, uint64_t v2, uint32_t m)
{
- int old_mode = s390_swap_bfp_rounding_mode(env, m3);
+ int old_mode = s390_swap_bfp_rounding_mode(env, m & 0xf);
int64_t ret = float64_to_int64(v2, &env->fpu_status);
s390_restore_bfp_rounding_mode(env, old_mode);
- handle_exceptions(env, false, GETPC());
+ handle_exceptions(env, (m >> 8) & 1, GETPC());
return ret;
}
/* convert 128-bit float to 64-bit int */
-uint64_t HELPER(cgxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m3)
+uint64_t HELPER(cgxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m)
{
- int old_mode = s390_swap_bfp_rounding_mode(env, m3);
+ int old_mode = s390_swap_bfp_rounding_mode(env, m & 0xf);
float128 v2 = make_float128(h, l);
int64_t ret = float128_to_int64(v2, &env->fpu_status);
s390_restore_bfp_rounding_mode(env, old_mode);
- handle_exceptions(env, false, GETPC());
+ handle_exceptions(env, (m >> 8) & 1, GETPC());
return ret;
}
/* convert 32-bit float to 32-bit int */
-uint64_t HELPER(cfeb)(CPUS390XState *env, uint64_t v2, uint32_t m3)
+uint64_t HELPER(cfeb)(CPUS390XState *env, uint64_t v2, uint32_t m)
{
- int old_mode = s390_swap_bfp_rounding_mode(env, m3);
+ int old_mode = s390_swap_bfp_rounding_mode(env, m & 0xf);
int32_t ret = float32_to_int32(v2, &env->fpu_status);
s390_restore_bfp_rounding_mode(env, old_mode);
- handle_exceptions(env, false, GETPC());
+ handle_exceptions(env, (m >> 8) & 1, GETPC());
return ret;
}
/* convert 64-bit float to 32-bit int */
-uint64_t HELPER(cfdb)(CPUS390XState *env, uint64_t v2, uint32_t m3)
+uint64_t HELPER(cfdb)(CPUS390XState *env, uint64_t v2, uint32_t m)
{
- int old_mode = s390_swap_bfp_rounding_mode(env, m3);
+ int old_mode = s390_swap_bfp_rounding_mode(env, m & 0xf);
int32_t ret = float64_to_int32(v2, &env->fpu_status);
s390_restore_bfp_rounding_mode(env, old_mode);
- handle_exceptions(env, false, GETPC());
+ handle_exceptions(env, (m >> 8) & 1, GETPC());
return ret;
}
/* convert 128-bit float to 32-bit int */
-uint64_t HELPER(cfxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m3)
+uint64_t HELPER(cfxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m)
{
- int old_mode = s390_swap_bfp_rounding_mode(env, m3);
+ int old_mode = s390_swap_bfp_rounding_mode(env, m & 0xf);
float128 v2 = make_float128(h, l);
int32_t ret = float128_to_int32(v2, &env->fpu_status);
s390_restore_bfp_rounding_mode(env, old_mode);
- handle_exceptions(env, false, GETPC());
+ handle_exceptions(env, (m >> 8) & 1, GETPC());
return ret;
}
/* convert 32-bit float to 64-bit uint */
-uint64_t HELPER(clgeb)(CPUS390XState *env, uint64_t v2, uint32_t m3)
+uint64_t HELPER(clgeb)(CPUS390XState *env, uint64_t v2, uint32_t m)
{
- int old_mode = s390_swap_bfp_rounding_mode(env, m3);
+ int old_mode = s390_swap_bfp_rounding_mode(env, m & 0xf);
uint64_t ret;
v2 = float32_to_float64(v2, &env->fpu_status);
ret = float64_to_uint64(v2, &env->fpu_status);
s390_restore_bfp_rounding_mode(env, old_mode);
- handle_exceptions(env, false, GETPC());
+ handle_exceptions(env, (m >> 8) & 1, GETPC());
return ret;
}
/* convert 64-bit float to 64-bit uint */
-uint64_t HELPER(clgdb)(CPUS390XState *env, uint64_t v2, uint32_t m3)
+uint64_t HELPER(clgdb)(CPUS390XState *env, uint64_t v2, uint32_t m)
{
- int old_mode = s390_swap_bfp_rounding_mode(env, m3);
+ int old_mode = s390_swap_bfp_rounding_mode(env, m & 0xf);
uint64_t ret = float64_to_uint64(v2, &env->fpu_status);
s390_restore_bfp_rounding_mode(env, old_mode);
- handle_exceptions(env, false, GETPC());
+ handle_exceptions(env, (m >> 8) & 1, GETPC());
return ret;
}
/* convert 128-bit float to 64-bit uint */
-uint64_t HELPER(clgxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m3)
+uint64_t HELPER(clgxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m)
{
- int old_mode = s390_swap_bfp_rounding_mode(env, m3);
+ int old_mode = s390_swap_bfp_rounding_mode(env, m & 0xf);
uint64_t ret = float128_to_uint64(make_float128(h, l), &env->fpu_status);
s390_restore_bfp_rounding_mode(env, old_mode);
- handle_exceptions(env, false, GETPC());
+ handle_exceptions(env, (m >> 8) & 1, GETPC());
return ret;
}
/* convert 32-bit float to 32-bit uint */
-uint64_t HELPER(clfeb)(CPUS390XState *env, uint64_t v2, uint32_t m3)
+uint64_t HELPER(clfeb)(CPUS390XState *env, uint64_t v2, uint32_t m)
{
- int old_mode = s390_swap_bfp_rounding_mode(env, m3);
+ int old_mode = s390_swap_bfp_rounding_mode(env, m & 0xf);
uint32_t ret = float32_to_uint32(v2, &env->fpu_status);
s390_restore_bfp_rounding_mode(env, old_mode);
- handle_exceptions(env, false, GETPC());
+ handle_exceptions(env, (m >> 8) & 1, GETPC());
return ret;
}
/* convert 64-bit float to 32-bit uint */
-uint64_t HELPER(clfdb)(CPUS390XState *env, uint64_t v2, uint32_t m3)
+uint64_t HELPER(clfdb)(CPUS390XState *env, uint64_t v2, uint32_t m)
{
- int old_mode = s390_swap_bfp_rounding_mode(env, m3);
+ int old_mode = s390_swap_bfp_rounding_mode(env, m & 0xf);
uint32_t ret = float64_to_uint32(v2, &env->fpu_status);
s390_restore_bfp_rounding_mode(env, old_mode);
- handle_exceptions(env, false, GETPC());
+ handle_exceptions(env, (m >> 8) & 1, GETPC());
return ret;
}
/* convert 128-bit float to 32-bit uint */
-uint64_t HELPER(clfxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m3)
+uint64_t HELPER(clfxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m)
{
- int old_mode = s390_swap_bfp_rounding_mode(env, m3);
+ int old_mode = s390_swap_bfp_rounding_mode(env, m & 0xf);
uint32_t ret = float128_to_uint32(make_float128(h, l), &env->fpu_status);
s390_restore_bfp_rounding_mode(env, old_mode);
- handle_exceptions(env, false, GETPC());
+ handle_exceptions(env, (m >> 8) & 1, GETPC());
return ret;
}
/* round to integer 32-bit */
-uint64_t HELPER(fieb)(CPUS390XState *env, uint64_t f2, uint32_t m3)
+uint64_t HELPER(fieb)(CPUS390XState *env, uint64_t f2, uint32_t m)
{
- int old_mode = s390_swap_bfp_rounding_mode(env, m3);
+ int old_mode = s390_swap_bfp_rounding_mode(env, m & 0xf);
float32 ret = float32_round_to_int(f2, &env->fpu_status);
s390_restore_bfp_rounding_mode(env, old_mode);
- handle_exceptions(env, false, GETPC());
+ handle_exceptions(env, (m >> 8) & 1, GETPC());
return ret;
}
/* round to integer 64-bit */
-uint64_t HELPER(fidb)(CPUS390XState *env, uint64_t f2, uint32_t m3)
+uint64_t HELPER(fidb)(CPUS390XState *env, uint64_t f2, uint32_t m)
{
- int old_mode = s390_swap_bfp_rounding_mode(env, m3);
+ int old_mode = s390_swap_bfp_rounding_mode(env, m & 0xf);
float64 ret = float64_round_to_int(f2, &env->fpu_status);
s390_restore_bfp_rounding_mode(env, old_mode);
- handle_exceptions(env, false, GETPC());
+ handle_exceptions(env, (m >> 8) & 1, GETPC());
return ret;
}
/* round to integer 128-bit */
-uint64_t HELPER(fixb)(CPUS390XState *env, uint64_t ah, uint64_t al, uint32_t
m3)
+uint64_t HELPER(fixb)(CPUS390XState *env, uint64_t ah, uint64_t al, uint32_t m)
{
- int old_mode = s390_swap_bfp_rounding_mode(env, m3);
+ int old_mode = s390_swap_bfp_rounding_mode(env, m & 0xf);
float128 ret = float128_round_to_int(make_float128(ah, al),
&env->fpu_status);
s390_restore_bfp_rounding_mode(env, old_mode);
- handle_exceptions(env, false, GETPC());
+ handle_exceptions(env, (m >> 8) & 1, GETPC());
return RET128(ret);
}
diff --git a/target/s390x/internal.h b/target/s390x/internal.h
index 122fe037bc..b7bb46404f 100644
--- a/target/s390x/internal.h
+++ b/target/s390x/internal.h
@@ -176,6 +176,12 @@ static inline uint64_t wrap_address(CPUS390XState *env,
uint64_t a)
return a;
}
+/* verify a bfp rounding mode as specified e.g. via m3 field */
+static inline bool valid_bfp_rounding_mode(uint8_t mode)
+{
+ return mode != 2 && mode <= 7;
+}
+
/* CC optimization */
/* Instead of computing the condition codes after each x86 instruction,
diff --git a/target/s390x/translate.c b/target/s390x/translate.c
index f58155f20c..e7cfc80131 100644
--- a/target/s390x/translate.c
+++ b/target/s390x/translate.c
@@ -1051,6 +1051,8 @@ struct DisasFields {
/* This is the way fields are to be accessed out of DisasFields. */
#define have_field(S, F) have_field1((S), FLD_O_##F)
#define get_field(S, F) get_field1((S), FLD_O_##F, FLD_C_##F)
+#define get_fields2(S, F1, F2) (get_field1((S), FLD_O_##F1, FLD_C_##F1) | \
+ get_field1((S), FLD_O_##F2, FLD_C_##F2) << 8)
static bool have_field1(const DisasFields *f, enum DisasFieldIndexO c)
{
@@ -1760,158 +1762,266 @@ static DisasJumpType op_cxb(DisasContext *s, DisasOps
*o)
static DisasJumpType op_cfeb(DisasContext *s, DisasOps *o)
{
- TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
- gen_helper_cfeb(o->out, cpu_env, o->in2, m3);
- tcg_temp_free_i32(m3);
+ TCGv_i32 m;
+
+ if (!valid_bfp_rounding_mode(get_field(s->fields, m3))) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+ m = tcg_const_i32(get_fields2(s->fields, m3, m4));
+ gen_helper_cfeb(o->out, cpu_env, o->in2, m);
+ tcg_temp_free_i32(m);
gen_set_cc_nz_f32(s, o->in2);
return DISAS_NEXT;
}
static DisasJumpType op_cfdb(DisasContext *s, DisasOps *o)
{
- TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
- gen_helper_cfdb(o->out, cpu_env, o->in2, m3);
- tcg_temp_free_i32(m3);
+ TCGv_i32 m;
+
+ if (!valid_bfp_rounding_mode(get_field(s->fields, m3))) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+ m = tcg_const_i32(get_fields2(s->fields, m3, m4));
+ gen_helper_cfdb(o->out, cpu_env, o->in2, m);
+ tcg_temp_free_i32(m);
gen_set_cc_nz_f64(s, o->in2);
return DISAS_NEXT;
}
static DisasJumpType op_cfxb(DisasContext *s, DisasOps *o)
{
- TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
- gen_helper_cfxb(o->out, cpu_env, o->in1, o->in2, m3);
- tcg_temp_free_i32(m3);
+ TCGv_i32 m;
+
+ if (!valid_bfp_rounding_mode(get_field(s->fields, m3))) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+ m = tcg_const_i32(get_fields2(s->fields, m3, m4));
+ gen_helper_cfxb(o->out, cpu_env, o->in1, o->in2, m);
+ tcg_temp_free_i32(m);
gen_set_cc_nz_f128(s, o->in1, o->in2);
return DISAS_NEXT;
}
static DisasJumpType op_cgeb(DisasContext *s, DisasOps *o)
{
- TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
- gen_helper_cgeb(o->out, cpu_env, o->in2, m3);
- tcg_temp_free_i32(m3);
+ TCGv_i32 m;
+
+ if (!valid_bfp_rounding_mode(get_field(s->fields, m3))) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+ m = tcg_const_i32(get_fields2(s->fields, m3, m4));
+ gen_helper_cgeb(o->out, cpu_env, o->in2, m);
+ tcg_temp_free_i32(m);
gen_set_cc_nz_f32(s, o->in2);
return DISAS_NEXT;
}
static DisasJumpType op_cgdb(DisasContext *s, DisasOps *o)
{
- TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
- gen_helper_cgdb(o->out, cpu_env, o->in2, m3);
- tcg_temp_free_i32(m3);
+ TCGv_i32 m;
+
+ if (!valid_bfp_rounding_mode(get_field(s->fields, m3))) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+ m = tcg_const_i32(get_fields2(s->fields, m3, m4));
+ gen_helper_cgdb(o->out, cpu_env, o->in2, m);
+ tcg_temp_free_i32(m);
gen_set_cc_nz_f64(s, o->in2);
return DISAS_NEXT;
}
static DisasJumpType op_cgxb(DisasContext *s, DisasOps *o)
{
- TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
- gen_helper_cgxb(o->out, cpu_env, o->in1, o->in2, m3);
- tcg_temp_free_i32(m3);
+ TCGv_i32 m;
+
+ if (!valid_bfp_rounding_mode(get_field(s->fields, m3))) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+ m = tcg_const_i32(get_fields2(s->fields, m3, m4));
+ gen_helper_cgxb(o->out, cpu_env, o->in1, o->in2, m);
+ tcg_temp_free_i32(m);
gen_set_cc_nz_f128(s, o->in1, o->in2);
return DISAS_NEXT;
}
static DisasJumpType op_clfeb(DisasContext *s, DisasOps *o)
{
- TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
- gen_helper_clfeb(o->out, cpu_env, o->in2, m3);
- tcg_temp_free_i32(m3);
+ TCGv_i32 m;
+
+ if (!valid_bfp_rounding_mode(get_field(s->fields, m3))) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+ m = tcg_const_i32(get_fields2(s->fields, m3, m4));
+ gen_helper_clfeb(o->out, cpu_env, o->in2, m);
+ tcg_temp_free_i32(m);
gen_set_cc_nz_f32(s, o->in2);
return DISAS_NEXT;
}
static DisasJumpType op_clfdb(DisasContext *s, DisasOps *o)
{
- TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
- gen_helper_clfdb(o->out, cpu_env, o->in2, m3);
- tcg_temp_free_i32(m3);
+ TCGv_i32 m;
+
+ if (!valid_bfp_rounding_mode(get_field(s->fields, m3))) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+ m = tcg_const_i32(get_fields2(s->fields, m3, m4));
+ gen_helper_clfdb(o->out, cpu_env, o->in2, m);
+ tcg_temp_free_i32(m);
gen_set_cc_nz_f64(s, o->in2);
return DISAS_NEXT;
}
static DisasJumpType op_clfxb(DisasContext *s, DisasOps *o)
{
- TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
- gen_helper_clfxb(o->out, cpu_env, o->in1, o->in2, m3);
- tcg_temp_free_i32(m3);
+ TCGv_i32 m;
+
+ if (!valid_bfp_rounding_mode(get_field(s->fields, m3))) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+ m = tcg_const_i32(get_fields2(s->fields, m3, m4));
+ gen_helper_clfxb(o->out, cpu_env, o->in1, o->in2, m);
+ tcg_temp_free_i32(m);
gen_set_cc_nz_f128(s, o->in1, o->in2);
return DISAS_NEXT;
}
static DisasJumpType op_clgeb(DisasContext *s, DisasOps *o)
{
- TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
- gen_helper_clgeb(o->out, cpu_env, o->in2, m3);
- tcg_temp_free_i32(m3);
+ TCGv_i32 m;
+
+ if (!valid_bfp_rounding_mode(get_field(s->fields, m3))) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+ m = tcg_const_i32(get_fields2(s->fields, m3, m4));
+ gen_helper_clgeb(o->out, cpu_env, o->in2, m);
+ tcg_temp_free_i32(m);
gen_set_cc_nz_f32(s, o->in2);
return DISAS_NEXT;
}
static DisasJumpType op_clgdb(DisasContext *s, DisasOps *o)
{
- TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
- gen_helper_clgdb(o->out, cpu_env, o->in2, m3);
- tcg_temp_free_i32(m3);
+ TCGv_i32 m;
+
+ if (!valid_bfp_rounding_mode(get_field(s->fields, m3))) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+ m = tcg_const_i32(get_fields2(s->fields, m3, m4));
+ gen_helper_clgdb(o->out, cpu_env, o->in2, m);
+ tcg_temp_free_i32(m);
gen_set_cc_nz_f64(s, o->in2);
return DISAS_NEXT;
}
static DisasJumpType op_clgxb(DisasContext *s, DisasOps *o)
{
- TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
- gen_helper_clgxb(o->out, cpu_env, o->in1, o->in2, m3);
- tcg_temp_free_i32(m3);
+ TCGv_i32 m;
+
+ if (!valid_bfp_rounding_mode(get_field(s->fields, m3))) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+ m = tcg_const_i32(get_fields2(s->fields, m3, m4));
+ gen_helper_clgxb(o->out, cpu_env, o->in1, o->in2, m);
+ tcg_temp_free_i32(m);
gen_set_cc_nz_f128(s, o->in1, o->in2);
return DISAS_NEXT;
}
static DisasJumpType op_cegb(DisasContext *s, DisasOps *o)
{
- TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
- gen_helper_cegb(o->out, cpu_env, o->in2, m3);
- tcg_temp_free_i32(m3);
+ TCGv_i32 m;
+
+ if (!valid_bfp_rounding_mode(get_field(s->fields, m3))) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+ m = tcg_const_i32(get_fields2(s->fields, m3, m4));
+ gen_helper_cegb(o->out, cpu_env, o->in2, m);
+ tcg_temp_free_i32(m);
return DISAS_NEXT;
}
static DisasJumpType op_cdgb(DisasContext *s, DisasOps *o)
{
- TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
- gen_helper_cdgb(o->out, cpu_env, o->in2, m3);
- tcg_temp_free_i32(m3);
+ TCGv_i32 m;
+
+ if (!valid_bfp_rounding_mode(get_field(s->fields, m3))) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+ m = tcg_const_i32(get_fields2(s->fields, m3, m4));
+ gen_helper_cdgb(o->out, cpu_env, o->in2, m);
+ tcg_temp_free_i32(m);
return DISAS_NEXT;
}
static DisasJumpType op_cxgb(DisasContext *s, DisasOps *o)
{
- TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
- gen_helper_cxgb(o->out, cpu_env, o->in2, m3);
- tcg_temp_free_i32(m3);
+ TCGv_i32 m;
+
+ if (!valid_bfp_rounding_mode(get_field(s->fields, m3))) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+ m = tcg_const_i32(get_fields2(s->fields, m3, m4));
+ gen_helper_cxgb(o->out, cpu_env, o->in2, m);
+ tcg_temp_free_i32(m);
return_low128(o->out2);
return DISAS_NEXT;
}
static DisasJumpType op_celgb(DisasContext *s, DisasOps *o)
{
- TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
- gen_helper_celgb(o->out, cpu_env, o->in2, m3);
- tcg_temp_free_i32(m3);
+ TCGv_i32 m;
+
+ if (!valid_bfp_rounding_mode(get_field(s->fields, m3))) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+ m = tcg_const_i32(get_fields2(s->fields, m3, m4));
+ gen_helper_celgb(o->out, cpu_env, o->in2, m);
+ tcg_temp_free_i32(m);
return DISAS_NEXT;
}
static DisasJumpType op_cdlgb(DisasContext *s, DisasOps *o)
{
- TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
- gen_helper_cdlgb(o->out, cpu_env, o->in2, m3);
- tcg_temp_free_i32(m3);
+ TCGv_i32 m;
+
+ if (!valid_bfp_rounding_mode(get_field(s->fields, m3))) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+ m = tcg_const_i32(get_fields2(s->fields, m3, m4));
+ gen_helper_cdlgb(o->out, cpu_env, o->in2, m);
+ tcg_temp_free_i32(m);
return DISAS_NEXT;
}
static DisasJumpType op_cxlgb(DisasContext *s, DisasOps *o)
{
- TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
- gen_helper_cxlgb(o->out, cpu_env, o->in2, m3);
- tcg_temp_free_i32(m3);
+ TCGv_i32 m;
+
+ if (!valid_bfp_rounding_mode(get_field(s->fields, m3))) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+ m = tcg_const_i32(get_fields2(s->fields, m3, m4));
+ gen_helper_cxlgb(o->out, cpu_env, o->in2, m);
+ tcg_temp_free_i32(m);
return_low128(o->out2);
return DISAS_NEXT;
}
@@ -2390,26 +2500,44 @@ static DisasJumpType op_ex(DisasContext *s, DisasOps *o)
static DisasJumpType op_fieb(DisasContext *s, DisasOps *o)
{
- TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
- gen_helper_fieb(o->out, cpu_env, o->in2, m3);
- tcg_temp_free_i32(m3);
+ TCGv_i32 m;
+
+ if (!valid_bfp_rounding_mode(get_field(s->fields, m3))) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+ m = tcg_const_i32(get_fields2(s->fields, m3, m4));
+ gen_helper_fieb(o->out, cpu_env, o->in2, m);
+ tcg_temp_free_i32(m);
return DISAS_NEXT;
}
static DisasJumpType op_fidb(DisasContext *s, DisasOps *o)
{
- TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
- gen_helper_fidb(o->out, cpu_env, o->in2, m3);
- tcg_temp_free_i32(m3);
+ TCGv_i32 m;
+
+ if (!valid_bfp_rounding_mode(get_field(s->fields, m3))) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+ m = tcg_const_i32(get_fields2(s->fields, m3, m4));
+ gen_helper_fidb(o->out, cpu_env, o->in2, m);
+ tcg_temp_free_i32(m);
return DISAS_NEXT;
}
static DisasJumpType op_fixb(DisasContext *s, DisasOps *o)
{
- TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
- gen_helper_fixb(o->out, cpu_env, o->in1, o->in2, m3);
+ TCGv_i32 m;
+
+ if (!valid_bfp_rounding_mode(get_field(s->fields, m3))) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+ m = tcg_const_i32(get_fields2(s->fields, m3, m4));
+ gen_helper_fixb(o->out, cpu_env, o->in1, o->in2, m);
return_low128(o->out2);
- tcg_temp_free_i32(m3);
+ tcg_temp_free_i32(m);
return DISAS_NEXT;
}
--
2.17.2
- Re: [qemu-s390x] [Qemu-devel] [PATCH v1 08/15] s390x/tcg: Handle SET FPC AND LOAD FPC 3-bit BFP rounding modes, (continued)
[qemu-s390x] [PATCH v1 02/15] s390x/tcg: Fix rounding from float128 to uint64_t/uin32_t, David Hildenbrand, 2019/02/12
[qemu-s390x] [PATCH v1 10/15] s390x/tcg: Refactor saving/restoring the bfp rounding mode, David Hildenbrand, 2019/02/12
[qemu-s390x] [PATCH v1 11/15] s390x/tcg: Prepare for IEEE-inexact-exception control (XxC), David Hildenbrand, 2019/02/12
[qemu-s390x] [PATCH v1 12/15] s390x/tcg: Implement XxC and checks for most FP instructions,
David Hildenbrand <=
[qemu-s390x] [PATCH v1 13/15] s390x/tcg: Implement rounding mode and XxC for LOAD ROUNDED, David Hildenbrand, 2019/02/12
[qemu-s390x] [PATCH v1 14/15] s390x/tcg: Handle all rounding modes overwritten by BFP instructions, David Hildenbrand, 2019/02/12
Re: [qemu-s390x] [PATCH v1] s390x: Add floating-point extension facility to "qemu" cpu model, David Hildenbrand, 2019/02/12
[qemu-s390x] [PATCH v1 15/15] s390x: Add floating-point extension facility to "qemu" cpu model, David Hildenbrand, 2019/02/12