23 |
23 |
#include "exec.h"
|
24 |
24 |
|
25 |
25 |
#ifndef CALL_FROM_TB0
|
26 |
|
#define CALL_FROM_TB0(func) func();
|
|
26 |
#define CALL_FROM_TB0(func) func()
|
27 |
27 |
#endif
|
28 |
28 |
#ifndef CALL_FROM_TB1
|
29 |
|
#define CALL_FROM_TB1(func, arg0) func(arg0);
|
|
29 |
#define CALL_FROM_TB1(func, arg0) func(arg0)
|
30 |
30 |
#endif
|
31 |
31 |
#ifndef CALL_FROM_TB1_CONST16
|
32 |
|
#define CALL_FROM_TB1_CONST16(func, arg0) CALL_FROM_TB1(func, arg0);
|
|
32 |
#define CALL_FROM_TB1_CONST16(func, arg0) CALL_FROM_TB1(func, arg0)
|
33 |
33 |
#endif
|
34 |
34 |
#ifndef CALL_FROM_TB2
|
35 |
|
#define CALL_FROM_TB2(func, arg0, arg1) func(arg0, arg1);
|
|
35 |
#define CALL_FROM_TB2(func, arg0, arg1) func(arg0, arg1)
|
36 |
36 |
#endif
|
37 |
37 |
#ifndef CALL_FROM_TB2_CONST16
|
38 |
38 |
#define CALL_FROM_TB2_CONST16(func, arg0, arg1) \
|
39 |
|
CALL_FROM_TB2(func, arg0, arg1);
|
|
39 |
CALL_FROM_TB2(func, arg0, arg1)
|
40 |
40 |
#endif
|
41 |
41 |
#ifndef CALL_FROM_TB3
|
42 |
|
#define CALL_FROM_TB3(func, arg0, arg1, arg2) func(arg0, arg1, arg2);
|
|
42 |
#define CALL_FROM_TB3(func, arg0, arg1, arg2) func(arg0, arg1, arg2)
|
43 |
43 |
#endif
|
44 |
44 |
#ifndef CALL_FROM_TB4
|
45 |
45 |
#define CALL_FROM_TB4(func, arg0, arg1, arg2, arg3) \
|
46 |
|
func(arg0, arg1, arg2, arg3);
|
|
46 |
func(arg0, arg1, arg2, arg3)
|
47 |
47 |
#endif
|
48 |
48 |
|
49 |
49 |
#define REG 1
|
... | ... | |
144 |
144 |
#include "op_template.c"
|
145 |
145 |
#undef TN
|
146 |
146 |
|
147 |
|
#define SFREG 0
|
148 |
|
#define DFREG 0
|
|
147 |
#define FREG 0
|
149 |
148 |
#include "fop_template.c"
|
150 |
|
#undef SFREG
|
151 |
|
#undef DFREG
|
152 |
|
#define SFREG 1
|
|
149 |
#undef FREG
|
|
150 |
#define FREG 1
|
153 |
151 |
#include "fop_template.c"
|
154 |
|
#undef SFREG
|
155 |
|
#define SFREG 2
|
156 |
|
#define DFREG 2
|
|
152 |
#undef FREG
|
|
153 |
#define FREG 2
|
157 |
154 |
#include "fop_template.c"
|
158 |
|
#undef SFREG
|
159 |
|
#undef DFREG
|
160 |
|
#define SFREG 3
|
|
155 |
#undef FREG
|
|
156 |
#define FREG 3
|
161 |
157 |
#include "fop_template.c"
|
162 |
|
#undef SFREG
|
163 |
|
#define SFREG 4
|
164 |
|
#define DFREG 4
|
|
158 |
#undef FREG
|
|
159 |
#define FREG 4
|
165 |
160 |
#include "fop_template.c"
|
166 |
|
#undef SFREG
|
167 |
|
#undef DFREG
|
168 |
|
#define SFREG 5
|
|
161 |
#undef FREG
|
|
162 |
#define FREG 5
|
169 |
163 |
#include "fop_template.c"
|
170 |
|
#undef SFREG
|
171 |
|
#define SFREG 6
|
172 |
|
#define DFREG 6
|
|
164 |
#undef FREG
|
|
165 |
#define FREG 6
|
173 |
166 |
#include "fop_template.c"
|
174 |
|
#undef SFREG
|
175 |
|
#undef DFREG
|
176 |
|
#define SFREG 7
|
|
167 |
#undef FREG
|
|
168 |
#define FREG 7
|
177 |
169 |
#include "fop_template.c"
|
178 |
|
#undef SFREG
|
179 |
|
#define SFREG 8
|
180 |
|
#define DFREG 8
|
|
170 |
#undef FREG
|
|
171 |
#define FREG 8
|
181 |
172 |
#include "fop_template.c"
|
182 |
|
#undef SFREG
|
183 |
|
#undef DFREG
|
184 |
|
#define SFREG 9
|
|
173 |
#undef FREG
|
|
174 |
#define FREG 9
|
185 |
175 |
#include "fop_template.c"
|
186 |
|
#undef SFREG
|
187 |
|
#define SFREG 10
|
188 |
|
#define DFREG 10
|
|
176 |
#undef FREG
|
|
177 |
#define FREG 10
|
189 |
178 |
#include "fop_template.c"
|
190 |
|
#undef SFREG
|
191 |
|
#undef DFREG
|
192 |
|
#define SFREG 11
|
|
179 |
#undef FREG
|
|
180 |
#define FREG 11
|
193 |
181 |
#include "fop_template.c"
|
194 |
|
#undef SFREG
|
195 |
|
#define SFREG 12
|
196 |
|
#define DFREG 12
|
|
182 |
#undef FREG
|
|
183 |
#define FREG 12
|
197 |
184 |
#include "fop_template.c"
|
198 |
|
#undef SFREG
|
199 |
|
#undef DFREG
|
200 |
|
#define SFREG 13
|
|
185 |
#undef FREG
|
|
186 |
#define FREG 13
|
201 |
187 |
#include "fop_template.c"
|
202 |
|
#undef SFREG
|
203 |
|
#define SFREG 14
|
204 |
|
#define DFREG 14
|
|
188 |
#undef FREG
|
|
189 |
#define FREG 14
|
205 |
190 |
#include "fop_template.c"
|
206 |
|
#undef SFREG
|
207 |
|
#undef DFREG
|
208 |
|
#define SFREG 15
|
|
191 |
#undef FREG
|
|
192 |
#define FREG 15
|
209 |
193 |
#include "fop_template.c"
|
210 |
|
#undef SFREG
|
211 |
|
#define SFREG 16
|
212 |
|
#define DFREG 16
|
|
194 |
#undef FREG
|
|
195 |
#define FREG 16
|
213 |
196 |
#include "fop_template.c"
|
214 |
|
#undef SFREG
|
215 |
|
#undef DFREG
|
216 |
|
#define SFREG 17
|
|
197 |
#undef FREG
|
|
198 |
#define FREG 17
|
217 |
199 |
#include "fop_template.c"
|
218 |
|
#undef SFREG
|
219 |
|
#define SFREG 18
|
220 |
|
#define DFREG 18
|
|
200 |
#undef FREG
|
|
201 |
#define FREG 18
|
221 |
202 |
#include "fop_template.c"
|
222 |
|
#undef SFREG
|
223 |
|
#undef DFREG
|
224 |
|
#define SFREG 19
|
|
203 |
#undef FREG
|
|
204 |
#define FREG 19
|
225 |
205 |
#include "fop_template.c"
|
226 |
|
#undef SFREG
|
227 |
|
#define SFREG 20
|
228 |
|
#define DFREG 20
|
|
206 |
#undef FREG
|
|
207 |
#define FREG 20
|
229 |
208 |
#include "fop_template.c"
|
230 |
|
#undef SFREG
|
231 |
|
#undef DFREG
|
232 |
|
#define SFREG 21
|
|
209 |
#undef FREG
|
|
210 |
#define FREG 21
|
233 |
211 |
#include "fop_template.c"
|
234 |
|
#undef SFREG
|
235 |
|
#define SFREG 22
|
236 |
|
#define DFREG 22
|
|
212 |
#undef FREG
|
|
213 |
#define FREG 22
|
237 |
214 |
#include "fop_template.c"
|
238 |
|
#undef SFREG
|
239 |
|
#undef DFREG
|
240 |
|
#define SFREG 23
|
|
215 |
#undef FREG
|
|
216 |
#define FREG 23
|
241 |
217 |
#include "fop_template.c"
|
242 |
|
#undef SFREG
|
243 |
|
#define SFREG 24
|
244 |
|
#define DFREG 24
|
|
218 |
#undef FREG
|
|
219 |
#define FREG 24
|
245 |
220 |
#include "fop_template.c"
|
246 |
|
#undef SFREG
|
247 |
|
#undef DFREG
|
248 |
|
#define SFREG 25
|
|
221 |
#undef FREG
|
|
222 |
#define FREG 25
|
249 |
223 |
#include "fop_template.c"
|
250 |
|
#undef SFREG
|
251 |
|
#define SFREG 26
|
252 |
|
#define DFREG 26
|
|
224 |
#undef FREG
|
|
225 |
#define FREG 26
|
253 |
226 |
#include "fop_template.c"
|
254 |
|
#undef SFREG
|
255 |
|
#undef DFREG
|
256 |
|
#define SFREG 27
|
|
227 |
#undef FREG
|
|
228 |
#define FREG 27
|
257 |
229 |
#include "fop_template.c"
|
258 |
|
#undef SFREG
|
259 |
|
#define SFREG 28
|
260 |
|
#define DFREG 28
|
|
230 |
#undef FREG
|
|
231 |
#define FREG 28
|
261 |
232 |
#include "fop_template.c"
|
262 |
|
#undef SFREG
|
263 |
|
#undef DFREG
|
264 |
|
#define SFREG 29
|
|
233 |
#undef FREG
|
|
234 |
#define FREG 29
|
265 |
235 |
#include "fop_template.c"
|
266 |
|
#undef SFREG
|
267 |
|
#define SFREG 30
|
268 |
|
#define DFREG 30
|
|
236 |
#undef FREG
|
|
237 |
#define FREG 30
|
269 |
238 |
#include "fop_template.c"
|
270 |
|
#undef SFREG
|
271 |
|
#undef DFREG
|
272 |
|
#define SFREG 31
|
|
239 |
#undef FREG
|
|
240 |
#define FREG 31
|
273 |
241 |
#include "fop_template.c"
|
274 |
|
#undef SFREG
|
|
242 |
#undef FREG
|
275 |
243 |
|
276 |
244 |
#define FTN
|
277 |
245 |
#include "fop_template.c"
|
... | ... | |
919 |
887 |
void op_movf (void)
|
920 |
888 |
{
|
921 |
889 |
if (!(env->fcr31 & PARAM1))
|
922 |
|
env->gpr[PARAM2] = env->gpr[PARAM3];
|
|
890 |
T0 = T1;
|
923 |
891 |
RETURN();
|
924 |
892 |
}
|
925 |
893 |
|
926 |
894 |
void op_movt (void)
|
927 |
895 |
{
|
928 |
896 |
if (env->fcr31 & PARAM1)
|
929 |
|
env->gpr[PARAM2] = env->gpr[PARAM3];
|
|
897 |
T0 = T1;
|
930 |
898 |
RETURN();
|
931 |
899 |
}
|
932 |
900 |
|
... | ... | |
1354 |
1322 |
void op_mtc0_status (void)
|
1355 |
1323 |
{
|
1356 |
1324 |
uint32_t val, old;
|
|
1325 |
uint32_t mask = env->Status_rw_bitmask;
|
1357 |
1326 |
|
1358 |
|
/* No 64bit FPU, no reverse endianness, no MDMX/DSP, no 64bit ops,
|
|
1327 |
/* No reverse endianness, no MDMX/DSP, no 64bit ops,
|
1359 |
1328 |
no 64bit addressing implemented. */
|
1360 |
|
val = (int32_t)T0 & 0xF878FF17;
|
|
1329 |
val = (int32_t)T0 & mask;
|
1361 |
1330 |
old = env->CP0_Status;
|
1362 |
1331 |
if (!(val & (1 << CP0St_EXL)) &&
|
1363 |
1332 |
!(val & (1 << CP0St_ERL)) &&
|
1364 |
1333 |
!(env->hflags & MIPS_HFLAG_DM) &&
|
1365 |
1334 |
(val & (1 << CP0St_UM)))
|
1366 |
1335 |
env->hflags |= MIPS_HFLAG_UM;
|
1367 |
|
env->CP0_Status = (env->CP0_Status & ~0xF878FF17) | val;
|
|
1336 |
env->CP0_Status = (env->CP0_Status & ~mask) | val;
|
1368 |
1337 |
if (loglevel & CPU_LOG_EXEC)
|
1369 |
1338 |
CALL_FROM_TB2(do_mtc0_status_debug, old, val);
|
1370 |
1339 |
CALL_FROM_TB1(cpu_mips_update_irq, env);
|
... | ... | |
1643 |
1612 |
}
|
1644 |
1613 |
#endif /* TARGET_MIPS64 */
|
1645 |
1614 |
|
|
1615 |
/* CP1 functions */
|
1646 |
1616 |
#if 0
|
1647 |
1617 |
# define DEBUG_FPU_STATE() CALL_FROM_TB1(dump_fpu, env)
|
1648 |
1618 |
#else
|
... | ... | |
1666 |
1636 |
RETURN();
|
1667 |
1637 |
}
|
1668 |
1638 |
|
1669 |
|
/* CP1 functions */
|
1670 |
|
void op_cfc1 (void)
|
1671 |
|
{
|
1672 |
|
if (T1 == 0) {
|
1673 |
|
T0 = env->fcr0;
|
1674 |
|
}
|
1675 |
|
else {
|
1676 |
|
/* fetch fcr31, masking unused bits */
|
1677 |
|
T0 = env->fcr31 & 0x0183FFFF;
|
1678 |
|
}
|
1679 |
|
DEBUG_FPU_STATE();
|
1680 |
|
RETURN();
|
1681 |
|
}
|
1682 |
|
|
1683 |
1639 |
/* convert MIPS rounding mode in FCR31 to IEEE library */
|
1684 |
1640 |
unsigned int ieee_rm[] = {
|
1685 |
1641 |
float_round_nearest_even,
|
... | ... | |
1691 |
1647 |
#define RESTORE_ROUNDING_MODE \
|
1692 |
1648 |
set_float_rounding_mode(ieee_rm[env->fcr31 & 3], &env->fp_status)
|
1693 |
1649 |
|
1694 |
|
void op_ctc1 (void)
|
|
1650 |
inline char ieee_ex_to_mips(char ieee)
|
1695 |
1651 |
{
|
1696 |
|
if (T1 == 0) {
|
1697 |
|
/* XXX should this throw an exception?
|
1698 |
|
* don't write to FCR0.
|
1699 |
|
* env->fcr0 = T0;
|
1700 |
|
*/
|
1701 |
|
}
|
1702 |
|
else {
|
1703 |
|
/* store new fcr31, masking unused bits */
|
1704 |
|
env->fcr31 = T0 & 0x0183FFFF;
|
|
1652 |
return (ieee & float_flag_inexact) >> 5 |
|
|
1653 |
(ieee & float_flag_underflow) >> 3 |
|
|
1654 |
(ieee & float_flag_overflow) >> 1 |
|
|
1655 |
(ieee & float_flag_divbyzero) << 1 |
|
|
1656 |
(ieee & float_flag_invalid) << 4;
|
|
1657 |
}
|
1705 |
1658 |
|
1706 |
|
/* set rounding mode */
|
1707 |
|
RESTORE_ROUNDING_MODE;
|
|
1659 |
inline char mips_ex_to_ieee(char mips)
|
|
1660 |
{
|
|
1661 |
return (mips & FP_INEXACT) << 5 |
|
|
1662 |
(mips & FP_UNDERFLOW) << 3 |
|
|
1663 |
(mips & FP_OVERFLOW) << 1 |
|
|
1664 |
(mips & FP_DIV0) >> 1 |
|
|
1665 |
(mips & FP_INVALID) >> 4;
|
|
1666 |
}
|
1708 |
1667 |
|
1709 |
|
#ifndef CONFIG_SOFTFLOAT
|
1710 |
|
/* no floating point exception for native float */
|
1711 |
|
SET_FP_ENABLE(env->fcr31, 0);
|
1712 |
|
#endif
|
|
1668 |
inline void update_fcr31(void)
|
|
1669 |
{
|
|
1670 |
int tmp = ieee_ex_to_mips(get_float_exception_flags(&env->fp_status));
|
|
1671 |
|
|
1672 |
SET_FP_CAUSE(env->fcr31, tmp);
|
|
1673 |
if (GET_FP_ENABLE(env->fcr31) & tmp)
|
|
1674 |
CALL_FROM_TB1(do_raise_exception, EXCP_FPE);
|
|
1675 |
else
|
|
1676 |
UPDATE_FP_FLAGS(env->fcr31, tmp);
|
|
1677 |
}
|
|
1678 |
|
|
1679 |
|
|
1680 |
void op_cfc1 (void)
|
|
1681 |
{
|
|
1682 |
switch (T1) {
|
|
1683 |
case 0:
|
|
1684 |
T0 = (int32_t)env->fcr0;
|
|
1685 |
break;
|
|
1686 |
case 25:
|
|
1687 |
T0 = ((env->fcr31 >> 24) & 0xfe) | ((env->fcr31 >> 23) & 0x1);
|
|
1688 |
break;
|
|
1689 |
case 26:
|
|
1690 |
T0 = env->fcr31 & 0x0003f07c;
|
|
1691 |
break;
|
|
1692 |
case 28:
|
|
1693 |
T0 = (env->fcr31 & 0x00000f83) | ((env->fcr31 >> 22) & 0x4);
|
|
1694 |
break;
|
|
1695 |
default:
|
|
1696 |
T0 = (int32_t)env->fcr31;
|
|
1697 |
break;
|
|
1698 |
}
|
|
1699 |
DEBUG_FPU_STATE();
|
|
1700 |
RETURN();
|
|
1701 |
}
|
|
1702 |
|
|
1703 |
void op_ctc1 (void)
|
|
1704 |
{
|
|
1705 |
switch(T1) {
|
|
1706 |
case 25:
|
|
1707 |
if (T0 & 0xffffff00)
|
|
1708 |
goto leave;
|
|
1709 |
env->fcr31 = (env->fcr31 & 0x017fffff) | ((T0 & 0xfe) << 24) |
|
|
1710 |
((T0 & 0x1) << 23);
|
|
1711 |
break;
|
|
1712 |
case 26:
|
|
1713 |
if (T0 & 0x007c0000)
|
|
1714 |
goto leave;
|
|
1715 |
env->fcr31 = (env->fcr31 & 0xfffc0f83) | (T0 & 0x0003f07c);
|
|
1716 |
break;
|
|
1717 |
case 28:
|
|
1718 |
if (T0 & 0x007c0000)
|
|
1719 |
goto leave;
|
|
1720 |
env->fcr31 = (env->fcr31 & 0xfefff07c) | (T0 & 0x00000f83) |
|
|
1721 |
((T0 & 0x4) << 22);
|
|
1722 |
break;
|
|
1723 |
case 31:
|
|
1724 |
if (T0 & 0x007c0000)
|
|
1725 |
goto leave;
|
|
1726 |
env->fcr31 = T0;
|
|
1727 |
break;
|
|
1728 |
default:
|
|
1729 |
goto leave;
|
1713 |
1730 |
}
|
|
1731 |
/* set rounding mode */
|
|
1732 |
RESTORE_ROUNDING_MODE;
|
|
1733 |
set_float_exception_flags(0, &env->fp_status);
|
|
1734 |
if ((GET_FP_ENABLE(env->fcr31) | 0x20) & GET_FP_CAUSE(env->fcr31))
|
|
1735 |
CALL_FROM_TB1(do_raise_exception, EXCP_FPE);
|
|
1736 |
leave:
|
1714 |
1737 |
DEBUG_FPU_STATE();
|
1715 |
1738 |
RETURN();
|
1716 |
1739 |
}
|
... | ... | |
1729 |
1752 |
RETURN();
|
1730 |
1753 |
}
|
1731 |
1754 |
|
|
1755 |
void op_dmfc1 (void)
|
|
1756 |
{
|
|
1757 |
T0 = DT0;
|
|
1758 |
DEBUG_FPU_STATE();
|
|
1759 |
RETURN();
|
|
1760 |
}
|
|
1761 |
|
|
1762 |
void op_dmtc1 (void)
|
|
1763 |
{
|
|
1764 |
DT0 = T0;
|
|
1765 |
DEBUG_FPU_STATE();
|
|
1766 |
RETURN();
|
|
1767 |
}
|
|
1768 |
|
|
1769 |
void op_mfhc1 (void)
|
|
1770 |
{
|
|
1771 |
T0 = WTH0;
|
|
1772 |
DEBUG_FPU_STATE();
|
|
1773 |
RETURN();
|
|
1774 |
}
|
|
1775 |
|
|
1776 |
void op_mthc1 (void)
|
|
1777 |
{
|
|
1778 |
WTH0 = T0;
|
|
1779 |
DEBUG_FPU_STATE();
|
|
1780 |
RETURN();
|
|
1781 |
}
|
|
1782 |
|
1732 |
1783 |
/* Float support.
|
1733 |
1784 |
Single precition routines have a "s" suffix, double precision a
|
1734 |
|
"d" suffix. */
|
|
1785 |
"d" suffix, 32bit integer "w", 64bit integer "l", paired singe "ps",
|
|
1786 |
paired single lowwer "pl", paired single upper "pu". */
|
1735 |
1787 |
|
1736 |
1788 |
#define FLOAT_OP(name, p) void OPPROTO op_float_##name##_##p(void)
|
1737 |
1789 |
|
1738 |
1790 |
FLOAT_OP(cvtd, s)
|
1739 |
1791 |
{
|
|
1792 |
set_float_exception_flags(0, &env->fp_status);
|
1740 |
1793 |
FDT2 = float32_to_float64(FST0, &env->fp_status);
|
|
1794 |
update_fcr31();
|
1741 |
1795 |
DEBUG_FPU_STATE();
|
1742 |
1796 |
RETURN();
|
1743 |
1797 |
}
|
1744 |
1798 |
FLOAT_OP(cvtd, w)
|
1745 |
1799 |
{
|
|
1800 |
set_float_exception_flags(0, &env->fp_status);
|
1746 |
1801 |
FDT2 = int32_to_float64(WT0, &env->fp_status);
|
|
1802 |
update_fcr31();
|
|
1803 |
DEBUG_FPU_STATE();
|
|
1804 |
RETURN();
|
|
1805 |
}
|
|
1806 |
FLOAT_OP(cvtd, l)
|
|
1807 |
{
|
|
1808 |
set_float_exception_flags(0, &env->fp_status);
|
|
1809 |
FDT2 = int64_to_float64(DT0, &env->fp_status);
|
|
1810 |
update_fcr31();
|
|
1811 |
DEBUG_FPU_STATE();
|
|
1812 |
RETURN();
|
|
1813 |
}
|
|
1814 |
FLOAT_OP(cvtl, d)
|
|
1815 |
{
|
|
1816 |
set_float_exception_flags(0, &env->fp_status);
|
|
1817 |
DT2 = float64_to_int64(FDT0, &env->fp_status);
|
|
1818 |
update_fcr31();
|
|
1819 |
if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
|
|
1820 |
DT2 = 0x7fffffffffffffffULL;
|
|
1821 |
DEBUG_FPU_STATE();
|
|
1822 |
RETURN();
|
|
1823 |
}
|
|
1824 |
FLOAT_OP(cvtl, s)
|
|
1825 |
{
|
|
1826 |
set_float_exception_flags(0, &env->fp_status);
|
|
1827 |
DT2 = float32_to_int64(FST0, &env->fp_status);
|
|
1828 |
update_fcr31();
|
|
1829 |
if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
|
|
1830 |
DT2 = 0x7fffffffffffffffULL;
|
|
1831 |
DEBUG_FPU_STATE();
|
|
1832 |
RETURN();
|
|
1833 |
}
|
|
1834 |
FLOAT_OP(cvtps, s)
|
|
1835 |
{
|
|
1836 |
WT2 = WT0;
|
|
1837 |
WTH2 = WT1;
|
|
1838 |
DEBUG_FPU_STATE();
|
|
1839 |
RETURN();
|
|
1840 |
}
|
|
1841 |
FLOAT_OP(cvtps, pw)
|
|
1842 |
{
|
|
1843 |
set_float_exception_flags(0, &env->fp_status);
|
|
1844 |
FST2 = int32_to_float32(WT0, &env->fp_status);
|
|
1845 |
FSTH2 = int32_to_float32(WTH0, &env->fp_status);
|
|
1846 |
update_fcr31();
|
|
1847 |
DEBUG_FPU_STATE();
|
|
1848 |
RETURN();
|
|
1849 |
}
|
|
1850 |
FLOAT_OP(cvtpw, ps)
|
|
1851 |
{
|
|
1852 |
set_float_exception_flags(0, &env->fp_status);
|
|
1853 |
WT2 = float32_to_int32(FST0, &env->fp_status);
|
|
1854 |
WTH2 = float32_to_int32(FSTH0, &env->fp_status);
|
|
1855 |
update_fcr31();
|
|
1856 |
if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
|
|
1857 |
WT2 = 0x7fffffff;
|
1747 |
1858 |
DEBUG_FPU_STATE();
|
1748 |
1859 |
RETURN();
|
1749 |
1860 |
}
|
1750 |
1861 |
FLOAT_OP(cvts, d)
|
1751 |
1862 |
{
|
|
1863 |
set_float_exception_flags(0, &env->fp_status);
|
1752 |
1864 |
FST2 = float64_to_float32(FDT0, &env->fp_status);
|
|
1865 |
update_fcr31();
|
1753 |
1866 |
DEBUG_FPU_STATE();
|
1754 |
1867 |
RETURN();
|
1755 |
1868 |
}
|
1756 |
1869 |
FLOAT_OP(cvts, w)
|
1757 |
1870 |
{
|
|
1871 |
set_float_exception_flags(0, &env->fp_status);
|
1758 |
1872 |
FST2 = int32_to_float32(WT0, &env->fp_status);
|
|
1873 |
update_fcr31();
|
|
1874 |
DEBUG_FPU_STATE();
|
|
1875 |
RETURN();
|
|
1876 |
}
|
|
1877 |
FLOAT_OP(cvts, l)
|
|
1878 |
{
|
|
1879 |
set_float_exception_flags(0, &env->fp_status);
|
|
1880 |
FST2 = int64_to_float32(DT0, &env->fp_status);
|
|
1881 |
update_fcr31();
|
|
1882 |
DEBUG_FPU_STATE();
|
|
1883 |
RETURN();
|
|
1884 |
}
|
|
1885 |
FLOAT_OP(cvts, pl)
|
|
1886 |
{
|
|
1887 |
set_float_exception_flags(0, &env->fp_status);
|
|
1888 |
WT2 = WT0;
|
|
1889 |
update_fcr31();
|
|
1890 |
DEBUG_FPU_STATE();
|
|
1891 |
RETURN();
|
|
1892 |
}
|
|
1893 |
FLOAT_OP(cvts, pu)
|
|
1894 |
{
|
|
1895 |
set_float_exception_flags(0, &env->fp_status);
|
|
1896 |
WT2 = WTH0;
|
|
1897 |
update_fcr31();
|
1759 |
1898 |
DEBUG_FPU_STATE();
|
1760 |
1899 |
RETURN();
|
1761 |
1900 |
}
|
1762 |
1901 |
FLOAT_OP(cvtw, s)
|
1763 |
1902 |
{
|
|
1903 |
set_float_exception_flags(0, &env->fp_status);
|
1764 |
1904 |
WT2 = float32_to_int32(FST0, &env->fp_status);
|
|
1905 |
update_fcr31();
|
|
1906 |
if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
|
|
1907 |
WT2 = 0x7fffffff;
|
1765 |
1908 |
DEBUG_FPU_STATE();
|
1766 |
1909 |
RETURN();
|
1767 |
1910 |
}
|
1768 |
1911 |
FLOAT_OP(cvtw, d)
|
1769 |
1912 |
{
|
|
1913 |
set_float_exception_flags(0, &env->fp_status);
|
1770 |
1914 |
WT2 = float64_to_int32(FDT0, &env->fp_status);
|
|
1915 |
update_fcr31();
|
|
1916 |
if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
|
|
1917 |
WT2 = 0x7fffffff;
|
|
1918 |
DEBUG_FPU_STATE();
|
|
1919 |
RETURN();
|
|
1920 |
}
|
|
1921 |
|
|
1922 |
FLOAT_OP(pll, ps)
|
|
1923 |
{
|
|
1924 |
DT2 = ((uint64_t)WT0 << 32) | WT1;
|
|
1925 |
DEBUG_FPU_STATE();
|
|
1926 |
RETURN();
|
|
1927 |
}
|
|
1928 |
FLOAT_OP(plu, ps)
|
|
1929 |
{
|
|
1930 |
DT2 = ((uint64_t)WT0 << 32) | WTH1;
|
|
1931 |
DEBUG_FPU_STATE();
|
|
1932 |
RETURN();
|
|
1933 |
}
|
|
1934 |
FLOAT_OP(pul, ps)
|
|
1935 |
{
|
|
1936 |
DT2 = ((uint64_t)WTH0 << 32) | WT1;
|
|
1937 |
DEBUG_FPU_STATE();
|
|
1938 |
RETURN();
|
|
1939 |
}
|
|
1940 |
FLOAT_OP(puu, ps)
|
|
1941 |
{
|
|
1942 |
DT2 = ((uint64_t)WTH0 << 32) | WTH1;
|
1771 |
1943 |
DEBUG_FPU_STATE();
|
1772 |
1944 |
RETURN();
|
1773 |
1945 |
}
|
1774 |
1946 |
|
|
1947 |
FLOAT_OP(roundl, d)
|
|
1948 |
{
|
|
1949 |
set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
|
|
1950 |
DT2 = float64_round_to_int(FDT0, &env->fp_status);
|
|
1951 |
RESTORE_ROUNDING_MODE;
|
|
1952 |
DEBUG_FPU_STATE();
|
|
1953 |
RETURN();
|
|
1954 |
}
|
|
1955 |
FLOAT_OP(roundl, s)
|
|
1956 |
{
|
|
1957 |
set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
|
|
1958 |
DT2 = float32_round_to_int(FST0, &env->fp_status);
|
|
1959 |
RESTORE_ROUNDING_MODE;
|
|
1960 |
DEBUG_FPU_STATE();
|
|
1961 |
RETURN();
|
|
1962 |
}
|
1775 |
1963 |
FLOAT_OP(roundw, d)
|
1776 |
1964 |
{
|
1777 |
1965 |
set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
|
1778 |
1966 |
WT2 = float64_round_to_int(FDT0, &env->fp_status);
|
1779 |
1967 |
RESTORE_ROUNDING_MODE;
|
1780 |
|
|
1781 |
1968 |
DEBUG_FPU_STATE();
|
1782 |
1969 |
RETURN();
|
1783 |
1970 |
}
|
... | ... | |
1790 |
1977 |
RETURN();
|
1791 |
1978 |
}
|
1792 |
1979 |
|
|
1980 |
FLOAT_OP(truncl, d)
|
|
1981 |
{
|
|
1982 |
DT2 = float64_to_int64_round_to_zero(FDT0, &env->fp_status);
|
|
1983 |
DEBUG_FPU_STATE();
|
|
1984 |
RETURN();
|
|
1985 |
}
|
|
1986 |
FLOAT_OP(truncl, s)
|
|
1987 |
{
|
|
1988 |
DT2 = float32_to_int64_round_to_zero(FST0, &env->fp_status);
|
|
1989 |
DEBUG_FPU_STATE();
|
|
1990 |
RETURN();
|
|
1991 |
}
|
1793 |
1992 |
FLOAT_OP(truncw, d)
|
1794 |
1993 |
{
|
1795 |
1994 |
WT2 = float64_to_int32_round_to_zero(FDT0, &env->fp_status);
|
... | ... | |
1803 |
2002 |
RETURN();
|
1804 |
2003 |
}
|
1805 |
2004 |
|
|
2005 |
FLOAT_OP(ceill, d)
|
|
2006 |
{
|
|
2007 |
set_float_rounding_mode(float_round_up, &env->fp_status);
|
|
2008 |
DT2 = float64_round_to_int(FDT0, &env->fp_status);
|
|
2009 |
RESTORE_ROUNDING_MODE;
|
|
2010 |
DEBUG_FPU_STATE();
|
|
2011 |
RETURN();
|
|
2012 |
}
|
|
2013 |
FLOAT_OP(ceill, s)
|
|
2014 |
{
|
|
2015 |
set_float_rounding_mode(float_round_up, &env->fp_status);
|
|
2016 |
DT2 = float32_round_to_int(FST0, &env->fp_status);
|
|
2017 |
RESTORE_ROUNDING_MODE;
|
|
2018 |
DEBUG_FPU_STATE();
|
|
2019 |
RETURN();
|
|
2020 |
}
|
1806 |
2021 |
FLOAT_OP(ceilw, d)
|
1807 |
2022 |
{
|
1808 |
2023 |
set_float_rounding_mode(float_round_up, &env->fp_status);
|
1809 |
2024 |
WT2 = float64_round_to_int(FDT0, &env->fp_status);
|
1810 |
2025 |
RESTORE_ROUNDING_MODE;
|
1811 |
|
|
1812 |
2026 |
DEBUG_FPU_STATE();
|
1813 |
2027 |
RETURN();
|
1814 |
2028 |
}
|
... | ... | |
1821 |
2035 |
RETURN();
|
1822 |
2036 |
}
|
1823 |
2037 |
|
|
2038 |
FLOAT_OP(floorl, d)
|
|
2039 |
{
|
|
2040 |
set_float_rounding_mode(float_round_down, &env->fp_status);
|
|
2041 |
DT2 = float64_round_to_int(FDT0, &env->fp_status);
|
|
2042 |
RESTORE_ROUNDING_MODE;
|
|
2043 |
DEBUG_FPU_STATE();
|
|
2044 |
RETURN();
|
|
2045 |
}
|
|
2046 |
FLOAT_OP(floorl, s)
|
|
2047 |
{
|
|
2048 |
set_float_rounding_mode(float_round_down, &env->fp_status);
|
|
2049 |
DT2 = float32_round_to_int(FST0, &env->fp_status);
|
|
2050 |
RESTORE_ROUNDING_MODE;
|
|
2051 |
DEBUG_FPU_STATE();
|
|
2052 |
RETURN();
|
|
2053 |
}
|
1824 |
2054 |
FLOAT_OP(floorw, d)
|
1825 |
2055 |
{
|
1826 |
2056 |
set_float_rounding_mode(float_round_down, &env->fp_status);
|
1827 |
2057 |
WT2 = float64_round_to_int(FDT0, &env->fp_status);
|
1828 |
2058 |
RESTORE_ROUNDING_MODE;
|
1829 |
|
|
1830 |
2059 |
DEBUG_FPU_STATE();
|
1831 |
2060 |
RETURN();
|
1832 |
2061 |
}
|
... | ... | |
1839 |
2068 |
RETURN();
|
1840 |
2069 |
}
|
1841 |
2070 |
|
|
2071 |
FLOAT_OP(movf, d)
|
|
2072 |
{
|
|
2073 |
if (!(env->fcr31 & PARAM1))
|
|
2074 |
DT2 = DT0;
|
|
2075 |
DEBUG_FPU_STATE();
|
|
2076 |
RETURN();
|
|
2077 |
}
|
|
2078 |
FLOAT_OP(movf, s)
|
|
2079 |
{
|
|
2080 |
if (!(env->fcr31 & PARAM1))
|
|
2081 |
WT2 = WT0;
|
|
2082 |
DEBUG_FPU_STATE();
|
|
2083 |
RETURN();
|
|
2084 |
}
|
|
2085 |
FLOAT_OP(movf, ps)
|
|
2086 |
{
|
|
2087 |
if (!(env->fcr31 & PARAM1)) {
|
|
2088 |
WT2 = WT0;
|
|
2089 |
WTH2 = WTH0;
|
|
2090 |
}
|
|
2091 |
DEBUG_FPU_STATE();
|
|
2092 |
RETURN();
|
|
2093 |
}
|
|
2094 |
FLOAT_OP(movt, d)
|
|
2095 |
{
|
|
2096 |
if (env->fcr31 & PARAM1)
|
|
2097 |
DT2 = DT0;
|
|
2098 |
DEBUG_FPU_STATE();
|
|
2099 |
RETURN();
|
|
2100 |
}
|
|
2101 |
FLOAT_OP(movt, s)
|
|
2102 |
{
|
|
2103 |
if (env->fcr31 & PARAM1)
|
|
2104 |
WT2 = WT0;
|
|
2105 |
DEBUG_FPU_STATE();
|
|
2106 |
RETURN();
|
|
2107 |
}
|
|
2108 |
FLOAT_OP(movt, ps)
|
|
2109 |
{
|
|
2110 |
if (env->fcr31 & PARAM1) {
|
|
2111 |
WT2 = WT0;
|
|
2112 |
WTH2 = WTH0;
|
|
2113 |
}
|
|
2114 |
DEBUG_FPU_STATE();
|
|
2115 |
RETURN();
|
|
2116 |
}
|
|
2117 |
FLOAT_OP(movz, d)
|
|
2118 |
{
|
|
2119 |
if (!T0)
|
|
2120 |
DT2 = DT0;
|
|
2121 |
DEBUG_FPU_STATE();
|
|
2122 |
RETURN();
|
|
2123 |
}
|
|
2124 |
FLOAT_OP(movz, s)
|
|
2125 |
{
|
|
2126 |
if (!T0)
|
|
2127 |
WT2 = WT0;
|
|
2128 |
DEBUG_FPU_STATE();
|
|
2129 |
RETURN();
|
|
2130 |
}
|
|
2131 |
FLOAT_OP(movz, ps)
|
|
2132 |
{
|
|
2133 |
if (!T0) {
|
|
2134 |
WT2 = WT0;
|
|
2135 |
WTH2 = WTH0;
|
|
2136 |
}
|
|
2137 |
DEBUG_FPU_STATE();
|
|
2138 |
RETURN();
|
|
2139 |
}
|
|
2140 |
FLOAT_OP(movn, d)
|
|
2141 |
{
|
|
2142 |
if (T0)
|
|
2143 |
DT2 = DT0;
|
|
2144 |
DEBUG_FPU_STATE();
|
|
2145 |
RETURN();
|
|
2146 |
}
|
|
2147 |
FLOAT_OP(movn, s)
|
|
2148 |
{
|
|
2149 |
if (T0)
|
|
2150 |
WT2 = WT0;
|
|
2151 |
DEBUG_FPU_STATE();
|
|
2152 |
RETURN();
|
|
2153 |
}
|
|
2154 |
FLOAT_OP(movn, ps)
|
|
2155 |
{
|
|
2156 |
if (T0) {
|
|
2157 |
WT2 = WT0;
|
|
2158 |
WTH2 = WTH0;
|
|
2159 |
}
|
|
2160 |
DEBUG_FPU_STATE();
|
|
2161 |
RETURN();
|
|
2162 |
}
|
|
2163 |
|
1842 |
2164 |
/* binary operations */
|
1843 |
2165 |
#define FLOAT_BINOP(name) \
|
1844 |
2166 |
FLOAT_OP(name, d) \
|
1845 |
2167 |
{ \
|
|
2168 |
set_float_exception_flags(0, &env->fp_status); \
|
1846 |
2169 |
FDT2 = float64_ ## name (FDT0, FDT1, &env->fp_status); \
|
|
2170 |
update_fcr31(); \
|
1847 |
2171 |
DEBUG_FPU_STATE(); \
|
1848 |
2172 |
} \
|
1849 |
2173 |
FLOAT_OP(name, s) \
|
1850 |
2174 |
{ \
|
|
2175 |
set_float_exception_flags(0, &env->fp_status); \
|
1851 |
2176 |
FST2 = float32_ ## name (FST0, FST1, &env->fp_status); \
|
|
2177 |
update_fcr31(); \
|
|
2178 |
DEBUG_FPU_STATE(); \
|
|
2179 |
} \
|
|
2180 |
FLOAT_OP(name, ps) \
|
|
2181 |
{ \
|
|
2182 |
set_float_exception_flags(0, &env->fp_status); \
|
|
2183 |
FST2 = float32_ ## name (FST0, FST1, &env->fp_status); \
|
|
2184 |
FSTH2 = float32_ ## name (FSTH0, FSTH1, &env->fp_status); \
|
|
2185 |
update_fcr31(); \
|
1852 |
2186 |
DEBUG_FPU_STATE(); \
|
1853 |
2187 |
}
|
1854 |
2188 |
FLOAT_BINOP(add)
|
... | ... | |
1857 |
2191 |
FLOAT_BINOP(div)
|
1858 |
2192 |
#undef FLOAT_BINOP
|
1859 |
2193 |
|
|
2194 |
/* ternary operations */
|
|
2195 |
#define FLOAT_TERNOP(name1, name2) \
|
|
2196 |
FLOAT_OP(name1 ## name2, d) \
|
|
2197 |
{ \
|
|
2198 |
FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fp_status); \
|
|
2199 |
FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fp_status); \
|
|
2200 |
DEBUG_FPU_STATE(); \
|
|
2201 |
} \
|
|
2202 |
FLOAT_OP(name1 ## name2, s) \
|
|
2203 |
{ \
|
|
2204 |
FST0 = float32_ ## name1 (FST0, FST1, &env->fp_status); \
|
|
2205 |
FST2 = float32_ ## name2 (FST0, FST2, &env->fp_status); \
|
|
2206 |
DEBUG_FPU_STATE(); \
|
|
2207 |
} \
|
|
2208 |
FLOAT_OP(name1 ## name2, ps) \
|
|
2209 |
{ \
|
|
2210 |
FST0 = float32_ ## name1 (FST0, FST1, &env->fp_status); \
|
|
2211 |
FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fp_status); \
|
|
2212 |
FST2 = float32_ ## name2 (FST0, FST2, &env->fp_status); \
|
|
2213 |
FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fp_status); \
|
|
2214 |
DEBUG_FPU_STATE(); \
|
|
2215 |
}
|
|
2216 |
FLOAT_TERNOP(mul, add)
|
|
2217 |
FLOAT_TERNOP(mul, sub)
|
|
2218 |
#undef FLOAT_TERNOP
|
|
2219 |
|
1860 |
2220 |
/* unary operations, modifying fp status */
|
1861 |
2221 |
#define FLOAT_UNOP(name) \
|
1862 |
2222 |
FLOAT_OP(name, d) \
|
... | ... | |
1868 |
2228 |
{ \
|
1869 |
2229 |
FST2 = float32_ ## name(FST0, &env->fp_status); \
|
1870 |
2230 |
DEBUG_FPU_STATE(); \
|
|
2231 |
} \
|
|
2232 |
FLOAT_OP(name, ps) \
|
|
2233 |
{ \
|
|
2234 |
FST2 = float32_ ## name(FST0, &env->fp_status); \
|
|
2235 |
FSTH2 = float32_ ## name(FSTH0, &env->fp_status); \
|
|
2236 |
DEBUG_FPU_STATE(); \
|
1871 |
2237 |
}
|
1872 |
2238 |
FLOAT_UNOP(sqrt)
|
1873 |
2239 |
#undef FLOAT_UNOP
|
... | ... | |
1883 |
2249 |
{ \
|
1884 |
2250 |
FST2 = float32_ ## name(FST0); \
|
1885 |
2251 |
DEBUG_FPU_STATE(); \
|
|
2252 |
} \
|
|
2253 |
FLOAT_OP(name, ps) \
|
|
2254 |
{ \
|
|
2255 |
FST2 = float32_ ## name(FST0); \
|
|
2256 |
FSTH2 = float32_ ## name(FSTH0); \
|
|
2257 |
DEBUG_FPU_STATE(); \
|
1886 |
2258 |
}
|
1887 |
2259 |
FLOAT_UNOP(abs)
|
1888 |
2260 |
FLOAT_UNOP(chs)
|
... | ... | |
1900 |
2272 |
DEBUG_FPU_STATE();
|
1901 |
2273 |
RETURN();
|
1902 |
2274 |
}
|
|
2275 |
FLOAT_OP(mov, ps)
|
|
2276 |
{
|
|
2277 |
FST2 = FST0;
|
|
2278 |
FSTH2 = FSTH0;
|
|
2279 |
DEBUG_FPU_STATE();
|
|
2280 |
RETURN();
|
|
2281 |
}
|
|
2282 |
FLOAT_OP(alnv, ps)
|
|
2283 |
{
|
|
2284 |
switch (T0 & 0x7) {
|
|
2285 |
case 0:
|
|
2286 |
FST2 = FST0;
|
|
2287 |
FSTH2 = FSTH0;
|
|
2288 |
break;
|
|
2289 |
case 4:
|
|
2290 |
#ifdef TARGET_WORDS_BIGENDIAN
|
|
2291 |
FSTH2 = FST0;
|
|
2292 |
FST2 = FSTH1;
|
|
2293 |
#else
|
|
2294 |
FSTH2 = FST1;
|
|
2295 |
FST2 = FSTH0;
|
|
2296 |
#endif
|
|
2297 |
break;
|
|
2298 |
default: /* unpredictable */
|
|
2299 |
break;
|
|
2300 |
}
|
|
2301 |
DEBUG_FPU_STATE();
|
|
2302 |
RETURN();
|
|
2303 |
}
|
1903 |
2304 |
|
1904 |
2305 |
#ifdef CONFIG_SOFTFLOAT
|
1905 |
2306 |
#define clear_invalid() do { \
|
... | ... | |
1913 |
2314 |
|
1914 |
2315 |
extern void dump_fpu_s(CPUState *env);
|
1915 |
2316 |
|
1916 |
|
#define FOP_COND(fmt, op, sig, cond) \
|
1917 |
|
void op_cmp_ ## fmt ## _ ## op (void) \
|
|
2317 |
#define FOP_COND_D(op, cond) \
|
|
2318 |
void op_cmp_d_ ## op (void) \
|
1918 |
2319 |
{ \
|
1919 |
|
if (cond) \
|
1920 |
|
SET_FP_COND(env->fcr31); \
|
|
2320 |
int c = cond; \
|
|
2321 |
update_fcr31(); \
|
|
2322 |
if (c) \
|
|
2323 |
SET_FP_COND(PARAM1, env); \
|
1921 |
2324 |
else \
|
1922 |
|
CLEAR_FP_COND(env->fcr31); \
|
1923 |
|
if (!sig) \
|
1924 |
|
clear_invalid(); \
|
1925 |
|
/*CALL_FROM_TB1(dump_fpu_s, env);*/ \
|
|
2325 |
CLEAR_FP_COND(PARAM1, env); \
|
1926 |
2326 |
DEBUG_FPU_STATE(); \
|
1927 |
2327 |
RETURN(); \
|
1928 |
2328 |
}
|
1929 |
2329 |
|
1930 |
|
int float64_is_unordered(float64 a, float64 b STATUS_PARAM)
|
|
2330 |
int float64_is_unordered(int sig, float64 a, float64 b STATUS_PARAM)
|
1931 |
2331 |
{
|
1932 |
|
if (float64_is_nan(a) || float64_is_nan(b)) {
|
|
2332 |
if (float64_is_signaling_nan(a) ||
|
|
2333 |
float64_is_signaling_nan(b) ||
|
|
2334 |
(sig && (float64_is_nan(a) || float64_is_nan(b)))) {
|
1933 |
2335 |
float_raise(float_flag_invalid, status);
|
1934 |
2336 |
return 1;
|
1935 |
|
}
|
1936 |
|
else {
|
|
2337 |
} else if (float64_is_nan(a) || float64_is_nan(b)) {
|
|
2338 |
return 1;
|
|
2339 |
} else {
|
1937 |
2340 |
return 0;
|
1938 |
2341 |
}
|
1939 |
2342 |
}
|
1940 |
2343 |
|
1941 |
|
FOP_COND(d, f, 0, 0)
|
1942 |
|
FOP_COND(d, un, 0, float64_is_unordered(FDT1, FDT0, &env->fp_status))
|
1943 |
|
FOP_COND(d, eq, 0, float64_eq(FDT0, FDT1, &env->fp_status))
|
1944 |
|
FOP_COND(d, ueq, 0, float64_is_unordered(FDT1, FDT0, &env->fp_status) || float64_eq(FDT0, FDT1, &env->fp_status))
|
1945 |
|
FOP_COND(d, olt, 0, float64_lt(FDT0, FDT1, &env->fp_status))
|
1946 |
|
FOP_COND(d, ult, 0, float64_is_unordered(FDT1, FDT0, &env->fp_status) || float64_lt(FDT0, FDT1, &env->fp_status))
|
1947 |
|
FOP_COND(d, ole, 0, float64_le(FDT0, FDT1, &env->fp_status))
|
1948 |
|
FOP_COND(d, ule, 0, float64_is_unordered(FDT1, FDT0, &env->fp_status) || float64_le(FDT0, FDT1, &env->fp_status))
|
1949 |
2344 |
/* NOTE: the comma operator will make "cond" to eval to false,
|
1950 |
|
* but float*_is_unordered() is still called
|
1951 |
|
*/
|
1952 |
|
FOP_COND(d, sf, 1, (float64_is_unordered(FDT0, FDT1, &env->fp_status), 0))
|
1953 |
|
FOP_COND(d, ngle,1, float64_is_unordered(FDT1, FDT0, &env->fp_status))
|
1954 |
|
FOP_COND(d, seq, 1, float64_eq(FDT0, FDT1, &env->fp_status))
|
1955 |
|
FOP_COND(d, ngl, 1, float64_is_unordered(FDT1, FDT0, &env->fp_status) || float64_eq(FDT0, FDT1, &env->fp_status))
|
1956 |
|
FOP_COND(d, lt, 1, float64_lt(FDT0, FDT1, &env->fp_status))
|
1957 |
|
FOP_COND(d, nge, 1, float64_is_unordered(FDT1, FDT0, &env->fp_status) || float64_lt(FDT0, FDT1, &env->fp_status))
|
1958 |
|
FOP_COND(d, le, 1, float64_le(FDT0, FDT1, &env->fp_status))
|
1959 |
|
FOP_COND(d, ngt, 1, float64_is_unordered(FDT1, FDT0, &env->fp_status) || float64_le(FDT0, FDT1, &env->fp_status))
|
1960 |
|
|
1961 |
|
flag float32_is_unordered(float32 a, float32 b STATUS_PARAM)
|
1962 |
|
{
|
1963 |
|
extern flag float32_is_nan( float32 a );
|
1964 |
|
if (float32_is_nan(a) || float32_is_nan(b)) {
|
|
2345 |
* but float*_is_unordered() is still called. */
|
|
2346 |
FOP_COND_D(f, (float64_is_unordered(0, FDT1, FDT0, &env->fp_status), 0))
|
|
2347 |
FOP_COND_D(un, float64_is_unordered(0, FDT1, FDT0, &env->fp_status))
|
|
2348 |
FOP_COND_D(eq, !float64_is_unordered(0, FDT1, FDT0, &env->fp_status) && float64_eq(FDT0, FDT1, &env->fp_status))
|
|
2349 |
FOP_COND_D(ueq, float64_is_unordered(0, FDT1, FDT0, &env->fp_status) || float64_eq(FDT0, FDT1, &env->fp_status))
|
|
2350 |
FOP_COND_D(olt, !float64_is_unordered(0, FDT1, FDT0, &env->fp_status) && float64_lt(FDT0, FDT1, &env->fp_status))
|
|
2351 |
FOP_COND_D(ult, float64_is_unordered(0, FDT1, FDT0, &env->fp_status) || float64_lt(FDT0, FDT1, &env->fp_status))
|
|
2352 |
FOP_COND_D(ole, !float64_is_unordered(0, FDT1, FDT0, &env->fp_status) && float64_le(FDT0, FDT1, &env->fp_status))
|
|
2353 |
FOP_COND_D(ule, float64_is_unordered(0, FDT1, FDT0, &env->fp_status) || float64_le(FDT0, FDT1, &env->fp_status))
|
|
2354 |
/* NOTE: the comma operator will make "cond" to eval to false,
|
|
2355 |
* but float*_is_unordered() is still called. */
|
|
2356 |
FOP_COND_D(sf, (float64_is_unordered(1, FDT1, FDT0, &env->fp_status), 0))
|
|
2357 |
FOP_COND_D(ngle,float64_is_unordered(1, FDT1, FDT0, &env->fp_status))
|
|
2358 |
FOP_COND_D(seq, !float64_is_unordered(1, FDT1, FDT0, &env->fp_status) && float64_eq(FDT0, FDT1, &env->fp_status))
|
|
2359 |
FOP_COND_D(ngl, float64_is_unordered(1, FDT1, FDT0, &env->fp_status) || float64_eq(FDT0, FDT1, &env->fp_status))
|
|
2360 |
FOP_COND_D(lt, !float64_is_unordered(1, FDT1, FDT0, &env->fp_status) && float64_lt(FDT0, FDT1, &env->fp_status))
|
|
2361 |
FOP_COND_D(nge, float64_is_unordered(1, FDT1, FDT0, &env->fp_status) || float64_lt(FDT0, FDT1, &env->fp_status))
|
|
2362 |
FOP_COND_D(le, !float64_is_unordered(1, FDT1, FDT0, &env->fp_status) && float64_le(FDT0, FDT1, &env->fp_status))
|
|
2363 |
FOP_COND_D(ngt, float64_is_unordered(1, FDT1, FDT0, &env->fp_status) || float64_le(FDT0, FDT1, &env->fp_status))
|
|
2364 |
|
|
2365 |
#define FOP_COND_S(op, cond) \
|
|
2366 |
void op_cmp_s_ ## op (void) \
|
|
2367 |
{ \
|
|
2368 |
int c = cond; \
|
|
2369 |
update_fcr31(); \
|
|
2370 |
if (c) \
|
|
2371 |
SET_FP_COND(PARAM1, env); \
|
|
2372 |
else \
|
|
2373 |
CLEAR_FP_COND(PARAM1, env); \
|
|
2374 |
DEBUG_FPU_STATE(); \
|
|
2375 |
RETURN(); \
|
|
2376 |
}
|
|
2377 |
|
|
2378 |
flag float32_is_unordered(int sig, float32 a, float32 b STATUS_PARAM)
|
|
2379 |
{
|
|
2380 |
extern flag float32_is_nan(float32 a);
|
|
2381 |
if (float32_is_signaling_nan(a) ||
|
|
2382 |
float32_is_signaling_nan(b) ||
|
|
2383 |
(sig && (float32_is_nan(a) || float32_is_nan(b)))) {
|
1965 |
2384 |
float_raise(float_flag_invalid, status);
|
1966 |
2385 |
return 1;
|
1967 |
|
}
|
1968 |
|
else {
|
|
2386 |
} else if (float32_is_nan(a) || float32_is_nan(b)) {
|
|
2387 |
return 1;
|
|
2388 |
} else {
|
1969 |
2389 |
return 0;
|
1970 |
2390 |
}
|
1971 |
2391 |
}
|
1972 |
2392 |
|
1973 |
2393 |
/* NOTE: the comma operator will make "cond" to eval to false,
|
1974 |
|
* but float*_is_unordered() is still called
|
1975 |
|
*/
|
1976 |
|
FOP_COND(s, f, 0, 0)
|
1977 |
|
FOP_COND(s, un, 0, float32_is_unordered(FST1, FST0, &env->fp_status))
|
1978 |
|
FOP_COND(s, eq, 0, float32_eq(FST0, FST1, &env->fp_status))
|
1979 |
|
FOP_COND(s, ueq, 0, float32_is_unordered(FST1, FST0, &env->fp_status) || float32_eq(FST0, FST1, &env->fp_status))
|
1980 |
|
FOP_COND(s, olt, 0, float32_lt(FST0, FST1, &env->fp_status))
|
1981 |
|
FOP_COND(s, ult, 0, float32_is_unordered(FST1, FST0, &env->fp_status) || float32_lt(FST0, FST1, &env->fp_status))
|
1982 |
|
FOP_COND(s, ole, 0, float32_le(FST0, FST1, &env->fp_status))
|
1983 |
|
FOP_COND(s, ule, 0, float32_is_unordered(FST1, FST0, &env->fp_status) || float32_le(FST0, FST1, &env->fp_status))
|
|
2394 |
* but float*_is_unordered() is still called. */
|
|
2395 |
FOP_COND_S(f, (float32_is_unordered(0, FST1, FST0, &env->fp_status), 0))
|
|
2396 |
FOP_COND_S(un, float32_is_unordered(0, FST1, FST0, &env->fp_status))
|
|
2397 |
FOP_COND_S(eq, !float32_is_unordered(0, FST1, FST0, &env->fp_status) && float32_eq(FST0, FST1, &env->fp_status))
|
|
2398 |
FOP_COND_S(ueq, float32_is_unordered(0, FST1, FST0, &env->fp_status) || float32_eq(FST0, FST1, &env->fp_status))
|
|
2399 |
FOP_COND_S(olt, !float32_is_unordered(0, FST1, FST0, &env->fp_status) && float32_lt(FST0, FST1, &env->fp_status))
|
|
2400 |
FOP_COND_S(ult, float32_is_unordered(0, FST1, FST0, &env->fp_status) || float32_lt(FST0, FST1, &env->fp_status))
|
|
2401 |
FOP_COND_S(ole, !float32_is_unordered(0, FST1, FST0, &env->fp_status) && float32_le(FST0, FST1, &env->fp_status))
|
|
2402 |
FOP_COND_S(ule, float32_is_unordered(0, FST1, FST0, &env->fp_status) || float32_le(FST0, FST1, &env->fp_status))
|
1984 |
2403 |
/* NOTE: the comma operator will make "cond" to eval to false,
|
1985 |
|
* but float*_is_unordered() is still called
|
1986 |
|
*/
|
1987 |
|
FOP_COND(s, sf, 1, (float32_is_unordered(FST0, FST1, &env->fp_status), 0))
|
1988 |
|
FOP_COND(s, ngle,1, float32_is_unordered(FST1, FST0, &env->fp_status))
|
1989 |
|
FOP_COND(s, seq, 1, float32_eq(FST0, FST1, &env->fp_status))
|
1990 |
|
FOP_COND(s, ngl, 1, float32_is_unordered(FST1, FST0, &env->fp_status) || float32_eq(FST0, FST1, &env->fp_status))
|
1991 |
|
FOP_COND(s, lt, 1, float32_lt(FST0, FST1, &env->fp_status))
|
1992 |
|
FOP_COND(s, nge, 1, float32_is_unordered(FST1, FST0, &env->fp_status) || float32_lt(FST0, FST1, &env->fp_status))
|
1993 |
|
FOP_COND(s, le, 1, float32_le(FST0, FST1, &env->fp_status))
|
1994 |
|
FOP_COND(s, ngt, 1, float32_is_unordered(FST1, FST0, &env->fp_status) || float32_le(FST0, FST1, &env->fp_status))
|
|
2404 |
* but float*_is_unordered() is still called. */
|
|
2405 |
FOP_COND_S(sf, (float32_is_unordered(1, FST1, FST0, &env->fp_status), 0))
|
|
2406 |
FOP_COND_S(ngle,float32_is_unordered(1, FST1, FST0, &env->fp_status))
|
|
2407 |
FOP_COND_S(seq, !float32_is_unordered(1, FST1, FST0, &env->fp_status) && float32_eq(FST0, FST1, &env->fp_status))
|
|
2408 |
FOP_COND_S(ngl, float32_is_unordered(1, FST1, FST0, &env->fp_status) || float32_eq(FST0, FST1, &env->fp_status))
|
|
2409 |
FOP_COND_S(lt, !float32_is_unordered(1, FST1, FST0, &env->fp_status) && float32_lt(FST0, FST1, &env->fp_status))
|
|
2410 |
FOP_COND_S(nge, float32_is_unordered(1, FST1, FST0, &env->fp_status) || float32_lt(FST0, FST1, &env->fp_status))
|
|
2411 |
FOP_COND_S(le, !float32_is_unordered(1, FST1, FST0, &env->fp_status) && float32_le(FST0, FST1, &env->fp_status))
|
|
2412 |
FOP_COND_S(ngt, float32_is_unordered(1, FST1, FST0, &env->fp_status) || float32_le(FST0, FST1, &env->fp_status))
|
|
2413 |
|
|
2414 |
#define FOP_COND_PS(op, condl, condh) \
|
|
2415 |
void op_cmp_ps_ ## op (void) \
|
|
2416 |
{ \
|
|
2417 |
int cl = condl; \
|
|
2418 |
int ch = condh; \
|
|
2419 |
update_fcr31(); \
|
|
2420 |
if (cl) \
|
|
2421 |
SET_FP_COND(PARAM1, env); \
|
|
2422 |
else \
|
|
2423 |
CLEAR_FP_COND(PARAM1, env); \
|
|
2424 |
if (ch) \
|
|
2425 |
SET_FP_COND(PARAM1 + 1, env); \
|
|
2426 |
else \
|
|
2427 |
CLEAR_FP_COND(PARAM1 + 1, env); \
|
|
2428 |
DEBUG_FPU_STATE(); \
|
|
2429 |
RETURN(); \
|
|
2430 |
}
|
|
2431 |
|
|
2432 |
/* NOTE: the comma operator will make "cond" to eval to false,
|
|
2433 |
* but float*_is_unordered() is still called. */
|
|
2434 |
FOP_COND_PS(f, (float32_is_unordered(0, FST1, FST0, &env->fp_status), 0),
|
|
2435 |
(float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status), 0))
|
|
2436 |
FOP_COND_PS(un, float32_is_unordered(0, FST1, FST0, &env->fp_status),
|
|
2437 |
float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status))
|
|
2438 |
FOP_COND_PS(eq, !float32_is_unordered(0, FST1, FST0, &env->fp_status) && float32_eq(FST0, FST1, &env->fp_status),
|
|
2439 |
!float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status) && float32_eq(FSTH0, FSTH1, &env->fp_status))
|
|
2440 |
FOP_COND_PS(ueq, float32_is_unordered(0, FST1, FST0, &env->fp_status) || float32_eq(FST0, FST1, &env->fp_status),
|
|
2441 |
float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status) || float32_eq(FSTH0, FSTH1, &env->fp_status))
|
|
2442 |
FOP_COND_PS(olt, !float32_is_unordered(0, FST1, FST0, &env->fp_status) && float32_lt(FST0, FST1, &env->fp_status),
|
|
2443 |
!float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status) && float32_lt(FSTH0, FSTH1, &env->fp_status))
|
|
2444 |
FOP_COND_PS(ult, float32_is_unordered(0, FST1, FST0, &env->fp_status) || float32_lt(FST0, FST1, &env->fp_status),
|
|
2445 |
float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status) || float32_lt(FSTH0, FSTH1, &env->fp_status))
|
|
2446 |
FOP_COND_PS(ole, !float32_is_unordered(0, FST1, FST0, &env->fp_status) && float32_le(FST0, FST1, &env->fp_status),
|
|
2447 |
!float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status) && float32_le(FSTH0, FSTH1, &env->fp_status))
|
|
2448 |
FOP_COND_PS(ule, float32_is_unordered(0, FST1, FST0, &env->fp_status) || float32_le(FST0, FST1, &env->fp_status),
|
|
2449 |
float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status) || float32_le(FSTH0, FSTH1, &env->fp_status))
|
|
2450 |
/* NOTE: the comma operator will make "cond" to eval to false,
|
|
2451 |
* but float*_is_unordered() is still called. */
|
|
2452 |
FOP_COND_PS(sf, (float32_is_unordered(1, FST1, FST0, &env->fp_status), 0),
|
|
2453 |
(float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status), 0))
|
|
2454 |
FOP_COND_PS(ngle,float32_is_unordered(1, FST1, FST0, &env->fp_status),
|
|
2455 |
float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status))
|
|
2456 |
FOP_COND_PS(seq, !float32_is_unordered(1, FST1, FST0, &env->fp_status) && float32_eq(FST0, FST1, &env->fp_status),
|
|
2457 |
!float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status) && float32_eq(FSTH0, FSTH1, &env->fp_status))
|
|
2458 |
FOP_COND_PS(ngl, float32_is_unordered(1, FST1, FST0, &env->fp_status) || float32_eq(FST0, FST1, &env->fp_status),
|
|
2459 |
float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status) || float32_eq(FSTH0, FSTH1, &env->fp_status))
|
|
2460 |
FOP_COND_PS(lt, !float32_is_unordered(1, FST1, FST0, &env->fp_status) && float32_lt(FST0, FST1, &env->fp_status),
|
|
2461 |
!float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status) && float32_lt(FSTH0, FSTH1, &env->fp_status))
|
|
2462 |
FOP_COND_PS(nge, float32_is_unordered(1, FST1, FST0, &env->fp_status) || float32_lt(FST0, FST1, &env->fp_status),
|
|
2463 |
float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status) || float32_lt(FSTH0, FSTH1, &env->fp_status))
|
|
2464 |
FOP_COND_PS(le, !float32_is_unordered(1, FST1, FST0, &env->fp_status) && float32_le(FST0, FST1, &env->fp_status),
|
|
2465 |
!float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status) && float32_le(FSTH0, FSTH1, &env->fp_status))
|
|
2466 |
FOP_COND_PS(ngt, float32_is_unordered(1, FST1, FST0, &env->fp_status) || float32_le(FST0, FST1, &env->fp_status),
|
|
2467 |
float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status) || float32_le(FSTH0, FSTH1, &env->fp_status))
|
1995 |
2468 |
|
1996 |
2469 |
void op_bc1f (void)
|
1997 |
2470 |
{
|
1998 |
|
T0 = ! IS_FP_COND_SET(env->fcr31);
|
|
2471 |
T0 = !IS_FP_COND_SET(PARAM1, env);
|
|
2472 |
DEBUG_FPU_STATE();
|
|
2473 |
RETURN();
|