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