summaryrefslogtreecommitdiff
path: root/tools/4.11/gdb/sparc/7.9/0004-sim-erc32-Use-fenv.h-for-host-FPU-access.patch
blob: 2ca90f68808ecb54b964039b3da946bf7fbd0084 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
From 7002592cb4072303c6a286e1c6479df99ae151b3 Mon Sep 17 00:00:00 2001
From: Jiri Gaisler <jiri@gaisler.se>
Date: Thu, 19 Feb 2015 22:14:36 +0100
Subject: [PATCH 04/23] sim/erc32: Use fenv.h for host FPU access

	* float.c (get_accex, clear_accex, set_fsr) Use functions from fenv.h
	instead of custom assembly.
---
 sim/erc32/float.c | 191 +++++++++---------------------------------------------
 1 file changed, 30 insertions(+), 161 deletions(-)

diff --git a/sim/erc32/float.c b/sim/erc32/float.c
index 598b7cc..40c133b 100644
--- a/sim/erc32/float.c
+++ b/sim/erc32/float.c
@@ -28,53 +28,38 @@
  * 4. Clear host exception bits
  *
  *
- * This can also be done using ieee_flags() library routine on sun.
  */
 
 #include "config.h"
 #include "sis.h"
+#include <fenv.h>
 
-/* Forward declarations */
-
-extern uint32	_get_sw (void);
-extern uint32	_get_cw (void);
-static void	__setfpucw (unsigned short fpu_control);
-
-/* This host dependent routine should return the accrued exceptions */
+/* This routine should return the accrued exceptions */
 int
 get_accex()
 {
-#ifdef sparc
-    return ((_get_fsr_raw() >> 5) & 0x1F);
-#elif i386
-    uint32 accx;
-
-    accx = _get_sw() & 0x3f;
-    accx = ((accx & 1) << 4) | ((accx & 2) >> 1) | ((accx & 4) >> 1) |
-	   (accx & 8) | ((accx & 16) >> 2) | ((accx & 32) >> 5);
+    int fexc, accx;
+
+    fexc = fetestexcept(FE_ALL_EXCEPT);
+    accx = 0;
+    if (fexc & FE_INEXACT)
+        accx |= 1;
+    if (fexc & FE_DIVBYZERO)
+        accx |= 2;
+    if (fexc & FE_UNDERFLOW)
+        accx |= 4;
+    if (fexc & FE_OVERFLOW)
+        accx |= 8;
+    if (fexc & FE_INVALID)
+        accx |= 0x10;
     return(accx);
-#else
-    return(0);
-#warning no fpu trap support for this target
-#endif
-
 }
 
 /* How to clear the accrued exceptions */
 void
 clear_accex()
 {
-#ifdef sparc
-    set_fsr((_get_fsr_raw() & ~0x3e0));
-#elif i386
-    asm("\n"
-".text\n"
-"	fnclex\n"
-"\n"
-"    ");
-#else
-#warning no fpu trap support for this target
-#endif
+    feclearexcept(FE_ALL_EXCEPT);
 }
 
 /* How to map SPARC FSR onto the host */
@@ -82,138 +67,22 @@ void
 set_fsr(fsr)
 uint32 fsr;
 {
-#ifdef sparc
-	_set_fsr_raw(fsr & ~0x0f800000);
-#elif i386
-     void __setfpucw(unsigned short fpu_control);
-     uint32 rawfsr;
+    int fround;
 
-     fsr >>= 30;
-     switch (fsr) {
+    fsr >>= 30;
+    switch (fsr) {
 	case 0: 
-	case 2:
-	  break;
-
+	    fround = FE_TONEAREST;
+	    break;
 	case 1:
-	  fsr = 3;
-	  break;
-
+	    fround = FE_TOWARDZERO;
+	    break;
+	case 2:
+	    fround = FE_UPWARD;
+	    break;
 	case 3:
-	  fsr = 1;
-	  break;
+	    fround = FE_DOWNWARD;
+	    break;
      }
-     rawfsr = _get_cw();
-     rawfsr |= (fsr << 10) | 0x3ff;
-     __setfpucw(rawfsr);
-#else
-#warning no fpu trap support for this target
-#endif
-}
-
-
-/* Host dependent support functions */
-
-#ifdef sparc
-
-    asm("\n"
-"\n"
-".text\n"
-"        .align 4\n"
-"        .global __set_fsr_raw,_set_fsr_raw\n"
-"__set_fsr_raw:\n"
-"_set_fsr_raw:\n"
-"        save %sp,-104,%sp\n"
-"        st %i0,[%fp+68]\n"
-"        ld [%fp+68], %fsr\n"
-"        mov 0,%i0\n"
-"        ret\n"
-"        restore\n"
-"\n"
-"        .align 4\n"
-"        .global __get_fsr_raw\n"
-"        .global _get_fsr_raw\n"
-"__get_fsr_raw:\n"
-"_get_fsr_raw:\n"
-"        save %sp,-104,%sp\n"
-"        st %fsr,[%fp+68]\n"
-"        ld [%fp+68], %i0\n"
-"        ret\n"
-"        restore\n"
-"\n"
-"    ");
-
-#elif i386
-
-    asm("\n"
-"\n"
-".text\n"
-"        .align 8\n"
-".globl _get_sw,__get_sw\n"
-"__get_sw:\n"
-"_get_sw:\n"
-"        pushl %ebp\n"
-"        movl %esp,%ebp\n"
-"        movl $0,%eax\n"
-"        fnstsw %ax\n"
-"        movl %ebp,%esp\n"
-"        popl %ebp\n"
-"        ret\n"
-"\n"
-"        .align 8\n"
-".globl _get_cw,__get_cw\n"
-"__get_cw:\n"
-"_get_cw:\n"
-"        pushl %ebp\n"
-"        movl %esp,%ebp\n"
-"        subw $2,%esp\n"
-"        fnstcw -2(%ebp)\n"
-"        movw -2(%ebp),%eax\n"
-"        movl %ebp,%esp\n"
-"        popl %ebp\n"
-"        ret\n"
-"\n"
-"\n"
-"    ");
-
-
-#else
-#warning no fpu trap support for this target
-#endif
-
-#if i386
-/* #if defined _WIN32 || defined __GO32__ */
-/* This is so floating exception handling works on NT
-   These definitions are from the linux fpu_control.h, which
-   doesn't exist on NT.
-
-   default to:
-     - extended precision
-     - rounding to nearest
-     - exceptions on overflow, zero divide and NaN
-*/
-#define _FPU_DEFAULT  0x1372 
-#define _FPU_RESERVED 0xF0C0  /* Reserved bits in cw */
-
-static void
-__setfpucw(unsigned short fpu_control)
-{
-  volatile unsigned short cw;
-
-  /* If user supplied _fpu_control, use it ! */
-  if (!fpu_control)
-  { 
-    /* use defaults */
-    fpu_control = _FPU_DEFAULT;
-  }
-  /* Get Control Word */
-  __asm__ volatile ("fnstcw %0" : "=m" (cw) : );
-  
-  /* mask in */
-  cw &= _FPU_RESERVED;
-  cw = cw | (fpu_control & ~_FPU_RESERVED);
-
-  /* set cw */
-  __asm__ volatile ("fldcw %0" :: "m" (cw));
+     fesetround(fround);
 }
-/* #endif */
-#endif
-- 
1.9.1