target/hppa: Pass d to do_sub_cond

Hoist the resolution of d up one level above do_sub_cond.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2023-09-16 19:28:12 -07:00
parent a751eb31b6
commit 4fe9533acc

View file

@ -446,12 +446,15 @@ static DisasCond cond_make_n(void)
}; };
} }
static DisasCond cond_make_0_tmp(TCGCond c, TCGv_reg a0) static DisasCond cond_make_tmp(TCGCond c, TCGv_reg a0, TCGv_reg a1)
{ {
assert (c != TCG_COND_NEVER && c != TCG_COND_ALWAYS); assert (c != TCG_COND_NEVER && c != TCG_COND_ALWAYS);
return (DisasCond){ return (DisasCond){ .c = c, .a0 = a0, .a1 = a1 };
.c = c, .a0 = a0, .a1 = tcg_constant_reg(0) }
};
static DisasCond cond_make_0_tmp(TCGCond c, TCGv_reg a0)
{
return cond_make_tmp(c, a0, tcg_constant_reg(0));
} }
static DisasCond cond_make_0(TCGCond c, TCGv_reg a0) static DisasCond cond_make_0(TCGCond c, TCGv_reg a0)
@ -463,15 +466,12 @@ static DisasCond cond_make_0(TCGCond c, TCGv_reg a0)
static DisasCond cond_make(TCGCond c, TCGv_reg a0, TCGv_reg a1) static DisasCond cond_make(TCGCond c, TCGv_reg a0, TCGv_reg a1)
{ {
DisasCond r = { .c = c }; TCGv_reg t0 = tcg_temp_new();
TCGv_reg t1 = tcg_temp_new();
assert (c != TCG_COND_NEVER && c != TCG_COND_ALWAYS); tcg_gen_mov_reg(t0, a0);
r.a0 = tcg_temp_new(); tcg_gen_mov_reg(t1, a1);
tcg_gen_mov_reg(r.a0, a0); return cond_make_tmp(c, t0, t1);
r.a1 = tcg_temp_new();
tcg_gen_mov_reg(r.a1, a1);
return r;
} }
static void cond_free(DisasCond *cond) static void cond_free(DisasCond *cond)
@ -923,36 +923,55 @@ static DisasCond do_cond(DisasContext *ctx, unsigned cf, bool d,
can use the inputs directly. This can allow other computation to be can use the inputs directly. This can allow other computation to be
deleted as unused. */ deleted as unused. */
static DisasCond do_sub_cond(DisasContext *ctx, unsigned cf, TCGv_reg res, static DisasCond do_sub_cond(DisasContext *ctx, unsigned cf, bool d,
TCGv_reg in1, TCGv_reg in2, TCGv_reg sv) TCGv_reg res, TCGv_reg in1,
TCGv_reg in2, TCGv_reg sv)
{ {
DisasCond cond; TCGCond tc;
bool d = false; bool ext_uns;
switch (cf >> 1) { switch (cf >> 1) {
case 1: /* = / <> */ case 1: /* = / <> */
cond = cond_make(TCG_COND_EQ, in1, in2); tc = TCG_COND_EQ;
ext_uns = true;
break; break;
case 2: /* < / >= */ case 2: /* < / >= */
cond = cond_make(TCG_COND_LT, in1, in2); tc = TCG_COND_LT;
ext_uns = false;
break; break;
case 3: /* <= / > */ case 3: /* <= / > */
cond = cond_make(TCG_COND_LE, in1, in2); tc = TCG_COND_LE;
ext_uns = false;
break; break;
case 4: /* << / >>= */ case 4: /* << / >>= */
cond = cond_make(TCG_COND_LTU, in1, in2); tc = TCG_COND_LTU;
ext_uns = true;
break; break;
case 5: /* <<= / >> */ case 5: /* <<= / >> */
cond = cond_make(TCG_COND_LEU, in1, in2); tc = TCG_COND_LEU;
ext_uns = true;
break; break;
default: default:
return do_cond(ctx, cf, d, res, NULL, sv); return do_cond(ctx, cf, d, res, NULL, sv);
} }
if (cf & 1) {
cond.c = tcg_invert_cond(cond.c);
}
return cond; if (cf & 1) {
tc = tcg_invert_cond(tc);
}
if (cond_need_ext(ctx, d)) {
TCGv_reg t1 = tcg_temp_new();
TCGv_reg t2 = tcg_temp_new();
if (ext_uns) {
tcg_gen_ext32u_reg(t1, in1);
tcg_gen_ext32u_reg(t2, in2);
} else {
tcg_gen_ext32s_reg(t1, in1);
tcg_gen_ext32s_reg(t2, in2);
}
return cond_make_tmp(tc, t1, t2);
}
return cond_make(tc, in1, in2);
} }
/* /*
@ -1280,7 +1299,7 @@ static void do_sub(DisasContext *ctx, unsigned rt, TCGv_reg in1,
/* Compute the condition. We cannot use the special case for borrow. */ /* Compute the condition. We cannot use the special case for borrow. */
if (!is_b) { if (!is_b) {
cond = do_sub_cond(ctx, cf, dest, in1, in2, sv); cond = do_sub_cond(ctx, cf, d, dest, in1, in2, sv);
} else { } else {
cond = do_cond(ctx, cf, d, dest, get_carry(ctx, d, cb, cb_msb), sv); cond = do_cond(ctx, cf, d, dest, get_carry(ctx, d, cb, cb_msb), sv);
} }
@ -1334,6 +1353,7 @@ static void do_cmpclr(DisasContext *ctx, unsigned rt, TCGv_reg in1,
{ {
TCGv_reg dest, sv; TCGv_reg dest, sv;
DisasCond cond; DisasCond cond;
bool d = false;
dest = tcg_temp_new(); dest = tcg_temp_new();
tcg_gen_sub_reg(dest, in1, in2); tcg_gen_sub_reg(dest, in1, in2);
@ -1345,7 +1365,7 @@ static void do_cmpclr(DisasContext *ctx, unsigned rt, TCGv_reg in1,
} }
/* Form the condition for the compare. */ /* Form the condition for the compare. */
cond = do_sub_cond(ctx, cf, dest, in1, in2, sv); cond = do_sub_cond(ctx, cf, d, dest, in1, in2, sv);
/* Clear. */ /* Clear. */
tcg_gen_movi_reg(dest, 0); tcg_gen_movi_reg(dest, 0);
@ -3049,6 +3069,7 @@ static bool do_cmpb(DisasContext *ctx, unsigned r, TCGv_reg in1,
{ {
TCGv_reg dest, in2, sv; TCGv_reg dest, in2, sv;
DisasCond cond; DisasCond cond;
bool d = false;
in2 = load_gpr(ctx, r); in2 = load_gpr(ctx, r);
dest = tcg_temp_new(); dest = tcg_temp_new();
@ -3060,7 +3081,7 @@ static bool do_cmpb(DisasContext *ctx, unsigned r, TCGv_reg in1,
sv = do_sub_sv(ctx, dest, in1, in2); sv = do_sub_sv(ctx, dest, in1, in2);
} }
cond = do_sub_cond(ctx, c * 2 + f, dest, in1, in2, sv); cond = do_sub_cond(ctx, c * 2 + f, d, dest, in1, in2, sv);
return do_cbranch(ctx, disp, n, &cond); return do_cbranch(ctx, disp, n, &cond);
} }