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} |