aboutsummaryrefslogtreecommitdiff
path: root/target-ppc/fpu_helper.c
diff options
context:
space:
mode:
authorTom Musta <tommusta@gmail.com>2014-01-02 16:21:20 -0600
committerAlexander Graf <agraf@suse.de>2014-03-05 03:06:27 +0100
commit3c3cbbdc84dbe594b4fa4df52eb8ed6f42d640d8 (patch)
treee8cc1bc155a55f734ad932d46b14c7aadd944ab5 /target-ppc/fpu_helper.c
parent59800ec8e52bcfa271fa61fb0aae19205ef1b7f1 (diff)
target-ppc: General Support for VSX Helpers
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> Reviewed-by: Richard Henderson <rth@twiddle.net> Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'target-ppc/fpu_helper.c')
-rw-r--r--target-ppc/fpu_helper.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index f0b0a49508..cea94acab6 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