1 /*
2 * UAE - The Un*x Amiga Emulator
3 *
4 * MC68881 emulation
5 * Support functions for IEEE 754-compatible host CPUs.
6 * These functions use a GCC extension (type punning through unions) and
7 * should only be compiled with compilers that support this.
8 *
9 * Copyright 1999 Sam Jordan
10 * Copyright 2007 Richard Drummond
11 *
12 * Note: Type punning through unions is no longer a gcc extension.
13 * As long as we are only compiling with strict C99/C11 this method is
14 * perfectly legal *and* portable. It was made explicit with C99/TC3,
15 * which added the following footnote to section 6.5.2.3:
16 * "If the member used to access the contents of a union object is not
17 * the same as the member last used to store a value in the object,
18 * the appropriate part of the object representation of the value is
19 * reinterpreted as an object representation in the new type as
20 * described in 6.2.6 (a process sometimes called "type punning").
21 * This might be a trap representation."
22 * Annex J still lists it as unspecified behavior, which is a known defect
23 * and has been corrected with C11, which changed
24 * "The value of a union member other than the last one stored into
25 * [is unspecified]"
26 * to
27 * "The values of bytes that correspond to union members other than the
28 * one last stored into [are unspecified]"
29 * It's not that big a deal as the annex is only informative, not normative.
30 * - Sven
31 */
32
33 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
to_single(uae_u32 value)34 STATIC_INLINE double to_single (uae_u32 value)
35 {
36 union {
37 float f;
38 uae_u32 u;
39 } val;
40
41 val.u = value;
42 return val.f;
43 }
44
from_single(double src)45 STATIC_INLINE uae_u32 from_single (double src)
46 {
47 union {
48 float f;
49 uae_u32 u;
50 } val;
51
52 val.f = src;
53 return val.u;
54 }
55
to_double(uae_u32 wrd1,uae_u32 wrd2)56 STATIC_INLINE double to_double (uae_u32 wrd1, uae_u32 wrd2)
57 {
58 union {
59 double d;
60 uae_u32 u[2];
61 } val;
62
63 #ifdef WORDS_BIGENDIAN
64 val.u[0] = wrd1;
65 val.u[1] = wrd2;
66 #else
67 val.u[1] = wrd1;
68 val.u[0] = wrd2;
69 #endif
70 return val.d;
71 }
72
from_double(double src,uae_u32 * wrd1,uae_u32 * wrd2)73 STATIC_INLINE void from_double (double src, uae_u32 * wrd1, uae_u32 * wrd2)
74 {
75 union {
76 double d;
77 uae_u32 u[2];
78 } val;
79
80 val.d = src;
81 #ifdef WORDS_BIGENDIAN
82 *wrd1 = val.u[0];
83 *wrd2 = val.u[1];
84 #else
85 *wrd1 = val.u[1];
86 *wrd2 = val.u[0];
87 #endif
88 }
89
90 #define HAVE_from_double
91 #define HAVE_to_double
92 #define HAVE_from_single
93 #define HAVE_to_single
94 #endif // C99 and newer
95
96 /* Get the rest of the conversion functions defined. */
97 #include "fpp-unknown.h"
98