From: Ojaswin Mujoo<[email protected]>
Convert the following instructions to decode tree specification:
doze
nap
sleep
rvwinkle
stop
The functionality was tested by comparing the qemu -D log -d op,in_asm
output as well as single stepping gdb to confirm behavior was not
changed for ISA3.x (stop) as well as ISA206 (doze, nap, sleep,
rvwinkle).
Signed-off-by: Ojaswin Mujoo<[email protected]>
Signed-off-by: Chinmay Rath<[email protected]>
---
target/ppc/insn32.decode | 8 ++
target/ppc/translate.c | 85 ---------------
.../ppc/translate/processor-ctrl-impl.c.inc | 101 ++++++++++++++++++
3 files changed, 109 insertions(+), 85 deletions(-)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 2c002f8513..a4454a2292 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -913,6 +913,14 @@ VPERMR 000100 ..... ..... ..... ..... 111011 @VA
VSEL 000100 ..... ..... ..... ..... 101010 @VA
+## Power Management Instructions
+
+DOZE 010011 ----- ----- ----- 0110010010 -
+NAP 010011 ----- ----- ----- 0110110010 -
+SLEEP 010011 ----- ----- ----- 0111010010 -
+RVWINKLE 010011 ----- ----- ----- 0111110010 -
+STOP 010011 ----- ----- ----- 0101110010 -
+
## Vector Integer Shift Instruction
VSLB 000100 ..... ..... ..... 00100000100 @VX
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 4a7fa6a6a9..d1e9ab61e9 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -2728,86 +2728,6 @@ static inline void gen_check_tlb_flush(DisasContext
*ctx, bool global) { }
#endif
#if defined(TARGET_PPC64)
-static void gen_doze(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV(ctx);
-#else
- TCGv_i32 t;
-
- CHK_HV(ctx);
- translator_io_start(&ctx->base);
- t = tcg_constant_i32(PPC_PM_DOZE);
- gen_helper_pminsn(tcg_env, t);
- /* Stop translation, as the CPU is supposed to sleep from now */
- gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-static void gen_nap(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV(ctx);
-#else
- TCGv_i32 t;
-
- CHK_HV(ctx);
- translator_io_start(&ctx->base);
- t = tcg_constant_i32(PPC_PM_NAP);
- gen_helper_pminsn(tcg_env, t);
- /* Stop translation, as the CPU is supposed to sleep from now */
- gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-static void gen_stop(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV(ctx);
-#else
- TCGv_i32 t;
-
- CHK_HV(ctx);
- translator_io_start(&ctx->base);
- t = tcg_constant_i32(PPC_PM_STOP);
- gen_helper_pminsn(tcg_env, t);
- /* Stop translation, as the CPU is supposed to sleep from now */
- gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-static void gen_sleep(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV(ctx);
-#else
- TCGv_i32 t;
-
- CHK_HV(ctx);
- translator_io_start(&ctx->base);
- t = tcg_constant_i32(PPC_PM_SLEEP);
- gen_helper_pminsn(tcg_env, t);
- /* Stop translation, as the CPU is supposed to sleep from now */
- gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-static void gen_rvwinkle(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV(ctx);
-#else
- TCGv_i32 t;
-
- CHK_HV(ctx);
- translator_io_start(&ctx->base);
- t = tcg_constant_i32(PPC_PM_RVWINKLE);
- gen_helper_pminsn(tcg_env, t);
- /* Stop translation, as the CPU is supposed to sleep from now */
- gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
static inline TCGv gen_write_bhrb(TCGv_ptr base, TCGv offset, TCGv mask, TCGv
value)
{
TCGv_ptr tmp = tcg_temp_new_ptr();
@@ -5141,11 +5061,6 @@ GEN_HANDLER_E(scv, 0x11, 0x10, 0xFF, 0x03FFF01E,
PPC_NONE, PPC2_ISA300),
GEN_HANDLER_E(scv, 0x11, 0x00, 0xFF, 0x03FFF01E, PPC_NONE, PPC2_ISA300),
GEN_HANDLER_E(rfscv, 0x13, 0x12, 0x02, 0x03FF8001, PPC_NONE, PPC2_ISA300),
#endif
-GEN_HANDLER_E(stop, 0x13, 0x12, 0x0b, 0x03FFF801, PPC_NONE, PPC2_ISA300),
-GEN_HANDLER_E(doze, 0x13, 0x12, 0x0c, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
-GEN_HANDLER_E(nap, 0x13, 0x12, 0x0d, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
-GEN_HANDLER_E(sleep, 0x13, 0x12, 0x0e, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
-GEN_HANDLER_E(rvwinkle, 0x13, 0x12, 0x0f, 0x03FFF801, PPC_NONE,
PPC2_PM_ISA206),
GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H),
#endif
/* Top bit of opc2 corresponds with low bit of LEV, so use two handlers */
diff --git a/target/ppc/translate/processor-ctrl-impl.c.inc
b/target/ppc/translate/processor-ctrl-impl.c.inc
index 8abbb89630..bdbc195294 100644
--- a/target/ppc/translate/processor-ctrl-impl.c.inc
+++ b/target/ppc/translate/processor-ctrl-impl.c.inc
@@ -103,3 +103,104 @@ static bool trans_MSGSYNC(DisasContext *ctx, arg_MSGSYNC
*a)
/* interpreted as no-op */
return true;
}
+
+static bool do_doze(DisasContext *ctx, arg_DOZE *a)
+{
+ REQUIRE_64BIT(ctx);
+
+#if defined(CONFIG_USER_ONLY)
+ gen_priv_opc(ctx);
+#else
+ TCGv_i32 t;
+
+ REQUIRE_HV(ctx);
+ translator_io_start(&ctx->base);
+ t = tcg_constant_i32(PPC_PM_DOZE);
+ gen_helper_pminsn(tcg_env, t);
+ /* Stop translation, as the CPU is supposed to sleep from now */
+ gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
+#endif /* defined(CONFIG_USER_ONLY) */
+
+ return true;
+}
+TRANS_FLAGS2(PM_ISA206, DOZE, do_doze);
+
+static bool do_nap(DisasContext *ctx, arg_NAP *a)
+{
+ REQUIRE_64BIT(ctx);
+
+#if defined(CONFIG_USER_ONLY)
+ gen_priv_opc(ctx);
+#else
+ TCGv_i32 t;
+
+ REQUIRE_HV(ctx);
+ translator_io_start(&ctx->base);
+ t = tcg_constant_i32(PPC_PM_NAP);
+ gen_helper_pminsn(tcg_env, t);
+ /* Stop translation, as the CPU is supposed to sleep from now */
+ gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
+#endif /* defined(CONFIG_USER_ONLY) */
+ return true;
+}
+TRANS_FLAGS2(PM_ISA206, NAP, do_nap);
+
+static bool do_sleep(DisasContext *ctx, arg_SLEEP *a)
+{
+ REQUIRE_64BIT(ctx);
+
+#if defined(CONFIG_USER_ONLY)
+ gen_priv_opc(ctx);
+#else
+ TCGv_i32 t;
+
+ REQUIRE_HV(ctx);
+ translator_io_start(&ctx->base);
+ t = tcg_constant_i32(PPC_PM_SLEEP);
+ gen_helper_pminsn(tcg_env, t);
+ /* Stop translation, as the CPU is supposed to sleep from now */
+ gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
+#endif /* defined(CONFIG_USER_ONLY) */
+ return true;
+}
+TRANS_FLAGS2(PM_ISA206, SLEEP, do_sleep);
+
+static bool do_rvwinkle(DisasContext *ctx, arg_RVWINKLE *a)
+{
+ REQUIRE_64BIT(ctx);
+
+#if defined(CONFIG_USER_ONLY)
+ gen_priv_opc(ctx);
+#else
+ TCGv_i32 t;
+
+ REQUIRE_HV(ctx);
+ translator_io_start(&ctx->base);
+ t = tcg_constant_i32(PPC_PM_RVWINKLE);
+ gen_helper_pminsn(tcg_env, t);
+ /* Stop translation, as the CPU is supposed to sleep from now */
+ gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
+#endif /* defined(CONFIG_USER_ONLY) */
+ return true;
+}
+TRANS_FLAGS2(PM_ISA206, RVWINKLE, do_rvwinkle);
+
+static bool do_stop(DisasContext *ctx, arg_STOP *a)
+{
+ REQUIRE_64BIT(ctx);
+
+#if defined(CONFIG_USER_ONLY)
+ gen_priv_opc(ctx);
+#else
+ TCGv_i32 t;
+
+ REQUIRE_HV(ctx);
+ translator_io_start(&ctx->base);
+ t = tcg_constant_i32(PPC_PM_STOP);
+ gen_helper_pminsn(tcg_env, t);
+ /* Stop translation, as the CPU is supposed to sleep from now */
+ gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
+#endif
+ return true;
+}
+TRANS_FLAGS2(ISA300, STOP, do_stop);