target/s390x: Use Int128 for returning float128

Acked-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
v2: Remove extraneous return_low128.
This commit is contained in:
Richard Henderson 2022-10-20 10:15:49 +10:00
parent f4031d9664
commit ee5e866fd2
4 changed files with 63 additions and 59 deletions

View file

@ -1103,6 +1103,7 @@ typedef struct {
bool g_out, g_out2, g_in1, g_in2;
TCGv_i64 out, out2, in1, in2;
TCGv_i64 addr1;
TCGv_i128 out_128;
} DisasOps;
/* Instructions can place constraints on their operands, raising specification
@ -1461,8 +1462,7 @@ static DisasJumpType op_adb(DisasContext *s, DisasOps *o)
static DisasJumpType op_axb(DisasContext *s, DisasOps *o)
{
gen_helper_axb(o->out, cpu_env, o->out, o->out2, o->in1, o->in2);
return_low128(o->out2);
gen_helper_axb(o->out_128, cpu_env, o->out, o->out2, o->in1, o->in2);
return DISAS_NEXT;
}
@ -1995,9 +1995,8 @@ static DisasJumpType op_cxgb(DisasContext *s, DisasOps *o)
if (!m34) {
return DISAS_NORETURN;
}
gen_helper_cxgb(o->out, cpu_env, o->in2, m34);
gen_helper_cxgb(o->out_128, cpu_env, o->in2, m34);
tcg_temp_free_i32(m34);
return_low128(o->out2);
return DISAS_NEXT;
}
@ -2032,9 +2031,8 @@ static DisasJumpType op_cxlgb(DisasContext *s, DisasOps *o)
if (!m34) {
return DISAS_NORETURN;
}
gen_helper_cxlgb(o->out, cpu_env, o->in2, m34);
gen_helper_cxlgb(o->out_128, cpu_env, o->in2, m34);
tcg_temp_free_i32(m34);
return_low128(o->out2);
return DISAS_NEXT;
}
@ -2447,8 +2445,7 @@ static DisasJumpType op_ddb(DisasContext *s, DisasOps *o)
static DisasJumpType op_dxb(DisasContext *s, DisasOps *o)
{
gen_helper_dxb(o->out, cpu_env, o->out, o->out2, o->in1, o->in2);
return_low128(o->out2);
gen_helper_dxb(o->out_128, cpu_env, o->out, o->out2, o->in1, o->in2);
return DISAS_NEXT;
}
@ -2553,8 +2550,7 @@ static DisasJumpType op_fixb(DisasContext *s, DisasOps *o)
if (!m34) {
return DISAS_NORETURN;
}
gen_helper_fixb(o->out, cpu_env, o->in1, o->in2, m34);
return_low128(o->out2);
gen_helper_fixb(o->out_128, cpu_env, o->in1, o->in2, m34);
tcg_temp_free_i32(m34);
return DISAS_NEXT;
}
@ -2866,15 +2862,13 @@ static DisasJumpType op_lexb(DisasContext *s, DisasOps *o)
static DisasJumpType op_lxdb(DisasContext *s, DisasOps *o)
{
gen_helper_lxdb(o->out, cpu_env, o->in2);
return_low128(o->out2);
gen_helper_lxdb(o->out_128, cpu_env, o->in2);
return DISAS_NEXT;
}
static DisasJumpType op_lxeb(DisasContext *s, DisasOps *o)
{
gen_helper_lxeb(o->out, cpu_env, o->in2);
return_low128(o->out2);
gen_helper_lxeb(o->out_128, cpu_env, o->in2);
return DISAS_NEXT;
}
@ -3590,15 +3584,13 @@ static DisasJumpType op_mdb(DisasContext *s, DisasOps *o)
static DisasJumpType op_mxb(DisasContext *s, DisasOps *o)
{
gen_helper_mxb(o->out, cpu_env, o->out, o->out2, o->in1, o->in2);
return_low128(o->out2);
gen_helper_mxb(o->out_128, cpu_env, o->out, o->out2, o->in1, o->in2);
return DISAS_NEXT;
}
static DisasJumpType op_mxdb(DisasContext *s, DisasOps *o)
{
gen_helper_mxdb(o->out, cpu_env, o->out, o->out2, o->in2);
return_low128(o->out2);
gen_helper_mxdb(o->out_128, cpu_env, o->out, o->out2, o->in2);
return DISAS_NEXT;
}
@ -4063,8 +4055,7 @@ static DisasJumpType op_sdb(DisasContext *s, DisasOps *o)
static DisasJumpType 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);
gen_helper_sxb(o->out_128, cpu_env, o->out, o->out2, o->in1, o->in2);
return DISAS_NEXT;
}
@ -4082,8 +4073,7 @@ static DisasJumpType op_sqdb(DisasContext *s, DisasOps *o)
static DisasJumpType op_sqxb(DisasContext *s, DisasOps *o)
{
gen_helper_sqxb(o->out, cpu_env, o->in1, o->in2);
return_low128(o->out2);
gen_helper_sqxb(o->out_128, cpu_env, o->in1, o->in2);
return DISAS_NEXT;
}
@ -5395,6 +5385,14 @@ static void prep_new_P(DisasContext *s, DisasOps *o)
}
#define SPEC_prep_new_P 0
static void prep_new_x(DisasContext *s, DisasOps *o)
{
o->out = tcg_temp_new_i64();
o->out2 = tcg_temp_new_i64();
o->out_128 = tcg_temp_new_i128();
}
#define SPEC_prep_new_x 0
static void prep_r1(DisasContext *s, DisasOps *o)
{
o->out = regs[get_field(s, r1)];
@ -5411,11 +5409,12 @@ static void prep_r1_P(DisasContext *s, DisasOps *o)
}
#define SPEC_prep_r1_P SPEC_r1_even
/* Whenever we need x1 in addition to other inputs, we'll load it to out/out2 */
static void prep_x1(DisasContext *s, DisasOps *o)
{
o->out = load_freg(get_field(s, r1));
o->out2 = load_freg(get_field(s, r1) + 2);
o->out_128 = tcg_temp_new_i128();
tcg_gen_concat_i64_i128(o->out_128, o->out2, o->out);
}
#define SPEC_prep_x1 SPEC_r1_f128
@ -5513,6 +5512,8 @@ static void wout_f1(DisasContext *s, DisasOps *o)
static void wout_x1(DisasContext *s, DisasOps *o)
{
int f1 = get_field(s, r1);
tcg_gen_extr_i128_i64(o->out2, o->out, o->out_128);
store_freg(f1, o->out);
store_freg(f1 + 2, o->out2);
}
@ -6588,7 +6589,9 @@ static DisasJumpType translate_one(CPUS390XState *env, DisasContext *s)
if (o.addr1) {
tcg_temp_free_i64(o.addr1);
}
if (o.out_128) {
tcg_temp_free_i128(o.out_128);
}
/* io should be the last instruction in tb when icount is enabled */
if (unlikely(icount && ret == DISAS_NEXT)) {
ret = DISAS_TOO_MANY;