ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/uae_cpu/fpu/flags.cpp
Revision: 1.4
Committed: 2008-01-01T09:40:36Z (16 years, 11 months ago) by gbeauche
Branch: MAIN
CVS Tags: HEAD
Changes since 1.3: +1 -1 lines
Log Message:
Happy New Year!

File Contents

# User Rev Content
1 gbeauche 1.1 /*
2     * fpu/flags.cpp - Floating-point flags
3     *
4 gbeauche 1.4 * Basilisk II (C) 1997-2008 Christian Bauer
5 gbeauche 1.1 *
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     /* NOTE: this file shall be included only from fpu/fpu_*.cpp */
29     #undef PRIVATE
30     #define PRIVATE /**/
31    
32     #undef PUBLIC
33     #define PUBLIC /**/
34    
35     #undef FFPU
36     #define FFPU /**/
37    
38     #undef FPU
39     #define FPU fpu.
40    
41     /* -------------------------------------------------------------------------- */
42     /* --- Native X86 floating-point flags --- */
43     /* -------------------------------------------------------------------------- */
44    
45     #ifdef FPU_USE_X86_FLAGS
46    
47     /* Initialization */
48     void FFPU fpu_init_native_fflags(void)
49     {
50     // Adapted from fpu_x86.cpp
51     #define SW_Z_I_NAN_MASK (SW_C0|SW_C2|SW_C3)
52     #define SW_Z (SW_C3)
53     #define SW_I (SW_C0|SW_C2)
54     #define SW_NAN (SW_C0)
55     #define SW_FINITE (SW_C2)
56     #define SW_EMPTY_REGISTER (SW_C0|SW_C3)
57     #define SW_DENORMAL (SW_C2|SW_C3)
58     #define SW_UNSUPPORTED (0)
59     #define SW_N (SW_C1)
60    
61     // Sanity checks
62     #if (SW_Z != NATIVE_FFLAG_ZERO)
63     #error "Incorrect X86 Z fflag"
64     #endif
65     #if (SW_I != NATIVE_FFLAG_INFINITY)
66     #error "Incorrect X86 I fflag"
67     #endif
68     #if (SW_N != NATIVE_FFLAG_NEGATIVE)
69     #error "Incorrect X86 N fflag"
70     #endif
71     #if (SW_NAN != NATIVE_FFLAG_NAN)
72     #error "Incorrect X86 NAN fflag"
73     #endif
74    
75     // Native status word to m68k mappings
76     for (uae_u32 i = 0; i < 0x48; i++) {
77     to_m68k_fpcond[i] = 0;
78     const uae_u32 native_fpcond = i << 8;
79     switch (native_fpcond & SW_Z_I_NAN_MASK) {
80     #ifndef FPU_UAE
81     // gb-- enabling it would lead to incorrect drawing of digits
82     // in Speedometer Performance Test
83     case SW_UNSUPPORTED:
84     #endif
85     case SW_NAN:
86     case SW_EMPTY_REGISTER:
87     to_m68k_fpcond[i] |= FPSR_CCB_NAN;
88     break;
89     case SW_FINITE:
90     case SW_DENORMAL:
91     break;
92     case SW_I:
93     to_m68k_fpcond[i] |= FPSR_CCB_INFINITY;
94     break;
95     case SW_Z:
96     to_m68k_fpcond[i] |= FPSR_CCB_ZERO;
97     break;
98     }
99     if (native_fpcond & SW_N)
100     to_m68k_fpcond[i] |= FPSR_CCB_NEGATIVE;
101     }
102    
103     // m68k to native status word mappings
104     for (uae_u32 i = 0; i < 0x10; i++) {
105     const uae_u32 m68k_fpcond = i << 24;
106     if (m68k_fpcond & FPSR_CCB_NAN)
107     to_host_fpcond[i] = SW_NAN;
108     else if (m68k_fpcond & FPSR_CCB_ZERO)
109     to_host_fpcond[i] = SW_Z;
110     else if (m68k_fpcond & FPSR_CCB_INFINITY)
111     to_host_fpcond[i] = SW_I;
112     else
113     to_host_fpcond[i] = SW_FINITE;
114     if (m68k_fpcond & FPSR_CCB_NEGATIVE)
115     to_host_fpcond[i] |= SW_N;
116     }
117    
118     // truth-table for FPU conditions
119     for (uae_u32 host_fpcond = 0; host_fpcond < 0x08; host_fpcond++) {
120     // host_fpcond: C3 on bit 2, C1 and C0 are respectively on bits 1 and 0
121     const uae_u32 real_host_fpcond = ((host_fpcond & 4) << 12) | ((host_fpcond & 3) << 8);
122     const bool N = ((real_host_fpcond & NATIVE_FFLAG_NEGATIVE) == NATIVE_FFLAG_NEGATIVE);
123     const bool Z = ((real_host_fpcond & NATIVE_FFLAG_ZERO) == NATIVE_FFLAG_ZERO);
124     const bool NaN = ((real_host_fpcond & NATIVE_FFLAG_NAN) == NATIVE_FFLAG_NAN);
125    
126     int value;
127     for (uae_u32 m68k_fpcond = 0; m68k_fpcond < 0x20; m68k_fpcond++) {
128     switch (m68k_fpcond) {
129     case 0x00: value = 0; break; // False
130     case 0x01: value = Z; break; // Equal
131     case 0x02: value = !(NaN || Z || N); break; // Ordered Greater Than
132     case 0x03: value = Z || !(NaN || N); break; // Ordered Greater Than or Equal
133     case 0x04: value = N && !(NaN || Z); break; // Ordered Less Than
134     case 0x05: value = Z || (N && !NaN); break; // Ordered Less Than or Equal
135     case 0x06: value = !(NaN || Z); break; // Ordered Greater or Less Than
136     case 0x07: value = !NaN; break; // Ordered
137     case 0x08: value = NaN; break; // Unordered
138     case 0x09: value = NaN || Z; break; // Unordered or Equal
139     case 0x0a: value = NaN || !(N || Z); break; // Unordered or Greater Than
140     case 0x0b: value = NaN || Z || !N; break; // Unordered or Greater or Equal
141     case 0x0c: value = NaN || (N && !Z); break; // Unordered or Less Than
142     case 0x0d: value = NaN || Z || N; break; // Unordered or Less or Equal
143     case 0x0e: value = !Z; break; // Not Equal
144     case 0x0f: value = 1; break; // True
145     case 0x10: value = 0; break; // Signaling False
146     case 0x11: value = Z; break; // Signaling Equal
147     case 0x12: value = !(NaN || Z || N); break; // Greater Than
148     case 0x13: value = Z || !(NaN || N); break; // Greater Than or Equal
149     case 0x14: value = N && !(NaN || Z); break; // Less Than
150     case 0x15: value = Z || (N && !NaN); break; // Less Than or Equal
151     case 0x16: value = !(NaN || Z); break; // Greater or Less Than
152     case 0x17: value = !NaN; break; // Greater, Less or Equal
153     case 0x18: value = NaN; break; // Not Greater, Less or Equal
154     case 0x19: value = NaN || Z; break; // Not Greater or Less Than
155     case 0x1a: value = NaN || !(N || Z); break; // Not Less Than or Equal
156     case 0x1b: value = NaN || Z || !N; break; // Not Less Than
157     case 0x1c: value = NaN || (N && !Z); break; // Not Greater Than or Equal
158     // case 0x1c: value = !Z && (NaN || N); break; // Not Greater Than or Equal
159     case 0x1d: value = NaN || Z || N; break; // Not Greater Than
160     case 0x1e: value = !Z; break; // Signaling Not Equal
161     case 0x1f: value = 1; break; // Signaling True
162     default: value = -1;
163     }
164     fpcond_truth_table[m68k_fpcond][host_fpcond] = value;
165     }
166     }
167     }
168    
169     #endif