Change Permissions to GFDL. Update Copyright.
[deliverable/binutils-gdb.git] / sim / erc32 / float.c
1 /*
2 * This file is part of SIS.
3 *
4 * SIS, SPARC instruction simulator. Copyright (C) 1995 Jiri Gaisler, European
5 * Space Agency
6 *
7 * This program is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc., 675
19 * Mass Ave, Cambridge, MA 02139, USA.
20 *
21 *
22 * This file implements the interface between the host and the simulated
23 * FPU. IEEE trap handling is done as follows:
24 * 1. In the host, all IEEE traps are masked
25 * 2. After each simulated FPU instruction, check if any exception occured
26 * by reading the exception bits from the host FPU status register
27 * (get_accex()).
28 * 3. Propagate any exceptions to the simulated FSR.
29 * 4. Clear host exception bits
30 *
31 *
32 * This can also be done using ieee_flags() library routine on sun.
33 */
34
35 #include "sis.h"
36
37 /* Forward declarations */
38
39 extern uint32 _get_sw PARAMS ((void));
40 extern uint32 _get_cw PARAMS ((void));
41 static void __setfpucw PARAMS ((unsigned short fpu_control));
42
43 /* This host dependent routine should return the accrued exceptions */
44 int
45 get_accex()
46 {
47 #ifdef sparc
48 return ((_get_fsr_raw() >> 5) & 0x1F);
49 #elif i386
50 uint32 accx;
51
52 accx = _get_sw() & 0x3f;
53 accx = ((accx & 1) << 4) | ((accx & 2) >> 1) | ((accx & 4) >> 1) |
54 (accx & 8) | ((accx & 16) >> 2) | ((accx & 32) >> 5);
55 return(accx);
56 #else
57 return(0);
58 #warning no fpu trap support for this target
59 #endif
60
61 }
62
63 /* How to clear the accrued exceptions */
64 void
65 clear_accex()
66 {
67 #ifdef sparc
68 set_fsr((_get_fsr_raw() & ~0x3e0));
69 #elif i386
70 asm("
71 .text
72 fnclex
73
74 ");
75 #else
76 #warning no fpu trap support for this target
77 #endif
78 }
79
80 /* How to map SPARC FSR onto the host */
81 void
82 set_fsr(fsr)
83 uint32 fsr;
84 {
85 #ifdef sparc
86 _set_fsr_raw(fsr & ~0x0f800000);
87 #elif i386
88 void __setfpucw(unsigned short fpu_control);
89 uint32 rawfsr;
90
91 fsr >>= 30;
92 switch (fsr) {
93 case 0:
94 case 2: break;
95 case 1: fsr = 3;
96 case 3: fsr = 1;
97 }
98 rawfsr = _get_cw();
99 rawfsr |= (fsr << 10) | 0x3ff;
100 __setfpucw(rawfsr);
101 #else
102 #warning no fpu trap support for this target
103 #endif
104 }
105
106
107 /* Host dependent support functions */
108
109 #ifdef sparc
110
111 asm("
112
113 .text
114 .align 4
115 .global __set_fsr_raw,_set_fsr_raw
116 __set_fsr_raw:
117 _set_fsr_raw:
118 save %sp,-104,%sp
119 st %i0,[%fp+68]
120 ld [%fp+68], %fsr
121 mov 0,%i0
122 ret
123 restore
124
125 .align 4
126 .global __get_fsr_raw
127 .global _get_fsr_raw
128 __get_fsr_raw:
129 _get_fsr_raw:
130 save %sp,-104,%sp
131 st %fsr,[%fp+68]
132 ld [%fp+68], %i0
133 ret
134 restore
135
136 ");
137
138 #elif i386
139
140 asm("
141
142 .text
143 .align 8
144 .globl _get_sw,__get_sw
145 __get_sw:
146 _get_sw:
147 pushl %ebp
148 movl %esp,%ebp
149 movl $0,%eax
150 fnstsw %ax
151 movl %ebp,%esp
152 popl %ebp
153 ret
154
155 .align 8
156 .globl _get_cw,__get_cw
157 __get_cw:
158 _get_cw:
159 pushl %ebp
160 movl %esp,%ebp
161 subw $2,%esp
162 fnstcw -2(%ebp)
163 movw -2(%ebp),%eax
164 movl %ebp,%esp
165 popl %ebp
166 ret
167
168
169 ");
170
171
172 #else
173 #warning no fpu trap support for this target
174 #endif
175
176 #if i386
177 /* #if defined _WIN32 || defined __GO32__ */
178 /* This is so floating exception handling works on NT
179 These definitions are from the linux fpu_control.h, which
180 doesn't exist on NT.
181
182 default to:
183 - extended precision
184 - rounding to nearest
185 - exceptions on overflow, zero divide and NaN
186 */
187 #define _FPU_DEFAULT 0x1372
188 #define _FPU_RESERVED 0xF0C0 /* Reserved bits in cw */
189
190 static void
191 __setfpucw(unsigned short fpu_control)
192 {
193 volatile unsigned short cw;
194
195 /* If user supplied _fpu_control, use it ! */
196 if (!fpu_control)
197 {
198 /* use defaults */
199 fpu_control = _FPU_DEFAULT;
200 }
201 /* Get Control Word */
202 __asm__ volatile ("fnstcw %0" : "=m" (cw) : );
203
204 /* mask in */
205 cw &= _FPU_RESERVED;
206 cw = cw | (fpu_control & ~_FPU_RESERVED);
207
208 /* set cw */
209 __asm__ volatile ("fldcw %0" :: "m" (cw));
210 }
211 /* #endif */
212 #endif
This page took 0.037157 seconds and 4 git commands to generate.