qemu-devel
[Top][All Lists]
Advanced

[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~

reply via email to

[Prev in Thread] Current Thread [Next in Thread]