diff mbox

[PATCHv2,24/31] ppc: Handle unconditional (always/never) traps at translation time

Message ID 1469602609-31349-24-git-send-email-benh@kernel.crashing.org (mailing list archive)
State New, archived
Headers show

Commit Message

Benjamin Herrenschmidt July 27, 2016, 6:56 a.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>
--

v2. Don't generate the helper call when trapping always
---
 target-ppc/translate.c | 49 +++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 43 insertions(+), 6 deletions(-)
diff mbox

Patch

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 20c9cbb..a29c7ce 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -3574,10 +3574,30 @@  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 true;
+    }
+    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);
@@ -3586,8 +3606,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);
@@ -3597,7 +3623,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);
@@ -3606,8 +3637,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);