From: Amit Machhiwal <[email protected]>
Move the below PPC instructions to decodetree specification:
st{d,h,w}brx, st{d,w,h,b}cix : X-form
The changes were verified by validating that the TCG micro-ops generated
by those insns remain the same. These TCG micro-ops were captured with
the `-d op,in_asm` QEMU flag.
Additionally, remove GEN_TX and GEN_STX_E macros as they are no longer
used anywhere else.
Signed-off-by: Amit Machhiwal <[email protected]>
Signed-off-by: Chinmay Rath <[email protected]>
[cr: ppc32 build fix, EA calc fix]
---
target/ppc/insn32.decode | 8 +++
target/ppc/translate.c | 52 +++-----------
target/ppc/translate/fixedpoint-impl.c.inc | 79 ++++++++++++++++++++++
3 files changed, 95 insertions(+), 44 deletions(-)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 44ef814fb9..4a28fad64b 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -372,6 +372,14 @@ STVDX 011111 ..... ..... ..... 0010010001 - @X
STSKU 111110 ..... ..... ............. 0 11 @DD
STCXU 111110 ..... ..... ............. 1 11 @DD
+STDBRX 011111 ..... ..... ..... 1010010100 - @X
+STDCIX 011111 ..... ..... ..... 1111110101 - @X
+STWCIX 011111 ..... ..... ..... 1110010101 - @X
+STHCIX 011111 ..... ..... ..... 1110110101 - @X
+STBCIX 011111 ..... ..... ..... 1111010101 - @X
+STHBRX 011111 ..... ..... ..... 1110010110 - @X
+STWBRX 011111 ..... ..... ..... 1010010110 - @X
+
### Fixed-Point Compare Instructions
CMP 011111 ... - . ..... ..... 0000000000 - @X_bfl
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 1fc2cd0b14..7bfbba85d0 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -2529,23 +2529,6 @@ GEN_LDX_HVRM(lhzcix, ld16u, 0x15, 0x19, PPC_CILDST)
GEN_LDX_HVRM(lbzcix, ld8u, 0x15, 0x1a, PPC_CILDST)
#endif
-/*** Integer store ***/
-#define GEN_STX_E(name, stop, opc2, opc3, type, type2, chk) \
-static void glue(gen_, name##x)(DisasContext *ctx) \
-{ \
- TCGv EA; \
- chk(ctx); \
- gen_set_access_type(ctx, ACCESS_INT); \
- EA = tcg_temp_new(); \
- gen_addr_reg_index(ctx, EA); \
- gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA); \
-}
-#define GEN_STX(name, stop, opc2, opc3, type) \
- GEN_STX_E(name, stop, opc2, opc3, type, PPC_NONE, CHK_NONE)
-
-#define GEN_STX_HVRM(name, stop, opc2, opc3, type) \
- GEN_STX_E(name, stop, opc2, opc3, type, PPC_NONE, CHK_HVRM)
-
#define GEN_STEPX(name, stop, opc2, opc3) \
static void glue(gen_, name##epx)(DisasContext *ctx) \
{ \
@@ -2565,12 +2548,6 @@ GEN_STEPX(stw, DEF_MEMOP(MO_UL), 0x1F, 0x04)
GEN_STEPX(std, DEF_MEMOP(MO_UQ), 0x1d, 0x04)
#endif
-#if defined(TARGET_PPC64)
-GEN_STX_HVRM(stdcix, st64_i64, 0x15, 0x1f, PPC_CILDST)
-GEN_STX_HVRM(stwcix, st32, 0x15, 0x1c, PPC_CILDST)
-GEN_STX_HVRM(sthcix, st16, 0x15, 0x1d, PPC_CILDST)
-GEN_STX_HVRM(stbcix, st8, 0x15, 0x1e, PPC_CILDST)
-#endif
/*** Integer load and store with byte reverse ***/
/* lhbrx */
@@ -2582,15 +2559,8 @@ GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER);
#if defined(TARGET_PPC64)
/* ldbrx */
GEN_LDX_E(ldbr, ld64ur_i64, 0x14, 0x10, PPC_NONE, PPC2_DBRX, CHK_NONE);
-/* stdbrx */
-GEN_STX_E(stdbr, st64r_i64, 0x14, 0x14, PPC_NONE, PPC2_DBRX, CHK_NONE);
#endif /* TARGET_PPC64 */
-/* sthbrx */
-GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER);
-/* stwbrx */
-GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER);
-
/*** Integer load and store multiple ***/
/* lmw */
@@ -5117,9 +5087,17 @@ static int64_t dw_compose_ea(DisasContext *ctx, int x)
return true; \
} \
} while (0)
+#define REQUIRE_HVRM(CTX) \
+ do { \
+ if (unlikely(ctx->pr || !ctx->hv || ctx->dr)) { \
+ gen_priv_opc(CTX); \
+ return true; \
+ } \
+ } while (0)
#else
#define REQUIRE_SV(CTX) do { gen_priv_opc(CTX); return true; } while (0)
#define REQUIRE_HV(CTX) do { gen_priv_opc(CTX); return true; } while (0)
+#define REQUIRE_HVRM(CTX) do { gen_priv_opc(CTX); return true; } while (0)
#endif
/*
@@ -5791,20 +5769,6 @@ GEN_LDEPX(lw, DEF_MEMOP(MO_UL), 0x1F, 0x00)
GEN_LDEPX(ld, DEF_MEMOP(MO_UQ), 0x1D, 0x00)
#endif
-#undef GEN_STX_E
-#define GEN_STX_E(name, stop, opc2, opc3, type, type2, chk) \
-GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000000, type, type2),
-
-#if defined(TARGET_PPC64)
-GEN_STX_E(stdbr, st64r_i64, 0x14, 0x14, PPC_NONE, PPC2_DBRX, CHK_NONE)
-GEN_STX_HVRM(stdcix, st64_i64, 0x15, 0x1f, PPC_CILDST)
-GEN_STX_HVRM(stwcix, st32, 0x15, 0x1c, PPC_CILDST)
-GEN_STX_HVRM(sthcix, st16, 0x15, 0x1d, PPC_CILDST)
-GEN_STX_HVRM(stbcix, st8, 0x15, 0x1e, PPC_CILDST)
-#endif
-GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER)
-GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER)
-
#undef GEN_STEPX
#define GEN_STEPX(name, ldop, opc2, opc3) \
GEN_HANDLER_E(name##epx, 0x1F, opc2, opc3, \
diff --git a/target/ppc/translate/fixedpoint-impl.c.inc
b/target/ppc/translate/fixedpoint-impl.c.inc
index 9f669894a3..25a60d3d3a 100644
--- a/target/ppc/translate/fixedpoint-impl.c.inc
+++ b/target/ppc/translate/fixedpoint-impl.c.inc
@@ -566,6 +566,85 @@ TRANS(ADDIC_, do_add_D, false, true, false, true);
TRANS(SLD, do_shift_X_rc, tcg_gen_shl_tl);
TRANS(SRD, do_shift_X_rc, tcg_gen_shr_tl);
+static bool do_stxx(DisasContext *ctx, arg_X *a,
+ void(*op)(DisasContext *, TCGv, TCGv), bool is_hvrm)
+{
+ TCGv ea;
+
+ if (is_hvrm) {
+ REQUIRE_HVRM(ctx);
+ }
+
+ gen_set_access_type(ctx, ACCESS_INT);
+ ea = do_ea_calc(ctx, a->ra, cpu_gpr[a->rb]);
+ op(ctx, cpu_gpr[a->rt], ea);
+
+ return true;
+}
+
+TRANS(STHBRX, do_stxx, gen_qemu_st16r, 0);
+TRANS(STWBRX, do_stxx, gen_qemu_st32r, 0);
+
+static bool trans_STDBRX(DisasContext *ctx, arg_STDBRX *a)
+{
+ REQUIRE_64BIT(ctx);
+ REQUIRE_INSNS_FLAGS2(ctx, DBRX);
+#if defined(TARGET_PPC64)
+ return do_stxx(ctx, a, gen_qemu_st64r_i64, false);
+#else
+ qemu_build_not_reached();
+#endif
+ return true;
+}
+
+static bool trans_STDCIX(DisasContext *ctx, arg_STDCIX *a)
+{
+ REQUIRE_64BIT(ctx);
+ REQUIRE_INSNS_FLAGS(ctx, CILDST);
+#if defined(TARGET_PPC64)
+ return do_stxx(ctx, a, gen_qemu_st64_i64, true);
+#else
+ qemu_build_not_reached();
+#endif
+ return true;
+}
+
+static bool trans_STWCIX(DisasContext *ctx, arg_STWCIX *a)
+{
+ REQUIRE_64BIT(ctx);
+ REQUIRE_INSNS_FLAGS(ctx, CILDST);
+#if defined(TARGET_PPC64)
+ return do_stxx(ctx, a, gen_qemu_st32, true);
+#else
+ qemu_build_not_reached();
+#endif
+ return true;
+}
+
+static bool trans_STHCIX(DisasContext *ctx, arg_STHCIX *a)
+{
+ REQUIRE_64BIT(ctx);
+ REQUIRE_INSNS_FLAGS(ctx, CILDST);
+#if defined(TARGET_PPC64)
+ return do_stxx(ctx, a, gen_qemu_st16, true);
+#else
+ qemu_build_not_reached();
+#endif
+ return true;
+}
+
+static bool trans_STBCIX(DisasContext *ctx, arg_STBCIX *a)
+{
+ REQUIRE_64BIT(ctx);
+ REQUIRE_INSNS_FLAGS(ctx, CILDST);
+#if defined(TARGET_PPC64)
+ return do_stxx(ctx, a, gen_qemu_st8, true);
+#else
+ qemu_build_not_reached();
+#endif
+ return true;
+}
+
static bool trans_SUBFIC(DisasContext *ctx, arg_D *a)
{
gen_op_arith_subf(ctx, cpu_gpr[a->rt], cpu_gpr[a->ra],
--
2.53.0