diff --git a/target/ppc/internal.h b/target/ppc/internal.h index 9a4a74a0d7..e83ea452f1 100644 --- a/target/ppc/internal.h +++ b/target/ppc/internal.h @@ -187,6 +187,7 @@ EXTRACT_HELPER(DCM, 10, 6) /* DFP Z23-form */ EXTRACT_HELPER(RMC, 9, 2) +EXTRACT_HELPER_SPLIT(DQxT, 3, 1, 21, 5); EXTRACT_HELPER_SPLIT(xT, 0, 1, 21, 5); EXTRACT_HELPER_SPLIT(xS, 0, 1, 21, 5); EXTRACT_HELPER_SPLIT(xA, 2, 1, 16, 5); diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 8032dc9fcd..87fc153692 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -6095,14 +6095,20 @@ static void gen_dform39(DisasContext *ctx) return gen_invalid(ctx); } -/* handles stfdp, stxsd, stxssp */ +/* handles stfdp, lxv, stxsd, stxssp lxvx */ static void gen_dform3D(DisasContext *ctx) { if ((ctx->opcode & 3) == 1) { /* DQ-FORM */ switch (ctx->opcode & 0x7) { case 1: /* lxv */ + if (ctx->insns_flags2 & PPC2_ISA300) { + return gen_lxv(ctx); + } break; case 5: /* stxv */ + if (ctx->insns_flags2 & PPC2_ISA300) { + return gen_stxv(ctx); + } break; } } else { /* DS-FORM */ @@ -6201,7 +6207,7 @@ GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B), #endif /* handles lfdp, lxsd, lxssp */ GEN_HANDLER_E(dform39, 0x39, 0xFF, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA205), -/* handles stfdp, stxsd, stxssp */ +/* handles stfdp, lxv, stxsd, stxssp, stxv */ GEN_HANDLER_E(dform3D, 0x3D, 0xFF, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA205), GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER), GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER), diff --git a/target/ppc/translate/vsx-impl.inc.c b/target/ppc/translate/vsx-impl.inc.c index 8ee44cfd17..2fbdbd2e63 100644 --- a/target/ppc/translate/vsx-impl.inc.c +++ b/target/ppc/translate/vsx-impl.inc.c @@ -190,6 +190,56 @@ static void gen_lxvb16x(DisasContext *ctx) tcg_temp_free(EA); } +#define VSX_VECTOR_LOAD_STORE(name, op, indexed) \ +static void gen_##name(DisasContext *ctx) \ +{ \ + int xt; \ + TCGv EA; \ + TCGv_i64 xth, xtl; \ + \ + if (indexed) { \ + xt = xT(ctx->opcode); \ + } else { \ + xt = DQxT(ctx->opcode); \ + } \ + xth = cpu_vsrh(xt); \ + xtl = cpu_vsrl(xt); \ + \ + if (xt < 32) { \ + if (unlikely(!ctx->vsx_enabled)) { \ + gen_exception(ctx, POWERPC_EXCP_VSXU); \ + return; \ + } \ + } else { \ + if (unlikely(!ctx->altivec_enabled)) { \ + gen_exception(ctx, POWERPC_EXCP_VPU); \ + return; \ + } \ + } \ + gen_set_access_type(ctx, ACCESS_INT); \ + EA = tcg_temp_new(); \ + if (indexed) { \ + gen_addr_reg_index(ctx, EA); \ + } else { \ + gen_addr_imm_index(ctx, EA, 0x0F); \ + } \ + if (ctx->le_mode) { \ + tcg_gen_qemu_##op(xtl, EA, ctx->mem_idx, MO_LEQ); \ + tcg_gen_addi_tl(EA, EA, 8); \ + tcg_gen_qemu_##op(xth, EA, ctx->mem_idx, MO_LEQ); \ + } else { \ + tcg_gen_qemu_##op(xth, EA, ctx->mem_idx, MO_BEQ); \ + tcg_gen_addi_tl(EA, EA, 8); \ + tcg_gen_qemu_##op(xtl, EA, ctx->mem_idx, MO_BEQ); \ + } \ + tcg_temp_free(EA); \ +} + +VSX_VECTOR_LOAD_STORE(lxv, ld_i64, 0) +VSX_VECTOR_LOAD_STORE(stxv, st_i64, 0) +VSX_VECTOR_LOAD_STORE(lxvx, ld_i64, 1) +VSX_VECTOR_LOAD_STORE(stxvx, st_i64, 1) + #define VSX_LOAD_SCALAR_DS(name, operation) \ static void gen_##name(DisasContext *ctx) \ { \ diff --git a/target/ppc/translate/vsx-ops.inc.c b/target/ppc/translate/vsx-ops.inc.c index 7f095277b7..8a1cbe005e 100644 --- a/target/ppc/translate/vsx-ops.inc.c +++ b/target/ppc/translate/vsx-ops.inc.c @@ -9,6 +9,7 @@ GEN_HANDLER_E(lxvdsx, 0x1F, 0x0C, 0x0A, 0, PPC_NONE, PPC2_VSX), GEN_HANDLER_E(lxvw4x, 0x1F, 0x0C, 0x18, 0, PPC_NONE, PPC2_VSX), GEN_HANDLER_E(lxvh8x, 0x1F, 0x0C, 0x19, 0, PPC_NONE, PPC2_ISA300), GEN_HANDLER_E(lxvb16x, 0x1F, 0x0C, 0x1B, 0, PPC_NONE, PPC2_ISA300), +GEN_HANDLER_E(lxvx, 0x1F, 0x0C, 0x08, 0x00000040, PPC_NONE, PPC2_ISA300), GEN_HANDLER_E(stxsdx, 0x1F, 0xC, 0x16, 0, PPC_NONE, PPC2_VSX), GEN_HANDLER_E(stxsibx, 0x1F, 0xD, 0x1C, 0, PPC_NONE, PPC2_ISA300), @@ -19,6 +20,7 @@ GEN_HANDLER_E(stxvd2x, 0x1F, 0xC, 0x1E, 0, PPC_NONE, PPC2_VSX), GEN_HANDLER_E(stxvw4x, 0x1F, 0xC, 0x1C, 0, PPC_NONE, PPC2_VSX), GEN_HANDLER_E(stxvh8x, 0x1F, 0x0C, 0x1D, 0, PPC_NONE, PPC2_ISA300), GEN_HANDLER_E(stxvb16x, 0x1F, 0x0C, 0x1F, 0, PPC_NONE, PPC2_ISA300), +GEN_HANDLER_E(stxvx, 0x1F, 0x0C, 0x0C, 0, PPC_NONE, PPC2_ISA300), GEN_HANDLER_E(mfvsrwz, 0x1F, 0x13, 0x03, 0x0000F800, PPC_NONE, PPC2_VSX207), GEN_HANDLER_E(mtvsrwa, 0x1F, 0x13, 0x06, 0x0000F800, PPC_NONE, PPC2_VSX207),