Message ID | 1469571686-7284-25-git-send-email-benh@kernel.crashing.org |
---|---|
State | New |
Headers | show |
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);
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 --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);
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(-)