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: Richard Henderson
Subject: Re: [Qemu-devel] [PATCH 5/5] ppc: Improve generation of conditional traps
Date: Sat, 6 Aug 2016 14:33:27 +0530
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.2.0

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.

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



reply via email to

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