^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 1999 Eddie C. Dost (ecd@atecom.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <asm/reg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <asm/switch_to.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <asm/sfp-machine.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <math-emu/double.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define FLOATFUNC(x) extern int x(void *, void *, void *, void *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) /* The instructions list which may be not implemented by a hardware FPU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) FLOATFUNC(fre);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) FLOATFUNC(frsqrtes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) FLOATFUNC(fsqrt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) FLOATFUNC(fsqrts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) FLOATFUNC(mtfsf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) FLOATFUNC(mtfsfi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #ifdef CONFIG_MATH_EMULATION_HW_UNIMPLEMENTED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #undef FLOATFUNC(x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define FLOATFUNC(x) static inline int x(void *op1, void *op2, void *op3, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) void *op4) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) FLOATFUNC(fadd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) FLOATFUNC(fadds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) FLOATFUNC(fdiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) FLOATFUNC(fdivs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) FLOATFUNC(fmul);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) FLOATFUNC(fmuls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) FLOATFUNC(fsub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) FLOATFUNC(fsubs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) FLOATFUNC(fmadd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) FLOATFUNC(fmadds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) FLOATFUNC(fmsub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) FLOATFUNC(fmsubs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) FLOATFUNC(fnmadd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) FLOATFUNC(fnmadds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) FLOATFUNC(fnmsub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) FLOATFUNC(fnmsubs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) FLOATFUNC(fctiw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) FLOATFUNC(fctiwz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) FLOATFUNC(frsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) FLOATFUNC(fcmpo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) FLOATFUNC(fcmpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) FLOATFUNC(mcrfs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) FLOATFUNC(mffs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) FLOATFUNC(mtfsb0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) FLOATFUNC(mtfsb1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) FLOATFUNC(lfd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) FLOATFUNC(lfs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) FLOATFUNC(stfd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) FLOATFUNC(stfs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) FLOATFUNC(stfiwx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) FLOATFUNC(fabs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) FLOATFUNC(fmr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) FLOATFUNC(fnabs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) FLOATFUNC(fneg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /* Optional */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) FLOATFUNC(fres);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) FLOATFUNC(frsqrte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) FLOATFUNC(fsel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define OP31 0x1f /* 31 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define LFS 0x30 /* 48 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define LFSU 0x31 /* 49 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define LFD 0x32 /* 50 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define LFDU 0x33 /* 51 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define STFS 0x34 /* 52 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define STFSU 0x35 /* 53 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define STFD 0x36 /* 54 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define STFDU 0x37 /* 55 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define OP59 0x3b /* 59 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define OP63 0x3f /* 63 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /* Opcode 31: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) /* X-Form: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define LFSX 0x217 /* 535 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define LFSUX 0x237 /* 567 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define LFDX 0x257 /* 599 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define LFDUX 0x277 /* 631 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define STFSX 0x297 /* 663 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define STFSUX 0x2b7 /* 695 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define STFDX 0x2d7 /* 727 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define STFDUX 0x2f7 /* 759 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define STFIWX 0x3d7 /* 983 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /* Opcode 59: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /* A-Form: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define FDIVS 0x012 /* 18 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define FSUBS 0x014 /* 20 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define FADDS 0x015 /* 21 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define FSQRTS 0x016 /* 22 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define FRES 0x018 /* 24 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define FMULS 0x019 /* 25 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define FRSQRTES 0x01a /* 26 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #define FMSUBS 0x01c /* 28 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define FMADDS 0x01d /* 29 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define FNMSUBS 0x01e /* 30 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #define FNMADDS 0x01f /* 31 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /* Opcode 63: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) /* A-Form: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define FDIV 0x012 /* 18 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define FSUB 0x014 /* 20 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #define FADD 0x015 /* 21 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #define FSQRT 0x016 /* 22 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #define FSEL 0x017 /* 23 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #define FRE 0x018 /* 24 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define FMUL 0x019 /* 25 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #define FRSQRTE 0x01a /* 26 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define FMSUB 0x01c /* 28 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define FMADD 0x01d /* 29 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define FNMSUB 0x01e /* 30 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define FNMADD 0x01f /* 31 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) /* X-Form: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define FCMPU 0x000 /* 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #define FRSP 0x00c /* 12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #define FCTIW 0x00e /* 14 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #define FCTIWZ 0x00f /* 15 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define FCMPO 0x020 /* 32 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #define MTFSB1 0x026 /* 38 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define FNEG 0x028 /* 40 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #define MCRFS 0x040 /* 64 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #define MTFSB0 0x046 /* 70 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define FMR 0x048 /* 72 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define MTFSFI 0x086 /* 134 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #define FNABS 0x088 /* 136 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #define FABS 0x108 /* 264 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #define MFFS 0x247 /* 583 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define MTFSF 0x2c7 /* 711 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define AB 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #define AC 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #define ABC 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #define D 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) #define DU 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #define X 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) #define XA 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) #define XB 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) #define XCR 11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) #define XCRB 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #define XCRI 13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) #define XCRL 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #define XE 14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #define XEU 15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #define XFLB 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) record_exception(struct pt_regs *regs, int eflag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) u32 fpscr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) fpscr = __FPU_FPSCR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (eflag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) fpscr |= FPSCR_FX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) if (eflag & EFLAG_OVERFLOW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) fpscr |= FPSCR_OX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (eflag & EFLAG_UNDERFLOW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) fpscr |= FPSCR_UX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (eflag & EFLAG_DIVZERO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) fpscr |= FPSCR_ZX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (eflag & EFLAG_INEXACT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) fpscr |= FPSCR_XX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) if (eflag & EFLAG_INVALID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) fpscr |= FPSCR_VX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (eflag & EFLAG_VXSNAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) fpscr |= FPSCR_VXSNAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (eflag & EFLAG_VXISI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) fpscr |= FPSCR_VXISI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if (eflag & EFLAG_VXIDI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) fpscr |= FPSCR_VXIDI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (eflag & EFLAG_VXZDZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) fpscr |= FPSCR_VXZDZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (eflag & EFLAG_VXIMZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) fpscr |= FPSCR_VXIMZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if (eflag & EFLAG_VXVC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) fpscr |= FPSCR_VXVC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) if (eflag & EFLAG_VXSOFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) fpscr |= FPSCR_VXSOFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (eflag & EFLAG_VXSQRT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) fpscr |= FPSCR_VXSQRT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (eflag & EFLAG_VXCVI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) fpscr |= FPSCR_VXCVI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) // fpscr &= ~(FPSCR_VX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (fpscr & (FPSCR_VXSNAN | FPSCR_VXISI | FPSCR_VXIDI |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) FPSCR_VXZDZ | FPSCR_VXIMZ | FPSCR_VXVC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) fpscr |= FPSCR_VX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) fpscr &= ~(FPSCR_FEX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (((fpscr & FPSCR_VX) && (fpscr & FPSCR_VE)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) ((fpscr & FPSCR_OX) && (fpscr & FPSCR_OE)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) ((fpscr & FPSCR_UX) && (fpscr & FPSCR_UE)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) ((fpscr & FPSCR_ZX) && (fpscr & FPSCR_ZE)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) ((fpscr & FPSCR_XX) && (fpscr & FPSCR_XE)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) fpscr |= FPSCR_FEX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) __FPU_FPSCR = fpscr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return (fpscr & FPSCR_FEX) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) do_mathemu(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) void *op0 = 0, *op1 = 0, *op2 = 0, *op3 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) unsigned long pc = regs->nip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) signed short sdisp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) u32 insn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) int idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) int (*func)(void *, void *, void *, void *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) int type = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) int eflag, trap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (get_user(insn, (u32 *)pc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) switch (insn >> 26) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) case LFS: func = lfs; type = D; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) case LFSU: func = lfs; type = DU; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) case LFD: func = lfd; type = D; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) case LFDU: func = lfd; type = DU; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) case STFS: func = stfs; type = D; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) case STFSU: func = stfs; type = DU; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) case STFD: func = stfd; type = D; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) case STFDU: func = stfd; type = DU; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) case OP31:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) switch ((insn >> 1) & 0x3ff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) case LFSX: func = lfs; type = XE; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) case LFSUX: func = lfs; type = XEU; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) case LFDX: func = lfd; type = XE; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) case LFDUX: func = lfd; type = XEU; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) case STFSX: func = stfs; type = XE; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) case STFSUX: func = stfs; type = XEU; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) case STFDX: func = stfd; type = XE; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) case STFDUX: func = stfd; type = XEU; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) case STFIWX: func = stfiwx; type = XE; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) goto illegal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) case OP59:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) switch ((insn >> 1) & 0x1f) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) case FDIVS: func = fdivs; type = AB; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) case FSUBS: func = fsubs; type = AB; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) case FADDS: func = fadds; type = AB; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) case FSQRTS: func = fsqrts; type = XB; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) case FRES: func = fres; type = XB; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) case FMULS: func = fmuls; type = AC; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) case FRSQRTES: func = frsqrtes;type = XB; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) case FMSUBS: func = fmsubs; type = ABC; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) case FMADDS: func = fmadds; type = ABC; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) case FNMSUBS: func = fnmsubs; type = ABC; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) case FNMADDS: func = fnmadds; type = ABC; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) goto illegal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) case OP63:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (insn & 0x20) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) switch ((insn >> 1) & 0x1f) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) case FDIV: func = fdiv; type = AB; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) case FSUB: func = fsub; type = AB; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) case FADD: func = fadd; type = AB; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) case FSQRT: func = fsqrt; type = XB; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) case FRE: func = fre; type = XB; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) case FSEL: func = fsel; type = ABC; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) case FMUL: func = fmul; type = AC; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) case FRSQRTE: func = frsqrte; type = XB; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) case FMSUB: func = fmsub; type = ABC; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) case FMADD: func = fmadd; type = ABC; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) case FNMSUB: func = fnmsub; type = ABC; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) case FNMADD: func = fnmadd; type = ABC; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) goto illegal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) switch ((insn >> 1) & 0x3ff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) case FCMPU: func = fcmpu; type = XCR; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) case FRSP: func = frsp; type = XB; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) case FCTIW: func = fctiw; type = XB; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) case FCTIWZ: func = fctiwz; type = XB; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) case FCMPO: func = fcmpo; type = XCR; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) case MTFSB1: func = mtfsb1; type = XCRB; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) case FNEG: func = fneg; type = XB; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) case MCRFS: func = mcrfs; type = XCRL; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) case MTFSB0: func = mtfsb0; type = XCRB; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) case FMR: func = fmr; type = XB; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) case MTFSFI: func = mtfsfi; type = XCRI; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) case FNABS: func = fnabs; type = XB; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) case FABS: func = fabs; type = XB; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) case MFFS: func = mffs; type = X; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) case MTFSF: func = mtfsf; type = XFLB; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) goto illegal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) goto illegal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) case AB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) op0 = (void *)¤t->thread.TS_FPR((insn >> 21) & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) op1 = (void *)¤t->thread.TS_FPR((insn >> 16) & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) op2 = (void *)¤t->thread.TS_FPR((insn >> 11) & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) case AC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) op0 = (void *)¤t->thread.TS_FPR((insn >> 21) & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) op1 = (void *)¤t->thread.TS_FPR((insn >> 16) & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) op2 = (void *)¤t->thread.TS_FPR((insn >> 6) & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) case ABC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) op0 = (void *)¤t->thread.TS_FPR((insn >> 21) & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) op1 = (void *)¤t->thread.TS_FPR((insn >> 16) & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) op2 = (void *)¤t->thread.TS_FPR((insn >> 11) & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) op3 = (void *)¤t->thread.TS_FPR((insn >> 6) & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) case D:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) idx = (insn >> 16) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) sdisp = (insn & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) op0 = (void *)¤t->thread.TS_FPR((insn >> 21) & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) op1 = (void *)((idx ? regs->gpr[idx] : 0) + sdisp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) case DU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) idx = (insn >> 16) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (!idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) goto illegal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) sdisp = (insn & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) op0 = (void *)¤t->thread.TS_FPR((insn >> 21) & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) op1 = (void *)(regs->gpr[idx] + sdisp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) case X:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) op0 = (void *)¤t->thread.TS_FPR((insn >> 21) & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) case XA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) op0 = (void *)¤t->thread.TS_FPR((insn >> 21) & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) op1 = (void *)¤t->thread.TS_FPR((insn >> 16) & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) case XB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) op0 = (void *)¤t->thread.TS_FPR((insn >> 21) & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) op1 = (void *)¤t->thread.TS_FPR((insn >> 11) & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) case XE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) idx = (insn >> 16) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) op0 = (void *)¤t->thread.TS_FPR((insn >> 21) & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) op1 = (void *)((idx ? regs->gpr[idx] : 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) + regs->gpr[(insn >> 11) & 0x1f]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) case XEU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) idx = (insn >> 16) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (!idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) goto illegal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) op0 = (void *)¤t->thread.TS_FPR((insn >> 21) & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) op1 = (void *)(regs->gpr[idx]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) + regs->gpr[(insn >> 11) & 0x1f]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) case XCR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) op0 = (void *)®s->ccr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) op1 = (void *)((insn >> 23) & 0x7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) op2 = (void *)¤t->thread.TS_FPR((insn >> 16) & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) op3 = (void *)¤t->thread.TS_FPR((insn >> 11) & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) case XCRL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) op0 = (void *)®s->ccr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) op1 = (void *)((insn >> 23) & 0x7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) op2 = (void *)((insn >> 18) & 0x7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) case XCRB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) op0 = (void *)((insn >> 21) & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) case XCRI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) op0 = (void *)((insn >> 23) & 0x7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) op1 = (void *)((insn >> 12) & 0xf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) case XFLB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) op0 = (void *)((insn >> 17) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) op1 = (void *)¤t->thread.TS_FPR((insn >> 11) & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) goto illegal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) * If we support a HW FPU, we need to ensure the FP state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) * is flushed into the thread_struct before attempting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) * emulation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) flush_fp_to_thread(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) eflag = func(op0, op1, op2, op3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if (insn & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) regs->ccr &= ~(0x0f000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) regs->ccr |= (__FPU_FPSCR >> 4) & 0x0f000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) trap = record_exception(regs, eflag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) if (trap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) case DU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) case XEU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) regs->gpr[idx] = (unsigned long)op1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) regs->nip += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) illegal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) }