ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/uae_cpu/fpu/rounding.h
Revision: 1.3
Committed: 2002-11-16T15:28:25Z (21 years, 8 months ago) by gbeauche
Content type: text/plain
Branch: MAIN
CVS Tags: nigel-build-12, nigel-build-13
Changes since 1.2: +4 -4 lines
Log Message:
Use old x87 FPU stack on x86-64 too because we now use long doubles there for
better accuracy. Aka. prefer compatibility over speed.

File Contents

# User Rev Content
1 gbeauche 1.1 /*
2     * fpu/rounding.h - system-dependant FPU rounding mode and precision
3     *
4     * Basilisk II (C) 1997-1999 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 gbeauche 1.3 #if defined(FPU_X86) && defined(USE_X87_ASSEMBLY)
54 gbeauche 1.1 # 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 gbeauche 1.3 #if defined(FPU_X86) && defined(USE_X87_ASSEMBLY)
60 gbeauche 1.1 # 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 gbeauche 1.3 #if defined(FPU_IEEE) && defined(USE_X87_ASSEMBLY)
67 gbeauche 1.1 # 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 gbeauche 1.3 #if defined(FPU_IEEE) && defined(USE_X87_ASSEMBLY)
73 gbeauche 1.1 # 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 gbeauche 1.2 static inline uae_u32 FFPU get_rounding_mode(void)
134 gbeauche 1.1 { return FPU fpcr.rounding_mode; }
135    
136     /* Convert and set to native rounding mode */
137 gbeauche 1.2 static inline void FFPU set_rounding_mode(uae_u32 new_rounding_mode)
138 gbeauche 1.1 { 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 gbeauche 1.2 static inline uae_u32 FFPU get_rounding_precision(void)
146 gbeauche 1.1 { return FPU fpcr.rounding_precision; }
147    
148     /* Convert and set to native rounding precision */
149 gbeauche 1.2 static inline void FFPU set_rounding_precision(uae_u32 new_rounding_precision)
150 gbeauche 1.1 { FPU fpcr.rounding_precision = new_rounding_precision; }
151    
152     #endif
153    
154     #endif /* FPU_ROUNDING_H */