diff mbox

[09/10] target-ppc: emulate store doubleword pair instructions

Message ID 1365857251-28173-10-git-send-email-aurelien@aurel32.net
State New
Headers show

Commit Message

Aurelien Jarno April 13, 2013, 12:47 p.m. UTC
Needed for Power ISA version 2.05 compliance.

Cc: Alexander Graf <agraf@suse.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-ppc/translate.c |   48 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)

Comments

Richard Henderson April 17, 2013, 2:26 p.m. UTC | #1
On 2013-04-13 14:47, Aurelien Jarno wrote:
> +        gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);

Actually, for both this and ldfp, don't you need to check for
odd rD and raise sigill or whatever?


r~
Aurelien Jarno April 19, 2013, 6:54 p.m. UTC | #2
On Wed, Apr 17, 2013 at 04:26:44PM +0200, Richard Henderson wrote:
> On 2013-04-13 14:47, Aurelien Jarno wrote:
> >+        gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
> 
> Actually, for both this and ldfp, don't you need to check for
> odd rD and raise sigill or whatever?
> 

This indeed needs to be checked, but it's already done using the invalid
bits:
+GEN_HANDLER_E(lfdp, 0x39, 0xFF, 0xFF, 0x00200003, PPC_NONE, PPC2_ISA205),
+GEN_HANDLER_E(lfdpx, 0x1F, 0x17, 0x18, 0x00200001, PPC_NONE, PPC2_ISA205),

The 2 there correspond to the last bit of the register pair, which thus
should be 0, otherwise the instruction generates an invalid exception.

I'll add that to the description when doing the respin.
diff mbox

Patch

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 248e8ca..4ea7015 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -3447,6 +3447,52 @@  GEN_STFS(stfd, st64, 0x16, PPC_FLOAT);
 /* stfs stfsu stfsux stfsx */
 GEN_STFS(stfs, st32fs, 0x14, PPC_FLOAT);
 
+/* stfdp */
+static void gen_stfdp(DisasContext *ctx)
+{
+    TCGv EA;
+    if (unlikely(!ctx->fpu_enabled)) {
+        gen_exception(ctx, POWERPC_EXCP_FPU);
+        return;
+    }
+    gen_set_access_type(ctx, ACCESS_FLOAT);
+    EA = tcg_temp_new();
+    gen_addr_imm_index(ctx, EA, 0);                                           \
+    if (unlikely(ctx->le_mode)) {
+        gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
+        tcg_gen_addi_tl(EA, EA, 8);
+        gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
+    } else {
+        gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
+        tcg_gen_addi_tl(EA, EA, 8);
+        gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
+    }
+    tcg_temp_free(EA);
+}
+
+/* stfdpx */
+static void gen_stfdpx(DisasContext *ctx)
+{
+    TCGv EA;
+    if (unlikely(!ctx->fpu_enabled)) {
+        gen_exception(ctx, POWERPC_EXCP_FPU);
+        return;
+    }
+    gen_set_access_type(ctx, ACCESS_FLOAT);
+    EA = tcg_temp_new();
+    gen_addr_reg_index(ctx, EA);
+    if (unlikely(ctx->le_mode)) {
+        gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
+        tcg_gen_addi_tl(EA, EA, 8);
+        gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
+    } else {
+        gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
+        tcg_gen_addi_tl(EA, EA, 8);
+        gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
+    }
+    tcg_temp_free(EA);
+}
+
 /* Optional: */
 static inline void gen_qemu_st32fiw(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
 {
@@ -9094,6 +9140,8 @@  GEN_STXF(name, stop, 0x17, op | 0x00, type)
 GEN_STFS(stfd, st64, 0x16, PPC_FLOAT)
 GEN_STFS(stfs, st32fs, 0x14, PPC_FLOAT)
 GEN_STXF(stfiw, st32fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX)
+GEN_HANDLER_E(stfdp, 0x3D, 0xFF, 0xFF, 0x00200003, PPC_NONE, PPC2_ISA205),
+GEN_HANDLER_E(stfdpx, 0x1F, 0x17, 0x1C, 0x00200001, PPC_NONE, PPC2_ISA205),
 
 #undef GEN_CRLOGIC
 #define GEN_CRLOGIC(name, tcg_op, opc)                                        \