qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] target-mips: add ERETNC instruction and Config5.LLB


From: Leon Alrae
Subject: [Qemu-devel] [PATCH] target-mips: add ERETNC instruction and Config5.LLB bit
Date: Thu, 4 Jun 2015 17:00:31 +0100

ERETNC is identical to ERET except that an ERETNC will not clear the LLbit
that is set by execution of an LL instruction, and thus when placed between
an LL and SC sequence, will never cause the SC to fail.

Presence of ERETNC is denoted by the Config5.LLB.

Signed-off-by: Leon Alrae <address@hidden>
---
 disas/mips.c                 |  1 +
 target-mips/cpu.h            |  1 +
 target-mips/helper.h         |  1 +
 target-mips/op_helper.c      | 12 +++++++++++-
 target-mips/translate.c      | 20 +++++++++++++++-----
 target-mips/translate_init.c |  4 +++-
 6 files changed, 32 insertions(+), 7 deletions(-)

diff --git a/disas/mips.c b/disas/mips.c
index 8aaa87c..32940fe 100644
--- a/disas/mips.c
+++ b/disas/mips.c
@@ -2409,6 +2409,7 @@ const struct mips_opcode mips_builtin_opcodes[] =
 {"emt",     "",                0x41600be1, 0xffffffff, TRAP,                   
0,              MT32    },
 {"emt",     "t",       0x41600be1, 0xffe0ffff, TRAP|WR_t,              0,      
        MT32    },
 {"eret",    "",         0x42000018, 0xffffffff, 0,                     0,      
        I3|I32  },
+{"eretnc",  "",         0x42000058, 0xffffffff, 0,                    0, I33},
 {"evpe",    "",                0x41600021, 0xffffffff, TRAP,                   
0,              MT32    },
 {"evpe",    "t",       0x41600021, 0xffe0ffff, TRAP|WR_t,              0,      
        MT32    },
 {"ext",     "t,r,+A,+C", 0x7c000000, 0xfc00003f, WR_t|RD_s,                    
0,              I33     },
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index 7b5ef36..474a0e3 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -474,6 +474,7 @@ struct CPUMIPSState {
 #define CP0C5_FRE        8
 #define CP0C5_SBRI       6
 #define CP0C5_MVH        5
+#define CP0C5_LLB        4
 #define CP0C5_UFR        2
 #define CP0C5_NFExists   0
     int32_t CP0_Config6;
diff --git a/target-mips/helper.h b/target-mips/helper.h
index bdd5ba5..8df98c7 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -348,6 +348,7 @@ DEF_HELPER_1(tlbinvf, void, env)
 DEF_HELPER_1(di, tl, env)
 DEF_HELPER_1(ei, tl, env)
 DEF_HELPER_1(eret, void, env)
+DEF_HELPER_1(eretnc, void, env)
 DEF_HELPER_1(deret, void, env)
 #endif /* !CONFIG_USER_ONLY */
 DEF_HELPER_1(rdhwr_cpunum, tl, env)
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index 5ca95c5..90394b0 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -2123,7 +2123,7 @@ static void set_pc(CPUMIPSState *env, target_ulong 
error_pc)
     }
 }
 
-void helper_eret(CPUMIPSState *env)
+static inline void exception_return(CPUMIPSState *env)
 {
     debug_pre_eret(env);
     if (env->CP0_Status & (1 << CP0St_ERL)) {
@@ -2135,9 +2135,19 @@ void helper_eret(CPUMIPSState *env)
     }
     compute_hflags(env);
     debug_post_eret(env);
+}
+
+void helper_eret(CPUMIPSState *env)
+{
+    exception_return(env);
     env->lladdr = 1;
 }
 
+void helper_eretnc(CPUMIPSState *env)
+{
+    exception_return(env);
+}
+
 void helper_deret(CPUMIPSState *env)
 {
     debug_pre_eret(env);
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 0ca610c..1bdc2e1 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -8142,16 +8142,26 @@ static void gen_cp0 (CPUMIPSState *env, DisasContext 
*ctx, uint32_t opc, int rt,
             goto die;
         gen_helper_tlbr(cpu_env);
         break;
-    case OPC_ERET:
-        opn = "eret";
-        check_insn(ctx, ISA_MIPS2);
+    case OPC_ERET: /* OPC_ERETNC */
         if ((ctx->insn_flags & ISA_MIPS32R6) &&
             (ctx->hflags & MIPS_HFLAG_BMASK)) {
             MIPS_DEBUG("CTI in delay / forbidden slot");
             goto die;
+        } else {
+            int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
+            if (ctx->opcode & (1 << bit_shift)) {
+                /* OPC_ERETNC */
+                opn = "eretnc";
+                check_insn(ctx, ISA_MIPS32R5);
+                gen_helper_eretnc(cpu_env);
+            } else {
+                /* OPC_ERET */
+                opn = "eret";
+                check_insn(ctx, ISA_MIPS2);
+                gen_helper_eret(cpu_env);
+            }
+            ctx->bstate = BS_EXCP;
         }
-        gen_helper_eret(cpu_env);
-        ctx->bstate = BS_EXCP;
         break;
     case OPC_DERET:
         opn = "deret";
diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c
index 836b7bf..fcf957b 100644
--- a/target-mips/translate_init.c
+++ b/target-mips/translate_init.c
@@ -404,7 +404,8 @@ static const mips_def_t mips_defs[] =
                        (1 << CP0C3_LPA),
         .CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M),
         .CP0_Config4_rw_bitmask = 0,
-        .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_UFR) | (1 << CP0C5_MVH),
+        .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_UFR) | (1 << CP0C5_MVH) |
+                       (1 << CP0C5_LLB),
         .CP0_Config5_rw_bitmask = (0 << CP0C5_M) | (1 << CP0C5_K) |
                                   (1 << CP0C5_CV) | (0 << CP0C5_EVA) |
                                   (1 << CP0C5_MSAEn) | (1 << CP0C5_UFR) |
@@ -622,6 +623,7 @@ static const mips_def_t mips_defs[] =
                        (1U << CP0C3_M),
         .CP0_Config4 = MIPS_CONFIG4 | (0xfc << CP0C4_KScrExist) |
                        (3 << CP0C4_IE) | (1 << CP0C4_M),
+        .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_LLB),
         .CP0_Config5_rw_bitmask = (1 << CP0C5_SBRI) | (1 << CP0C5_FRE) |
                                   (1 << CP0C5_UFE),
         .CP0_LLAddr_rw_bitmask = 0,



reply via email to

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