4 * Copyright (c) 2006-2007 CodeSourcery
5 * Written by Paul Brook
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 #include "qemu/osdep.h"
23 #include "exec/helper-proto.h"
24 #include "exec/exec-all.h"
25 #include "exec/cpu_ldst.h"
26 #include "softfloat.h"
29 * Undefined offsets may be different on various FPU.
30 * On 68040 they return 0.0 (floatx80_zero)
33 static const floatx80 fpu_rom
[128] = {
34 [0x00] = make_floatx80_init(0x4000, 0xc90fdaa22168c235ULL
), /* Pi */
35 [0x0b] = make_floatx80_init(0x3ffd, 0x9a209a84fbcff798ULL
), /* Log10(2) */
36 [0x0c] = make_floatx80_init(0x4000, 0xadf85458a2bb4a9aULL
), /* e */
37 [0x0d] = make_floatx80_init(0x3fff, 0xb8aa3b295c17f0bcULL
), /* Log2(e) */
38 [0x0e] = make_floatx80_init(0x3ffd, 0xde5bd8a937287195ULL
), /* Log10(e) */
39 [0x0f] = make_floatx80_init(0x0000, 0x0000000000000000ULL
), /* Zero */
40 [0x30] = make_floatx80_init(0x3ffe, 0xb17217f7d1cf79acULL
), /* ln(2) */
41 [0x31] = make_floatx80_init(0x4000, 0x935d8dddaaa8ac17ULL
), /* ln(10) */
42 [0x32] = make_floatx80_init(0x3fff, 0x8000000000000000ULL
), /* 10^0 */
43 [0x33] = make_floatx80_init(0x4002, 0xa000000000000000ULL
), /* 10^1 */
44 [0x34] = make_floatx80_init(0x4005, 0xc800000000000000ULL
), /* 10^2 */
45 [0x35] = make_floatx80_init(0x400c, 0x9c40000000000000ULL
), /* 10^4 */
46 [0x36] = make_floatx80_init(0x4019, 0xbebc200000000000ULL
), /* 10^8 */
47 [0x37] = make_floatx80_init(0x4034, 0x8e1bc9bf04000000ULL
), /* 10^16 */
48 [0x38] = make_floatx80_init(0x4069, 0x9dc5ada82b70b59eULL
), /* 10^32 */
49 [0x39] = make_floatx80_init(0x40d3, 0xc2781f49ffcfa6d5ULL
), /* 10^64 */
50 [0x3a] = make_floatx80_init(0x41a8, 0x93ba47c980e98ce0ULL
), /* 10^128 */
51 [0x3b] = make_floatx80_init(0x4351, 0xaa7eebfb9df9de8eULL
), /* 10^256 */
52 [0x3c] = make_floatx80_init(0x46a3, 0xe319a0aea60e91c7ULL
), /* 10^512 */
53 [0x3d] = make_floatx80_init(0x4d48, 0xc976758681750c17ULL
), /* 10^1024 */
54 [0x3e] = make_floatx80_init(0x5a92, 0x9e8b3b5dc53d5de5ULL
), /* 10^2048 */
55 [0x3f] = make_floatx80_init(0x7525, 0xc46052028a20979bULL
), /* 10^4096 */
58 int32_t HELPER(reds32
)(CPUM68KState
*env
, FPReg
*val
)
60 return floatx80_to_int32(val
->d
, &env
->fp_status
);
63 float32
HELPER(redf32
)(CPUM68KState
*env
, FPReg
*val
)
65 return floatx80_to_float32(val
->d
, &env
->fp_status
);
68 void HELPER(exts32
)(CPUM68KState
*env
, FPReg
*res
, int32_t val
)
70 res
->d
= int32_to_floatx80(val
, &env
->fp_status
);
73 void HELPER(extf32
)(CPUM68KState
*env
, FPReg
*res
, float32 val
)
75 res
->d
= float32_to_floatx80(val
, &env
->fp_status
);
78 void HELPER(extf64
)(CPUM68KState
*env
, FPReg
*res
, float64 val
)
80 res
->d
= float64_to_floatx80(val
, &env
->fp_status
);
83 float64
HELPER(redf64
)(CPUM68KState
*env
, FPReg
*val
)
85 return floatx80_to_float64(val
->d
, &env
->fp_status
);
88 void HELPER(firound
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val
)
90 res
->d
= floatx80_round_to_int(val
->d
, &env
->fp_status
);
93 static void m68k_restore_precision_mode(CPUM68KState
*env
)
95 switch (env
->fpcr
& FPCR_PREC_MASK
) {
96 case FPCR_PREC_X
: /* extended */
97 set_floatx80_rounding_precision(floatx80_precision_x
, &env
->fp_status
);
99 case FPCR_PREC_S
: /* single */
100 set_floatx80_rounding_precision(floatx80_precision_s
, &env
->fp_status
);
102 case FPCR_PREC_D
: /* double */
103 set_floatx80_rounding_precision(floatx80_precision_d
, &env
->fp_status
);
105 case FPCR_PREC_U
: /* undefined */
111 static void cf_restore_precision_mode(CPUM68KState
*env
)
113 if (env
->fpcr
& FPCR_PREC_S
) { /* single */
114 set_floatx80_rounding_precision(floatx80_precision_s
, &env
->fp_status
);
115 } else { /* double */
116 set_floatx80_rounding_precision(floatx80_precision_d
, &env
->fp_status
);
120 static void restore_rounding_mode(CPUM68KState
*env
)
122 switch (env
->fpcr
& FPCR_RND_MASK
) {
123 case FPCR_RND_N
: /* round to nearest */
124 set_float_rounding_mode(float_round_nearest_even
, &env
->fp_status
);
126 case FPCR_RND_Z
: /* round to zero */
127 set_float_rounding_mode(float_round_to_zero
, &env
->fp_status
);
129 case FPCR_RND_M
: /* round toward minus infinity */
130 set_float_rounding_mode(float_round_down
, &env
->fp_status
);
132 case FPCR_RND_P
: /* round toward positive infinity */
133 set_float_rounding_mode(float_round_up
, &env
->fp_status
);
138 void cpu_m68k_restore_fp_status(CPUM68KState
*env
)
140 if (m68k_feature(env
, M68K_FEATURE_CF_FPU
)) {
141 cf_restore_precision_mode(env
);
143 m68k_restore_precision_mode(env
);
145 restore_rounding_mode(env
);
148 void cpu_m68k_set_fpcr(CPUM68KState
*env
, uint32_t val
)
150 env
->fpcr
= val
& 0xffff;
151 cpu_m68k_restore_fp_status(env
);
154 void HELPER(fitrunc
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val
)
156 FloatRoundMode rounding_mode
= get_float_rounding_mode(&env
->fp_status
);
157 set_float_rounding_mode(float_round_to_zero
, &env
->fp_status
);
158 res
->d
= floatx80_round_to_int(val
->d
, &env
->fp_status
);
159 set_float_rounding_mode(rounding_mode
, &env
->fp_status
);
162 void HELPER(set_fpcr
)(CPUM68KState
*env
, uint32_t val
)
164 cpu_m68k_set_fpcr(env
, val
);
167 /* Convert host exception flags to cpu_m68k form. */
168 static int cpu_m68k_exceptbits_from_host(int host_bits
)
172 if (host_bits
& float_flag_invalid
) {
175 if (host_bits
& float_flag_overflow
) {
178 if (host_bits
& (float_flag_underflow
| float_flag_output_denormal
)) {
181 if (host_bits
& float_flag_divbyzero
) {
184 if (host_bits
& float_flag_inexact
) {
190 /* Convert cpu_m68k exception flags to target form. */
191 static int cpu_m68k_exceptbits_to_host(int target_bits
)
195 if (target_bits
& 0x80) {
196 host_bits
|= float_flag_invalid
;
198 if (target_bits
& 0x40) {
199 host_bits
|= float_flag_overflow
;
201 if (target_bits
& 0x20) {
202 host_bits
|= float_flag_underflow
;
204 if (target_bits
& 0x10) {
205 host_bits
|= float_flag_divbyzero
;
207 if (target_bits
& 0x08) {
208 host_bits
|= float_flag_inexact
;
213 uint32_t cpu_m68k_get_fpsr(CPUM68KState
*env
)
215 int host_flags
= get_float_exception_flags(&env
->fp_status
);
216 int target_flags
= cpu_m68k_exceptbits_from_host(host_flags
);
217 int except
= (env
->fpsr
& ~(0xf8)) | target_flags
;
221 uint32_t HELPER(get_fpsr
)(CPUM68KState
*env
)
223 return cpu_m68k_get_fpsr(env
);
226 void cpu_m68k_set_fpsr(CPUM68KState
*env
, uint32_t val
)
230 int host_flags
= cpu_m68k_exceptbits_to_host((int) env
->fpsr
);
231 set_float_exception_flags(host_flags
, &env
->fp_status
);
234 void HELPER(set_fpsr
)(CPUM68KState
*env
, uint32_t val
)
236 cpu_m68k_set_fpsr(env
, val
);
239 #define PREC_BEGIN(prec) \
241 FloatX80RoundPrec old = \
242 get_floatx80_rounding_precision(&env->fp_status); \
243 set_floatx80_rounding_precision(prec, &env->fp_status) \
246 set_floatx80_rounding_precision(old, &env->fp_status); \
249 void HELPER(fsround
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val
)
251 PREC_BEGIN(floatx80_precision_s
);
252 res
->d
= floatx80_round(val
->d
, &env
->fp_status
);
256 void HELPER(fdround
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val
)
258 PREC_BEGIN(floatx80_precision_d
);
259 res
->d
= floatx80_round(val
->d
, &env
->fp_status
);
263 void HELPER(fsqrt
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val
)
265 res
->d
= floatx80_sqrt(val
->d
, &env
->fp_status
);
268 void HELPER(fssqrt
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val
)
270 PREC_BEGIN(floatx80_precision_s
);
271 res
->d
= floatx80_sqrt(val
->d
, &env
->fp_status
);
275 void HELPER(fdsqrt
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val
)
277 PREC_BEGIN(floatx80_precision_d
);
278 res
->d
= floatx80_sqrt(val
->d
, &env
->fp_status
);
282 void HELPER(fabs
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val
)
284 res
->d
= floatx80_round(floatx80_abs(val
->d
), &env
->fp_status
);
287 void HELPER(fsabs
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val
)
289 PREC_BEGIN(floatx80_precision_s
);
290 res
->d
= floatx80_round(floatx80_abs(val
->d
), &env
->fp_status
);
294 void HELPER(fdabs
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val
)
296 PREC_BEGIN(floatx80_precision_d
);
297 res
->d
= floatx80_round(floatx80_abs(val
->d
), &env
->fp_status
);
301 void HELPER(fneg
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val
)
303 res
->d
= floatx80_round(floatx80_chs(val
->d
), &env
->fp_status
);
306 void HELPER(fsneg
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val
)
308 PREC_BEGIN(floatx80_precision_s
);
309 res
->d
= floatx80_round(floatx80_chs(val
->d
), &env
->fp_status
);
313 void HELPER(fdneg
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val
)
315 PREC_BEGIN(floatx80_precision_d
);
316 res
->d
= floatx80_round(floatx80_chs(val
->d
), &env
->fp_status
);
320 void HELPER(fadd
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val0
, FPReg
*val1
)
322 res
->d
= floatx80_add(val0
->d
, val1
->d
, &env
->fp_status
);
325 void HELPER(fsadd
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val0
, FPReg
*val1
)
327 PREC_BEGIN(floatx80_precision_s
);
328 res
->d
= floatx80_add(val0
->d
, val1
->d
, &env
->fp_status
);
332 void HELPER(fdadd
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val0
, FPReg
*val1
)
334 PREC_BEGIN(floatx80_precision_d
);
335 res
->d
= floatx80_add(val0
->d
, val1
->d
, &env
->fp_status
);
339 void HELPER(fsub
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val0
, FPReg
*val1
)
341 res
->d
= floatx80_sub(val1
->d
, val0
->d
, &env
->fp_status
);
344 void HELPER(fssub
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val0
, FPReg
*val1
)
346 PREC_BEGIN(floatx80_precision_s
);
347 res
->d
= floatx80_sub(val1
->d
, val0
->d
, &env
->fp_status
);
351 void HELPER(fdsub
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val0
, FPReg
*val1
)
353 PREC_BEGIN(floatx80_precision_d
);
354 res
->d
= floatx80_sub(val1
->d
, val0
->d
, &env
->fp_status
);
358 void HELPER(fmul
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val0
, FPReg
*val1
)
360 res
->d
= floatx80_mul(val0
->d
, val1
->d
, &env
->fp_status
);
363 void HELPER(fsmul
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val0
, FPReg
*val1
)
365 PREC_BEGIN(floatx80_precision_s
);
366 res
->d
= floatx80_mul(val0
->d
, val1
->d
, &env
->fp_status
);
370 void HELPER(fdmul
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val0
, FPReg
*val1
)
372 PREC_BEGIN(floatx80_precision_d
);
373 res
->d
= floatx80_mul(val0
->d
, val1
->d
, &env
->fp_status
);
377 void HELPER(fsglmul
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val0
, FPReg
*val1
)
379 FloatRoundMode rounding_mode
= get_float_rounding_mode(&env
->fp_status
);
382 PREC_BEGIN(floatx80_precision_s
);
383 set_float_rounding_mode(float_round_to_zero
, &env
->fp_status
);
384 a
= floatx80_round(val0
->d
, &env
->fp_status
);
385 b
= floatx80_round(val1
->d
, &env
->fp_status
);
386 set_float_rounding_mode(rounding_mode
, &env
->fp_status
);
387 res
->d
= floatx80_mul(a
, b
, &env
->fp_status
);
391 void HELPER(fdiv
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val0
, FPReg
*val1
)
393 res
->d
= floatx80_div(val1
->d
, val0
->d
, &env
->fp_status
);
396 void HELPER(fsdiv
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val0
, FPReg
*val1
)
398 PREC_BEGIN(floatx80_precision_s
);
399 res
->d
= floatx80_div(val1
->d
, val0
->d
, &env
->fp_status
);
403 void HELPER(fddiv
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val0
, FPReg
*val1
)
405 PREC_BEGIN(floatx80_precision_d
);
406 res
->d
= floatx80_div(val1
->d
, val0
->d
, &env
->fp_status
);
410 void HELPER(fsgldiv
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val0
, FPReg
*val1
)
412 FloatRoundMode rounding_mode
= get_float_rounding_mode(&env
->fp_status
);
415 PREC_BEGIN(floatx80_precision_s
);
416 set_float_rounding_mode(float_round_to_zero
, &env
->fp_status
);
417 a
= floatx80_round(val1
->d
, &env
->fp_status
);
418 b
= floatx80_round(val0
->d
, &env
->fp_status
);
419 set_float_rounding_mode(rounding_mode
, &env
->fp_status
);
420 res
->d
= floatx80_div(a
, b
, &env
->fp_status
);
424 static int float_comp_to_cc(FloatRelation float_compare
)
426 switch (float_compare
) {
427 case float_relation_equal
:
429 case float_relation_less
:
431 case float_relation_unordered
:
433 case float_relation_greater
:
436 g_assert_not_reached();
440 void HELPER(fcmp
)(CPUM68KState
*env
, FPReg
*val0
, FPReg
*val1
)
442 FloatRelation float_compare
;
444 float_compare
= floatx80_compare(val1
->d
, val0
->d
, &env
->fp_status
);
445 env
->fpsr
= (env
->fpsr
& ~FPSR_CC_MASK
) | float_comp_to_cc(float_compare
);
448 void HELPER(ftst
)(CPUM68KState
*env
, FPReg
*val
)
452 if (floatx80_is_neg(val
->d
)) {
456 if (floatx80_is_any_nan(val
->d
)) {
458 } else if (floatx80_is_infinity(val
->d
)) {
460 } else if (floatx80_is_zero(val
->d
)) {
463 env
->fpsr
= (env
->fpsr
& ~FPSR_CC_MASK
) | cc
;
466 void HELPER(fconst
)(CPUM68KState
*env
, FPReg
*val
, uint32_t offset
)
468 val
->d
= fpu_rom
[offset
];
471 typedef int (*float_access
)(CPUM68KState
*env
, uint32_t addr
, FPReg
*fp
,
474 static uint32_t fmovem_predec(CPUM68KState
*env
, uint32_t addr
, uint32_t mask
,
475 float_access access_fn
)
477 uintptr_t ra
= GETPC();
480 for (i
= 7; i
>= 0; i
--, mask
<<= 1) {
482 size
= access_fn(env
, addr
, &env
->fregs
[i
], ra
);
483 if ((mask
& 0xff) != 0x80) {
492 static uint32_t fmovem_postinc(CPUM68KState
*env
, uint32_t addr
, uint32_t mask
,
493 float_access access_fn
)
495 uintptr_t ra
= GETPC();
498 for (i
= 0; i
< 8; i
++, mask
<<= 1) {
500 size
= access_fn(env
, addr
, &env
->fregs
[i
], ra
);
508 static int cpu_ld_floatx80_ra(CPUM68KState
*env
, uint32_t addr
, FPReg
*fp
,
514 high
= cpu_ldl_data_ra(env
, addr
, ra
);
515 low
= cpu_ldq_data_ra(env
, addr
+ 4, ra
);
517 fp
->l
.upper
= high
>> 16;
523 static int cpu_st_floatx80_ra(CPUM68KState
*env
, uint32_t addr
, FPReg
*fp
,
526 cpu_stl_data_ra(env
, addr
, fp
->l
.upper
<< 16, ra
);
527 cpu_stq_data_ra(env
, addr
+ 4, fp
->l
.lower
, ra
);
532 static int cpu_ld_float64_ra(CPUM68KState
*env
, uint32_t addr
, FPReg
*fp
,
537 val
= cpu_ldq_data_ra(env
, addr
, ra
);
538 fp
->d
= float64_to_floatx80(*(float64
*)&val
, &env
->fp_status
);
543 static int cpu_st_float64_ra(CPUM68KState
*env
, uint32_t addr
, FPReg
*fp
,
548 val
= floatx80_to_float64(fp
->d
, &env
->fp_status
);
549 cpu_stq_data_ra(env
, addr
, *(uint64_t *)&val
, ra
);
554 uint32_t HELPER(fmovemx_st_predec
)(CPUM68KState
*env
, uint32_t addr
,
557 return fmovem_predec(env
, addr
, mask
, cpu_st_floatx80_ra
);
560 uint32_t HELPER(fmovemx_st_postinc
)(CPUM68KState
*env
, uint32_t addr
,
563 return fmovem_postinc(env
, addr
, mask
, cpu_st_floatx80_ra
);
566 uint32_t HELPER(fmovemx_ld_postinc
)(CPUM68KState
*env
, uint32_t addr
,
569 return fmovem_postinc(env
, addr
, mask
, cpu_ld_floatx80_ra
);
572 uint32_t HELPER(fmovemd_st_predec
)(CPUM68KState
*env
, uint32_t addr
,
575 return fmovem_predec(env
, addr
, mask
, cpu_st_float64_ra
);
578 uint32_t HELPER(fmovemd_st_postinc
)(CPUM68KState
*env
, uint32_t addr
,
581 return fmovem_postinc(env
, addr
, mask
, cpu_st_float64_ra
);
584 uint32_t HELPER(fmovemd_ld_postinc
)(CPUM68KState
*env
, uint32_t addr
,
587 return fmovem_postinc(env
, addr
, mask
, cpu_ld_float64_ra
);
590 static void make_quotient(CPUM68KState
*env
, int sign
, uint32_t quotient
)
592 quotient
= (sign
<< 7) | (quotient
& 0x7f);
593 env
->fpsr
= (env
->fpsr
& ~FPSR_QT_MASK
) | (quotient
<< FPSR_QT_SHIFT
);
596 void HELPER(fmod
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val0
, FPReg
*val1
)
599 int sign
= extractFloatx80Sign(val1
->d
) ^ extractFloatx80Sign(val0
->d
);
601 res
->d
= floatx80_modrem(val1
->d
, val0
->d
, true, "ient
,
604 if (floatx80_is_any_nan(res
->d
)) {
608 make_quotient(env
, sign
, quotient
);
611 void HELPER(frem
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val0
, FPReg
*val1
)
616 fp_rem
= floatx80_rem(val1
->d
, val0
->d
, &env
->fp_status
);
617 if (!floatx80_is_any_nan(fp_rem
)) {
618 float_status fp_status
= { };
622 /* Calculate quotient directly using round to nearest mode */
623 set_float_rounding_mode(float_round_nearest_even
, &fp_status
);
624 set_floatx80_rounding_precision(
625 get_floatx80_rounding_precision(&env
->fp_status
), &fp_status
);
626 fp_quot
.d
= floatx80_div(val1
->d
, val0
->d
, &fp_status
);
628 sign
= extractFloatx80Sign(fp_quot
.d
);
629 quotient
= floatx80_to_int32(floatx80_abs(fp_quot
.d
), &env
->fp_status
);
630 make_quotient(env
, sign
, quotient
);
636 void HELPER(fgetexp
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val
)
638 res
->d
= floatx80_getexp(val
->d
, &env
->fp_status
);
641 void HELPER(fgetman
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val
)
643 res
->d
= floatx80_getman(val
->d
, &env
->fp_status
);
646 void HELPER(fscale
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val0
, FPReg
*val1
)
648 res
->d
= floatx80_scale(val1
->d
, val0
->d
, &env
->fp_status
);
651 void HELPER(flognp1
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val
)
653 res
->d
= floatx80_lognp1(val
->d
, &env
->fp_status
);
656 void HELPER(flogn
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val
)
658 res
->d
= floatx80_logn(val
->d
, &env
->fp_status
);
661 void HELPER(flog10
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val
)
663 res
->d
= floatx80_log10(val
->d
, &env
->fp_status
);
666 void HELPER(flog2
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val
)
668 res
->d
= floatx80_log2(val
->d
, &env
->fp_status
);
671 void HELPER(fetox
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val
)
673 res
->d
= floatx80_etox(val
->d
, &env
->fp_status
);
676 void HELPER(ftwotox
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val
)
678 res
->d
= floatx80_twotox(val
->d
, &env
->fp_status
);
681 void HELPER(ftentox
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val
)
683 res
->d
= floatx80_tentox(val
->d
, &env
->fp_status
);
686 void HELPER(ftan
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val
)
688 res
->d
= floatx80_tan(val
->d
, &env
->fp_status
);
691 void HELPER(fsin
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val
)
693 res
->d
= floatx80_sin(val
->d
, &env
->fp_status
);
696 void HELPER(fcos
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val
)
698 res
->d
= floatx80_cos(val
->d
, &env
->fp_status
);
701 void HELPER(fsincos
)(CPUM68KState
*env
, FPReg
*res0
, FPReg
*res1
, FPReg
*val
)
705 * If res0 and res1 specify the same floating-point data register,
706 * the sine result is stored in the register, and the cosine
707 * result is discarded.
709 res1
->d
= floatx80_cos(a
, &env
->fp_status
);
710 res0
->d
= floatx80_sin(a
, &env
->fp_status
);
713 void HELPER(fatan
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val
)
715 res
->d
= floatx80_atan(val
->d
, &env
->fp_status
);
718 void HELPER(fasin
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val
)
720 res
->d
= floatx80_asin(val
->d
, &env
->fp_status
);
723 void HELPER(facos
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val
)
725 res
->d
= floatx80_acos(val
->d
, &env
->fp_status
);
728 void HELPER(fatanh
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val
)
730 res
->d
= floatx80_atanh(val
->d
, &env
->fp_status
);
733 void HELPER(fetoxm1
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val
)
735 res
->d
= floatx80_etoxm1(val
->d
, &env
->fp_status
);
738 void HELPER(ftanh
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val
)
740 res
->d
= floatx80_tanh(val
->d
, &env
->fp_status
);
743 void HELPER(fsinh
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val
)
745 res
->d
= floatx80_sinh(val
->d
, &env
->fp_status
);
748 void HELPER(fcosh
)(CPUM68KState
*env
, FPReg
*res
, FPReg
*val
)
750 res
->d
= floatx80_cosh(val
->d
, &env
->fp_status
);