diff mbox

[V3,04/19] General Support for VSX Helpers

Message ID 1383312955-2607-5-git-send-email-tommusta@gmail.com
State New
Headers show

Commit Message

Tom Musta Nov. 1, 2013, 1:35 p.m. UTC
This patch adds general support that will be used by the VSX helper
routines:

  - a union describing the various VSR subfields.
  - access routines to get and set VSRs
  - VSX decoders
  - a general routine to generate a handler that invokes a VSX
    helper.

Signed-off-by: Tom Musta <tommusta@gmail.com>
---
 target-ppc/fpu_helper.c |   41 +++++++++++++++++++++++++++++++++++++++++
 target-ppc/translate.c  |   14 ++++++++++++++
 2 files changed, 55 insertions(+), 0 deletions(-)
diff mbox

Patch

diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index f0b0a49..cea94ac 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -1717,3 +1717,44 @@  uint32_t helper_efdcmpeq(CPUPPCState *env, uint64_t op1, uint64_t op2)
     /* XXX: TODO: test special values (NaN, infinites, ...) */
     return helper_efdtsteq(env, op1, op2);
 }
+
+#define DECODE_SPLIT(opcode, shift1, nb1, shift2, nb2) \
+    (((((opcode) >> (shift1)) & ((1 << (nb1)) - 1)) << nb2) |    \
+     (((opcode) >> (shift2)) & ((1 << (nb2)) - 1)))
+
+#define xT(opcode) DECODE_SPLIT(opcode, 0, 1, 21, 5)
+#define xA(opcode) DECODE_SPLIT(opcode, 2, 1, 16, 5)
+#define xB(opcode) DECODE_SPLIT(opcode, 1, 1, 11, 5)
+#define xC(opcode) DECODE_SPLIT(opcode, 3, 1,  6, 5)
+#define BF(opcode) (((opcode) >> (31-8)) & 7)
+
+typedef union _ppc_vsr_t {
+    uint64_t u64[2];
+    uint32_t u32[4];
+    float32 f32[4];
+    float64 f64[2];
+} ppc_vsr_t;
+
+static void getVSR(int n, ppc_vsr_t *vsr, CPUPPCState *env)
+{
+    if (n < 32) {
+        vsr->f64[0] = env->fpr[n];
+        vsr->u64[1] = env->vsr[n];
+    } else {
+        vsr->u64[0] = env->avr[n-32].u64[0];
+        vsr->u64[1] = env->avr[n-32].u64[1];
+    }
+}
+
+static void putVSR(int n, ppc_vsr_t *vsr, CPUPPCState *env)
+{
+    if (n < 32) {
+        env->fpr[n] = vsr->f64[0];
+        env->vsr[n] = vsr->u64[1];
+    } else {
+        env->avr[n-32].u64[0] = vsr->u64[0];
+        env->avr[n-32].u64[1] = vsr->u64[1];
+    }
+}
+
+#define float64_to_float64(x, env) x
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index ce07a56..0453900 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7280,6 +7280,20 @@  VSX_VECTOR_MOVE(xvnabssp, OP_NABS, SGN_MASK_SP)
 VSX_VECTOR_MOVE(xvnegsp, OP_NEG, SGN_MASK_SP)
 VSX_VECTOR_MOVE(xvcpsgnsp, OP_CPSGN, SGN_MASK_SP)
 
+#define GEN_VSX_HELPER_2(name, op1, op2, inval, type)                         \
+static void gen_##name(DisasContext * ctx)                                    \
+{                                                                             \
+    TCGv_i32 opc;                                                             \
+    if (unlikely(!ctx->vsx_enabled)) {                                        \
+        gen_exception(ctx, POWERPC_EXCP_VSXU);                                \
+        return;                                                               \
+    }                                                                         \
+    /* NIP cannot be restored if the memory exception comes from an helper */ \
+    gen_update_nip(ctx, ctx->nip - 4);                                        \
+    opc = tcg_const_i32(ctx->opcode);                                         \
+    gen_helper_##name(cpu_env, opc);                                          \
+    tcg_temp_free_i32(opc);                                                   \
+}
 
 #define VSX_LOGICAL(name, tcg_op)                                    \
 static void glue(gen_, name)(DisasContext * ctx)                     \