* end.c: Include config.h before system header files.
[deliverable/binutils-gdb.git] / sim / erc32 / float.c
CommitLineData
c906108c
SS
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
5272643f 35#include "config.h"
c906108c
SS
36#include "sis.h"
37
38/* Forward declarations */
39
40extern uint32 _get_sw PARAMS ((void));
41extern uint32 _get_cw PARAMS ((void));
42static void __setfpucw PARAMS ((unsigned short fpu_control));
43
44/* This host dependent routine should return the accrued exceptions */
45int
46get_accex()
47{
48#ifdef sparc
49 return ((_get_fsr_raw() >> 5) & 0x1F);
50#elif i386
51 uint32 accx;
52
53 accx = _get_sw() & 0x3f;
54 accx = ((accx & 1) << 4) | ((accx & 2) >> 1) | ((accx & 4) >> 1) |
55 (accx & 8) | ((accx & 16) >> 2) | ((accx & 32) >> 5);
56 return(accx);
57#else
58 return(0);
59#warning no fpu trap support for this target
60#endif
61
62}
63
64/* How to clear the accrued exceptions */
65void
66clear_accex()
67{
68#ifdef sparc
69 set_fsr((_get_fsr_raw() & ~0x3e0));
70#elif i386
187d3d28
JG
71 asm("\n"
72".text\n"
73" fnclex\n"
74"\n"
75" ");
c906108c
SS
76#else
77#warning no fpu trap support for this target
78#endif
79}
80
81/* How to map SPARC FSR onto the host */
82void
83set_fsr(fsr)
84uint32 fsr;
85{
86#ifdef sparc
87 _set_fsr_raw(fsr & ~0x0f800000);
88#elif i386
89 void __setfpucw(unsigned short fpu_control);
90 uint32 rawfsr;
91
92 fsr >>= 30;
93 switch (fsr) {
94 case 0:
95 case 2: break;
96 case 1: fsr = 3;
97 case 3: fsr = 1;
98 }
99 rawfsr = _get_cw();
100 rawfsr |= (fsr << 10) | 0x3ff;
101 __setfpucw(rawfsr);
102#else
103#warning no fpu trap support for this target
104#endif
105}
106
107
108/* Host dependent support functions */
109
110#ifdef sparc
111
187d3d28
JG
112 asm("\n"
113"\n"
114".text\n"
115" .align 4\n"
116" .global __set_fsr_raw,_set_fsr_raw\n"
117"__set_fsr_raw:\n"
118"_set_fsr_raw:\n"
119" save %sp,-104,%sp\n"
120" st %i0,[%fp+68]\n"
121" ld [%fp+68], %fsr\n"
122" mov 0,%i0\n"
123" ret\n"
124" restore\n"
125"\n"
126" .align 4\n"
127" .global __get_fsr_raw\n"
128" .global _get_fsr_raw\n"
129"__get_fsr_raw:\n"
130"_get_fsr_raw:\n"
131" save %sp,-104,%sp\n"
132" st %fsr,[%fp+68]\n"
133" ld [%fp+68], %i0\n"
134" ret\n"
135" restore\n"
136"\n"
137" ");
c906108c
SS
138
139#elif i386
140
187d3d28
JG
141 asm("\n"
142"\n"
143".text\n"
144" .align 8\n"
145".globl _get_sw,__get_sw\n"
146"__get_sw:\n"
147"_get_sw:\n"
148" pushl %ebp\n"
149" movl %esp,%ebp\n"
150" movl $0,%eax\n"
151" fnstsw %ax\n"
152" movl %ebp,%esp\n"
153" popl %ebp\n"
154" ret\n"
155"\n"
156" .align 8\n"
157".globl _get_cw,__get_cw\n"
158"__get_cw:\n"
159"_get_cw:\n"
160" pushl %ebp\n"
161" movl %esp,%ebp\n"
162" subw $2,%esp\n"
163" fnstcw -2(%ebp)\n"
164" movw -2(%ebp),%eax\n"
165" movl %ebp,%esp\n"
166" popl %ebp\n"
167" ret\n"
168"\n"
169"\n"
170" ");
c906108c
SS
171
172
173#else
174#warning no fpu trap support for this target
175#endif
176
177#if i386
178/* #if defined _WIN32 || defined __GO32__ */
179/* This is so floating exception handling works on NT
180 These definitions are from the linux fpu_control.h, which
181 doesn't exist on NT.
182
183 default to:
184 - extended precision
185 - rounding to nearest
186 - exceptions on overflow, zero divide and NaN
187*/
188#define _FPU_DEFAULT 0x1372
189#define _FPU_RESERVED 0xF0C0 /* Reserved bits in cw */
190
191static void
192__setfpucw(unsigned short fpu_control)
193{
194 volatile unsigned short cw;
195
196 /* If user supplied _fpu_control, use it ! */
197 if (!fpu_control)
198 {
199 /* use defaults */
200 fpu_control = _FPU_DEFAULT;
201 }
202 /* Get Control Word */
203 __asm__ volatile ("fnstcw %0" : "=m" (cw) : );
204
205 /* mask in */
206 cw &= _FPU_RESERVED;
207 cw = cw | (fpu_control & ~_FPU_RESERVED);
208
209 /* set cw */
210 __asm__ volatile ("fldcw %0" :: "m" (cw));
211}
212/* #endif */
213#endif
This page took 0.577918 seconds and 4 git commands to generate.