cp1emu.c (c909ca718e8f50cf484ef06a8dd935e738e8e53d) | cp1emu.c (f8c3c6717a7128f9601b20f890d658283d59561a) |
---|---|
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. --- 1380 unchanged lines hidden (view full) --- 1389 IEEE754_CEQ, /* cmp_eq (sig) cmp_seq */ 1390 IEEE754_CEQ | IEEE754_CUN, /* cmp_ueq (sig) cmp_ngl */ 1391 IEEE754_CLT, /* cmp_olt (sig) cmp_lt */ 1392 IEEE754_CLT | IEEE754_CUN, /* cmp_ult (sig) cmp_nge */ 1393 IEEE754_CLT | IEEE754_CEQ, /* cmp_ole (sig) cmp_le */ 1394 IEEE754_CLT | IEEE754_CEQ | IEEE754_CUN, /* cmp_ule (sig) cmp_ngt */ 1395}; 1396 | 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. --- 1380 unchanged lines hidden (view full) --- 1389 IEEE754_CEQ, /* cmp_eq (sig) cmp_seq */ 1390 IEEE754_CEQ | IEEE754_CUN, /* cmp_ueq (sig) cmp_ngl */ 1391 IEEE754_CLT, /* cmp_olt (sig) cmp_lt */ 1392 IEEE754_CLT | IEEE754_CUN, /* cmp_ult (sig) cmp_nge */ 1393 IEEE754_CLT | IEEE754_CEQ, /* cmp_ole (sig) cmp_le */ 1394 IEEE754_CLT | IEEE754_CEQ | IEEE754_CUN, /* cmp_ule (sig) cmp_ngt */ 1395}; 1396 |
1397static const unsigned char negative_cmptab[8] = { 1398 0, /* Reserved */ 1399 IEEE754_CLT | IEEE754_CGT | IEEE754_CEQ, 1400 IEEE754_CLT | IEEE754_CGT | IEEE754_CUN, 1401 IEEE754_CLT | IEEE754_CGT, 1402 /* Reserved */ 1403}; |
|
1397 | 1404 |
1405 |
|
1398/* 1399 * Additional MIPS4 instructions 1400 */ 1401 1402#define DEF3OP(name, p, f1, f2, f3) \ 1403static union ieee754##p fpemu_##p##_##name(union ieee754##p r, \ 1404 union ieee754##p s, union ieee754##p t) \ 1405{ \ --- 427 unchanged lines hidden (view full) --- 1833 SPFROMREG(fs, MIPSInst_FS(ir)); 1834 ieee754_csr.rm = MIPSInst_FUNC(ir); 1835 rv.l = ieee754sp_tlong(fs); 1836 ieee754_csr.rm = oldrm; 1837 rfmt = l_fmt; 1838 goto copcsr; 1839 1840 default: | 1406/* 1407 * Additional MIPS4 instructions 1408 */ 1409 1410#define DEF3OP(name, p, f1, f2, f3) \ 1411static union ieee754##p fpemu_##p##_##name(union ieee754##p r, \ 1412 union ieee754##p s, union ieee754##p t) \ 1413{ \ --- 427 unchanged lines hidden (view full) --- 1841 SPFROMREG(fs, MIPSInst_FS(ir)); 1842 ieee754_csr.rm = MIPSInst_FUNC(ir); 1843 rv.l = ieee754sp_tlong(fs); 1844 ieee754_csr.rm = oldrm; 1845 rfmt = l_fmt; 1846 goto copcsr; 1847 1848 default: |
1841 if (MIPSInst_FUNC(ir) >= fcmp_op) { | 1849 if (!NO_R6EMU && MIPSInst_FUNC(ir) >= fcmp_op) { |
1842 unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op; 1843 union ieee754sp fs, ft; 1844 1845 SPFROMREG(fs, MIPSInst_FS(ir)); 1846 SPFROMREG(ft, MIPSInst_FT(ir)); 1847 rv.w = ieee754sp_cmp(fs, ft, 1848 cmptab[cmpop & 0x7], cmpop & 0x8); 1849 rfmt = -1; --- 160 unchanged lines hidden (view full) --- 2010 DPFROMREG(fs, MIPSInst_FS(ir)); 2011 ieee754_csr.rm = MIPSInst_FUNC(ir); 2012 rv.l = ieee754dp_tlong(fs); 2013 ieee754_csr.rm = oldrm; 2014 rfmt = l_fmt; 2015 goto copcsr; 2016 2017 default: | 1850 unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op; 1851 union ieee754sp fs, ft; 1852 1853 SPFROMREG(fs, MIPSInst_FS(ir)); 1854 SPFROMREG(ft, MIPSInst_FT(ir)); 1855 rv.w = ieee754sp_cmp(fs, ft, 1856 cmptab[cmpop & 0x7], cmpop & 0x8); 1857 rfmt = -1; --- 160 unchanged lines hidden (view full) --- 2018 DPFROMREG(fs, MIPSInst_FS(ir)); 2019 ieee754_csr.rm = MIPSInst_FUNC(ir); 2020 rv.l = ieee754dp_tlong(fs); 2021 ieee754_csr.rm = oldrm; 2022 rfmt = l_fmt; 2023 goto copcsr; 2024 2025 default: |
2018 if (MIPSInst_FUNC(ir) >= fcmp_op) { | 2026 if (!NO_R6EMU && MIPSInst_FUNC(ir) >= fcmp_op) { |
2019 unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op; 2020 union ieee754dp fs, ft; 2021 2022 DPFROMREG(fs, MIPSInst_FS(ir)); 2023 DPFROMREG(ft, MIPSInst_FT(ir)); 2024 rv.w = ieee754dp_cmp(fs, ft, 2025 cmptab[cmpop & 0x7], cmpop & 0x8); 2026 rfmt = -1; --- 25 unchanged lines hidden (view full) --- 2052 rfmt = s_fmt; 2053 goto copcsr; 2054 case fcvtd_op: 2055 /* convert word to double precision real */ 2056 SPFROMREG(fs, MIPSInst_FS(ir)); 2057 rv.d = ieee754dp_fint(fs.bits); 2058 rfmt = d_fmt; 2059 goto copcsr; | 2027 unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op; 2028 union ieee754dp fs, ft; 2029 2030 DPFROMREG(fs, MIPSInst_FS(ir)); 2031 DPFROMREG(ft, MIPSInst_FT(ir)); 2032 rv.w = ieee754dp_cmp(fs, ft, 2033 cmptab[cmpop & 0x7], cmpop & 0x8); 2034 rfmt = -1; --- 25 unchanged lines hidden (view full) --- 2060 rfmt = s_fmt; 2061 goto copcsr; 2062 case fcvtd_op: 2063 /* convert word to double precision real */ 2064 SPFROMREG(fs, MIPSInst_FS(ir)); 2065 rv.d = ieee754dp_fint(fs.bits); 2066 rfmt = d_fmt; 2067 goto copcsr; |
2060 default: 2061 return SIGILL; | 2068 default: { 2069 /* Emulating the new CMP.condn.fmt R6 instruction */ 2070#define CMPOP_MASK 0x7 2071#define SIGN_BIT (0x1 << 3) 2072#define PREDICATE_BIT (0x1 << 4) 2073 2074 int cmpop = MIPSInst_FUNC(ir) & CMPOP_MASK; 2075 int sig = MIPSInst_FUNC(ir) & SIGN_BIT; 2076 union ieee754sp fs, ft; 2077 2078 /* This is an R6 only instruction */ 2079 if (!cpu_has_mips_r6 || 2080 (MIPSInst_FUNC(ir) & 0x20)) 2081 return SIGILL; 2082 2083 /* fmt is w_fmt for single precision so fix it */ 2084 rfmt = s_fmt; 2085 /* default to false */ 2086 rv.w = 0; 2087 2088 /* CMP.condn.S */ 2089 SPFROMREG(fs, MIPSInst_FS(ir)); 2090 SPFROMREG(ft, MIPSInst_FT(ir)); 2091 2092 /* positive predicates */ 2093 if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) { 2094 if (ieee754sp_cmp(fs, ft, cmptab[cmpop], 2095 sig)) 2096 rv.w = -1; /* true, all 1s */ 2097 if ((sig) && 2098 ieee754_cxtest(IEEE754_INVALID_OPERATION)) 2099 rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S; 2100 else 2101 goto copcsr; 2102 } else { 2103 /* negative predicates */ 2104 switch (cmpop) { 2105 case 1: 2106 case 2: 2107 case 3: 2108 if (ieee754sp_cmp(fs, ft, 2109 negative_cmptab[cmpop], 2110 sig)) 2111 rv.w = -1; /* true, all 1s */ 2112 if (sig && 2113 ieee754_cxtest(IEEE754_INVALID_OPERATION)) 2114 rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S; 2115 else 2116 goto copcsr; 2117 break; 2118 default: 2119 /* Reserved R6 ops */ 2120 pr_err("Reserved MIPS R6 CMP.condn.S operation\n"); 2121 return SIGILL; 2122 } 2123 } 2124 break; 2125 } |
2062 } | 2126 } |
2063 break; | |
2064 } 2065 2066 case l_fmt: 2067 2068 if (!cpu_has_mips_3_4_5_64_r2_r6) 2069 return SIGILL; 2070 2071 DIFROMREG(bits, MIPSInst_FS(ir)); --- 4 unchanged lines hidden (view full) --- 2076 rv.s = ieee754sp_flong(bits); 2077 rfmt = s_fmt; 2078 goto copcsr; 2079 case fcvtd_op: 2080 /* convert long to double precision real */ 2081 rv.d = ieee754dp_flong(bits); 2082 rfmt = d_fmt; 2083 goto copcsr; | 2127 } 2128 2129 case l_fmt: 2130 2131 if (!cpu_has_mips_3_4_5_64_r2_r6) 2132 return SIGILL; 2133 2134 DIFROMREG(bits, MIPSInst_FS(ir)); --- 4 unchanged lines hidden (view full) --- 2139 rv.s = ieee754sp_flong(bits); 2140 rfmt = s_fmt; 2141 goto copcsr; 2142 case fcvtd_op: 2143 /* convert long to double precision real */ 2144 rv.d = ieee754dp_flong(bits); 2145 rfmt = d_fmt; 2146 goto copcsr; |
2084 default: 2085 return SIGILL; 2086 } 2087 break; | 2147 default: { 2148 /* Emulating the new CMP.condn.fmt R6 instruction */ 2149 int cmpop = MIPSInst_FUNC(ir) & CMPOP_MASK; 2150 int sig = MIPSInst_FUNC(ir) & SIGN_BIT; 2151 union ieee754dp fs, ft; |
2088 | 2152 |
2153 if (!cpu_has_mips_r6 || 2154 (MIPSInst_FUNC(ir) & 0x20)) 2155 return SIGILL; 2156 2157 /* fmt is l_fmt for double precision so fix it */ 2158 rfmt = d_fmt; 2159 /* default to false */ 2160 rv.l = 0; 2161 2162 /* CMP.condn.D */ 2163 DPFROMREG(fs, MIPSInst_FS(ir)); 2164 DPFROMREG(ft, MIPSInst_FT(ir)); 2165 2166 /* positive predicates */ 2167 if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) { 2168 if (ieee754dp_cmp(fs, ft, 2169 cmptab[cmpop], sig)) 2170 rv.l = -1LL; /* true, all 1s */ 2171 if (sig && 2172 ieee754_cxtest(IEEE754_INVALID_OPERATION)) 2173 rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S; 2174 else 2175 goto copcsr; 2176 } else { 2177 /* negative predicates */ 2178 switch (cmpop) { 2179 case 1: 2180 case 2: 2181 case 3: 2182 if (ieee754dp_cmp(fs, ft, 2183 negative_cmptab[cmpop], 2184 sig)) 2185 rv.l = -1LL; /* true, all 1s */ 2186 if (sig && 2187 ieee754_cxtest(IEEE754_INVALID_OPERATION)) 2188 rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S; 2189 else 2190 goto copcsr; 2191 break; 2192 default: 2193 /* Reserved R6 ops */ 2194 pr_err("Reserved MIPS R6 CMP.condn.D operation\n"); 2195 return SIGILL; 2196 } 2197 } 2198 break; 2199 } 2200 } |
|
2089 default: 2090 return SIGILL; 2091 } 2092 2093 /* 2094 * Update the fpu CSR register for this operation. 2095 * If an exception is required, generate a tidy SIGFPE exception, 2096 * without updating the result register. --- 143 unchanged lines hidden --- | 2201 default: 2202 return SIGILL; 2203 } 2204 2205 /* 2206 * Update the fpu CSR register for this operation. 2207 * If an exception is required, generate a tidy SIGFPE exception, 2208 * without updating the result register. --- 143 unchanged lines hidden --- |