cp1emu.c (5d77cf2895edea277878a526b4c47abfdbf6ffd2) cp1emu.c (2cfcf8a8313bd9bdb54d62ca4ea581f130869aca)
1/*
2 * cp1emu.c: a MIPS coprocessor 1 (FPU) instruction emulator
3 *
4 * MIPS floating point support
5 * Copyright (C) 1994-2000 Algorithmics Ltd.
6 *
7 * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
8 * Copyright (C) 2000 MIPS Technologies, Inc.

--- 51 unchanged lines hidden (view full) ---

60static int fpux_emu(struct pt_regs *,
61 struct mips_fpu_struct *, mips_instruction, void *__user *);
62
63/* Control registers */
64
65#define FPCREG_RID 0 /* $0 = revision id */
66#define FPCREG_CSR 31 /* $31 = csr */
67
1/*
2 * cp1emu.c: a MIPS coprocessor 1 (FPU) instruction emulator
3 *
4 * MIPS floating point support
5 * Copyright (C) 1994-2000 Algorithmics Ltd.
6 *
7 * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
8 * Copyright (C) 2000 MIPS Technologies, Inc.

--- 51 unchanged lines hidden (view full) ---

60static int fpux_emu(struct pt_regs *,
61 struct mips_fpu_struct *, mips_instruction, void *__user *);
62
63/* Control registers */
64
65#define FPCREG_RID 0 /* $0 = revision id */
66#define FPCREG_CSR 31 /* $31 = csr */
67
68/* Determine rounding mode from the RM bits of the FCSR */
69#define modeindex(v) ((v) & FPU_CSR_RM)
70
71/* convert condition code register number to csr bit */
72const unsigned int fpucondbit[8] = {
73 FPU_CSR_COND0,
74 FPU_CSR_COND1,
75 FPU_CSR_COND2,
76 FPU_CSR_COND3,
77 FPU_CSR_COND4,
78 FPU_CSR_COND5,

--- 967 unchanged lines hidden (view full) ---

1046 /* copregister rd <- rt */
1047 SITOREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
1048 break;
1049
1050 case cfc_op:
1051 /* cop control register rd -> gpr[rt] */
1052 if (MIPSInst_RD(ir) == FPCREG_CSR) {
1053 value = ctx->fcr31;
68/* convert condition code register number to csr bit */
69const unsigned int fpucondbit[8] = {
70 FPU_CSR_COND0,
71 FPU_CSR_COND1,
72 FPU_CSR_COND2,
73 FPU_CSR_COND3,
74 FPU_CSR_COND4,
75 FPU_CSR_COND5,

--- 967 unchanged lines hidden (view full) ---

1043 /* copregister rd <- rt */
1044 SITOREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
1045 break;
1046
1047 case cfc_op:
1048 /* cop control register rd -> gpr[rt] */
1049 if (MIPSInst_RD(ir) == FPCREG_CSR) {
1050 value = ctx->fcr31;
1054 value = (value & ~FPU_CSR_RM) | modeindex(value);
1055 pr_debug("%p gpr[%d]<-csr=%08x\n",
1056 (void *) (xcp->cp0_epc),
1057 MIPSInst_RT(ir), value);
1058 }
1059 else if (MIPSInst_RD(ir) == FPCREG_RID)
1060 value = 0;
1061 else
1062 value = 0;

--- 10 unchanged lines hidden (view full) ---

1073
1074 /* we only have one writable control reg
1075 */
1076 if (MIPSInst_RD(ir) == FPCREG_CSR) {
1077 pr_debug("%p gpr[%d]->csr=%08x\n",
1078 (void *) (xcp->cp0_epc),
1079 MIPSInst_RT(ir), value);
1080
1051 pr_debug("%p gpr[%d]<-csr=%08x\n",
1052 (void *) (xcp->cp0_epc),
1053 MIPSInst_RT(ir), value);
1054 }
1055 else if (MIPSInst_RD(ir) == FPCREG_RID)
1056 value = 0;
1057 else
1058 value = 0;

--- 10 unchanged lines hidden (view full) ---

1069
1070 /* we only have one writable control reg
1071 */
1072 if (MIPSInst_RD(ir) == FPCREG_CSR) {
1073 pr_debug("%p gpr[%d]->csr=%08x\n",
1074 (void *) (xcp->cp0_epc),
1075 MIPSInst_RT(ir), value);
1076
1081 /*
1082 * Don't write reserved bits,
1083 * and convert to ieee library modes
1084 */
1085 ctx->fcr31 = (value & ~(FPU_CSR_RSVD | FPU_CSR_RM)) |
1086 modeindex(value);
1077 /* Don't write reserved bits. */
1078 ctx->fcr31 = value & ~FPU_CSR_RSVD;
1087 }
1088 if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
1089 return SIGFPE;
1090 }
1091 break;
1092
1093 case bc_op:
1094 if (delay_slot(xcp))

--- 575 unchanged lines hidden (view full) ---

1670 case ftrunc_op:
1671 case fceil_op:
1672 case ffloor_op:
1673 if (!cpu_has_mips_2_3_4_5 && !cpu_has_mips64)
1674 return SIGILL;
1675
1676 oldrm = ieee754_csr.rm;
1677 SPFROMREG(fs, MIPSInst_FS(ir));
1079 }
1080 if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
1081 return SIGFPE;
1082 }
1083 break;
1084
1085 case bc_op:
1086 if (delay_slot(xcp))

--- 575 unchanged lines hidden (view full) ---

1662 case ftrunc_op:
1663 case fceil_op:
1664 case ffloor_op:
1665 if (!cpu_has_mips_2_3_4_5 && !cpu_has_mips64)
1666 return SIGILL;
1667
1668 oldrm = ieee754_csr.rm;
1669 SPFROMREG(fs, MIPSInst_FS(ir));
1678 ieee754_csr.rm = modeindex(MIPSInst_FUNC(ir));
1670 ieee754_csr.rm = MIPSInst_FUNC(ir);
1679 rv.w = ieee754sp_tint(fs);
1680 ieee754_csr.rm = oldrm;
1681 rfmt = w_fmt;
1682 goto copcsr;
1683
1684 case fcvtl_op:
1685 if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
1686 return SIGILL;

--- 7 unchanged lines hidden (view full) ---

1694 case ftruncl_op:
1695 case fceill_op:
1696 case ffloorl_op:
1697 if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
1698 return SIGILL;
1699
1700 oldrm = ieee754_csr.rm;
1701 SPFROMREG(fs, MIPSInst_FS(ir));
1671 rv.w = ieee754sp_tint(fs);
1672 ieee754_csr.rm = oldrm;
1673 rfmt = w_fmt;
1674 goto copcsr;
1675
1676 case fcvtl_op:
1677 if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
1678 return SIGILL;

--- 7 unchanged lines hidden (view full) ---

1686 case ftruncl_op:
1687 case fceill_op:
1688 case ffloorl_op:
1689 if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
1690 return SIGILL;
1691
1692 oldrm = ieee754_csr.rm;
1693 SPFROMREG(fs, MIPSInst_FS(ir));
1702 ieee754_csr.rm = modeindex(MIPSInst_FUNC(ir));
1694 ieee754_csr.rm = MIPSInst_FUNC(ir);
1703 rv.l = ieee754sp_tlong(fs);
1704 ieee754_csr.rm = oldrm;
1705 rfmt = l_fmt;
1706 goto copcsr;
1707
1708 default:
1709 if (MIPSInst_FUNC(ir) >= fcmp_op) {
1710 unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op;

--- 136 unchanged lines hidden (view full) ---

1847 case ftrunc_op:
1848 case fceil_op:
1849 case ffloor_op:
1850 if (!cpu_has_mips_2_3_4_5_r)
1851 return SIGILL;
1852
1853 oldrm = ieee754_csr.rm;
1854 DPFROMREG(fs, MIPSInst_FS(ir));
1695 rv.l = ieee754sp_tlong(fs);
1696 ieee754_csr.rm = oldrm;
1697 rfmt = l_fmt;
1698 goto copcsr;
1699
1700 default:
1701 if (MIPSInst_FUNC(ir) >= fcmp_op) {
1702 unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op;

--- 136 unchanged lines hidden (view full) ---

1839 case ftrunc_op:
1840 case fceil_op:
1841 case ffloor_op:
1842 if (!cpu_has_mips_2_3_4_5_r)
1843 return SIGILL;
1844
1845 oldrm = ieee754_csr.rm;
1846 DPFROMREG(fs, MIPSInst_FS(ir));
1855 ieee754_csr.rm = modeindex(MIPSInst_FUNC(ir));
1847 ieee754_csr.rm = MIPSInst_FUNC(ir);
1856 rv.w = ieee754dp_tint(fs);
1857 ieee754_csr.rm = oldrm;
1858 rfmt = w_fmt;
1859 goto copcsr;
1860
1861 case fcvtl_op:
1862 if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
1863 return SIGILL;

--- 7 unchanged lines hidden (view full) ---

1871 case ftruncl_op:
1872 case fceill_op:
1873 case ffloorl_op:
1874 if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
1875 return SIGILL;
1876
1877 oldrm = ieee754_csr.rm;
1878 DPFROMREG(fs, MIPSInst_FS(ir));
1848 rv.w = ieee754dp_tint(fs);
1849 ieee754_csr.rm = oldrm;
1850 rfmt = w_fmt;
1851 goto copcsr;
1852
1853 case fcvtl_op:
1854 if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
1855 return SIGILL;

--- 7 unchanged lines hidden (view full) ---

1863 case ftruncl_op:
1864 case fceill_op:
1865 case ffloorl_op:
1866 if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
1867 return SIGILL;
1868
1869 oldrm = ieee754_csr.rm;
1870 DPFROMREG(fs, MIPSInst_FS(ir));
1879 ieee754_csr.rm = modeindex(MIPSInst_FUNC(ir));
1871 ieee754_csr.rm = MIPSInst_FUNC(ir);
1880 rv.l = ieee754dp_tlong(fs);
1881 ieee754_csr.rm = oldrm;
1882 rfmt = l_fmt;
1883 goto copcsr;
1884
1885 default:
1886 if (MIPSInst_FUNC(ir) >= fcmp_op) {
1887 unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op;

--- 188 unchanged lines hidden (view full) ---

2076 }
2077
2078 if ((dec_insn.insn == 0) ||
2079 ((dec_insn.pc_inc == 2) &&
2080 ((dec_insn.insn & 0xffff) == MM_NOP16)))
2081 xcp->cp0_epc += dec_insn.pc_inc; /* Skip NOPs */
2082 else {
2083 /*
1872 rv.l = ieee754dp_tlong(fs);
1873 ieee754_csr.rm = oldrm;
1874 rfmt = l_fmt;
1875 goto copcsr;
1876
1877 default:
1878 if (MIPSInst_FUNC(ir) >= fcmp_op) {
1879 unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op;

--- 188 unchanged lines hidden (view full) ---

2068 }
2069
2070 if ((dec_insn.insn == 0) ||
2071 ((dec_insn.pc_inc == 2) &&
2072 ((dec_insn.insn & 0xffff) == MM_NOP16)))
2073 xcp->cp0_epc += dec_insn.pc_inc; /* Skip NOPs */
2074 else {
2075 /*
2084 * The 'ieee754_csr' is an alias of
2085 * ctx->fcr31. No need to copy ctx->fcr31 to
2086 * ieee754_csr. But ieee754_csr.rm is ieee
2087 * library modes. (not mips rounding mode)
2076 * The 'ieee754_csr' is an alias of ctx->fcr31.
2077 * No need to copy ctx->fcr31 to ieee754_csr.
2088 */
2089 sig = cop1Emulate(xcp, ctx, dec_insn, fault_addr);
2090 }
2091
2092 if (has_fpu)
2093 break;
2094 if (sig)
2095 break;
2096
2097 cond_resched();
2098 } while (xcp->cp0_epc > prevepc);
2099
2100 /* SIGILL indicates a non-fpu instruction */
2101 if (sig == SIGILL && xcp->cp0_epc != oldepc)
2102 /* but if EPC has advanced, then ignore it */
2103 sig = 0;
2104
2105 return sig;
2106}
2078 */
2079 sig = cop1Emulate(xcp, ctx, dec_insn, fault_addr);
2080 }
2081
2082 if (has_fpu)
2083 break;
2084 if (sig)
2085 break;
2086
2087 cond_resched();
2088 } while (xcp->cp0_epc > prevepc);
2089
2090 /* SIGILL indicates a non-fpu instruction */
2091 if (sig == SIGILL && xcp->cp0_epc != oldepc)
2092 /* but if EPC has advanced, then ignore it */
2093 sig = 0;
2094
2095 return sig;
2096}