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

login
register
mail settings
Submitter Aurelien Jarno
Date April 13, 2013, 12:47 p.m.
Message ID <1365857251-28173-10-git-send-email-aurelien@aurel32.net>
Download mbox | patch
Permalink /patch/236342/
State New
Headers show

Comments

Aurelien Jarno - April 13, 2013, 12:47 p.m.
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(+)
Richard Henderson - April 17, 2013, 2:26 p.m.
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.
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.

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)                                        \