[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH 5/5] ppc: Improve generation of conditional trap
From: |
Benjamin Herrenschmidt |
Subject: |
Re: [Qemu-devel] [PATCH 5/5] ppc: Improve generation of conditional traps |
Date: |
Sun, 07 Aug 2016 10:47:39 +1000 |
On Sat, 2016-08-06 at 14:33 +0530, Richard Henderson wrote:
> On 07/31/2016 10:43 AM, Benjamin Herrenschmidt wrote:
> >
> > Translate most conditions to TCG conditions and avoid the helper
> > for most of the common cases.
> >
> > > > Signed-off-by: Benjamin Herrenschmidt <address@hidden>
> > ---
> > target-ppc/translate.c | 168
> > ++++++++++++++++++++++++++++++++++++++-----------
> > 1 file changed, 132 insertions(+), 36 deletions(-)
> >
> > diff --git a/target-ppc/translate.c b/target-ppc/translate.c
> > index 47eb9ed..561976f 100644
> > --- a/target-ppc/translate.c
> > +++ b/target-ppc/translate.c
> > @@ -3639,82 +3639,178 @@ static void gen_sc(DisasContext *ctx)
> >
> > /*** Trap
> > ***/
> >
> > -/* Check for unconditional traps (always or never) */
> > -static bool check_unconditional_trap(DisasContext *ctx)
> > +static int TO2tcg[32] = {
>
> Should be const.
Indeed.
> >
> > + -1, /* 0x0f > or = or u> or u< */
> > + -1, /* 0x13 < or u< or u> -> weird */
> > + -1, /* 0x19 < or > or u> -> weird */
> > + -1, /* 0x1a < or > or u< -> weird */
> > + -1, /* 0x1b < or > or u> or u< -> weird */
>
> Not that it matters much, but when you have both < and >, or both u< and u>,
> you can collapse to NE, no matter what else is there.
Not necessarily, if = is there too it beomes always ;-) But as
a rule I bail to the helper for anything that mixes signed and
non-signed, in part bcs I was thinking of tracing them in case
anybody uses such oddball constructs. I expect them to never
happen unless somebody has a bug.
> >
> > +#define TRAP_UNCOND (-1)
> > +#define TRAP_HELPER (-2)
> > +
> > +static int precheck_trap(DisasContext *ctx)
> > {
> > - /* Trap never */
> > - if (TO(ctx->opcode) == 0) {
> > - return true;
> > + int cond = TO2tcg[TO(ctx->opcode)];
> > +
> > + /* Weird traps go to helper */
> > + if (cond < 0) {
> > + return TRAP_HELPER;
> > }
> > - /* Trap always */
> > - if (TO(ctx->opcode) == 31) {
> > + /* Unconditionals */
> > + if (cond == TCG_COND_ALWAYS) {
> > gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_TRAP);
> > - return true;
> > + return TRAP_UNCOND;
> > }
> > - return false;
> > + if (cond == TCG_COND_NEVER) {
> > + return TRAP_UNCOND;
> > + }
> > + /* Invert the condition as we branch over the exception when the
> > + * condition is *not* met
> > + */
> > + return tcg_invert_cond(cond);
> > +}
> > +
> > +static void gen_trap(DisasContext *ctx)
> > +{
> > + TCGv_i32 t0, t1;
> > +
> > + t0 = tcg_const_i32(POWERPC_EXCP_PROGRAM);
> > + t1 = tcg_const_i32(POWERPC_EXCP_TRAP);
> > + gen_update_nip(ctx, ctx->nip - 4);
> > + gen_helper_raise_exception_err(cpu_env, t0, t1);
>
> gen_exception_err, as with the unconditional trap?
No, we call it from gen_tw etc... but we may also branch
around that call, so we should not exit the TB with an
exception in the context.
> >
> > static void gen_tw(DisasContext *ctx)
> > {
> > - TCGv_i32 t0;
> > + int cond = precheck_trap(ctx);
> > + TCGLabel *l1;
> > + TCGv t0;
> > + TCGv t1;
> >
> > - if (check_unconditional_trap(ctx)) {
> > + if (cond == TRAP_UNCOND) {
> > + return;
> > + } else if (cond == TRAP_HELPER) {
> > + TCGv_i32 trapop = tcg_const_i32(TO(ctx->opcode));
> > + gen_helper_tw(cpu_env, cpu_gpr[rA(ctx->opcode)],
> > + cpu_gpr[rB(ctx->opcode)], trapop);
> > + tcg_temp_free_i32(trapop);
> > return;
> > }
> > - t0 = tcg_const_i32(TO(ctx->opcode));
> > - gen_helper_tw(cpu_env, cpu_gpr[rA(ctx->opcode)],
> > cpu_gpr[rB(ctx->opcode)],
> > - t0);
> > - tcg_temp_free_i32(t0);
> > + l1 = gen_new_label();
> > + t0 = tcg_temp_new();
> > + t1 = tcg_temp_new();
> > + tcg_gen_ext32s_tl(t0, cpu_gpr[rA(ctx->opcode)]);
> > + tcg_gen_ext32s_tl(t1, cpu_gpr[rB(ctx->opcode)]);
> > + tcg_gen_brcond_tl(cond, t0, t1, l1);
>
> It's just as easy, and perhaps better, to truncate to 32 bits instead of
> extending to TL bits.
Ok, I'll have a look. I'm not actually *that* familiar with the various
ops in the IR, but I shall figure it out :-)
Cheers,
Ben.
>
> r~