Message ID | 1469941993-27576-5-git-send-email-benh@kernel.crashing.org |
---|---|
State | New |
Headers | show |
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 <benh@kernel.crashing.org> > --- > 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. > + -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. > +#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? > 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. r~
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 <benh@kernel.crashing.org> > > --- > > 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~
On Sun, Jul 31, 2016 at 03:13:13PM +1000, Benjamin Herrenschmidt wrote: > Translate most conditions to TCG conditions and avoid the helper > for most of the common cases. > > Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> > --- > target-ppc/translate.c | 168 ++++++++++++++++++++++++++++++++++++++----------- > 1 file changed, 132 insertions(+), 36 deletions(-) I've merged 1-4 of this series into ppc-for-2.8. I'm not really clear whether a change is still needed on patch 5, so please resend either way. > > 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] = { > + TCG_COND_NEVER, /* no condition */ > + TCG_COND_GTU, /* 0x01 u> */ > + TCG_COND_LTU, /* 0x02 u< */ > + TCG_COND_NE, /* 0x03 u< or u> -> NE */ > + TCG_COND_EQ, /* 0x04 = */ > + TCG_COND_GEU, /* 0x05 u> or = */ > + TCG_COND_LEU, /* 0x06 u< or = */ > + TCG_COND_ALWAYS,/* 0x07 u< or u> or = -> ALWAYS */ > + TCG_COND_GT, /* 0x08 > */ > + -1, /* 0x09 > or u> -> weird */ > + -1, /* 0x0a > or u< -> weird */ > + -1, /* 0x0b > or u< or u> -> weird */ > + TCG_COND_GE, /* 0x0c > or = */ > + -1, /* 0x0d > or = or u> */ > + -1, /* 0x0e > or = or u< */ > + -1, /* 0x0f > or = or u> or u< */ > + TCG_COND_LT, /* 0x10 < */ > + -1, /* 0x11 < or u> -> weird */ > + -1, /* 0x12 < or u< -> weird */ > + -1, /* 0x13 < or u< or u> -> weird */ > + TCG_COND_LE, /* 0x14 < or = */ > + -1, /* 0x15 < or = or u> -> weird */ > + -1, /* 0x16 < or = or u< -> weird */ > + TCG_COND_ALWAYS,/* 0x17 < or = or u< or u> -> ALWAYS */ > + TCG_COND_NE, /* 0x18 < or > -> NE */ > + -1, /* 0x19 < or > or u> -> weird */ > + -1, /* 0x1a < or > or u< -> weird */ > + -1, /* 0x1b < or > or u> or u< -> weird */ > + TCG_COND_ALWAYS,/* 0x1c < or > or = -> ALWAYS */ > + TCG_COND_ALWAYS,/* 0x1d < or > or = or u> -> ALWAYS */ > + TCG_COND_ALWAYS,/* 0x1e < or > or = or u< -> ALWAYS */ > + TCG_COND_ALWAYS,/* 0x1f < or > or = or u< -> ALWAYS */ > +}; > + > +#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); > + tcg_temp_free_i32(t0); > + tcg_temp_free_i32(t1); > } > > /* tw */ > 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); > + gen_trap(ctx); > + gen_set_label(l1); > + tcg_temp_free(t0); > + tcg_temp_free(t1); > } > > /* twi */ > static void gen_twi(DisasContext *ctx) > { > + int cond = precheck_trap(ctx); > + TCGLabel *l1; > TCGv t0; > - TCGv_i32 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)); > + t0 = tcg_const_tl(SIMM(ctx->opcode)); > + gen_helper_tw(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, trapop); > + tcg_temp_free_i32(trapop); > + tcg_temp_free(t0); > 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); > + l1 = gen_new_label(); > + t0 = tcg_temp_new(); > + tcg_gen_ext32s_tl(t0, cpu_gpr[rA(ctx->opcode)]); > + tcg_gen_brcondi_tl(cond, t0, SIMM(ctx->opcode), l1); > + gen_trap(ctx); > + gen_set_label(l1); > tcg_temp_free(t0); > - tcg_temp_free_i32(t1); > } > > #if defined(TARGET_PPC64) > /* td */ > static void gen_td(DisasContext *ctx) > { > - TCGv_i32 t0; > + int cond = precheck_trap(ctx); > + TCGLabel *l1; > > - 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_td(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_td(cpu_env, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], > - t0); > - tcg_temp_free_i32(t0); > + l1 = gen_new_label(); > + tcg_gen_brcond_tl(cond, cpu_gpr[rA(ctx->opcode)], > + cpu_gpr[rB(ctx->opcode)], l1); > + gen_trap(ctx); > + gen_set_label(l1); > } > > /* tdi */ > static void gen_tdi(DisasContext *ctx) > { > - TCGv t0; > - TCGv_i32 t1; > + int cond = precheck_trap(ctx); > + TCGLabel *l1; > > - if (check_unconditional_trap(ctx)) { > + if (cond == TRAP_UNCOND) { > + return; > + } else if (cond == TRAP_HELPER) { > + TCGv_i32 trapop = tcg_const_i32(TO(ctx->opcode)); > + TCGv t0 = tcg_const_tl(SIMM(ctx->opcode)); > + gen_helper_td(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, trapop); > + tcg_temp_free_i32(trapop); > + tcg_temp_free(t0); > 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); > + l1 = gen_new_label(); > + tcg_gen_brcondi_tl(cond, cpu_gpr[rA(ctx->opcode)], SIMM(ctx->opcode), l1); > + gen_trap(ctx); > + gen_set_label(l1); > } > -#endif > +#endif /* defined(TARGET_PPC64) */ > > /*** Processor control ***/ >
On Tue, 2016-08-09 at 12:07 +1000, David Gibson wrote: > On Sun, Jul 31, 2016 at 03:13:13PM +1000, Benjamin Herrenschmidt > wrote: > > > > Translate most conditions to TCG conditions and avoid the helper > > for most of the common cases. > > > > Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> > > --- > > target-ppc/translate.c | 168 > > ++++++++++++++++++++++++++++++++++++++----------- > > 1 file changed, 132 insertions(+), 36 deletions(-) > > I've merged 1-4 of this series into ppc-for-2.8. I'm not really > clear > whether a change is still needed on patch 5, so please resend either > way. What you merged works fine. Richard suggestions are refinements I can do separately and apply on top. Cheers, Ben.
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] = { + TCG_COND_NEVER, /* no condition */ + TCG_COND_GTU, /* 0x01 u> */ + TCG_COND_LTU, /* 0x02 u< */ + TCG_COND_NE, /* 0x03 u< or u> -> NE */ + TCG_COND_EQ, /* 0x04 = */ + TCG_COND_GEU, /* 0x05 u> or = */ + TCG_COND_LEU, /* 0x06 u< or = */ + TCG_COND_ALWAYS,/* 0x07 u< or u> or = -> ALWAYS */ + TCG_COND_GT, /* 0x08 > */ + -1, /* 0x09 > or u> -> weird */ + -1, /* 0x0a > or u< -> weird */ + -1, /* 0x0b > or u< or u> -> weird */ + TCG_COND_GE, /* 0x0c > or = */ + -1, /* 0x0d > or = or u> */ + -1, /* 0x0e > or = or u< */ + -1, /* 0x0f > or = or u> or u< */ + TCG_COND_LT, /* 0x10 < */ + -1, /* 0x11 < or u> -> weird */ + -1, /* 0x12 < or u< -> weird */ + -1, /* 0x13 < or u< or u> -> weird */ + TCG_COND_LE, /* 0x14 < or = */ + -1, /* 0x15 < or = or u> -> weird */ + -1, /* 0x16 < or = or u< -> weird */ + TCG_COND_ALWAYS,/* 0x17 < or = or u< or u> -> ALWAYS */ + TCG_COND_NE, /* 0x18 < or > -> NE */ + -1, /* 0x19 < or > or u> -> weird */ + -1, /* 0x1a < or > or u< -> weird */ + -1, /* 0x1b < or > or u> or u< -> weird */ + TCG_COND_ALWAYS,/* 0x1c < or > or = -> ALWAYS */ + TCG_COND_ALWAYS,/* 0x1d < or > or = or u> -> ALWAYS */ + TCG_COND_ALWAYS,/* 0x1e < or > or = or u< -> ALWAYS */ + TCG_COND_ALWAYS,/* 0x1f < or > or = or u< -> ALWAYS */ +}; + +#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); + tcg_temp_free_i32(t0); + tcg_temp_free_i32(t1); } /* tw */ 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); + gen_trap(ctx); + gen_set_label(l1); + tcg_temp_free(t0); + tcg_temp_free(t1); } /* twi */ static void gen_twi(DisasContext *ctx) { + int cond = precheck_trap(ctx); + TCGLabel *l1; TCGv t0; - TCGv_i32 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)); + t0 = tcg_const_tl(SIMM(ctx->opcode)); + gen_helper_tw(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, trapop); + tcg_temp_free_i32(trapop); + tcg_temp_free(t0); 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); + l1 = gen_new_label(); + t0 = tcg_temp_new(); + tcg_gen_ext32s_tl(t0, cpu_gpr[rA(ctx->opcode)]); + tcg_gen_brcondi_tl(cond, t0, SIMM(ctx->opcode), l1); + gen_trap(ctx); + gen_set_label(l1); tcg_temp_free(t0); - tcg_temp_free_i32(t1); } #if defined(TARGET_PPC64) /* td */ static void gen_td(DisasContext *ctx) { - TCGv_i32 t0; + int cond = precheck_trap(ctx); + TCGLabel *l1; - 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_td(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_td(cpu_env, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], - t0); - tcg_temp_free_i32(t0); + l1 = gen_new_label(); + tcg_gen_brcond_tl(cond, cpu_gpr[rA(ctx->opcode)], + cpu_gpr[rB(ctx->opcode)], l1); + gen_trap(ctx); + gen_set_label(l1); } /* tdi */ static void gen_tdi(DisasContext *ctx) { - TCGv t0; - TCGv_i32 t1; + int cond = precheck_trap(ctx); + TCGLabel *l1; - if (check_unconditional_trap(ctx)) { + if (cond == TRAP_UNCOND) { + return; + } else if (cond == TRAP_HELPER) { + TCGv_i32 trapop = tcg_const_i32(TO(ctx->opcode)); + TCGv t0 = tcg_const_tl(SIMM(ctx->opcode)); + gen_helper_td(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, trapop); + tcg_temp_free_i32(trapop); + tcg_temp_free(t0); 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); + l1 = gen_new_label(); + tcg_gen_brcondi_tl(cond, cpu_gpr[rA(ctx->opcode)], SIMM(ctx->opcode), l1); + gen_trap(ctx); + gen_set_label(l1); } -#endif +#endif /* defined(TARGET_PPC64) */ /*** Processor control ***/
Translate most conditions to TCG conditions and avoid the helper for most of the common cases. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> --- target-ppc/translate.c | 168 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 132 insertions(+), 36 deletions(-)