aboutsummaryrefslogtreecommitdiff
path: root/target/ppc/translate.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/ppc/translate.c')
-rw-r--r--target/ppc/translate.c141
1 files changed, 141 insertions, 0 deletions
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 4e59dd5f42..c999832426 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -2579,6 +2579,26 @@ GEN_LDS(lha, ld16s, 0x0A, PPC_INTEGER);
GEN_LDS(lhz, ld16u, 0x08, PPC_INTEGER);
/* lwz lwzu lwzux lwzx */
GEN_LDS(lwz, ld32u, 0x00, PPC_INTEGER);
+
+#define GEN_LDEPX(name, ldop, opc2, opc3) \
+static void glue(gen_, name##epx)(DisasContext *ctx) \
+{ \
+ TCGv EA; \
+ CHK_SV; \
+ gen_set_access_type(ctx, ACCESS_INT); \
+ EA = tcg_temp_new(); \
+ gen_addr_reg_index(ctx, EA); \
+ tcg_gen_qemu_ld_tl(cpu_gpr[rD(ctx->opcode)], EA, PPC_TLB_EPID_LOAD, ldop);\
+ tcg_temp_free(EA); \
+}
+
+GEN_LDEPX(lb, DEF_MEMOP(MO_UB), 0x1F, 0x02)
+GEN_LDEPX(lh, DEF_MEMOP(MO_UW), 0x1F, 0x08)
+GEN_LDEPX(lw, DEF_MEMOP(MO_UL), 0x1F, 0x00)
+#if defined(TARGET_PPC64)
+GEN_LDEPX(ld, DEF_MEMOP(MO_Q), 0x1D, 0x00)
+#endif
+
#if defined(TARGET_PPC64)
/* lwaux */
GEN_LDUX(lwa, ld32s, 0x15, 0x0B, PPC_64B);
@@ -2760,6 +2780,27 @@ GEN_STS(stb, st8, 0x06, PPC_INTEGER);
GEN_STS(sth, st16, 0x0C, PPC_INTEGER);
/* stw stwu stwux stwx */
GEN_STS(stw, st32, 0x04, PPC_INTEGER);
+
+#define GEN_STEPX(name, stop, opc2, opc3) \
+static void glue(gen_, name##epx)(DisasContext *ctx) \
+{ \
+ TCGv EA; \
+ CHK_SV; \
+ gen_set_access_type(ctx, ACCESS_INT); \
+ EA = tcg_temp_new(); \
+ gen_addr_reg_index(ctx, EA); \
+ tcg_gen_qemu_st_tl( \
+ cpu_gpr[rD(ctx->opcode)], EA, PPC_TLB_EPID_STORE, stop); \
+ tcg_temp_free(EA); \
+}
+
+GEN_STEPX(stb, DEF_MEMOP(MO_UB), 0x1F, 0x06)
+GEN_STEPX(sth, DEF_MEMOP(MO_UW), 0x1F, 0x0C)
+GEN_STEPX(stw, DEF_MEMOP(MO_UL), 0x1F, 0x04)
+#if defined(TARGET_PPC64)
+GEN_STEPX(std, DEF_MEMOP(MO_Q), 0x1d, 0x04)
+#endif
+
#if defined(TARGET_PPC64)
GEN_STUX(std, st64_i64, 0x15, 0x05, PPC_64B);
GEN_STX(std, st64_i64, 0x15, 0x04, PPC_64B);
@@ -4392,6 +4433,19 @@ static void gen_dcbf(DisasContext *ctx)
tcg_temp_free(t0);
}
+/* dcbfep (external PID dcbf) */
+static void gen_dcbfep(DisasContext *ctx)
+{
+ /* XXX: specification says this is treated as a load by the MMU */
+ TCGv t0;
+ CHK_SV;
+ gen_set_access_type(ctx, ACCESS_CACHE);
+ t0 = tcg_temp_new();
+ gen_addr_reg_index(ctx, t0);
+ tcg_gen_qemu_ld_tl(t0, t0, PPC_TLB_EPID_LOAD, DEF_MEMOP(MO_UB));
+ tcg_temp_free(t0);
+}
+
/* dcbi (Supervisor only) */
static void gen_dcbi(DisasContext *ctx)
{
@@ -4425,6 +4479,18 @@ static void gen_dcbst(DisasContext *ctx)
tcg_temp_free(t0);
}
+/* dcbstep (dcbstep External PID version) */
+static void gen_dcbstep(DisasContext *ctx)
+{
+ /* XXX: specification say this is treated as a load by the MMU */
+ TCGv t0;
+ gen_set_access_type(ctx, ACCESS_CACHE);
+ t0 = tcg_temp_new();
+ gen_addr_reg_index(ctx, t0);
+ tcg_gen_qemu_ld_tl(t0, t0, PPC_TLB_EPID_LOAD, DEF_MEMOP(MO_UB));
+ tcg_temp_free(t0);
+}
+
/* dcbt */
static void gen_dcbt(DisasContext *ctx)
{
@@ -4434,6 +4500,15 @@ static void gen_dcbt(DisasContext *ctx)
*/
}
+/* dcbtep */
+static void gen_dcbtep(DisasContext *ctx)
+{
+ /* interpreted as no-op */
+ /* XXX: specification say this is treated as a load by the MMU
+ * but does not generate any exception
+ */
+}
+
/* dcbtst */
static void gen_dcbtst(DisasContext *ctx)
{
@@ -4443,6 +4518,15 @@ static void gen_dcbtst(DisasContext *ctx)
*/
}
+/* dcbtstep */
+static void gen_dcbtstep(DisasContext *ctx)
+{
+ /* interpreted as no-op */
+ /* XXX: specification say this is treated as a load by the MMU
+ * but does not generate any exception
+ */
+}
+
/* dcbtls */
static void gen_dcbtls(DisasContext *ctx)
{
@@ -4469,6 +4553,21 @@ static void gen_dcbz(DisasContext *ctx)
tcg_temp_free_i32(tcgv_op);
}
+/* dcbzep */
+static void gen_dcbzep(DisasContext *ctx)
+{
+ TCGv tcgv_addr;
+ TCGv_i32 tcgv_op;
+
+ gen_set_access_type(ctx, ACCESS_CACHE);
+ tcgv_addr = tcg_temp_new();
+ tcgv_op = tcg_const_i32(ctx->opcode & 0x03FF000);
+ gen_addr_reg_index(ctx, tcgv_addr);
+ gen_helper_dcbzep(cpu_env, tcgv_addr, tcgv_op);
+ tcg_temp_free(tcgv_addr);
+ tcg_temp_free_i32(tcgv_op);
+}
+
/* dst / dstt */
static void gen_dst(DisasContext *ctx)
{
@@ -4507,6 +4606,17 @@ static void gen_icbi(DisasContext *ctx)
tcg_temp_free(t0);
}
+/* icbiep */
+static void gen_icbiep(DisasContext *ctx)
+{
+ TCGv t0;
+ gen_set_access_type(ctx, ACCESS_CACHE);
+ t0 = tcg_temp_new();
+ gen_addr_reg_index(ctx, t0);
+ gen_helper_icbiep(cpu_env, t0);
+ tcg_temp_free(t0);
+}
+
/* Optional: */
/* dcba */
static void gen_dcba(DisasContext *ctx)
@@ -6774,16 +6884,22 @@ GEN_HANDLER_E(mcrxrx, 0x1F, 0x00, 0x12, 0x007FF801, PPC_NONE, PPC2_ISA300),
GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001EF801, PPC_MISC),
GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000000, PPC_MISC),
GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE),
+GEN_HANDLER_E(dcbfep, 0x1F, 0x1F, 0x03, 0x03C00001, PPC_NONE, PPC2_BOOKE206),
GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE),
GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE),
+GEN_HANDLER_E(dcbstep, 0x1F, 0x1F, 0x01, 0x03E00001, PPC_NONE, PPC2_BOOKE206),
GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x00000001, PPC_CACHE),
+GEN_HANDLER_E(dcbtep, 0x1F, 0x1F, 0x09, 0x00000001, PPC_NONE, PPC2_BOOKE206),
GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x00000001, PPC_CACHE),
+GEN_HANDLER_E(dcbtstep, 0x1F, 0x1F, 0x07, 0x00000001, PPC_NONE, PPC2_BOOKE206),
GEN_HANDLER_E(dcbtls, 0x1F, 0x06, 0x05, 0x02000001, PPC_BOOKE, PPC2_BOOKE206),
GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZ),
+GEN_HANDLER_E(dcbzep, 0x1F, 0x1F, 0x1F, 0x03C00001, PPC_NONE, PPC2_BOOKE206),
GEN_HANDLER(dst, 0x1F, 0x16, 0x0A, 0x01800001, PPC_ALTIVEC),
GEN_HANDLER(dstst, 0x1F, 0x16, 0x0B, 0x01800001, PPC_ALTIVEC),
GEN_HANDLER(dss, 0x1F, 0x16, 0x19, 0x019FF801, PPC_ALTIVEC),
GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE_ICBI),
+GEN_HANDLER_E(icbiep, 0x1F, 0x1F, 0x1E, 0x03E00001, PPC_NONE, PPC2_BOOKE206),
GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA),
GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT),
GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT),
@@ -7086,6 +7202,19 @@ GEN_LDX_HVRM(lbzcix, ld8u, 0x15, 0x1a, PPC_CILDST)
GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER)
GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER)
+/* External PID based load */
+#undef GEN_LDEPX
+#define GEN_LDEPX(name, ldop, opc2, opc3) \
+GEN_HANDLER_E(name##epx, 0x1F, opc2, opc3, \
+ 0x00000001, PPC_NONE, PPC2_BOOKE206),
+
+GEN_LDEPX(lb, DEF_MEMOP(MO_UB), 0x1F, 0x02)
+GEN_LDEPX(lh, DEF_MEMOP(MO_UW), 0x1F, 0x08)
+GEN_LDEPX(lw, DEF_MEMOP(MO_UL), 0x1F, 0x00)
+#if defined(TARGET_PPC64)
+GEN_LDEPX(ld, DEF_MEMOP(MO_Q), 0x1D, 0x00)
+#endif
+
#undef GEN_ST
#undef GEN_STU
#undef GEN_STUX
@@ -7120,6 +7249,18 @@ GEN_STX_HVRM(stbcix, st8, 0x15, 0x1e, PPC_CILDST)
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, \
+ 0x00000001, PPC_NONE, PPC2_BOOKE206),
+
+GEN_STEPX(stb, DEF_MEMOP(MO_UB), 0x1F, 0x06)
+GEN_STEPX(sth, DEF_MEMOP(MO_UW), 0x1F, 0x0C)
+GEN_STEPX(stw, DEF_MEMOP(MO_UL), 0x1F, 0x04)
+#if defined(TARGET_PPC64)
+GEN_STEPX(std, DEF_MEMOP(MO_Q), 0x1D, 0x04)
+#endif
+
#undef GEN_CRLOGIC
#define GEN_CRLOGIC(name, tcg_op, opc) \
GEN_HANDLER(name, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)