diff mbox

[25/32] ppc: Handle unconditional (always/never) traps at translation time

Message ID 1469571686-7284-25-git-send-email-benh@kernel.crashing.org (mailing list archive)
State New, archived
Headers show

Commit Message

Benjamin Herrenschmidt July 26, 2016, 10:21 p.m. UTC
We don't need to call a helper for trap always and trap never
which are used by Linux under some circumstances.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 target-ppc/translate.c | 48 ++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 42 insertions(+), 6 deletions(-)

Comments

David Gibson July 27, 2016, 2:33 a.m. UTC | #1
On Wed, Jul 27, 2016 at 08:21:19AM +1000, Benjamin Herrenschmidt wrote:
> We don't need to call a helper for trap always and trap never
> which are used by Linux under some circumstances.
> 
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> ---
>  target-ppc/translate.c | 48 ++++++++++++++++++++++++++++++++++++++++++------
>  1 file changed, 42 insertions(+), 6 deletions(-)
> 
> diff --git a/target-ppc/translate.c b/target-ppc/translate.c
> index 9af3f5f..57a891b 100644
> --- a/target-ppc/translate.c
> +++ b/target-ppc/translate.c
> @@ -3360,10 +3360,29 @@ static void gen_sc(DisasContext *ctx)
>  
>  /***                                Trap                                   ***/
>  
> +/* Check for unconditional traps (always or never) */
> +static bool check_unconditional_trap(DisasContext *ctx)
> +{
> +    /* Trap never */
> +    if (TO(ctx->opcode) == 0) {
> +        return true;
> +    }
> +    /* Trap always */
> +    if (TO(ctx->opcode) == 31) {
> +        gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_TRAP);

Should you be returning true here?

Without it, IIUC, the functions below will generate the unconditional
trap, then generate more code to actually test the condition and trap
again.

> +    }
> +    return false;
> +}
> +
>  /* tw */
>  static void gen_tw(DisasContext *ctx)
>  {
> -    TCGv_i32 t0 = tcg_const_i32(TO(ctx->opcode));
> +    TCGv_i32 t0;
> +
> +    if (check_unconditional_trap(ctx)) {
> +        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);
> @@ -3372,8 +3391,14 @@ static void gen_tw(DisasContext *ctx)
>  /* twi */
>  static void gen_twi(DisasContext *ctx)
>  {
> -    TCGv t0 = tcg_const_tl(SIMM(ctx->opcode));
> -    TCGv_i32 t1 = tcg_const_i32(TO(ctx->opcode));
> +    TCGv t0;
> +    TCGv_i32 t1;
> +
> +    if (check_unconditional_trap(ctx)) {
> +        return;
> +    }
> +    t0 = tcg_const_tl(SIMM(ctx->opcode));
> +    t1 = tcg_const_i32(TO(ctx->opcode));
>      gen_helper_tw(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, t1);
>      tcg_temp_free(t0);
>      tcg_temp_free_i32(t1);
> @@ -3383,7 +3408,12 @@ static void gen_twi(DisasContext *ctx)
>  /* td */
>  static void gen_td(DisasContext *ctx)
>  {
> -    TCGv_i32 t0 = tcg_const_i32(TO(ctx->opcode));
> +    TCGv_i32 t0;
> +
> +    if (check_unconditional_trap(ctx)) {
> +        return;
> +    }
> +    t0 = tcg_const_i32(TO(ctx->opcode));
>      gen_helper_td(cpu_env, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
>                    t0);
>      tcg_temp_free_i32(t0);
> @@ -3392,8 +3422,14 @@ static void gen_td(DisasContext *ctx)
>  /* tdi */
>  static void gen_tdi(DisasContext *ctx)
>  {
> -    TCGv t0 = tcg_const_tl(SIMM(ctx->opcode));
> -    TCGv_i32 t1 = tcg_const_i32(TO(ctx->opcode));
> +    TCGv t0;
> +    TCGv_i32 t1;
> +
> +    if (check_unconditional_trap(ctx)) {
> +        return;
> +    }
> +    t0 = tcg_const_tl(SIMM(ctx->opcode));
> +    t1 = tcg_const_i32(TO(ctx->opcode));
>      gen_helper_td(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, t1);
>      tcg_temp_free(t0);
>      tcg_temp_free_i32(t1);
Benjamin Herrenschmidt July 27, 2016, 4 a.m. UTC | #2
On Wed, 2016-07-27 at 12:33 +1000, David Gibson wrote:

> Should you be returning true here?

> 

> Without it, IIUC, the functions below will generate the unconditional

> trap, then generate more code to actually test the condition and trap

> again.


You are right, we generate dead code, will fix.

Cheers,
Ben.

> > 

> > +    }

> > +    return false;

> > +}

> > +

> >  /* tw */

> >  static void gen_tw(DisasContext *ctx)

> >  {

> > -    TCGv_i32 t0 = tcg_const_i32(TO(ctx->opcode));

> > +    TCGv_i32 t0;

> > +

> > +    if (check_unconditional_trap(ctx)) {

> > +        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);

> > @@ -3372,8 +3391,14 @@ static void gen_tw(DisasContext *ctx)

> >  /* twi */

> >  static void gen_twi(DisasContext *ctx)

> >  {

> > -    TCGv t0 = tcg_const_tl(SIMM(ctx->opcode));

> > -    TCGv_i32 t1 = tcg_const_i32(TO(ctx->opcode));

> > +    TCGv t0;

> > +    TCGv_i32 t1;

> > +

> > +    if (check_unconditional_trap(ctx)) {

> > +        return;

> > +    }

> > +    t0 = tcg_const_tl(SIMM(ctx->opcode));

> > +    t1 = tcg_const_i32(TO(ctx->opcode));

> >      gen_helper_tw(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, t1);

> >      tcg_temp_free(t0);

> >      tcg_temp_free_i32(t1);

> > @@ -3383,7 +3408,12 @@ static void gen_twi(DisasContext *ctx)

> >  /* td */

> >  static void gen_td(DisasContext *ctx)

> >  {

> > -    TCGv_i32 t0 = tcg_const_i32(TO(ctx->opcode));

> > +    TCGv_i32 t0;

> > +

> > +    if (check_unconditional_trap(ctx)) {

> > +        return;

> > +    }

> > +    t0 = tcg_const_i32(TO(ctx->opcode));

> >      gen_helper_td(cpu_env, cpu_gpr[rA(ctx->opcode)],

> > cpu_gpr[rB(ctx->opcode)],

> >                    t0);

> >      tcg_temp_free_i32(t0);

> > @@ -3392,8 +3422,14 @@ static void gen_td(DisasContext *ctx)

> >  /* tdi */

> >  static void gen_tdi(DisasContext *ctx)

> >  {

> > -    TCGv t0 = tcg_const_tl(SIMM(ctx->opcode));

> > -    TCGv_i32 t1 = tcg_const_i32(TO(ctx->opcode));

> > +    TCGv t0;

> > +    TCGv_i32 t1;

> > +

> > +    if (check_unconditional_trap(ctx)) {

> > +        return;

> > +    }

> > +    t0 = tcg_const_tl(SIMM(ctx->opcode));

> > +    t1 = tcg_const_i32(TO(ctx->opcode));

> >      gen_helper_td(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, t1);

> >      tcg_temp_free(t0);

> >      tcg_temp_free_i32(t1);

>
diff mbox

Patch

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 9af3f5f..57a891b 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -3360,10 +3360,29 @@  static void gen_sc(DisasContext *ctx)
 
 /***                                Trap                                   ***/
 
+/* Check for unconditional traps (always or never) */
+static bool check_unconditional_trap(DisasContext *ctx)
+{
+    /* Trap never */
+    if (TO(ctx->opcode) == 0) {
+        return true;
+    }
+    /* Trap always */
+    if (TO(ctx->opcode) == 31) {
+        gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_TRAP);
+    }
+    return false;
+}
+
 /* tw */
 static void gen_tw(DisasContext *ctx)
 {
-    TCGv_i32 t0 = tcg_const_i32(TO(ctx->opcode));
+    TCGv_i32 t0;
+
+    if (check_unconditional_trap(ctx)) {
+        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);
@@ -3372,8 +3391,14 @@  static void gen_tw(DisasContext *ctx)
 /* twi */
 static void gen_twi(DisasContext *ctx)
 {
-    TCGv t0 = tcg_const_tl(SIMM(ctx->opcode));
-    TCGv_i32 t1 = tcg_const_i32(TO(ctx->opcode));
+    TCGv t0;
+    TCGv_i32 t1;
+
+    if (check_unconditional_trap(ctx)) {
+        return;
+    }
+    t0 = tcg_const_tl(SIMM(ctx->opcode));
+    t1 = tcg_const_i32(TO(ctx->opcode));
     gen_helper_tw(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, t1);
     tcg_temp_free(t0);
     tcg_temp_free_i32(t1);
@@ -3383,7 +3408,12 @@  static void gen_twi(DisasContext *ctx)
 /* td */
 static void gen_td(DisasContext *ctx)
 {
-    TCGv_i32 t0 = tcg_const_i32(TO(ctx->opcode));
+    TCGv_i32 t0;
+
+    if (check_unconditional_trap(ctx)) {
+        return;
+    }
+    t0 = tcg_const_i32(TO(ctx->opcode));
     gen_helper_td(cpu_env, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
                   t0);
     tcg_temp_free_i32(t0);
@@ -3392,8 +3422,14 @@  static void gen_td(DisasContext *ctx)
 /* tdi */
 static void gen_tdi(DisasContext *ctx)
 {
-    TCGv t0 = tcg_const_tl(SIMM(ctx->opcode));
-    TCGv_i32 t1 = tcg_const_i32(TO(ctx->opcode));
+    TCGv t0;
+    TCGv_i32 t1;
+
+    if (check_unconditional_trap(ctx)) {
+        return;
+    }
+    t0 = tcg_const_tl(SIMM(ctx->opcode));
+    t1 = tcg_const_i32(TO(ctx->opcode));
     gen_helper_td(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, t1);
     tcg_temp_free(t0);
     tcg_temp_free_i32(t1);