target-ppc: Introduce tbegin
authorTom Musta <tommusta@gmail.com>
Thu, 18 Dec 2014 16:34:34 +0000 (10:34 -0600)
committerAlexander Graf <agraf@suse.de>
Wed, 7 Jan 2015 15:16:27 +0000 (16:16 +0100)
Provide a degenerate implementation of the tbegin instruction.  This
implementation always fails the transaction, recording the failure
per Book II Section 5.3.2 of the Power ISA V2.07.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
target-ppc/helper.h
target-ppc/mem_helper.c
target-ppc/translate.c

index 2841f61aba5244159e6e213d2f414f0886e763a0..869be1509df00729cb41284632587da139f4f656 100644 (file)
@@ -665,3 +665,5 @@ DEF_HELPER_4(dscri, void, env, fprp, fprp, i32)
 DEF_HELPER_4(dscriq, void, env, fprp, fprp, i32)
 DEF_HELPER_4(dscli, void, env, fprp, fprp, i32)
 DEF_HELPER_4(dscliq, void, env, fprp, fprp, i32)
+
+DEF_HELPER_1(tbegin, void, env)
index 50344b81cf438f830ff08f69ce411fdbcc555e2a..6d37dae7b0fb594a199a753766cb929c21a259c2 100644 (file)
@@ -269,3 +269,25 @@ STVE(stvewx, cpu_stl_data, bswap32, u32)
 
 #undef HI_IDX
 #undef LO_IDX
+
+void helper_tbegin(CPUPPCState *env)
+{
+    /* As a degenerate implementation, always fail tbegin.  The reason
+     * given is "Nesting overflow".  The "persistent" bit is set,
+     * providing a hint to the error handler to not retry.  The TFIAR
+     * captures the address of the failure, which is this tbegin
+     * instruction.  Instruction execution will continue with the
+     * next instruction in memory, which is precisely what we want.
+     */
+
+    env->spr[SPR_TEXASR] =
+        (1ULL << TEXASR_FAILURE_PERSISTENT) |
+        (1ULL << TEXASR_NESTING_OVERFLOW) |
+        (msr_hv << TEXASR_PRIVILEGE_HV) |
+        (msr_pr << TEXASR_PRIVILEGE_PR) |
+        (1ULL << TEXASR_FAILURE_SUMMARY) |
+        (1ULL << TEXASR_TFIAR_EXACT);
+    env->spr[SPR_TFIAR] = env->nip | (msr_hv << 1) | msr_pr;
+    env->spr[SPR_TFHAR] = env->nip + 4;
+    env->crf[0] = 0xB; /* 0b1010 = transaction failure */
+}
index 3b004f3bf7b2118bf38330caf9487106a183da41..f4a0332ca92d2584a60e6ade36b5757a5d437441 100644 (file)
@@ -9674,6 +9674,15 @@ GEN_SPE(efdctsiz,  speundef,  0x1D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE
 GEN_SPE(efdtstgt,  efdtstlt,  0x1E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE); //
 GEN_SPE(efdtsteq,  speundef,  0x1F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_DOUBLE); //
 
+static void gen_tbegin(DisasContext *ctx)
+{
+    if (unlikely(!ctx->tm_enabled)) {
+        gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM);
+        return;
+    }
+    gen_helper_tbegin(cpu_env);
+}
+
 static opcode_t opcodes[] = {
 GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE),
 GEN_HANDLER(cmp, 0x1F, 0x00, 0x00, 0x00400000, PPC_INTEGER),
@@ -11086,6 +11095,9 @@ GEN_SPEOP_LDST(evstwhe, 0x18, 2),
 GEN_SPEOP_LDST(evstwho, 0x1A, 2),
 GEN_SPEOP_LDST(evstwwe, 0x1C, 2),
 GEN_SPEOP_LDST(evstwwo, 0x1E, 2),
+
+GEN_HANDLER2_E(tbegin, "tbegin", 0x1F, 0x0E, 0x14, 0x01DFF800, \
+               PPC_NONE, PPC2_TM),
 };
 
 #include "helper_regs.h"