int err;
union {
float f;
- double d;
- unsigned long l;
- u8 b[sizeof(double)];
+ double d[2];
+ unsigned long l[2];
+ u8 b[2 * sizeof(double)];
} u;
if (!address_ok(regs, ea, nb))
return err;
preempt_disable();
if (nb == 4)
- conv_sp_to_dp(&u.f, &u.d);
+ conv_sp_to_dp(&u.f, &u.d[0]);
if (regs->msr & MSR_FP)
- put_fpr(rn, &u.d);
+ put_fpr(rn, &u.d[0]);
else
- current->thread.TS_FPR(rn) = u.l;
+ current->thread.TS_FPR(rn) = u.l[0];
+ if (nb == 16) {
+ /* lfdp */
+ rn |= 1;
+ if (regs->msr & MSR_FP)
+ put_fpr(rn, &u.d[1]);
+ else
+ current->thread.TS_FPR(rn) = u.l[1];
+ }
preempt_enable();
return 0;
}
{
union {
float f;
- double d;
- unsigned long l;
- u8 b[sizeof(double)];
+ double d[2];
+ unsigned long l[2];
+ u8 b[2 * sizeof(double)];
} u;
if (!address_ok(regs, ea, nb))
return -EFAULT;
preempt_disable();
if (regs->msr & MSR_FP)
- get_fpr(rn, &u.d);
+ get_fpr(rn, &u.d[0]);
else
- u.l = current->thread.TS_FPR(rn);
+ u.l[0] = current->thread.TS_FPR(rn);
if (nb == 4)
- conv_dp_to_sp(&u.d, &u.f);
+ conv_dp_to_sp(&u.d[0], &u.f);
+ if (nb == 16) {
+ rn |= 1;
+ if (regs->msr & MSR_FP)
+ get_fpr(rn, &u.d[1]);
+ else
+ u.l[1] = current->thread.TS_FPR(rn);
+ }
preempt_enable();
return copy_mem_out(u.b, ea, nb);
}
case 759: /* stfdux */
op->type = MKOP(STORE_FP, u, 8);
break;
-#endif
+
+#ifdef __powerpc64__
+ case 791: /* lfdpx */
+ op->type = MKOP(LOAD_FP, 0, 16);
+ break;
+
+ case 919: /* stfdpx */
+ op->type = MKOP(STORE_FP, 0, 16);
+ break;
+#endif /* __powerpc64 */
+#endif /* CONFIG_PPC_FPU */
#ifdef __powerpc64__
case 660: /* stdbrx */
op->val = byterev_4(regs->gpr[rd]);
break;
- case 725:
+ case 725: /* stswi */
if (rb == 0)
rb = 32; /* # bytes to store */
op->type = MKOP(STORE_MULTI, 0, rb);
#endif
#ifdef CONFIG_VSX
- case 57: /* lxsd, lxssp */
+ case 57: /* lfdp, lxsd, lxssp */
op->ea = dsform_ea(instr, regs);
switch (instr & 3) {
+ case 0: /* lfdp */
+ if (rd & 1)
+ break; /* reg must be even */
+ op->type = MKOP(LOAD_FP, 0, 16);
+ break;
case 2: /* lxsd */
op->reg = rd + 32;
op->type = MKOP(LOAD_VSX, 0, 8);
#endif
#ifdef CONFIG_VSX
- case 61: /* lxv, stxsd, stxssp, stxv */
+ case 61: /* stfdp, lxv, stxsd, stxssp, stxv */
switch (instr & 7) {
+ case 0: /* stfdp with LSB of DS field = 0 */
+ case 4: /* stfdp with LSB of DS field = 1 */
+ op->ea = dsform_ea(instr, regs);
+ op->type = MKOP(STORE_FP, 0, 16);
+ break;
+
case 1: /* lxv */
op->ea = dqform_ea(instr, regs);
if (instr & 8)