target-s390x: implement LOAD FP INTEGER instructions

This is needed to pass the gcc.c-torture/execute/ieee/20010114-2.c test
in the gcc testsuite.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
Aurelien Jarno 2015-06-03 23:09:46 +02:00 committed by Alexander Graf
parent 9182886d79
commit ed0bcecec1
4 changed files with 63 additions and 0 deletions

View file

@ -552,6 +552,37 @@ uint64_t HELPER(clfxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m3)
return ret;
}
/* round to integer 32-bit */
uint64_t HELPER(fieb)(CPUS390XState *env, uint64_t f2, uint32_t m3)
{
int hold = swap_round_mode(env, m3);
float32 ret = float32_round_to_int(f2, &env->fpu_status);
set_float_rounding_mode(hold, &env->fpu_status);
handle_exceptions(env, GETPC());
return ret;
}
/* round to integer 64-bit */
uint64_t HELPER(fidb)(CPUS390XState *env, uint64_t f2, uint32_t m3)
{
int hold = swap_round_mode(env, m3);
float64 ret = float64_round_to_int(f2, &env->fpu_status);
set_float_rounding_mode(hold, &env->fpu_status);
handle_exceptions(env, GETPC());
return ret;
}
/* round to integer 128-bit */
uint64_t HELPER(fixb)(CPUS390XState *env, uint64_t ah, uint64_t al, uint32_t m3)
{
int hold = swap_round_mode(env, m3);
float128 ret = float128_round_to_int(make_float128(ah, al),
&env->fpu_status);
set_float_rounding_mode(hold, &env->fpu_status);
handle_exceptions(env, GETPC());
return RET128(ret);
}
/* 32-bit FP multiply and add */
uint64_t HELPER(maeb)(CPUS390XState *env, uint64_t f1,
uint64_t f2, uint64_t f3)

View file

@ -60,6 +60,9 @@ DEF_HELPER_FLAGS_4(clgxb, TCG_CALL_NO_WG, i64, env, i64, i64, i32)
DEF_HELPER_FLAGS_3(clfeb, TCG_CALL_NO_WG, i64, env, i64, i32)
DEF_HELPER_FLAGS_3(clfdb, TCG_CALL_NO_WG, i64, env, i64, i32)
DEF_HELPER_FLAGS_4(clfxb, TCG_CALL_NO_WG, i64, env, i64, i64, i32)
DEF_HELPER_FLAGS_3(fieb, TCG_CALL_NO_WG, i64, env, i64, i32)
DEF_HELPER_FLAGS_3(fidb, TCG_CALL_NO_WG, i64, env, i64, i32)
DEF_HELPER_FLAGS_4(fixb, TCG_CALL_NO_WG, i64, env, i64, i64, i32)
DEF_HELPER_FLAGS_4(maeb, TCG_CALL_NO_WG, i64, env, i64, i64, i64)
DEF_HELPER_FLAGS_4(madb, TCG_CALL_NO_WG, i64, env, i64, i64, i64)
DEF_HELPER_FLAGS_4(mseb, TCG_CALL_NO_WG, i64, env, i64, i64, i64)

View file

@ -479,6 +479,10 @@
C(0xb29d, LFPC, S, Z, 0, m2_32u, 0, 0, sfpc, 0)
/* LOAD FPC AND SIGNAL */
C(0xb2bd, LFAS, S, IEEEE_SIM, 0, m2_32u, 0, 0, sfas, 0)
/* LOAD FP INTEGER */
C(0xb357, FIEBR, RRF_e, Z, 0, e2, new, e1, fieb, 0)
C(0xb35f, FIDBR, RRF_e, Z, 0, f2_o, f1, 0, fidb, 0)
C(0xb347, FIXBR, RRF_e, Z, 0, x2_o, x1, 0, fixb, 0)
/* LOAD LENGTHENED */
C(0xb304, LDEBR, RRE, Z, 0, e2, f1, 0, ldeb, 0)

View file

@ -2116,6 +2116,31 @@ static ExitStatus op_ex(DisasContext *s, DisasOps *o)
return NO_EXIT;
}
static ExitStatus 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);
return NO_EXIT;
}
static ExitStatus 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);
return NO_EXIT;
}
static ExitStatus 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);
return_low128(o->out2);
tcg_temp_free_i32(m3);
return NO_EXIT;
}
static ExitStatus op_flogr(DisasContext *s, DisasOps *o)
{
/* We'll use the original input for cc computation, since we get to