aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/math-emu/cp1emu.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/math-emu/cp1emu.c')
-rw-r--r--arch/mips/math-emu/cp1emu.c298
1 files changed, 121 insertions, 177 deletions
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
index 3a0dfa4feadd..6258291354eb 100644
--- a/arch/mips/math-emu/cp1emu.c
+++ b/arch/mips/math-emu/cp1emu.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * cp1emu.c: a MIPS coprocessor 1 (fpu) instruction emulator 2 * cp1emu.c: a MIPS coprocessor 1 (FPU) instruction emulator
3 * 3 *
4 * MIPS floating point support 4 * MIPS floating point support
5 * Copyright (C) 1994-2000 Algorithmics Ltd. 5 * Copyright (C) 1994-2000 Algorithmics Ltd.
@@ -18,19 +18,19 @@
18 * 18 *
19 * You should have received a copy of the GNU General Public License along 19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc., 20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. 21 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
22 * 22 *
23 * A complete emulator for MIPS coprocessor 1 instructions. This is 23 * A complete emulator for MIPS coprocessor 1 instructions. This is
24 * required for #float(switch) or #float(trap), where it catches all 24 * required for #float(switch) or #float(trap), where it catches all
25 * COP1 instructions via the "CoProcessor Unusable" exception. 25 * COP1 instructions via the "CoProcessor Unusable" exception.
26 * 26 *
27 * More surprisingly it is also required for #float(ieee), to help out 27 * More surprisingly it is also required for #float(ieee), to help out
28 * the hardware fpu at the boundaries of the IEEE-754 representation 28 * the hardware FPU at the boundaries of the IEEE-754 representation
29 * (denormalised values, infinities, underflow, etc). It is made 29 * (denormalised values, infinities, underflow, etc). It is made
30 * quite nasty because emulation of some non-COP1 instructions is 30 * quite nasty because emulation of some non-COP1 instructions is
31 * required, e.g. in branch delay slots. 31 * required, e.g. in branch delay slots.
32 * 32 *
33 * Note if you know that you won't have an fpu, then you'll get much 33 * Note if you know that you won't have an FPU, then you'll get much
34 * better performance by compiling with -msoft-float! 34 * better performance by compiling with -msoft-float!
35 */ 35 */
36#include <linux/sched.h> 36#include <linux/sched.h>
@@ -72,14 +72,14 @@ static int fpux_emu(struct pt_regs *,
72#define MM_POOL32A_MINOR_SHIFT 0x6 72#define MM_POOL32A_MINOR_SHIFT 0x6
73#define MM_MIPS32_COND_FC 0x30 73#define MM_MIPS32_COND_FC 0x30
74 74
75/* Convert Mips rounding mode (0..3) to IEEE library modes. */ 75/* Convert MIPS rounding mode (0..3) to IEEE library modes. */
76static const unsigned char ieee_rm[4] = { 76static const unsigned char ieee_rm[4] = {
77 [FPU_CSR_RN] = IEEE754_RN, 77 [FPU_CSR_RN] = IEEE754_RN,
78 [FPU_CSR_RZ] = IEEE754_RZ, 78 [FPU_CSR_RZ] = IEEE754_RZ,
79 [FPU_CSR_RU] = IEEE754_RU, 79 [FPU_CSR_RU] = IEEE754_RU,
80 [FPU_CSR_RD] = IEEE754_RD, 80 [FPU_CSR_RD] = IEEE754_RD,
81}; 81};
82/* Convert IEEE library modes to Mips rounding mode (0..3). */ 82/* Convert IEEE library modes to MIPS rounding mode (0..3). */
83static const unsigned char mips_rm[4] = { 83static const unsigned char mips_rm[4] = {
84 [IEEE754_RN] = FPU_CSR_RN, 84 [IEEE754_RN] = FPU_CSR_RN,
85 [IEEE754_RZ] = FPU_CSR_RZ, 85 [IEEE754_RZ] = FPU_CSR_RZ,
@@ -914,10 +914,16 @@ do { \
914static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx, 914static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
915 struct mm_decoded_insn dec_insn, void *__user *fault_addr) 915 struct mm_decoded_insn dec_insn, void *__user *fault_addr)
916{ 916{
917 mips_instruction ir;
918 unsigned long contpc = xcp->cp0_epc + dec_insn.pc_inc; 917 unsigned long contpc = xcp->cp0_epc + dec_insn.pc_inc;
919 unsigned int cond; 918 unsigned int cond, cbit;
920 int pc_inc; 919 mips_instruction ir;
920 int likely, pc_inc;
921 u32 __user *wva;
922 u64 __user *dva;
923 u32 value;
924 u32 wval;
925 u64 dval;
926 int sig;
921 927
922 /* XXX NEC Vr54xx bug workaround */ 928 /* XXX NEC Vr54xx bug workaround */
923 if (delay_slot(xcp)) { 929 if (delay_slot(xcp)) {
@@ -972,94 +978,81 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
972 return SIGILL; 978 return SIGILL;
973 } 979 }
974 980
975 emul: 981emul:
976 perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, xcp, 0); 982 perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, xcp, 0);
977 MIPS_FPU_EMU_INC_STATS(emulated); 983 MIPS_FPU_EMU_INC_STATS(emulated);
978 switch (MIPSInst_OPCODE(ir)) { 984 switch (MIPSInst_OPCODE(ir)) {
979 case ldc1_op:{ 985 case ldc1_op:
980 u64 __user *va = (u64 __user *) (xcp->regs[MIPSInst_RS(ir)] + 986 dva = (u64 __user *) (xcp->regs[MIPSInst_RS(ir)] +
981 MIPSInst_SIMM(ir)); 987 MIPSInst_SIMM(ir));
982 u64 val;
983
984 MIPS_FPU_EMU_INC_STATS(loads); 988 MIPS_FPU_EMU_INC_STATS(loads);
985 989
986 if (!access_ok(VERIFY_READ, va, sizeof(u64))) { 990 if (!access_ok(VERIFY_READ, dva, sizeof(u64))) {
987 MIPS_FPU_EMU_INC_STATS(errors); 991 MIPS_FPU_EMU_INC_STATS(errors);
988 *fault_addr = va; 992 *fault_addr = dva;
989 return SIGBUS; 993 return SIGBUS;
990 } 994 }
991 if (__get_user(val, va)) { 995 if (__get_user(dval, dva)) {
992 MIPS_FPU_EMU_INC_STATS(errors); 996 MIPS_FPU_EMU_INC_STATS(errors);
993 *fault_addr = va; 997 *fault_addr = dva;
994 return SIGSEGV; 998 return SIGSEGV;
995 } 999 }
996 DITOREG(val, MIPSInst_RT(ir)); 1000 DITOREG(dval, MIPSInst_RT(ir));
997 break; 1001 break;
998 }
999
1000 case sdc1_op:{
1001 u64 __user *va = (u64 __user *) (xcp->regs[MIPSInst_RS(ir)] +
1002 MIPSInst_SIMM(ir));
1003 u64 val;
1004 1002
1003 case sdc1_op:
1004 dva = (u64 __user *) (xcp->regs[MIPSInst_RS(ir)] +
1005 MIPSInst_SIMM(ir));
1005 MIPS_FPU_EMU_INC_STATS(stores); 1006 MIPS_FPU_EMU_INC_STATS(stores);
1006 DIFROMREG(val, MIPSInst_RT(ir)); 1007 DIFROMREG(dval, MIPSInst_RT(ir));
1007 if (!access_ok(VERIFY_WRITE, va, sizeof(u64))) { 1008 if (!access_ok(VERIFY_WRITE, dva, sizeof(u64))) {
1008 MIPS_FPU_EMU_INC_STATS(errors); 1009 MIPS_FPU_EMU_INC_STATS(errors);
1009 *fault_addr = va; 1010 *fault_addr = dva;
1010 return SIGBUS; 1011 return SIGBUS;
1011 } 1012 }
1012 if (__put_user(val, va)) { 1013 if (__put_user(dval, dva)) {
1013 MIPS_FPU_EMU_INC_STATS(errors); 1014 MIPS_FPU_EMU_INC_STATS(errors);
1014 *fault_addr = va; 1015 *fault_addr = dva;
1015 return SIGSEGV; 1016 return SIGSEGV;
1016 } 1017 }
1017 break; 1018 break;
1018 }
1019
1020 case lwc1_op:{
1021 u32 __user *va = (u32 __user *) (xcp->regs[MIPSInst_RS(ir)] +
1022 MIPSInst_SIMM(ir));
1023 u32 val;
1024 1019
1020 case lwc1_op:
1021 wva = (u32 __user *) (xcp->regs[MIPSInst_RS(ir)] +
1022 MIPSInst_SIMM(ir));
1025 MIPS_FPU_EMU_INC_STATS(loads); 1023 MIPS_FPU_EMU_INC_STATS(loads);
1026 if (!access_ok(VERIFY_READ, va, sizeof(u32))) { 1024 if (!access_ok(VERIFY_READ, wva, sizeof(u32))) {
1027 MIPS_FPU_EMU_INC_STATS(errors); 1025 MIPS_FPU_EMU_INC_STATS(errors);
1028 *fault_addr = va; 1026 *fault_addr = wva;
1029 return SIGBUS; 1027 return SIGBUS;
1030 } 1028 }
1031 if (__get_user(val, va)) { 1029 if (__get_user(wval, wva)) {
1032 MIPS_FPU_EMU_INC_STATS(errors); 1030 MIPS_FPU_EMU_INC_STATS(errors);
1033 *fault_addr = va; 1031 *fault_addr = wva;
1034 return SIGSEGV; 1032 return SIGSEGV;
1035 } 1033 }
1036 SITOREG(val, MIPSInst_RT(ir)); 1034 SITOREG(wval, MIPSInst_RT(ir));
1037 break; 1035 break;
1038 }
1039
1040 case swc1_op:{
1041 u32 __user *va = (u32 __user *) (xcp->regs[MIPSInst_RS(ir)] +
1042 MIPSInst_SIMM(ir));
1043 u32 val;
1044 1036
1037 case swc1_op:
1038 wva = (u32 __user *) (xcp->regs[MIPSInst_RS(ir)] +
1039 MIPSInst_SIMM(ir));
1045 MIPS_FPU_EMU_INC_STATS(stores); 1040 MIPS_FPU_EMU_INC_STATS(stores);
1046 SIFROMREG(val, MIPSInst_RT(ir)); 1041 SIFROMREG(wval, MIPSInst_RT(ir));
1047 if (!access_ok(VERIFY_WRITE, va, sizeof(u32))) { 1042 if (!access_ok(VERIFY_WRITE, wva, sizeof(u32))) {
1048 MIPS_FPU_EMU_INC_STATS(errors); 1043 MIPS_FPU_EMU_INC_STATS(errors);
1049 *fault_addr = va; 1044 *fault_addr = wva;
1050 return SIGBUS; 1045 return SIGBUS;
1051 } 1046 }
1052 if (__put_user(val, va)) { 1047 if (__put_user(wval, wva)) {
1053 MIPS_FPU_EMU_INC_STATS(errors); 1048 MIPS_FPU_EMU_INC_STATS(errors);
1054 *fault_addr = va; 1049 *fault_addr = wva;
1055 return SIGSEGV; 1050 return SIGSEGV;
1056 } 1051 }
1057 break; 1052 break;
1058 }
1059 1053
1060 case cop1_op: 1054 case cop1_op:
1061 switch (MIPSInst_RS(ir)) { 1055 switch (MIPSInst_RS(ir)) {
1062
1063 case dmfc_op: 1056 case dmfc_op:
1064 if (!cpu_has_mips_3_4_5 && !cpu_has_mips64) 1057 if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
1065 return SIGILL; 1058 return SIGILL;
@@ -1111,10 +1104,8 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1111 SITOREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir)); 1104 SITOREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
1112 break; 1105 break;
1113 1106
1114 case cfc_op:{ 1107 case cfc_op:
1115 /* cop control register rd -> gpr[rt] */ 1108 /* cop control register rd -> gpr[rt] */
1116 u32 value;
1117
1118 if (MIPSInst_RD(ir) == FPCREG_CSR) { 1109 if (MIPSInst_RD(ir) == FPCREG_CSR) {
1119 value = ctx->fcr31; 1110 value = ctx->fcr31;
1120 value = (value & ~FPU_CSR_RM) | 1111 value = (value & ~FPU_CSR_RM) |
@@ -1130,12 +1121,9 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1130 if (MIPSInst_RT(ir)) 1121 if (MIPSInst_RT(ir))
1131 xcp->regs[MIPSInst_RT(ir)] = value; 1122 xcp->regs[MIPSInst_RT(ir)] = value;
1132 break; 1123 break;
1133 }
1134 1124
1135 case ctc_op:{ 1125 case ctc_op:
1136 /* copregister rd <- rt */ 1126 /* copregister rd <- rt */
1137 u32 value;
1138
1139 if (MIPSInst_RT(ir) == 0) 1127 if (MIPSInst_RT(ir) == 0)
1140 value = 0; 1128 value = 0;
1141 else 1129 else
@@ -1160,12 +1148,8 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1160 return SIGFPE; 1148 return SIGFPE;
1161 } 1149 }
1162 break; 1150 break;
1163 }
1164
1165 case bc_op:{
1166 unsigned int cbit;
1167 int likely = 0;
1168 1151
1152 case bc_op:
1169 if (delay_slot(xcp)) 1153 if (delay_slot(xcp))
1170 return SIGILL; 1154 return SIGILL;
1171 1155
@@ -1175,6 +1159,7 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1175 cbit = FPU_CSR_COND; 1159 cbit = FPU_CSR_COND;
1176 cond = ctx->fcr31 & cbit; 1160 cond = ctx->fcr31 & cbit;
1177 1161
1162 likely = 0;
1178 switch (MIPSInst_RT(ir) & 3) { 1163 switch (MIPSInst_RT(ir) & 3) {
1179 case bcfl_op: 1164 case bcfl_op:
1180 likely = 1; 1165 likely = 1;
@@ -1192,8 +1177,8 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1192 1177
1193 set_delay_slot(xcp); 1178 set_delay_slot(xcp);
1194 if (cond) { 1179 if (cond) {
1195 /* branch taken: emulate dslot 1180 /*
1196 * instruction 1181 * Branch taken: emulate dslot instruction
1197 */ 1182 */
1198 xcp->cp0_epc += dec_insn.pc_inc; 1183 xcp->cp0_epc += dec_insn.pc_inc;
1199 1184
@@ -1228,8 +1213,10 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1228 switch (MIPSInst_OPCODE(ir)) { 1213 switch (MIPSInst_OPCODE(ir)) {
1229 case lwc1_op: 1214 case lwc1_op:
1230 goto emul; 1215 goto emul;
1216
1231 case swc1_op: 1217 case swc1_op:
1232 goto emul; 1218 goto emul;
1219
1233 case ldc1_op: 1220 case ldc1_op:
1234 case sdc1_op: 1221 case sdc1_op:
1235 if (cpu_has_mips_2_3_4_5 || 1222 if (cpu_has_mips_2_3_4_5 ||
@@ -1238,14 +1225,17 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1238 1225
1239 return SIGILL; 1226 return SIGILL;
1240 goto emul; 1227 goto emul;
1228
1241 case cop1_op: 1229 case cop1_op:
1242 goto emul; 1230 goto emul;
1231
1243 case cop1x_op: 1232 case cop1x_op:
1244 if (cpu_has_mips_4_5 || cpu_has_mips64) 1233 if (cpu_has_mips_4_5 || cpu_has_mips64)
1245 /* its one of ours */ 1234 /* its one of ours */
1246 goto emul; 1235 goto emul;
1247 1236
1248 return SIGILL; 1237 return SIGILL;
1238
1249 case spec_op: 1239 case spec_op:
1250 if (!cpu_has_mips_4_5_r) 1240 if (!cpu_has_mips_4_5_r)
1251 return SIGILL; 1241 return SIGILL;
@@ -1260,10 +1250,7 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1260 * instruction in the dslot 1250 * instruction in the dslot
1261 */ 1251 */
1262 return mips_dsemul(xcp, ir, contpc); 1252 return mips_dsemul(xcp, ir, contpc);
1263 } 1253 } else if (likely) { /* branch not taken */
1264 else {
1265 /* branch not taken */
1266 if (likely) {
1267 /* 1254 /*
1268 * branch likely nullifies 1255 * branch likely nullifies
1269 * dslot if not taken 1256 * dslot if not taken
@@ -1275,26 +1262,19 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1275 * dslot as normal insn 1262 * dslot as normal insn
1276 */ 1263 */
1277 } 1264 }
1278 }
1279 break; 1265 break;
1280 }
1281 1266
1282 default: 1267 default:
1283 if (!(MIPSInst_RS(ir) & 0x10)) 1268 if (!(MIPSInst_RS(ir) & 0x10))
1284 return SIGILL; 1269 return SIGILL;
1285 {
1286 int sig;
1287 1270
1288 /* a real fpu computation instruction */ 1271 /* a real fpu computation instruction */
1289 if ((sig = fpu_emu(xcp, ctx, ir))) 1272 if ((sig = fpu_emu(xcp, ctx, ir)))
1290 return sig; 1273 return sig;
1291 }
1292 } 1274 }
1293 break; 1275 break;
1294 1276
1295 case cop1x_op:{ 1277 case cop1x_op:
1296 int sig;
1297
1298 if (!cpu_has_mips_4_5 && !cpu_has_mips64) 1278 if (!cpu_has_mips_4_5 && !cpu_has_mips64)
1299 return SIGILL; 1279 return SIGILL;
1300 1280
@@ -1302,7 +1282,6 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1302 if (sig) 1282 if (sig)
1303 return sig; 1283 return sig;
1304 break; 1284 break;
1305 }
1306 1285
1307 case spec_op: 1286 case spec_op:
1308 if (!cpu_has_mips_4_5_r) 1287 if (!cpu_has_mips_4_5_r)
@@ -1477,7 +1456,7 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1477 1456
1478 ctx->fcr31 = (ctx->fcr31 & ~FPU_CSR_ALL_X) | rcsr; 1457 ctx->fcr31 = (ctx->fcr31 & ~FPU_CSR_ALL_X) | rcsr;
1479 if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) { 1458 if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
1480 /*printk ("SIGFPE: fpu csr = %08x\n", 1459 /*printk ("SIGFPE: FPU csr = %08x\n",
1481 ctx->fcr31); */ 1460 ctx->fcr31); */
1482 return SIGFPE; 1461 return SIGFPE;
1483 } 1462 }
@@ -1584,6 +1563,8 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1584{ 1563{
1585 int rfmt; /* resulting format */ 1564 int rfmt; /* resulting format */
1586 unsigned rcsr = 0; /* resulting csr */ 1565 unsigned rcsr = 0; /* resulting csr */
1566 unsigned int oldrm;
1567 unsigned int cbit;
1587 unsigned cond; 1568 unsigned cond;
1588 union { 1569 union {
1589 union ieee754dp d; 1570 union ieee754dp d;
@@ -1591,14 +1572,16 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1591 int w; 1572 int w;
1592 s64 l; 1573 s64 l;
1593 } rv; /* resulting value */ 1574 } rv; /* resulting value */
1575 u64 bits;
1594 1576
1595 MIPS_FPU_EMU_INC_STATS(cp1ops); 1577 MIPS_FPU_EMU_INC_STATS(cp1ops);
1596 switch (rfmt = (MIPSInst_FFMT(ir) & 0xf)) { 1578 switch (rfmt = (MIPSInst_FFMT(ir) & 0xf)) {
1597 case s_fmt:{ /* 0 */ 1579 case s_fmt: { /* 0 */
1598 union { 1580 union {
1599 union ieee754sp(*b) (union ieee754sp, union ieee754sp); 1581 union ieee754sp(*b) (union ieee754sp, union ieee754sp);
1600 union ieee754sp(*u) (union ieee754sp); 1582 union ieee754sp(*u) (union ieee754sp);
1601 } handler; 1583 } handler;
1584 union ieee754sp fs, ft;
1602 1585
1603 switch (MIPSInst_FUNC(ir)) { 1586 switch (MIPSInst_FUNC(ir)) {
1604 /* binary ops */ 1587 /* binary ops */
@@ -1622,6 +1605,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1622 1605
1623 handler.u = ieee754sp_sqrt; 1606 handler.u = ieee754sp_sqrt;
1624 goto scopuop; 1607 goto scopuop;
1608
1625 /* 1609 /*
1626 * Note that on some MIPS IV implementations such as the 1610 * Note that on some MIPS IV implementations such as the
1627 * R5000 and R8000 the FSQRT and FRECIP instructions do not 1611 * R5000 and R8000 the FSQRT and FRECIP instructions do not
@@ -1633,6 +1617,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1633 1617
1634 handler.u = fpemu_sp_rsqrt; 1618 handler.u = fpemu_sp_rsqrt;
1635 goto scopuop; 1619 goto scopuop;
1620
1636 case frecip_op: 1621 case frecip_op:
1637 if (!cpu_has_mips_4_5_r2) 1622 if (!cpu_has_mips_4_5_r2)
1638 return SIGILL; 1623 return SIGILL;
@@ -1650,6 +1635,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1650 return 0; 1635 return 0;
1651 SPFROMREG(rv.s, MIPSInst_FS(ir)); 1636 SPFROMREG(rv.s, MIPSInst_FS(ir));
1652 break; 1637 break;
1638
1653 case fmovz_op: 1639 case fmovz_op:
1654 if (!cpu_has_mips_4_5_r) 1640 if (!cpu_has_mips_4_5_r)
1655 return SIGILL; 1641 return SIGILL;
@@ -1658,6 +1644,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1658 return 0; 1644 return 0;
1659 SPFROMREG(rv.s, MIPSInst_FS(ir)); 1645 SPFROMREG(rv.s, MIPSInst_FS(ir));
1660 break; 1646 break;
1647
1661 case fmovn_op: 1648 case fmovn_op:
1662 if (!cpu_has_mips_4_5_r) 1649 if (!cpu_has_mips_4_5_r)
1663 return SIGILL; 1650 return SIGILL;
@@ -1666,37 +1653,32 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1666 return 0; 1653 return 0;
1667 SPFROMREG(rv.s, MIPSInst_FS(ir)); 1654 SPFROMREG(rv.s, MIPSInst_FS(ir));
1668 break; 1655 break;
1656
1669 case fabs_op: 1657 case fabs_op:
1670 handler.u = ieee754sp_abs; 1658 handler.u = ieee754sp_abs;
1671 goto scopuop; 1659 goto scopuop;
1660
1672 case fneg_op: 1661 case fneg_op:
1673 handler.u = ieee754sp_neg; 1662 handler.u = ieee754sp_neg;
1674 goto scopuop; 1663 goto scopuop;
1664
1675 case fmov_op: 1665 case fmov_op:
1676 /* an easy one */ 1666 /* an easy one */
1677 SPFROMREG(rv.s, MIPSInst_FS(ir)); 1667 SPFROMREG(rv.s, MIPSInst_FS(ir));
1678 goto copcsr; 1668 goto copcsr;
1679 1669
1680 /* binary op on handler */ 1670 /* binary op on handler */
1681 scopbop: 1671scopbop:
1682 { 1672 SPFROMREG(fs, MIPSInst_FS(ir));
1683 union ieee754sp fs, ft; 1673 SPFROMREG(ft, MIPSInst_FT(ir));
1684
1685 SPFROMREG(fs, MIPSInst_FS(ir));
1686 SPFROMREG(ft, MIPSInst_FT(ir));
1687
1688 rv.s = (*handler.b) (fs, ft);
1689 goto copcsr;
1690 }
1691 scopuop:
1692 {
1693 union ieee754sp fs;
1694 1674
1695 SPFROMREG(fs, MIPSInst_FS(ir)); 1675 rv.s = (*handler.b) (fs, ft);
1696 rv.s = (*handler.u) (fs); 1676 goto copcsr;
1697 goto copcsr; 1677scopuop:
1698 } 1678 SPFROMREG(fs, MIPSInst_FS(ir));
1699 copcsr: 1679 rv.s = (*handler.u) (fs);
1680 goto copcsr;
1681copcsr:
1700 if (ieee754_cxtest(IEEE754_INEXACT)) 1682 if (ieee754_cxtest(IEEE754_INEXACT))
1701 rcsr |= FPU_CSR_INE_X | FPU_CSR_INE_S; 1683 rcsr |= FPU_CSR_INE_X | FPU_CSR_INE_S;
1702 if (ieee754_cxtest(IEEE754_UNDERFLOW)) 1684 if (ieee754_cxtest(IEEE754_UNDERFLOW))
@@ -1712,44 +1694,35 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1712 /* unary conv ops */ 1694 /* unary conv ops */
1713 case fcvts_op: 1695 case fcvts_op:
1714 return SIGILL; /* not defined */ 1696 return SIGILL; /* not defined */
1715 case fcvtd_op:{
1716 union ieee754sp fs;
1717 1697
1698 case fcvtd_op:
1718 SPFROMREG(fs, MIPSInst_FS(ir)); 1699 SPFROMREG(fs, MIPSInst_FS(ir));
1719 rv.d = ieee754dp_fsp(fs); 1700 rv.d = ieee754dp_fsp(fs);
1720 rfmt = d_fmt; 1701 rfmt = d_fmt;
1721 goto copcsr; 1702 goto copcsr;
1722 }
1723 case fcvtw_op:{
1724 union ieee754sp fs;
1725 1703
1704 case fcvtw_op:
1726 SPFROMREG(fs, MIPSInst_FS(ir)); 1705 SPFROMREG(fs, MIPSInst_FS(ir));
1727 rv.w = ieee754sp_tint(fs); 1706 rv.w = ieee754sp_tint(fs);
1728 rfmt = w_fmt; 1707 rfmt = w_fmt;
1729 goto copcsr; 1708 goto copcsr;
1730 }
1731 1709
1732 case fround_op: 1710 case fround_op:
1733 case ftrunc_op: 1711 case ftrunc_op:
1734 case fceil_op: 1712 case fceil_op:
1735 case ffloor_op:{ 1713 case ffloor_op:
1736 unsigned int oldrm = ieee754_csr.rm;
1737 union ieee754sp fs;
1738
1739 if (!cpu_has_mips_2_3_4_5 && !cpu_has_mips64) 1714 if (!cpu_has_mips_2_3_4_5 && !cpu_has_mips64)
1740 return SIGILL; 1715 return SIGILL;
1741 1716
1717 oldrm = ieee754_csr.rm;
1742 SPFROMREG(fs, MIPSInst_FS(ir)); 1718 SPFROMREG(fs, MIPSInst_FS(ir));
1743 ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))]; 1719 ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))];
1744 rv.w = ieee754sp_tint(fs); 1720 rv.w = ieee754sp_tint(fs);
1745 ieee754_csr.rm = oldrm; 1721 ieee754_csr.rm = oldrm;
1746 rfmt = w_fmt; 1722 rfmt = w_fmt;
1747 goto copcsr; 1723 goto copcsr;
1748 }
1749
1750 case fcvtl_op:{
1751 union ieee754sp fs;
1752 1724
1725 case fcvtl_op:
1753 if (!cpu_has_mips_3_4_5 && !cpu_has_mips64) 1726 if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
1754 return SIGILL; 1727 return SIGILL;
1755 1728
@@ -1757,25 +1730,21 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1757 rv.l = ieee754sp_tlong(fs); 1730 rv.l = ieee754sp_tlong(fs);
1758 rfmt = l_fmt; 1731 rfmt = l_fmt;
1759 goto copcsr; 1732 goto copcsr;
1760 }
1761 1733
1762 case froundl_op: 1734 case froundl_op:
1763 case ftruncl_op: 1735 case ftruncl_op:
1764 case fceill_op: 1736 case fceill_op:
1765 case ffloorl_op:{ 1737 case ffloorl_op:
1766 unsigned int oldrm = ieee754_csr.rm;
1767 union ieee754sp fs;
1768
1769 if (!cpu_has_mips_3_4_5 && !cpu_has_mips64) 1738 if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
1770 return SIGILL; 1739 return SIGILL;
1771 1740
1741 oldrm = ieee754_csr.rm;
1772 SPFROMREG(fs, MIPSInst_FS(ir)); 1742 SPFROMREG(fs, MIPSInst_FS(ir));
1773 ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))]; 1743 ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))];
1774 rv.l = ieee754sp_tlong(fs); 1744 rv.l = ieee754sp_tlong(fs);
1775 ieee754_csr.rm = oldrm; 1745 ieee754_csr.rm = oldrm;
1776 rfmt = l_fmt; 1746 rfmt = l_fmt;
1777 goto copcsr; 1747 goto copcsr;
1778 }
1779 1748
1780 default: 1749 default:
1781 if (MIPSInst_FUNC(ir) >= fcmp_op) { 1750 if (MIPSInst_FUNC(ir) >= fcmp_op) {
@@ -1793,16 +1762,15 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1793 else 1762 else
1794 goto copcsr; 1763 goto copcsr;
1795 1764
1796 } 1765 } else
1797 else {
1798 return SIGILL; 1766 return SIGILL;
1799 }
1800 break; 1767 break;
1801 } 1768 }
1802 break; 1769 break;
1803 } 1770 }
1804 1771
1805 case d_fmt:{ 1772 case d_fmt: {
1773 union ieee754dp fs, ft;
1806 union { 1774 union {
1807 union ieee754dp(*b) (union ieee754dp, union ieee754dp); 1775 union ieee754dp(*b) (union ieee754dp, union ieee754dp);
1808 union ieee754dp(*u) (union ieee754dp); 1776 union ieee754dp(*u) (union ieee754dp);
@@ -1887,65 +1855,51 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1887 goto copcsr; 1855 goto copcsr;
1888 1856
1889 /* binary op on handler */ 1857 /* binary op on handler */
1890 dcopbop:{ 1858dcopbop:
1891 union ieee754dp fs, ft; 1859 DPFROMREG(fs, MIPSInst_FS(ir));
1892 1860 DPFROMREG(ft, MIPSInst_FT(ir));
1893 DPFROMREG(fs, MIPSInst_FS(ir));
1894 DPFROMREG(ft, MIPSInst_FT(ir));
1895
1896 rv.d = (*handler.b) (fs, ft);
1897 goto copcsr;
1898 }
1899 dcopuop:{
1900 union ieee754dp fs;
1901
1902 DPFROMREG(fs, MIPSInst_FS(ir));
1903 rv.d = (*handler.u) (fs);
1904 goto copcsr;
1905 }
1906 1861
1907 /* unary conv ops */ 1862 rv.d = (*handler.b) (fs, ft);
1908 case fcvts_op:{ 1863 goto copcsr;
1909 union ieee754dp fs; 1864dcopuop:
1865 DPFROMREG(fs, MIPSInst_FS(ir));
1866 rv.d = (*handler.u) (fs);
1867 goto copcsr;
1910 1868
1869 /*
1870 * unary conv ops
1871 */
1872 case fcvts_op:
1911 DPFROMREG(fs, MIPSInst_FS(ir)); 1873 DPFROMREG(fs, MIPSInst_FS(ir));
1912 rv.s = ieee754sp_fdp(fs); 1874 rv.s = ieee754sp_fdp(fs);
1913 rfmt = s_fmt; 1875 rfmt = s_fmt;
1914 goto copcsr; 1876 goto copcsr;
1915 } 1877
1916 case fcvtd_op: 1878 case fcvtd_op:
1917 return SIGILL; /* not defined */ 1879 return SIGILL; /* not defined */
1918 1880
1919 case fcvtw_op:{ 1881 case fcvtw_op:
1920 union ieee754dp fs;
1921
1922 DPFROMREG(fs, MIPSInst_FS(ir)); 1882 DPFROMREG(fs, MIPSInst_FS(ir));
1923 rv.w = ieee754dp_tint(fs); /* wrong */ 1883 rv.w = ieee754dp_tint(fs); /* wrong */
1924 rfmt = w_fmt; 1884 rfmt = w_fmt;
1925 goto copcsr; 1885 goto copcsr;
1926 }
1927 1886
1928 case fround_op: 1887 case fround_op:
1929 case ftrunc_op: 1888 case ftrunc_op:
1930 case fceil_op: 1889 case fceil_op:
1931 case ffloor_op:{ 1890 case ffloor_op:
1932 unsigned int oldrm = ieee754_csr.rm;
1933 union ieee754dp fs;
1934
1935 if (!cpu_has_mips_2_3_4_5_r) 1891 if (!cpu_has_mips_2_3_4_5_r)
1936 return SIGILL; 1892 return SIGILL;
1937 1893
1894 oldrm = ieee754_csr.rm;
1938 DPFROMREG(fs, MIPSInst_FS(ir)); 1895 DPFROMREG(fs, MIPSInst_FS(ir));
1939 ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))]; 1896 ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))];
1940 rv.w = ieee754dp_tint(fs); 1897 rv.w = ieee754dp_tint(fs);
1941 ieee754_csr.rm = oldrm; 1898 ieee754_csr.rm = oldrm;
1942 rfmt = w_fmt; 1899 rfmt = w_fmt;
1943 goto copcsr; 1900 goto copcsr;
1944 }
1945
1946 case fcvtl_op:{
1947 union ieee754dp fs;
1948 1901
1902 case fcvtl_op:
1949 if (!cpu_has_mips_3_4_5 && !cpu_has_mips64) 1903 if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
1950 return SIGILL; 1904 return SIGILL;
1951 1905
@@ -1953,25 +1907,21 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1953 rv.l = ieee754dp_tlong(fs); 1907 rv.l = ieee754dp_tlong(fs);
1954 rfmt = l_fmt; 1908 rfmt = l_fmt;
1955 goto copcsr; 1909 goto copcsr;
1956 }
1957 1910
1958 case froundl_op: 1911 case froundl_op:
1959 case ftruncl_op: 1912 case ftruncl_op:
1960 case fceill_op: 1913 case fceill_op:
1961 case ffloorl_op:{ 1914 case ffloorl_op:
1962 unsigned int oldrm = ieee754_csr.rm;
1963 union ieee754dp fs;
1964
1965 if (!cpu_has_mips_3_4_5 && !cpu_has_mips64) 1915 if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
1966 return SIGILL; 1916 return SIGILL;
1967 1917
1918 oldrm = ieee754_csr.rm;
1968 DPFROMREG(fs, MIPSInst_FS(ir)); 1919 DPFROMREG(fs, MIPSInst_FS(ir));
1969 ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))]; 1920 ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))];
1970 rv.l = ieee754dp_tlong(fs); 1921 rv.l = ieee754dp_tlong(fs);
1971 ieee754_csr.rm = oldrm; 1922 ieee754_csr.rm = oldrm;
1972 rfmt = l_fmt; 1923 rfmt = l_fmt;
1973 goto copcsr; 1924 goto copcsr;
1974 }
1975 1925
1976 default: 1926 default:
1977 if (MIPSInst_FUNC(ir) >= fcmp_op) { 1927 if (MIPSInst_FUNC(ir) >= fcmp_op) {
@@ -1998,11 +1948,8 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1998 break; 1948 break;
1999 } 1949 }
2000 break; 1950 break;
2001 }
2002
2003 case w_fmt:{
2004 union ieee754sp fs;
2005 1951
1952 case w_fmt:
2006 switch (MIPSInst_FUNC(ir)) { 1953 switch (MIPSInst_FUNC(ir)) {
2007 case fcvts_op: 1954 case fcvts_op:
2008 /* convert word to single precision real */ 1955 /* convert word to single precision real */
@@ -2022,8 +1969,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
2022 break; 1969 break;
2023 } 1970 }
2024 1971
2025 case l_fmt:{ 1972 case l_fmt:
2026 u64 bits;
2027 1973
2028 if (!cpu_has_mips_3_4_5 && !cpu_has_mips64) 1974 if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
2029 return SIGILL; 1975 return SIGILL;
@@ -2045,7 +1991,6 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
2045 return SIGILL; 1991 return SIGILL;
2046 } 1992 }
2047 break; 1993 break;
2048 }
2049 1994
2050 default: 1995 default:
2051 return SIGILL; 1996 return SIGILL;
@@ -2060,7 +2005,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
2060 */ 2005 */
2061 ctx->fcr31 = (ctx->fcr31 & ~FPU_CSR_ALL_X) | rcsr; 2006 ctx->fcr31 = (ctx->fcr31 & ~FPU_CSR_ALL_X) | rcsr;
2062 if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) { 2007 if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
2063 /*printk ("SIGFPE: fpu csr = %08x\n",ctx->fcr31); */ 2008 /*printk ("SIGFPE: FPU csr = %08x\n",ctx->fcr31); */
2064 return SIGFPE; 2009 return SIGFPE;
2065 } 2010 }
2066 2011
@@ -2068,7 +2013,6 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
2068 * Now we can safely write the result back to the register file. 2013 * Now we can safely write the result back to the register file.
2069 */ 2014 */
2070 switch (rfmt) { 2015 switch (rfmt) {
2071 unsigned int cbit;
2072 case -1: 2016 case -1:
2073 2017
2074 if (cpu_has_mips_4_5_r) 2018 if (cpu_has_mips_4_5_r)
@@ -2200,7 +2144,7 @@ int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
2200 2144
2201 /* SIGILL indicates a non-fpu instruction */ 2145 /* SIGILL indicates a non-fpu instruction */
2202 if (sig == SIGILL && xcp->cp0_epc != oldepc) 2146 if (sig == SIGILL && xcp->cp0_epc != oldepc)
2203 /* but if epc has advanced, then ignore it */ 2147 /* but if EPC has advanced, then ignore it */
2204 sig = 0; 2148 sig = 0;
2205 2149
2206 return sig; 2150 return sig;