Skip to content

Commit

Permalink
target-s390x: implement LOAD FP INTEGER instructions
Browse files Browse the repository at this point in the history
This is needed to pass the gcc.c-torture/execute/ieee/20010114-2.c test
in the gcc testsuite.

Signed-off-by: Aurelien Jarno <[email protected]>
Reviewed-by: Richard Henderson <[email protected]>
Signed-off-by: Alexander Graf <[email protected]>
  • Loading branch information
aurel32 authored and agraf committed Jun 4, 2015
1 parent 9182886 commit ed0bcec
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 0 deletions.
31 changes: 31 additions & 0 deletions target-s390x/fpu_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
3 changes: 3 additions & 0 deletions target-s390x/helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 4 additions & 0 deletions target-s390x/insn-data.def
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
25 changes: 25 additions & 0 deletions target-s390x/translate.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit ed0bcec

Please sign in to comment.