ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/uae_cpu/fpu/rounding.h
Revision: 1.6
Committed: 2008-01-01T09:40:36Z (16 years, 5 months ago) by gbeauche
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.5: +1 -1 lines
Log Message:
Happy New Year!

File Contents

# Content
1 /*
2 * fpu/rounding.h - system-dependant FPU rounding mode and precision
3 *
4 * Basilisk II (C) 1997-2008 Christian Bauer
5 *
6 * MC68881/68040 fpu emulation
7 *
8 * Original UAE FPU, copyright 1996 Herman ten Brugge
9 * Rewrite for x86, copyright 1999-2000 Lauri Pesonen
10 * New framework, copyright 2000 Gwenole Beauchesne
11 * Adapted for JIT compilation (c) Bernd Meyer, 2000
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 */
27
28 #ifndef FPU_ROUNDING_H
29 #define FPU_ROUNDING_H
30
31 /* NOTE: this file shall be included from fpu/fpu_*.cpp */
32 #undef PUBLIC
33 #define PUBLIC extern
34
35 #undef PRIVATE
36 #define PRIVATE static
37
38 #undef FFPU
39 #define FFPU /**/
40
41 #undef FPU
42 #define FPU fpu.
43
44 /* Defaults to generic rounding mode and precision handling */
45 #define FPU_USE_GENERIC_ROUNDING_MODE
46 #define FPU_USE_GENERIC_ROUNDING_PRECISION
47
48 /* -------------------------------------------------------------------------- */
49 /* --- Selection of floating-point rounding mode and precision --- */
50 /* -------------------------------------------------------------------------- */
51
52 /* Optimized i386 fpu core must use native rounding mode */
53 #if defined(FPU_X86) && defined(USE_X87_ASSEMBLY)
54 # undef FPU_USE_GENERIC_ROUNDING_MODE
55 # define FPU_USE_X86_ROUNDING_MODE
56 #endif
57
58 /* Optimized i386 fpu core must use native rounding precision */
59 #if defined(FPU_X86) && defined(USE_X87_ASSEMBLY)
60 # undef FPU_USE_GENERIC_ROUNDING_PRECISION
61 # define FPU_USE_X86_ROUNDING_PRECISION
62 #endif
63
64 #if 0 // gb-- FIXME: that doesn't work
65 /* IEEE-based fpu core can have native rounding mode on i386 */
66 #if defined(FPU_IEEE) && defined(USE_X87_ASSEMBLY)
67 # undef FPU_USE_GENERIC_ROUNDING_MODE
68 # define FPU_USE_X86_ROUNDING_MODE
69 #endif
70
71 /* IEEE-based fpu core can have native rounding precision on i386 */
72 #if defined(FPU_IEEE) && defined(USE_X87_ASSEMBLY)
73 # undef FPU_USE_GENERIC_ROUNDING_PRECISION
74 # define FPU_USE_X86_ROUNDING_PRECISION
75 #endif
76 #endif
77
78 /* -------------------------------------------------------------------------- */
79 /* --- Sanity checks --- */
80 /* -------------------------------------------------------------------------- */
81
82 /* X86 rounding mode and precision work together */
83 #if defined(FPU_USE_X86_ROUNDING_MODE) && defined(FPU_USE_X86_ROUNDING_PRECISION)
84 # define FPU_USE_X86_ROUNDING
85 # define CW_INITIAL (CW_RESET|CW_X|CW_PC_EXTENDED|CW_RC_NEAR|CW_PM|CW_UM|CW_OM|CW_ZM|CW_DM|CW_IM)
86 PRIVATE uae_u32 x86_control_word;
87 #endif
88
89 /* Control word -- rounding mode */
90 #ifdef FPU_USE_X86_ROUNDING_MODE
91 PUBLIC const uae_u32 x86_control_word_rm_mac2host[];
92 #endif
93
94 /* Control word -- rounding precision */
95 #ifdef FPU_USE_X86_ROUNDING_PRECISION
96 PUBLIC const uae_u32 x86_control_word_rp_mac2host[];
97 #endif
98
99 #if defined(FPU_USE_X86_ROUNDING_MODE) && defined(FPU_USE_X86_ROUNDING_PRECISION)
100 /* Set host control word for rounding mode and rounding precision */
101 PRIVATE inline void set_host_control_word(void)
102 {
103 /*
104 Exception enable byte is ignored, but the same value is returned
105 that was previously set.
106 */
107 x86_control_word
108 = (x86_control_word & ~(X86_ROUNDING_MODE|X86_ROUNDING_PRECISION))
109 | x86_control_word_rm_mac2host[(FPU fpcr.rounding_mode & FPCR_ROUNDING_MODE) >> 4]
110 | x86_control_word_rp_mac2host[(FPU fpcr.rounding_precision & FPCR_ROUNDING_PRECISION) >> 6]
111 ;
112 __asm__ __volatile__("fldcw %0" : : "m" (x86_control_word));
113 }
114 #endif
115
116 /* -------------------------------------------------------------------------- */
117 /* --- Generic rounding mode and precision --- */
118 /* -------------------------------------------------------------------------- */
119
120 #if defined(FPU_USE_GENERIC_ROUNDING_MODE) && defined(FPU_USE_GENERIC_ROUNDING_PRECISION)
121 /* Set host control word for rounding mode and rounding precision */
122 PRIVATE inline void set_host_control_word(void)
123 { }
124 #endif
125
126 /* -------------------------------------------------------------------------- */
127 /* --- Common rounding mode and precision --- */
128 /* -------------------------------------------------------------------------- */
129
130 #if defined(FPU_USE_GENERIC_ROUNDING_MODE) || defined(FPU_USE_X86_ROUNDING_MODE)
131
132 /* Return the current rounding mode in m68k format */
133 static inline uae_u32 FFPU get_rounding_mode(void)
134 { return FPU fpcr.rounding_mode; }
135
136 /* Convert and set to native rounding mode */
137 static inline void FFPU set_rounding_mode(uae_u32 new_rounding_mode)
138 { FPU fpcr.rounding_mode = new_rounding_mode; }
139
140 #endif
141
142 #if defined(FPU_USE_GENERIC_ROUNDING_PRECISION) || defined(FPU_USE_X86_ROUNDING_PRECISION)
143
144 /* Return the current rounding precision in m68k format */
145 static inline uae_u32 FFPU get_rounding_precision(void)
146 { return FPU fpcr.rounding_precision; }
147
148 /* Convert and set to native rounding precision */
149 static inline void FFPU set_rounding_precision(uae_u32 new_rounding_precision)
150 { FPU fpcr.rounding_precision = new_rounding_precision; }
151
152 #endif
153
154 #endif /* FPU_ROUNDING_H */