@@ -28,6 +28,9 @@
%dq_rtp 22:4 !function=times_2
@DQ_rtp ...... ....0 ra:5 ............ .... &D rt=%dq_rtp si=%dq_si
+%dq_rt_tsx 3:1 21:5
+@DQ_TSX ...... ..... ra:5 ............ .... &D si=%dq_si rt=%dq_rt_tsx
+
%ds_si 2:s14 !function=times_4
@DS ...... rt:5 ra:5 .............. .. &D si=%ds_si
@@ -385,3 +388,8 @@ VINSWVRX 000100 ..... ..... ..... 00110001111 @VX
VSLDBI 000100 ..... ..... ..... 00 ... 010110 @VN
VSRDBI 000100 ..... ..... ..... 01 ... 010110 @VN
+
+# VSX Load/Store Instructions
+
+LXV 111101 ..... ..... ............ . 001 @DQ_TSX
+STXV 111101 ..... ..... ............ . 101 @DQ_TSX
@@ -7444,20 +7444,7 @@ static void gen_dform39(DisasContext *ctx)
/* 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 */
+ if ((ctx->opcode & 3) != 1) { /* DS-FORM */
switch (ctx->opcode & 0x3) {
case 0: /* stfdp */
if (ctx->insns_flags2 & PPC2_ISA205) {
@@ -7582,7 +7569,7 @@ GEN_HANDLER2_E(extswsli1, "extswsli", 0x1F, 0x1B, 0x1B, 0x00000000,
#endif
/* handles lfdp, lxsd, lxssp */
GEN_HANDLER_E(dform39, 0x39, 0xFF, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA205),
-/* handles stfdp, lxv, stxsd, stxssp, stxv */
+/* handles stfdp, stxsd, stxssp */
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),
@@ -317,7 +317,6 @@ static void gen_##name(DisasContext *ctx) \
tcg_temp_free_i64(xtl); \
}
-VSX_VECTOR_LOAD(lxv, ld_i64, 0)
VSX_VECTOR_LOAD(lxvx, ld_i64, 1)
#define VSX_VECTOR_STORE(name, op, indexed) \
@@ -370,7 +369,6 @@ static void gen_##name(DisasContext *ctx) \
tcg_temp_free_i64(xtl); \
}
-VSX_VECTOR_STORE(stxv, st_i64, 0)
VSX_VECTOR_STORE(stxvx, st_i64, 1)
#ifdef TARGET_PPC64
@@ -2077,6 +2075,64 @@ static void gen_xvxsigdp(DisasContext *ctx)
tcg_temp_free_i64(xbl);
}
+static bool do_lstxv(DisasContext *ctx, int ra, int displ,
+ int rt, bool store)
+{
+ TCGv ea;
+ TCGv_i64 xt;
+ MemOp mop;
+ int offset;
+
+ ea = tcg_temp_new();
+ xt = tcg_temp_new_i64();
+
+ mop = DEF_MEMOP(MO_Q);
+
+ gen_set_access_type(ctx, ACCESS_INT);
+ do_ea_calc(ctx, ra, tcg_const_tl(displ), ea);
+
+ if (ctx->le_mode) {
+ gen_addr_add(ctx, ea, ea, 8);
+ offset = -8;
+ } else {
+ offset = 8;
+ }
+
+ if (store) {
+ get_cpu_vsrh(xt, rt);
+ tcg_gen_qemu_st_i64(xt, ea, ctx->mem_idx, mop);
+ gen_addr_add(ctx, ea, ea, offset);
+ get_cpu_vsrl(xt, rt);
+ tcg_gen_qemu_st_i64(xt, ea, ctx->mem_idx, mop);
+ } else {
+ tcg_gen_qemu_ld_i64(xt, ea, ctx->mem_idx, mop);
+ set_cpu_vsrh(rt, xt);
+ gen_addr_add(ctx, ea, ea, offset);
+ tcg_gen_qemu_ld_i64(xt, ea, ctx->mem_idx, mop);
+ set_cpu_vsrl(rt, xt);
+ }
+
+ tcg_temp_free(ea);
+ tcg_temp_free_i64(xt);
+ return true;
+}
+
+static bool do_lstxv_D(DisasContext *ctx, arg_D *a, bool store)
+{
+ REQUIRE_INSNS_FLAGS2(ctx, ISA300);
+
+ if (a->rt >= 32) {
+ REQUIRE_VSX(ctx);
+ } else {
+ REQUIRE_VECTOR(ctx);
+ }
+
+ return do_lstxv(ctx, a->ra, a->si, a->rt, store);
+}
+
+TRANS(STXV, do_lstxv_D, true)
+TRANS(LXV, do_lstxv_D, false)
+
#undef GEN_XX2FORM
#undef GEN_XX3FORM
#undef GEN_XX2IFORM