Commit f148af2593ef76ac705d1cc6abe48f455c9912cc

Authored by Richard Purdie
Committed by Russell King
1 parent 1fcf844861

[PATCH] ARM: 2837/2: Re: ARM: Make NWFPE preempt safe

Patch from Richard Purdie

NWFPE used global variables which meant it wasn't safe for use with
preemptive kernels. This patch removes them and communicates the
information between functions in a preempt safe manner. Generation
of some exceptions was broken and this has also been corrected.
Tests with glibc's maths test suite show no change in the results
before/after this patch.

Signed-off-by: Richard Purdie <rpurdie@rpsys.net>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

Showing 11 changed files with 304 additions and 304 deletions Side-by-side Diff

arch/arm/nwfpe/double_cpdo.c
... ... @@ -40,17 +40,17 @@
40 40 float64 float64_pow(float64 rFn, float64 rFm);
41 41 float64 float64_pol(float64 rFn, float64 rFm);
42 42  
43   -static float64 float64_rsf(float64 rFn, float64 rFm)
  43 +static float64 float64_rsf(struct roundingData *roundData, float64 rFn, float64 rFm)
44 44 {
45   - return float64_sub(rFm, rFn);
  45 + return float64_sub(roundData, rFm, rFn);
46 46 }
47 47  
48   -static float64 float64_rdv(float64 rFn, float64 rFm)
  48 +static float64 float64_rdv(struct roundingData *roundData, float64 rFn, float64 rFm)
49 49 {
50   - return float64_div(rFm, rFn);
  50 + return float64_div(roundData, rFm, rFn);
51 51 }
52 52  
53   -static float64 (*const dyadic_double[16])(float64 rFn, float64 rFm) = {
  53 +static float64 (*const dyadic_double[16])(struct roundingData*, float64 rFn, float64 rFm) = {
54 54 [ADF_CODE >> 20] = float64_add,
55 55 [MUF_CODE >> 20] = float64_mul,
56 56 [SUF_CODE >> 20] = float64_sub,
57 57  
... ... @@ -65,12 +65,12 @@
65 65 [FRD_CODE >> 20] = float64_rdv,
66 66 };
67 67  
68   -static float64 float64_mvf(float64 rFm)
  68 +static float64 float64_mvf(struct roundingData *roundData,float64 rFm)
69 69 {
70 70 return rFm;
71 71 }
72 72  
73   -static float64 float64_mnf(float64 rFm)
  73 +static float64 float64_mnf(struct roundingData *roundData,float64 rFm)
74 74 {
75 75 union float64_components u;
76 76  
... ... @@ -84,7 +84,7 @@
84 84 return u.f64;
85 85 }
86 86  
87   -static float64 float64_abs(float64 rFm)
  87 +static float64 float64_abs(struct roundingData *roundData,float64 rFm)
88 88 {
89 89 union float64_components u;
90 90  
... ... @@ -98,7 +98,7 @@
98 98 return u.f64;
99 99 }
100 100  
101   -static float64 (*const monadic_double[16])(float64 rFm) = {
  101 +static float64 (*const monadic_double[16])(struct roundingData *, float64 rFm) = {
102 102 [MVF_CODE >> 20] = float64_mvf,
103 103 [MNF_CODE >> 20] = float64_mnf,
104 104 [ABS_CODE >> 20] = float64_abs,
... ... @@ -108,7 +108,7 @@
108 108 [NRM_CODE >> 20] = float64_mvf,
109 109 };
110 110  
111   -unsigned int DoubleCPDO(const unsigned int opcode, FPREG * rFd)
  111 +unsigned int DoubleCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd)
112 112 {
113 113 FPA11 *fpa11 = GET_FPA11();
114 114 float64 rFm;
115 115  
... ... @@ -151,13 +151,13 @@
151 151 }
152 152  
153 153 if (dyadic_double[opc_mask_shift]) {
154   - rFd->fDouble = dyadic_double[opc_mask_shift](rFn, rFm);
  154 + rFd->fDouble = dyadic_double[opc_mask_shift](roundData, rFn, rFm);
155 155 } else {
156 156 return 0;
157 157 }
158 158 } else {
159 159 if (monadic_double[opc_mask_shift]) {
160   - rFd->fDouble = monadic_double[opc_mask_shift](rFm);
  160 + rFd->fDouble = monadic_double[opc_mask_shift](roundData, rFm);
161 161 } else {
162 162 return 0;
163 163 }
arch/arm/nwfpe/extended_cpdo.c
... ... @@ -35,17 +35,17 @@
35 35 floatx80 floatx80_pow(floatx80 rFn, floatx80 rFm);
36 36 floatx80 floatx80_pol(floatx80 rFn, floatx80 rFm);
37 37  
38   -static floatx80 floatx80_rsf(floatx80 rFn, floatx80 rFm)
  38 +static floatx80 floatx80_rsf(struct roundingData *roundData, floatx80 rFn, floatx80 rFm)
39 39 {
40   - return floatx80_sub(rFm, rFn);
  40 + return floatx80_sub(roundData, rFm, rFn);
41 41 }
42 42  
43   -static floatx80 floatx80_rdv(floatx80 rFn, floatx80 rFm)
  43 +static floatx80 floatx80_rdv(struct roundingData *roundData, floatx80 rFn, floatx80 rFm)
44 44 {
45   - return floatx80_div(rFm, rFn);
  45 + return floatx80_div(roundData, rFm, rFn);
46 46 }
47 47  
48   -static floatx80 (*const dyadic_extended[16])(floatx80 rFn, floatx80 rFm) = {
  48 +static floatx80 (*const dyadic_extended[16])(struct roundingData*, floatx80 rFn, floatx80 rFm) = {
49 49 [ADF_CODE >> 20] = floatx80_add,
50 50 [MUF_CODE >> 20] = floatx80_mul,
51 51 [SUF_CODE >> 20] = floatx80_sub,
52 52  
53 53  
54 54  
... ... @@ -60,24 +60,24 @@
60 60 [FRD_CODE >> 20] = floatx80_rdv,
61 61 };
62 62  
63   -static floatx80 floatx80_mvf(floatx80 rFm)
  63 +static floatx80 floatx80_mvf(struct roundingData *roundData, floatx80 rFm)
64 64 {
65 65 return rFm;
66 66 }
67 67  
68   -static floatx80 floatx80_mnf(floatx80 rFm)
  68 +static floatx80 floatx80_mnf(struct roundingData *roundData, floatx80 rFm)
69 69 {
70 70 rFm.high ^= 0x8000;
71 71 return rFm;
72 72 }
73 73  
74   -static floatx80 floatx80_abs(floatx80 rFm)
  74 +static floatx80 floatx80_abs(struct roundingData *roundData, floatx80 rFm)
75 75 {
76 76 rFm.high &= 0x7fff;
77 77 return rFm;
78 78 }
79 79  
80   -static floatx80 (*const monadic_extended[16])(floatx80 rFm) = {
  80 +static floatx80 (*const monadic_extended[16])(struct roundingData*, floatx80 rFm) = {
81 81 [MVF_CODE >> 20] = floatx80_mvf,
82 82 [MNF_CODE >> 20] = floatx80_mnf,
83 83 [ABS_CODE >> 20] = floatx80_abs,
... ... @@ -87,7 +87,7 @@
87 87 [NRM_CODE >> 20] = floatx80_mvf,
88 88 };
89 89  
90   -unsigned int ExtendedCPDO(const unsigned int opcode, FPREG * rFd)
  90 +unsigned int ExtendedCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd)
91 91 {
92 92 FPA11 *fpa11 = GET_FPA11();
93 93 floatx80 rFm;
94 94  
... ... @@ -138,13 +138,13 @@
138 138 }
139 139  
140 140 if (dyadic_extended[opc_mask_shift]) {
141   - rFd->fExtended = dyadic_extended[opc_mask_shift](rFn, rFm);
  141 + rFd->fExtended = dyadic_extended[opc_mask_shift](roundData, rFn, rFm);
142 142 } else {
143 143 return 0;
144 144 }
145 145 } else {
146 146 if (monadic_extended[opc_mask_shift]) {
147   - rFd->fExtended = monadic_extended[opc_mask_shift](rFm);
  147 + rFd->fExtended = monadic_extended[opc_mask_shift](roundData, rFm);
148 148 } else {
149 149 return 0;
150 150 }
arch/arm/nwfpe/fpa11.c
... ... @@ -51,48 +51,42 @@
51 51 fpa11->fpsr = FP_EMULATOR | BIT_AC;
52 52 }
53 53  
54   -void SetRoundingMode(const unsigned int opcode)
  54 +int8 SetRoundingMode(const unsigned int opcode)
55 55 {
56 56 switch (opcode & MASK_ROUNDING_MODE) {
57 57 default:
58 58 case ROUND_TO_NEAREST:
59   - float_rounding_mode = float_round_nearest_even;
60   - break;
  59 + return float_round_nearest_even;
61 60  
62 61 case ROUND_TO_PLUS_INFINITY:
63   - float_rounding_mode = float_round_up;
64   - break;
  62 + return float_round_up;
65 63  
66 64 case ROUND_TO_MINUS_INFINITY:
67   - float_rounding_mode = float_round_down;
68   - break;
  65 + return float_round_down;
69 66  
70 67 case ROUND_TO_ZERO:
71   - float_rounding_mode = float_round_to_zero;
72   - break;
  68 + return float_round_to_zero;
73 69 }
74 70 }
75 71  
76   -void SetRoundingPrecision(const unsigned int opcode)
  72 +int8 SetRoundingPrecision(const unsigned int opcode)
77 73 {
78 74 #ifdef CONFIG_FPE_NWFPE_XP
79 75 switch (opcode & MASK_ROUNDING_PRECISION) {
80 76 case ROUND_SINGLE:
81   - floatx80_rounding_precision = 32;
82   - break;
  77 + return 32;
83 78  
84 79 case ROUND_DOUBLE:
85   - floatx80_rounding_precision = 64;
86   - break;
  80 + return 64;
87 81  
88 82 case ROUND_EXTENDED:
89   - floatx80_rounding_precision = 80;
90   - break;
  83 + return 80;
91 84  
92 85 default:
93   - floatx80_rounding_precision = 80;
  86 + return 80;
94 87 }
95 88 #endif
  89 + return 80;
96 90 }
97 91  
98 92 void nwfpe_init_fpa(union fp_state *fp)
... ... @@ -103,8 +97,6 @@
103 97 #endif
104 98 memset(fpa11, 0, sizeof(FPA11));
105 99 resetFPA11();
106   - SetRoundingMode(ROUND_TO_NEAREST);
107   - SetRoundingPrecision(ROUND_EXTENDED);
108 100 fpa11->initflag = 1;
109 101 }
110 102  
arch/arm/nwfpe/fpa11.h
... ... @@ -37,6 +37,13 @@
37 37 /* includes */
38 38 #include "fpsr.h" /* FP control and status register definitions */
39 39 #include "milieu.h"
  40 +
  41 +struct roundingData {
  42 + int8 mode;
  43 + int8 precision;
  44 + signed char exception;
  45 +};
  46 +
40 47 #include "softfloat.h"
41 48  
42 49 #define typeNone 0x00
... ... @@ -84,8 +91,8 @@
84 91 initialised. */
85 92 } FPA11;
86 93  
87   -extern void SetRoundingMode(const unsigned int);
88   -extern void SetRoundingPrecision(const unsigned int);
  94 +extern int8 SetRoundingMode(const unsigned int);
  95 +extern int8 SetRoundingPrecision(const unsigned int);
89 96 extern void nwfpe_init_fpa(union fp_state *fp);
90 97  
91 98 #endif
arch/arm/nwfpe/fpa11_cpdo.c
... ... @@ -24,15 +24,16 @@
24 24 #include "fpa11.h"
25 25 #include "fpopcode.h"
26 26  
27   -unsigned int SingleCPDO(const unsigned int opcode, FPREG * rFd);
28   -unsigned int DoubleCPDO(const unsigned int opcode, FPREG * rFd);
29   -unsigned int ExtendedCPDO(const unsigned int opcode, FPREG * rFd);
  27 +unsigned int SingleCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd);
  28 +unsigned int DoubleCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd);
  29 +unsigned int ExtendedCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd);
30 30  
31 31 unsigned int EmulateCPDO(const unsigned int opcode)
32 32 {
33 33 FPA11 *fpa11 = GET_FPA11();
34 34 FPREG *rFd;
35 35 unsigned int nType, nDest, nRc;
  36 + struct roundingData roundData;
36 37  
37 38 /* Get the destination size. If not valid let Linux perform
38 39 an invalid instruction trap. */
... ... @@ -40,7 +41,9 @@
40 41 if (typeNone == nDest)
41 42 return 0;
42 43  
43   - SetRoundingMode(opcode);
  44 + roundData.mode = SetRoundingMode(opcode);
  45 + roundData.precision = SetRoundingPrecision(opcode);
  46 + roundData.exception = 0;
44 47  
45 48 /* Compare the size of the operands in Fn and Fm.
46 49 Choose the largest size and perform operations in that size,
47 50  
48 51  
... ... @@ -63,14 +66,14 @@
63 66  
64 67 switch (nType) {
65 68 case typeSingle:
66   - nRc = SingleCPDO(opcode, rFd);
  69 + nRc = SingleCPDO(&roundData, opcode, rFd);
67 70 break;
68 71 case typeDouble:
69   - nRc = DoubleCPDO(opcode, rFd);
  72 + nRc = DoubleCPDO(&roundData, opcode, rFd);
70 73 break;
71 74 #ifdef CONFIG_FPE_NWFPE_XP
72 75 case typeExtended:
73   - nRc = ExtendedCPDO(opcode, rFd);
  76 + nRc = ExtendedCPDO(&roundData, opcode, rFd);
74 77 break;
75 78 #endif
76 79 default:
77 80  
... ... @@ -93,9 +96,9 @@
93 96 case typeSingle:
94 97 {
95 98 if (typeDouble == nType)
96   - rFd->fSingle = float64_to_float32(rFd->fDouble);
  99 + rFd->fSingle = float64_to_float32(&roundData, rFd->fDouble);
97 100 else
98   - rFd->fSingle = floatx80_to_float32(rFd->fExtended);
  101 + rFd->fSingle = floatx80_to_float32(&roundData, rFd->fExtended);
99 102 }
100 103 break;
101 104  
... ... @@ -104,7 +107,7 @@
104 107 if (typeSingle == nType)
105 108 rFd->fDouble = float32_to_float64(rFd->fSingle);
106 109 else
107   - rFd->fDouble = floatx80_to_float64(rFd->fExtended);
  110 + rFd->fDouble = floatx80_to_float64(&roundData, rFd->fExtended);
108 111 }
109 112 break;
110 113  
111 114  
... ... @@ -121,12 +124,15 @@
121 124 #else
122 125 if (nDest != nType) {
123 126 if (nDest == typeSingle)
124   - rFd->fSingle = float64_to_float32(rFd->fDouble);
  127 + rFd->fSingle = float64_to_float32(&roundData, rFd->fDouble);
125 128 else
126 129 rFd->fDouble = float32_to_float64(rFd->fSingle);
127 130 }
128 131 #endif
129 132 }
  133 +
  134 + if (roundData.exception)
  135 + float_raise(roundData.exception);
130 136  
131 137 return nRc;
132 138 }
arch/arm/nwfpe/fpa11_cpdt.c
... ... @@ -96,7 +96,7 @@
96 96 }
97 97 }
98 98  
99   -static inline void storeSingle(const unsigned int Fn, unsigned int __user *pMem)
  99 +static inline void storeSingle(struct roundingData *roundData, const unsigned int Fn, unsigned int __user *pMem)
100 100 {
101 101 FPA11 *fpa11 = GET_FPA11();
102 102 union {
103 103  
... ... @@ -106,12 +106,12 @@
106 106  
107 107 switch (fpa11->fType[Fn]) {
108 108 case typeDouble:
109   - val.f = float64_to_float32(fpa11->fpreg[Fn].fDouble);
  109 + val.f = float64_to_float32(roundData, fpa11->fpreg[Fn].fDouble);
110 110 break;
111 111  
112 112 #ifdef CONFIG_FPE_NWFPE_XP
113 113 case typeExtended:
114   - val.f = floatx80_to_float32(fpa11->fpreg[Fn].fExtended);
  114 + val.f = floatx80_to_float32(roundData, fpa11->fpreg[Fn].fExtended);
115 115 break;
116 116 #endif
117 117  
... ... @@ -122,7 +122,7 @@
122 122 put_user(val.i[0], pMem);
123 123 }
124 124  
125   -static inline void storeDouble(const unsigned int Fn, unsigned int __user *pMem)
  125 +static inline void storeDouble(struct roundingData *roundData, const unsigned int Fn, unsigned int __user *pMem)
126 126 {
127 127 FPA11 *fpa11 = GET_FPA11();
128 128 union {
... ... @@ -137,7 +137,7 @@
137 137  
138 138 #ifdef CONFIG_FPE_NWFPE_XP
139 139 case typeExtended:
140   - val.f = floatx80_to_float64(fpa11->fpreg[Fn].fExtended);
  140 + val.f = floatx80_to_float64(roundData, fpa11->fpreg[Fn].fExtended);
141 141 break;
142 142 #endif
143 143  
144 144  
... ... @@ -259,8 +259,11 @@
259 259 {
260 260 unsigned int __user *pBase, *pAddress, *pFinal;
261 261 unsigned int nRc = 1, write_back = WRITE_BACK(opcode);
  262 + struct roundingData roundData;
262 263  
263   - SetRoundingMode(ROUND_TO_NEAREST);
  264 + roundData.mode = SetRoundingMode(opcode);
  265 + roundData.precision = SetRoundingPrecision(opcode);
  266 + roundData.exception = 0;
264 267  
265 268 pBase = (unsigned int __user *) readRegister(getRn(opcode));
266 269 if (REG_PC == getRn(opcode)) {
267 270  
... ... @@ -281,10 +284,10 @@
281 284  
282 285 switch (opcode & MASK_TRANSFER_LENGTH) {
283 286 case TRANSFER_SINGLE:
284   - storeSingle(getFd(opcode), pAddress);
  287 + storeSingle(&roundData, getFd(opcode), pAddress);
285 288 break;
286 289 case TRANSFER_DOUBLE:
287   - storeDouble(getFd(opcode), pAddress);
  290 + storeDouble(&roundData, getFd(opcode), pAddress);
288 291 break;
289 292 #ifdef CONFIG_FPE_NWFPE_XP
290 293 case TRANSFER_EXTENDED:
... ... @@ -294,6 +297,9 @@
294 297 default:
295 298 nRc = 0;
296 299 }
  300 +
  301 + if (roundData.exception)
  302 + float_raise(roundData.exception);
297 303  
298 304 if (write_back)
299 305 writeRegister(getRn(opcode), (unsigned long) pFinal);
arch/arm/nwfpe/fpa11_cprt.c
... ... @@ -33,8 +33,6 @@
33 33 extern flag float64_is_nan(float64);
34 34 extern flag float32_is_nan(float32);
35 35  
36   -void SetRoundingMode(const unsigned int opcode);
37   -
38 36 unsigned int PerformFLT(const unsigned int opcode);
39 37 unsigned int PerformFIX(const unsigned int opcode);
40 38  
41 39  
42 40  
... ... @@ -77,14 +75,17 @@
77 75 unsigned int PerformFLT(const unsigned int opcode)
78 76 {
79 77 FPA11 *fpa11 = GET_FPA11();
80   - SetRoundingMode(opcode);
81   - SetRoundingPrecision(opcode);
  78 + struct roundingData roundData;
82 79  
  80 + roundData.mode = SetRoundingMode(opcode);
  81 + roundData.precision = SetRoundingPrecision(opcode);
  82 + roundData.exception = 0;
  83 +
83 84 switch (opcode & MASK_ROUNDING_PRECISION) {
84 85 case ROUND_SINGLE:
85 86 {
86 87 fpa11->fType[getFn(opcode)] = typeSingle;
87   - fpa11->fpreg[getFn(opcode)].fSingle = int32_to_float32(readRegister(getRd(opcode)));
  88 + fpa11->fpreg[getFn(opcode)].fSingle = int32_to_float32(&roundData, readRegister(getRd(opcode)));
88 89 }
89 90 break;
90 91  
... ... @@ -108,6 +109,9 @@
108 109 return 0;
109 110 }
110 111  
  112 + if (roundData.exception)
  113 + float_raise(roundData.exception);
  114 +
111 115 return 1;
112 116 }
113 117  
114 118  
115 119  
116 120  
117 121  
... ... @@ -115,26 +119,29 @@
115 119 {
116 120 FPA11 *fpa11 = GET_FPA11();
117 121 unsigned int Fn = getFm(opcode);
  122 + struct roundingData roundData;
118 123  
119   - SetRoundingMode(opcode);
  124 + roundData.mode = SetRoundingMode(opcode);
  125 + roundData.precision = SetRoundingPrecision(opcode);
  126 + roundData.exception = 0;
120 127  
121 128 switch (fpa11->fType[Fn]) {
122 129 case typeSingle:
123 130 {
124   - writeRegister(getRd(opcode), float32_to_int32(fpa11->fpreg[Fn].fSingle));
  131 + writeRegister(getRd(opcode), float32_to_int32(&roundData, fpa11->fpreg[Fn].fSingle));
125 132 }
126 133 break;
127 134  
128 135 case typeDouble:
129 136 {
130   - writeRegister(getRd(opcode), float64_to_int32(fpa11->fpreg[Fn].fDouble));
  137 + writeRegister(getRd(opcode), float64_to_int32(&roundData, fpa11->fpreg[Fn].fDouble));
131 138 }
132 139 break;
133 140  
134 141 #ifdef CONFIG_FPE_NWFPE_XP
135 142 case typeExtended:
136 143 {
137   - writeRegister(getRd(opcode), floatx80_to_int32(fpa11->fpreg[Fn].fExtended));
  144 + writeRegister(getRd(opcode), floatx80_to_int32(&roundData, fpa11->fpreg[Fn].fExtended));
138 145 }
139 146 break;
140 147 #endif
... ... @@ -142,6 +149,9 @@
142 149 default:
143 150 return 0;
144 151 }
  152 +
  153 + if (roundData.exception)
  154 + float_raise(roundData.exception);
145 155  
146 156 return 1;
147 157 }
arch/arm/nwfpe/fpmodule.c
... ... @@ -116,8 +116,6 @@
116 116 code to access data in user space in some other source files at the
117 117 moment (grep for get_user / put_user calls). --philb]
118 118  
119   -float_exception_flags is a global variable in SoftFloat.
120   -
121 119 This function is called by the SoftFloat routines to raise a floating
122 120 point exception. We check the trap enable byte in the FPSR, and raise
123 121 a SIGFPE exception if necessary. If not the relevant bits in the
124 122  
... ... @@ -129,14 +127,13 @@
129 127 register unsigned int fpsr, cumulativeTraps;
130 128  
131 129 #ifdef CONFIG_DEBUG_USER
132   - printk(KERN_DEBUG
133   - "NWFPE: %s[%d] takes exception %08x at %p from %08lx\n",
134   - current->comm, current->pid, flags,
135   - __builtin_return_address(0), GET_USERREG()->ARM_pc);
  130 + /* Ignore inexact errors as there are far too many of them to log */
  131 + if (flags & ~BIT_IXC)
  132 + printk(KERN_DEBUG
  133 + "NWFPE: %s[%d] takes exception %08x at %p from %08lx\n",
  134 + current->comm, current->pid, flags,
  135 + __builtin_return_address(0), GET_USERREG()->ARM_pc);
136 136 #endif
137   -
138   - /* Keep SoftFloat exception flags up to date. */
139   - float_exception_flags |= flags;
140 137  
141 138 /* Read fpsr and initialize the cumulativeTraps. */
142 139 fpsr = readFPSR();
arch/arm/nwfpe/single_cpdo.c
... ... @@ -36,17 +36,17 @@
36 36 float32 float32_pow(float32 rFn, float32 rFm);
37 37 float32 float32_pol(float32 rFn, float32 rFm);
38 38  
39   -static float32 float32_rsf(float32 rFn, float32 rFm)
  39 +static float32 float32_rsf(struct roundingData *roundData, float32 rFn, float32 rFm)
40 40 {
41   - return float32_sub(rFm, rFn);
  41 + return float32_sub(roundData, rFm, rFn);
42 42 }
43 43  
44   -static float32 float32_rdv(float32 rFn, float32 rFm)
  44 +static float32 float32_rdv(struct roundingData *roundData, float32 rFn, float32 rFm)
45 45 {
46   - return float32_div(rFm, rFn);
  46 + return float32_div(roundData, rFm, rFn);
47 47 }
48 48  
49   -static float32 (*const dyadic_single[16])(float32 rFn, float32 rFm) = {
  49 +static float32 (*const dyadic_single[16])(struct roundingData *, float32 rFn, float32 rFm) = {
50 50 [ADF_CODE >> 20] = float32_add,
51 51 [MUF_CODE >> 20] = float32_mul,
52 52 [SUF_CODE >> 20] = float32_sub,
53 53  
54 54  
55 55  
... ... @@ -60,22 +60,22 @@
60 60 [FRD_CODE >> 20] = float32_rdv,
61 61 };
62 62  
63   -static float32 float32_mvf(float32 rFm)
  63 +static float32 float32_mvf(struct roundingData *roundData, float32 rFm)
64 64 {
65 65 return rFm;
66 66 }
67 67  
68   -static float32 float32_mnf(float32 rFm)
  68 +static float32 float32_mnf(struct roundingData *roundData, float32 rFm)
69 69 {
70 70 return rFm ^ 0x80000000;
71 71 }
72 72  
73   -static float32 float32_abs(float32 rFm)
  73 +static float32 float32_abs(struct roundingData *roundData, float32 rFm)
74 74 {
75 75 return rFm & 0x7fffffff;
76 76 }
77 77  
78   -static float32 (*const monadic_single[16])(float32 rFm) = {
  78 +static float32 (*const monadic_single[16])(struct roundingData*, float32 rFm) = {
79 79 [MVF_CODE >> 20] = float32_mvf,
80 80 [MNF_CODE >> 20] = float32_mnf,
81 81 [ABS_CODE >> 20] = float32_abs,
... ... @@ -85,7 +85,7 @@
85 85 [NRM_CODE >> 20] = float32_mvf,
86 86 };
87 87  
88   -unsigned int SingleCPDO(const unsigned int opcode, FPREG * rFd)
  88 +unsigned int SingleCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd)
89 89 {
90 90 FPA11 *fpa11 = GET_FPA11();
91 91 float32 rFm;
92 92  
... ... @@ -108,13 +108,13 @@
108 108 if (fpa11->fType[Fn] == typeSingle &&
109 109 dyadic_single[opc_mask_shift]) {
110 110 rFn = fpa11->fpreg[Fn].fSingle;
111   - rFd->fSingle = dyadic_single[opc_mask_shift](rFn, rFm);
  111 + rFd->fSingle = dyadic_single[opc_mask_shift](roundData, rFn, rFm);
112 112 } else {
113 113 return 0;
114 114 }
115 115 } else {
116 116 if (monadic_single[opc_mask_shift]) {
117   - rFd->fSingle = monadic_single[opc_mask_shift](rFm);
  117 + rFd->fSingle = monadic_single[opc_mask_shift](roundData, rFm);
118 118 } else {
119 119 return 0;
120 120 }
arch/arm/nwfpe/softfloat.c
Changes suppressed. Click to show
... ... @@ -36,16 +36,6 @@
36 36  
37 37 /*
38 38 -------------------------------------------------------------------------------
39   -Floating-point rounding mode, extended double-precision rounding precision,
40   -and exception flags.
41   --------------------------------------------------------------------------------
42   -*/
43   -int8 float_rounding_mode = float_round_nearest_even;
44   -int8 floatx80_rounding_precision = 80;
45   -int8 float_exception_flags;
46   -
47   -/*
48   --------------------------------------------------------------------------------
49 39 Primitive arithmetic functions, including multi-word arithmetic, and
50 40 division and square root approximations. (Can be specialized to target if
51 41 desired.)
52 42  
... ... @@ -77,14 +67,14 @@
77 67 positive or negative integer is returned.
78 68 -------------------------------------------------------------------------------
79 69 */
80   -static int32 roundAndPackInt32( flag zSign, bits64 absZ )
  70 +static int32 roundAndPackInt32( struct roundingData *roundData, flag zSign, bits64 absZ )
81 71 {
82 72 int8 roundingMode;
83 73 flag roundNearestEven;
84 74 int8 roundIncrement, roundBits;
85 75 int32 z;
86 76  
87   - roundingMode = float_rounding_mode;
  77 + roundingMode = roundData->mode;
88 78 roundNearestEven = ( roundingMode == float_round_nearest_even );
89 79 roundIncrement = 0x40;
90 80 if ( ! roundNearestEven ) {
91 81  
... ... @@ -107,10 +97,10 @@
107 97 z = absZ;
108 98 if ( zSign ) z = - z;
109 99 if ( ( absZ>>32 ) || ( z && ( ( z < 0 ) ^ zSign ) ) ) {
110   - float_exception_flags |= float_flag_invalid;
  100 + roundData->exception |= float_flag_invalid;
111 101 return zSign ? 0x80000000 : 0x7FFFFFFF;
112 102 }
113   - if ( roundBits ) float_exception_flags |= float_flag_inexact;
  103 + if ( roundBits ) roundData->exception |= float_flag_inexact;
114 104 return z;
115 105  
116 106 }
117 107  
... ... @@ -224,14 +214,14 @@
224 214 Binary Floating-point Arithmetic.
225 215 -------------------------------------------------------------------------------
226 216 */
227   -static float32 roundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig )
  217 +static float32 roundAndPackFloat32( struct roundingData *roundData, flag zSign, int16 zExp, bits32 zSig )
228 218 {
229 219 int8 roundingMode;
230 220 flag roundNearestEven;
231 221 int8 roundIncrement, roundBits;
232 222 flag isTiny;
233 223  
234   - roundingMode = float_rounding_mode;
  224 + roundingMode = roundData->mode;
235 225 roundNearestEven = ( roundingMode == float_round_nearest_even );
236 226 roundIncrement = 0x40;
237 227 if ( ! roundNearestEven ) {
... ... @@ -254,7 +244,7 @@
254 244 || ( ( zExp == 0xFD )
255 245 && ( (sbits32) ( zSig + roundIncrement ) < 0 ) )
256 246 ) {
257   - float_raise( float_flag_overflow | float_flag_inexact );
  247 + roundData->exception |= float_flag_overflow | float_flag_inexact;
258 248 return packFloat32( zSign, 0xFF, 0 ) - ( roundIncrement == 0 );
259 249 }
260 250 if ( zExp < 0 ) {
261 251  
... ... @@ -265,10 +255,10 @@
265 255 shift32RightJamming( zSig, - zExp, &zSig );
266 256 zExp = 0;
267 257 roundBits = zSig & 0x7F;
268   - if ( isTiny && roundBits ) float_raise( float_flag_underflow );
  258 + if ( isTiny && roundBits ) roundData->exception |= float_flag_underflow;
269 259 }
270 260 }
271   - if ( roundBits ) float_exception_flags |= float_flag_inexact;
  261 + if ( roundBits ) roundData->exception |= float_flag_inexact;
272 262 zSig = ( zSig + roundIncrement )>>7;
273 263 zSig &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
274 264 if ( zSig == 0 ) zExp = 0;
275 265  
... ... @@ -287,12 +277,12 @@
287 277 -------------------------------------------------------------------------------
288 278 */
289 279 static float32
290   - normalizeRoundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig )
  280 + normalizeRoundAndPackFloat32( struct roundingData *roundData, flag zSign, int16 zExp, bits32 zSig )
291 281 {
292 282 int8 shiftCount;
293 283  
294 284 shiftCount = countLeadingZeros32( zSig ) - 1;
295   - return roundAndPackFloat32( zSign, zExp - shiftCount, zSig<<shiftCount );
  285 + return roundAndPackFloat32( roundData, zSign, zExp - shiftCount, zSig<<shiftCount );
296 286  
297 287 }
298 288  
299 289  
... ... @@ -395,14 +385,14 @@
395 385 Binary Floating-point Arithmetic.
396 386 -------------------------------------------------------------------------------
397 387 */
398   -static float64 roundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig )
  388 +static float64 roundAndPackFloat64( struct roundingData *roundData, flag zSign, int16 zExp, bits64 zSig )
399 389 {
400 390 int8 roundingMode;
401 391 flag roundNearestEven;
402 392 int16 roundIncrement, roundBits;
403 393 flag isTiny;
404 394  
405   - roundingMode = float_rounding_mode;
  395 + roundingMode = roundData->mode;
406 396 roundNearestEven = ( roundingMode == float_round_nearest_even );
407 397 roundIncrement = 0x200;
408 398 if ( ! roundNearestEven ) {
... ... @@ -427,7 +417,7 @@
427 417 ) {
428 418 //register int lr = __builtin_return_address(0);
429 419 //printk("roundAndPackFloat64 called from 0x%08x\n",lr);
430   - float_raise( float_flag_overflow | float_flag_inexact );
  420 + roundData->exception |= float_flag_overflow | float_flag_inexact;
431 421 return packFloat64( zSign, 0x7FF, 0 ) - ( roundIncrement == 0 );
432 422 }
433 423 if ( zExp < 0 ) {
434 424  
... ... @@ -438,10 +428,10 @@
438 428 shift64RightJamming( zSig, - zExp, &zSig );
439 429 zExp = 0;
440 430 roundBits = zSig & 0x3FF;
441   - if ( isTiny && roundBits ) float_raise( float_flag_underflow );
  431 + if ( isTiny && roundBits ) roundData->exception |= float_flag_underflow;
442 432 }
443 433 }
444   - if ( roundBits ) float_exception_flags |= float_flag_inexact;
  434 + if ( roundBits ) roundData->exception |= float_flag_inexact;
445 435 zSig = ( zSig + roundIncrement )>>10;
446 436 zSig &= ~ ( ( ( roundBits ^ 0x200 ) == 0 ) & roundNearestEven );
447 437 if ( zSig == 0 ) zExp = 0;
448 438  
... ... @@ -460,12 +450,12 @@
460 450 -------------------------------------------------------------------------------
461 451 */
462 452 static float64
463   - normalizeRoundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig )
  453 + normalizeRoundAndPackFloat64( struct roundingData *roundData, flag zSign, int16 zExp, bits64 zSig )
464 454 {
465 455 int8 shiftCount;
466 456  
467 457 shiftCount = countLeadingZeros64( zSig ) - 1;
468   - return roundAndPackFloat64( zSign, zExp - shiftCount, zSig<<shiftCount );
  458 + return roundAndPackFloat64( roundData, zSign, zExp - shiftCount, zSig<<shiftCount );
469 459  
470 460 }
471 461  
472 462  
473 463  
... ... @@ -572,14 +562,15 @@
572 562 */
573 563 static floatx80
574 564 roundAndPackFloatx80(
575   - int8 roundingPrecision, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1
  565 + struct roundingData *roundData, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1
576 566 )
577 567 {
578   - int8 roundingMode;
  568 + int8 roundingMode, roundingPrecision;
579 569 flag roundNearestEven, increment, isTiny;
580 570 int64 roundIncrement, roundMask, roundBits;
581 571  
582   - roundingMode = float_rounding_mode;
  572 + roundingMode = roundData->mode;
  573 + roundingPrecision = roundData->precision;
583 574 roundNearestEven = ( roundingMode == float_round_nearest_even );
584 575 if ( roundingPrecision == 80 ) goto precision80;
585 576 if ( roundingPrecision == 64 ) {
... ... @@ -623,8 +614,8 @@
623 614 shift64RightJamming( zSig0, 1 - zExp, &zSig0 );
624 615 zExp = 0;
625 616 roundBits = zSig0 & roundMask;
626   - if ( isTiny && roundBits ) float_raise( float_flag_underflow );
627   - if ( roundBits ) float_exception_flags |= float_flag_inexact;
  617 + if ( isTiny && roundBits ) roundData->exception |= float_flag_underflow;
  618 + if ( roundBits ) roundData->exception |= float_flag_inexact;
628 619 zSig0 += roundIncrement;
629 620 if ( (sbits64) zSig0 < 0 ) zExp = 1;
630 621 roundIncrement = roundMask + 1;
... ... @@ -635,7 +626,7 @@
635 626 return packFloatx80( zSign, zExp, zSig0 );
636 627 }
637 628 }
638   - if ( roundBits ) float_exception_flags |= float_flag_inexact;
  629 + if ( roundBits ) roundData->exception |= float_flag_inexact;
639 630 zSig0 += roundIncrement;
640 631 if ( zSig0 < roundIncrement ) {
641 632 ++zExp;
... ... @@ -672,7 +663,7 @@
672 663 ) {
673 664 roundMask = 0;
674 665 overflow:
675   - float_raise( float_flag_overflow | float_flag_inexact );
  666 + roundData->exception |= float_flag_overflow | float_flag_inexact;
676 667 if ( ( roundingMode == float_round_to_zero )
677 668 || ( zSign && ( roundingMode == float_round_up ) )
678 669 || ( ! zSign && ( roundingMode == float_round_down ) )
... ... @@ -689,8 +680,8 @@
689 680 || ( zSig0 < LIT64( 0xFFFFFFFFFFFFFFFF ) );
690 681 shift64ExtraRightJamming( zSig0, zSig1, 1 - zExp, &zSig0, &zSig1 );
691 682 zExp = 0;
692   - if ( isTiny && zSig1 ) float_raise( float_flag_underflow );
693   - if ( zSig1 ) float_exception_flags |= float_flag_inexact;
  683 + if ( isTiny && zSig1 ) roundData->exception |= float_flag_underflow;
  684 + if ( zSig1 ) roundData->exception |= float_flag_inexact;
694 685 if ( roundNearestEven ) {
695 686 increment = ( (sbits64) zSig1 < 0 );
696 687 }
... ... @@ -710,7 +701,7 @@
710 701 return packFloatx80( zSign, zExp, zSig0 );
711 702 }
712 703 }
713   - if ( zSig1 ) float_exception_flags |= float_flag_inexact;
  704 + if ( zSig1 ) roundData->exception |= float_flag_inexact;
714 705 if ( increment ) {
715 706 ++zSig0;
716 707 if ( zSig0 == 0 ) {
... ... @@ -740,7 +731,7 @@
740 731 */
741 732 static floatx80
742 733 normalizeRoundAndPackFloatx80(
743   - int8 roundingPrecision, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1
  734 + struct roundingData *roundData, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1
744 735 )
745 736 {
746 737 int8 shiftCount;
... ... @@ -754,7 +745,7 @@
754 745 shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
755 746 zExp -= shiftCount;
756 747 return
757   - roundAndPackFloatx80( roundingPrecision, zSign, zExp, zSig0, zSig1 );
  748 + roundAndPackFloatx80( roundData, zSign, zExp, zSig0, zSig1 );
758 749  
759 750 }
760 751  
761 752  
... ... @@ -767,14 +758,14 @@
767 758 according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
768 759 -------------------------------------------------------------------------------
769 760 */
770   -float32 int32_to_float32( int32 a )
  761 +float32 int32_to_float32(struct roundingData *roundData, int32 a)
771 762 {
772 763 flag zSign;
773 764  
774 765 if ( a == 0 ) return 0;
775 766 if ( a == 0x80000000 ) return packFloat32( 1, 0x9E, 0 );
776 767 zSign = ( a < 0 );
777   - return normalizeRoundAndPackFloat32( zSign, 0x9C, zSign ? - a : a );
  768 + return normalizeRoundAndPackFloat32( roundData, zSign, 0x9C, zSign ? - a : a );
778 769  
779 770 }
780 771  
... ... @@ -840,7 +831,7 @@
840 831 largest integer with the same sign as `a' is returned.
841 832 -------------------------------------------------------------------------------
842 833 */
843   -int32 float32_to_int32( float32 a )
  834 +int32 float32_to_int32( struct roundingData *roundData, float32 a )
844 835 {
845 836 flag aSign;
846 837 int16 aExp, shiftCount;
... ... @@ -856,7 +847,7 @@
856 847 zSig = aSig;
857 848 zSig <<= 32;
858 849 if ( 0 < shiftCount ) shift64RightJamming( zSig, shiftCount, &zSig );
859   - return roundAndPackInt32( aSign, zSig );
  850 + return roundAndPackInt32( roundData, aSign, zSig );
860 851  
861 852 }
862 853  
863 854  
... ... @@ -889,13 +880,13 @@
889 880 return 0x80000000;
890 881 }
891 882 else if ( aExp <= 0x7E ) {
892   - if ( aExp | aSig ) float_exception_flags |= float_flag_inexact;
  883 + if ( aExp | aSig ) float_raise( float_flag_inexact );
893 884 return 0;
894 885 }
895 886 aSig = ( aSig | 0x00800000 )<<8;
896 887 z = aSig>>( - shiftCount );
897 888 if ( (bits32) ( aSig<<( shiftCount & 31 ) ) ) {
898   - float_exception_flags |= float_flag_inexact;
  889 + float_raise( float_flag_inexact );
899 890 }
900 891 return aSign ? - z : z;
901 892  
... ... @@ -973,7 +964,7 @@
973 964 Floating-point Arithmetic.
974 965 -------------------------------------------------------------------------------
975 966 */
976   -float32 float32_round_to_int( float32 a )
  967 +float32 float32_round_to_int( struct roundingData *roundData, float32 a )
977 968 {
978 969 flag aSign;
979 970 int16 aExp;
980 971  
981 972  
... ... @@ -988,11 +979,12 @@
988 979 }
989 980 return a;
990 981 }
  982 + roundingMode = roundData->mode;
991 983 if ( aExp <= 0x7E ) {
992 984 if ( (bits32) ( a<<1 ) == 0 ) return a;
993   - float_exception_flags |= float_flag_inexact;
  985 + roundData->exception |= float_flag_inexact;
994 986 aSign = extractFloat32Sign( a );
995   - switch ( float_rounding_mode ) {
  987 + switch ( roundingMode ) {
996 988 case float_round_nearest_even:
997 989 if ( ( aExp == 0x7E ) && extractFloat32Frac( a ) ) {
998 990 return packFloat32( aSign, 0x7F, 0 );
... ... @@ -1009,7 +1001,6 @@
1009 1001 lastBitMask <<= 0x96 - aExp;
1010 1002 roundBitsMask = lastBitMask - 1;
1011 1003 z = a;
1012   - roundingMode = float_rounding_mode;
1013 1004 if ( roundingMode == float_round_nearest_even ) {
1014 1005 z += lastBitMask>>1;
1015 1006 if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask;
... ... @@ -1020,7 +1011,7 @@
1020 1011 }
1021 1012 }
1022 1013 z &= ~ roundBitsMask;
1023   - if ( z != a ) float_exception_flags |= float_flag_inexact;
  1014 + if ( z != a ) roundData->exception |= float_flag_inexact;
1024 1015 return z;
1025 1016  
1026 1017 }
... ... @@ -1034,7 +1025,7 @@
1034 1025 Floating-point Arithmetic.
1035 1026 -------------------------------------------------------------------------------
1036 1027 */
1037   -static float32 addFloat32Sigs( float32 a, float32 b, flag zSign )
  1028 +static float32 addFloat32Sigs( struct roundingData *roundData, float32 a, float32 b, flag zSign )
1038 1029 {
1039 1030 int16 aExp, bExp, zExp;
1040 1031 bits32 aSig, bSig, zSig;
... ... @@ -1093,7 +1084,7 @@
1093 1084 ++zExp;
1094 1085 }
1095 1086 roundAndPack:
1096   - return roundAndPackFloat32( zSign, zExp, zSig );
  1087 + return roundAndPackFloat32( roundData, zSign, zExp, zSig );
1097 1088  
1098 1089 }
1099 1090  
... ... @@ -1106,7 +1097,7 @@
1106 1097 Standard for Binary Floating-point Arithmetic.
1107 1098 -------------------------------------------------------------------------------
1108 1099 */
1109   -static float32 subFloat32Sigs( float32 a, float32 b, flag zSign )
  1100 +static float32 subFloat32Sigs( struct roundingData *roundData, float32 a, float32 b, flag zSign )
1110 1101 {
1111 1102 int16 aExp, bExp, zExp;
1112 1103 bits32 aSig, bSig, zSig;
... ... @@ -1123,7 +1114,7 @@
1123 1114 if ( expDiff < 0 ) goto bExpBigger;
1124 1115 if ( aExp == 0xFF ) {
1125 1116 if ( aSig | bSig ) return propagateFloat32NaN( a, b );
1126   - float_raise( float_flag_invalid );
  1117 + roundData->exception |= float_flag_invalid;
1127 1118 return float32_default_nan;
1128 1119 }
1129 1120 if ( aExp == 0 ) {
... ... @@ -1132,7 +1123,7 @@
1132 1123 }
1133 1124 if ( bSig < aSig ) goto aBigger;
1134 1125 if ( aSig < bSig ) goto bBigger;
1135   - return packFloat32( float_rounding_mode == float_round_down, 0, 0 );
  1126 + return packFloat32( roundData->mode == float_round_down, 0, 0 );
1136 1127 bExpBigger:
1137 1128 if ( bExp == 0xFF ) {
1138 1129 if ( bSig ) return propagateFloat32NaN( a, b );
... ... @@ -1169,7 +1160,7 @@
1169 1160 zExp = aExp;
1170 1161 normalizeRoundAndPack:
1171 1162 --zExp;
1172   - return normalizeRoundAndPackFloat32( zSign, zExp, zSig );
  1163 + return normalizeRoundAndPackFloat32( roundData, zSign, zExp, zSig );
1173 1164  
1174 1165 }
1175 1166  
1176 1167  
1177 1168  
... ... @@ -1180,17 +1171,17 @@
1180 1171 Binary Floating-point Arithmetic.
1181 1172 -------------------------------------------------------------------------------
1182 1173 */
1183   -float32 float32_add( float32 a, float32 b )
  1174 +float32 float32_add( struct roundingData *roundData, float32 a, float32 b )
1184 1175 {
1185 1176 flag aSign, bSign;
1186 1177  
1187 1178 aSign = extractFloat32Sign( a );
1188 1179 bSign = extractFloat32Sign( b );
1189 1180 if ( aSign == bSign ) {
1190   - return addFloat32Sigs( a, b, aSign );
  1181 + return addFloat32Sigs( roundData, a, b, aSign );
1191 1182 }
1192 1183 else {
1193   - return subFloat32Sigs( a, b, aSign );
  1184 + return subFloat32Sigs( roundData, a, b, aSign );
1194 1185 }
1195 1186  
1196 1187 }
1197 1188  
1198 1189  
... ... @@ -1202,17 +1193,17 @@
1202 1193 for Binary Floating-point Arithmetic.
1203 1194 -------------------------------------------------------------------------------
1204 1195 */
1205   -float32 float32_sub( float32 a, float32 b )
  1196 +float32 float32_sub( struct roundingData *roundData, float32 a, float32 b )
1206 1197 {
1207 1198 flag aSign, bSign;
1208 1199  
1209 1200 aSign = extractFloat32Sign( a );
1210 1201 bSign = extractFloat32Sign( b );
1211 1202 if ( aSign == bSign ) {
1212   - return subFloat32Sigs( a, b, aSign );
  1203 + return subFloat32Sigs( roundData, a, b, aSign );
1213 1204 }
1214 1205 else {
1215   - return addFloat32Sigs( a, b, aSign );
  1206 + return addFloat32Sigs( roundData, a, b, aSign );
1216 1207 }
1217 1208  
1218 1209 }
... ... @@ -1224,7 +1215,7 @@
1224 1215 for Binary Floating-point Arithmetic.
1225 1216 -------------------------------------------------------------------------------
1226 1217 */
1227   -float32 float32_mul( float32 a, float32 b )
  1218 +float32 float32_mul( struct roundingData *roundData, float32 a, float32 b )
1228 1219 {
1229 1220 flag aSign, bSign, zSign;
1230 1221 int16 aExp, bExp, zExp;
... ... @@ -1244,7 +1235,7 @@
1244 1235 return propagateFloat32NaN( a, b );
1245 1236 }
1246 1237 if ( ( bExp | bSig ) == 0 ) {
1247   - float_raise( float_flag_invalid );
  1238 + roundData->exception |= float_flag_invalid;
1248 1239 return float32_default_nan;
1249 1240 }
1250 1241 return packFloat32( zSign, 0xFF, 0 );
... ... @@ -1252,7 +1243,7 @@
1252 1243 if ( bExp == 0xFF ) {
1253 1244 if ( bSig ) return propagateFloat32NaN( a, b );
1254 1245 if ( ( aExp | aSig ) == 0 ) {
1255   - float_raise( float_flag_invalid );
  1246 + roundData->exception |= float_flag_invalid;
1256 1247 return float32_default_nan;
1257 1248 }
1258 1249 return packFloat32( zSign, 0xFF, 0 );
... ... @@ -1274,7 +1265,7 @@
1274 1265 zSig <<= 1;
1275 1266 --zExp;
1276 1267 }
1277   - return roundAndPackFloat32( zSign, zExp, zSig );
  1268 + return roundAndPackFloat32( roundData, zSign, zExp, zSig );
1278 1269  
1279 1270 }
1280 1271  
... ... @@ -1285,7 +1276,7 @@
1285 1276 IEC/IEEE Standard for Binary Floating-point Arithmetic.
1286 1277 -------------------------------------------------------------------------------
1287 1278 */
1288   -float32 float32_div( float32 a, float32 b )
  1279 +float32 float32_div( struct roundingData *roundData, float32 a, float32 b )
1289 1280 {
1290 1281 flag aSign, bSign, zSign;
1291 1282 int16 aExp, bExp, zExp;
... ... @@ -1302,7 +1293,7 @@
1302 1293 if ( aSig ) return propagateFloat32NaN( a, b );
1303 1294 if ( bExp == 0xFF ) {
1304 1295 if ( bSig ) return propagateFloat32NaN( a, b );
1305   - float_raise( float_flag_invalid );
  1296 + roundData->exception |= float_flag_invalid;
1306 1297 return float32_default_nan;
1307 1298 }
1308 1299 return packFloat32( zSign, 0xFF, 0 );
1309 1300  
... ... @@ -1314,10 +1305,10 @@
1314 1305 if ( bExp == 0 ) {
1315 1306 if ( bSig == 0 ) {
1316 1307 if ( ( aExp | aSig ) == 0 ) {
1317   - float_raise( float_flag_invalid );
  1308 + roundData->exception |= float_flag_invalid;
1318 1309 return float32_default_nan;
1319 1310 }
1320   - float_raise( float_flag_divbyzero );
  1311 + roundData->exception |= float_flag_divbyzero;
1321 1312 return packFloat32( zSign, 0xFF, 0 );
1322 1313 }
1323 1314 normalizeFloat32Subnormal( bSig, &bExp, &bSig );
... ... @@ -1341,7 +1332,7 @@
1341 1332 if ( ( zSig & 0x3F ) == 0 ) {
1342 1333 zSig |= ( ( (bits64) bSig ) * zSig != ( (bits64) aSig )<<32 );
1343 1334 }
1344   - return roundAndPackFloat32( zSign, zExp, zSig );
  1335 + return roundAndPackFloat32( roundData, zSign, zExp, zSig );
1345 1336  
1346 1337 }
1347 1338  
... ... @@ -1352,7 +1343,7 @@
1352 1343 according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
1353 1344 -------------------------------------------------------------------------------
1354 1345 */
1355   -float32 float32_rem( float32 a, float32 b )
  1346 +float32 float32_rem( struct roundingData *roundData, float32 a, float32 b )
1356 1347 {
1357 1348 flag aSign, bSign, zSign;
1358 1349 int16 aExp, bExp, expDiff;
... ... @@ -1372,7 +1363,7 @@
1372 1363 if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
1373 1364 return propagateFloat32NaN( a, b );
1374 1365 }
1375   - float_raise( float_flag_invalid );
  1366 + roundData->exception |= float_flag_invalid;
1376 1367 return float32_default_nan;
1377 1368 }
1378 1369 if ( bExp == 0xFF ) {
... ... @@ -1381,7 +1372,7 @@
1381 1372 }
1382 1373 if ( bExp == 0 ) {
1383 1374 if ( bSig == 0 ) {
1384   - float_raise( float_flag_invalid );
  1375 + roundData->exception |= float_flag_invalid;
1385 1376 return float32_default_nan;
1386 1377 }
1387 1378 normalizeFloat32Subnormal( bSig, &bExp, &bSig );
... ... @@ -1444,7 +1435,7 @@
1444 1435 }
1445 1436 zSign = ( (sbits32) aSig < 0 );
1446 1437 if ( zSign ) aSig = - aSig;
1447   - return normalizeRoundAndPackFloat32( aSign ^ zSign, bExp, aSig );
  1438 + return normalizeRoundAndPackFloat32( roundData, aSign ^ zSign, bExp, aSig );
1448 1439  
1449 1440 }
1450 1441  
... ... @@ -1455,7 +1446,7 @@
1455 1446 Floating-point Arithmetic.
1456 1447 -------------------------------------------------------------------------------
1457 1448 */
1458   -float32 float32_sqrt( float32 a )
  1449 +float32 float32_sqrt( struct roundingData *roundData, float32 a )
1459 1450 {
1460 1451 flag aSign;
1461 1452 int16 aExp, zExp;
1462 1453  
... ... @@ -1468,12 +1459,12 @@
1468 1459 if ( aExp == 0xFF ) {
1469 1460 if ( aSig ) return propagateFloat32NaN( a, 0 );
1470 1461 if ( ! aSign ) return a;
1471   - float_raise( float_flag_invalid );
  1462 + roundData->exception |= float_flag_invalid;
1472 1463 return float32_default_nan;
1473 1464 }
1474 1465 if ( aSign ) {
1475 1466 if ( ( aExp | aSig ) == 0 ) return a;
1476   - float_raise( float_flag_invalid );
  1467 + roundData->exception |= float_flag_invalid;
1477 1468 return float32_default_nan;
1478 1469 }
1479 1470 if ( aExp == 0 ) {
... ... @@ -1499,7 +1490,7 @@
1499 1490 }
1500 1491 }
1501 1492 shift32RightJamming( zSig, 1, &zSig );
1502   - return roundAndPackFloat32( 0, zExp, zSig );
  1493 + return roundAndPackFloat32( roundData, 0, zExp, zSig );
1503 1494  
1504 1495 }
1505 1496  
... ... @@ -1661,7 +1652,7 @@
1661 1652 largest integer with the same sign as `a' is returned.
1662 1653 -------------------------------------------------------------------------------
1663 1654 */
1664   -int32 float64_to_int32( float64 a )
  1655 +int32 float64_to_int32( struct roundingData *roundData, float64 a )
1665 1656 {
1666 1657 flag aSign;
1667 1658 int16 aExp, shiftCount;
... ... @@ -1674,7 +1665,7 @@
1674 1665 if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
1675 1666 shiftCount = 0x42C - aExp;
1676 1667 if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig );
1677   - return roundAndPackInt32( aSign, aSig );
  1668 + return roundAndPackInt32( roundData, aSign, aSig );
1678 1669  
1679 1670 }
1680 1671  
... ... @@ -1705,7 +1696,7 @@
1705 1696 goto invalid;
1706 1697 }
1707 1698 else if ( 52 < shiftCount ) {
1708   - if ( aExp || aSig ) float_exception_flags |= float_flag_inexact;
  1699 + if ( aExp || aSig ) float_raise( float_flag_inexact );
1709 1700 return 0;
1710 1701 }
1711 1702 aSig |= LIT64( 0x0010000000000000 );
1712 1703  
... ... @@ -1715,11 +1706,11 @@
1715 1706 if ( aSign ) z = - z;
1716 1707 if ( ( z < 0 ) ^ aSign ) {
1717 1708 invalid:
1718   - float_exception_flags |= float_flag_invalid;
  1709 + float_raise( float_flag_invalid );
1719 1710 return aSign ? 0x80000000 : 0x7FFFFFFF;
1720 1711 }
1721 1712 if ( ( aSig<<shiftCount ) != savedASig ) {
1722   - float_exception_flags |= float_flag_inexact;
  1713 + float_raise( float_flag_inexact );
1723 1714 }
1724 1715 return z;
1725 1716  
... ... @@ -1736,7 +1727,7 @@
1736 1727 largest positive integer is returned.
1737 1728 -------------------------------------------------------------------------------
1738 1729 */
1739   -int32 float64_to_uint32( float64 a )
  1730 +int32 float64_to_uint32( struct roundingData *roundData, float64 a )
1740 1731 {
1741 1732 flag aSign;
1742 1733 int16 aExp, shiftCount;
... ... @@ -1749,7 +1740,7 @@
1749 1740 if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
1750 1741 shiftCount = 0x42C - aExp;
1751 1742 if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig );
1752   - return roundAndPackInt32( aSign, aSig );
  1743 + return roundAndPackInt32( roundData, aSign, aSig );
1753 1744 }
1754 1745  
1755 1746 /*
... ... @@ -1778,7 +1769,7 @@
1778 1769 goto invalid;
1779 1770 }
1780 1771 else if ( 52 < shiftCount ) {
1781   - if ( aExp || aSig ) float_exception_flags |= float_flag_inexact;
  1772 + if ( aExp || aSig ) float_raise( float_flag_inexact );
1782 1773 return 0;
1783 1774 }
1784 1775 aSig |= LIT64( 0x0010000000000000 );
1785 1776  
... ... @@ -1788,11 +1779,11 @@
1788 1779 if ( aSign ) z = - z;
1789 1780 if ( ( z < 0 ) ^ aSign ) {
1790 1781 invalid:
1791   - float_exception_flags |= float_flag_invalid;
  1782 + float_raise( float_flag_invalid );
1792 1783 return aSign ? 0x80000000 : 0x7FFFFFFF;
1793 1784 }
1794 1785 if ( ( aSig<<shiftCount ) != savedASig ) {
1795   - float_exception_flags |= float_flag_inexact;
  1786 + float_raise( float_flag_inexact );
1796 1787 }
1797 1788 return z;
1798 1789 }
... ... @@ -1805,7 +1796,7 @@
1805 1796 Arithmetic.
1806 1797 -------------------------------------------------------------------------------
1807 1798 */
1808   -float32 float64_to_float32( float64 a )
  1799 +float32 float64_to_float32( struct roundingData *roundData, float64 a )
1809 1800 {
1810 1801 flag aSign;
1811 1802 int16 aExp;
... ... @@ -1825,7 +1816,7 @@
1825 1816 zSig |= 0x40000000;
1826 1817 aExp -= 0x381;
1827 1818 }
1828   - return roundAndPackFloat32( aSign, aExp, zSig );
  1819 + return roundAndPackFloat32( roundData, aSign, aExp, zSig );
1829 1820  
1830 1821 }
1831 1822  
... ... @@ -1872,7 +1863,7 @@
1872 1863 Floating-point Arithmetic.
1873 1864 -------------------------------------------------------------------------------
1874 1865 */
1875   -float64 float64_round_to_int( float64 a )
  1866 +float64 float64_round_to_int( struct roundingData *roundData, float64 a )
1876 1867 {
1877 1868 flag aSign;
1878 1869 int16 aExp;
1879 1870  
... ... @@ -1889,9 +1880,9 @@
1889 1880 }
1890 1881 if ( aExp <= 0x3FE ) {
1891 1882 if ( (bits64) ( a<<1 ) == 0 ) return a;
1892   - float_exception_flags |= float_flag_inexact;
  1883 + roundData->exception |= float_flag_inexact;
1893 1884 aSign = extractFloat64Sign( a );
1894   - switch ( float_rounding_mode ) {
  1885 + switch ( roundData->mode ) {
1895 1886 case float_round_nearest_even:
1896 1887 if ( ( aExp == 0x3FE ) && extractFloat64Frac( a ) ) {
1897 1888 return packFloat64( aSign, 0x3FF, 0 );
... ... @@ -1909,7 +1900,7 @@
1909 1900 lastBitMask <<= 0x433 - aExp;
1910 1901 roundBitsMask = lastBitMask - 1;
1911 1902 z = a;
1912   - roundingMode = float_rounding_mode;
  1903 + roundingMode = roundData->mode;
1913 1904 if ( roundingMode == float_round_nearest_even ) {
1914 1905 z += lastBitMask>>1;
1915 1906 if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask;
... ... @@ -1920,7 +1911,7 @@
1920 1911 }
1921 1912 }
1922 1913 z &= ~ roundBitsMask;
1923   - if ( z != a ) float_exception_flags |= float_flag_inexact;
  1914 + if ( z != a ) roundData->exception |= float_flag_inexact;
1924 1915 return z;
1925 1916  
1926 1917 }
... ... @@ -1934,7 +1925,7 @@
1934 1925 Floating-point Arithmetic.
1935 1926 -------------------------------------------------------------------------------
1936 1927 */
1937   -static float64 addFloat64Sigs( float64 a, float64 b, flag zSign )
  1928 +static float64 addFloat64Sigs( struct roundingData *roundData, float64 a, float64 b, flag zSign )
1938 1929 {
1939 1930 int16 aExp, bExp, zExp;
1940 1931 bits64 aSig, bSig, zSig;
... ... @@ -1993,7 +1984,7 @@
1993 1984 ++zExp;
1994 1985 }
1995 1986 roundAndPack:
1996   - return roundAndPackFloat64( zSign, zExp, zSig );
  1987 + return roundAndPackFloat64( roundData, zSign, zExp, zSig );
1997 1988  
1998 1989 }
1999 1990  
... ... @@ -2006,7 +1997,7 @@
2006 1997 Standard for Binary Floating-point Arithmetic.
2007 1998 -------------------------------------------------------------------------------
2008 1999 */
2009   -static float64 subFloat64Sigs( float64 a, float64 b, flag zSign )
  2000 +static float64 subFloat64Sigs( struct roundingData *roundData, float64 a, float64 b, flag zSign )
2010 2001 {
2011 2002 int16 aExp, bExp, zExp;
2012 2003 bits64 aSig, bSig, zSig;
... ... @@ -2023,7 +2014,7 @@
2023 2014 if ( expDiff < 0 ) goto bExpBigger;
2024 2015 if ( aExp == 0x7FF ) {
2025 2016 if ( aSig | bSig ) return propagateFloat64NaN( a, b );
2026   - float_raise( float_flag_invalid );
  2017 + roundData->exception |= float_flag_invalid;
2027 2018 return float64_default_nan;
2028 2019 }
2029 2020 if ( aExp == 0 ) {
... ... @@ -2032,7 +2023,7 @@
2032 2023 }
2033 2024 if ( bSig < aSig ) goto aBigger;
2034 2025 if ( aSig < bSig ) goto bBigger;
2035   - return packFloat64( float_rounding_mode == float_round_down, 0, 0 );
  2026 + return packFloat64( roundData->mode == float_round_down, 0, 0 );
2036 2027 bExpBigger:
2037 2028 if ( bExp == 0x7FF ) {
2038 2029 if ( bSig ) return propagateFloat64NaN( a, b );
... ... @@ -2069,7 +2060,7 @@
2069 2060 zExp = aExp;
2070 2061 normalizeRoundAndPack:
2071 2062 --zExp;
2072   - return normalizeRoundAndPackFloat64( zSign, zExp, zSig );
  2063 + return normalizeRoundAndPackFloat64( roundData, zSign, zExp, zSig );
2073 2064  
2074 2065 }
2075 2066  
2076 2067  
2077 2068  
... ... @@ -2080,17 +2071,17 @@
2080 2071 Binary Floating-point Arithmetic.
2081 2072 -------------------------------------------------------------------------------
2082 2073 */
2083   -float64 float64_add( float64 a, float64 b )
  2074 +float64 float64_add( struct roundingData *roundData, float64 a, float64 b )
2084 2075 {
2085 2076 flag aSign, bSign;
2086 2077  
2087 2078 aSign = extractFloat64Sign( a );
2088 2079 bSign = extractFloat64Sign( b );
2089 2080 if ( aSign == bSign ) {
2090   - return addFloat64Sigs( a, b, aSign );
  2081 + return addFloat64Sigs( roundData, a, b, aSign );
2091 2082 }
2092 2083 else {
2093   - return subFloat64Sigs( a, b, aSign );
  2084 + return subFloat64Sigs( roundData, a, b, aSign );
2094 2085 }
2095 2086  
2096 2087 }
2097 2088  
2098 2089  
... ... @@ -2102,17 +2093,17 @@
2102 2093 for Binary Floating-point Arithmetic.
2103 2094 -------------------------------------------------------------------------------
2104 2095 */
2105   -float64 float64_sub( float64 a, float64 b )
  2096 +float64 float64_sub( struct roundingData *roundData, float64 a, float64 b )
2106 2097 {
2107 2098 flag aSign, bSign;
2108 2099  
2109 2100 aSign = extractFloat64Sign( a );
2110 2101 bSign = extractFloat64Sign( b );
2111 2102 if ( aSign == bSign ) {
2112   - return subFloat64Sigs( a, b, aSign );
  2103 + return subFloat64Sigs( roundData, a, b, aSign );
2113 2104 }
2114 2105 else {
2115   - return addFloat64Sigs( a, b, aSign );
  2106 + return addFloat64Sigs( roundData, a, b, aSign );
2116 2107 }
2117 2108  
2118 2109 }
... ... @@ -2124,7 +2115,7 @@
2124 2115 for Binary Floating-point Arithmetic.
2125 2116 -------------------------------------------------------------------------------
2126 2117 */
2127   -float64 float64_mul( float64 a, float64 b )
  2118 +float64 float64_mul( struct roundingData *roundData, float64 a, float64 b )
2128 2119 {
2129 2120 flag aSign, bSign, zSign;
2130 2121 int16 aExp, bExp, zExp;
... ... @@ -2142,7 +2133,7 @@
2142 2133 return propagateFloat64NaN( a, b );
2143 2134 }
2144 2135 if ( ( bExp | bSig ) == 0 ) {
2145   - float_raise( float_flag_invalid );
  2136 + roundData->exception |= float_flag_invalid;
2146 2137 return float64_default_nan;
2147 2138 }
2148 2139 return packFloat64( zSign, 0x7FF, 0 );
... ... @@ -2150,7 +2141,7 @@
2150 2141 if ( bExp == 0x7FF ) {
2151 2142 if ( bSig ) return propagateFloat64NaN( a, b );
2152 2143 if ( ( aExp | aSig ) == 0 ) {
2153   - float_raise( float_flag_invalid );
  2144 + roundData->exception |= float_flag_invalid;
2154 2145 return float64_default_nan;
2155 2146 }
2156 2147 return packFloat64( zSign, 0x7FF, 0 );
... ... @@ -2172,7 +2163,7 @@
2172 2163 zSig0 <<= 1;
2173 2164 --zExp;
2174 2165 }
2175   - return roundAndPackFloat64( zSign, zExp, zSig0 );
  2166 + return roundAndPackFloat64( roundData, zSign, zExp, zSig0 );
2176 2167  
2177 2168 }
2178 2169  
... ... @@ -2183,7 +2174,7 @@
2183 2174 the IEC/IEEE Standard for Binary Floating-point Arithmetic.
2184 2175 -------------------------------------------------------------------------------
2185 2176 */
2186   -float64 float64_div( float64 a, float64 b )
  2177 +float64 float64_div( struct roundingData *roundData, float64 a, float64 b )
2187 2178 {
2188 2179 flag aSign, bSign, zSign;
2189 2180 int16 aExp, bExp, zExp;
... ... @@ -2202,7 +2193,7 @@
2202 2193 if ( aSig ) return propagateFloat64NaN( a, b );
2203 2194 if ( bExp == 0x7FF ) {
2204 2195 if ( bSig ) return propagateFloat64NaN( a, b );
2205   - float_raise( float_flag_invalid );
  2196 + roundData->exception |= float_flag_invalid;
2206 2197 return float64_default_nan;
2207 2198 }
2208 2199 return packFloat64( zSign, 0x7FF, 0 );
2209 2200  
... ... @@ -2214,10 +2205,10 @@
2214 2205 if ( bExp == 0 ) {
2215 2206 if ( bSig == 0 ) {
2216 2207 if ( ( aExp | aSig ) == 0 ) {
2217   - float_raise( float_flag_invalid );
  2208 + roundData->exception |= float_flag_invalid;
2218 2209 return float64_default_nan;
2219 2210 }
2220   - float_raise( float_flag_divbyzero );
  2211 + roundData->exception |= float_flag_divbyzero;
2221 2212 return packFloat64( zSign, 0x7FF, 0 );
2222 2213 }
2223 2214 normalizeFloat64Subnormal( bSig, &bExp, &bSig );
... ... @@ -2243,7 +2234,7 @@
2243 2234 }
2244 2235 zSig |= ( rem1 != 0 );
2245 2236 }
2246   - return roundAndPackFloat64( zSign, zExp, zSig );
  2237 + return roundAndPackFloat64( roundData, zSign, zExp, zSig );
2247 2238  
2248 2239 }
2249 2240  
... ... @@ -2254,7 +2245,7 @@
2254 2245 according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
2255 2246 -------------------------------------------------------------------------------
2256 2247 */
2257   -float64 float64_rem( float64 a, float64 b )
  2248 +float64 float64_rem( struct roundingData *roundData, float64 a, float64 b )
2258 2249 {
2259 2250 flag aSign, bSign, zSign;
2260 2251 int16 aExp, bExp, expDiff;
... ... @@ -2272,7 +2263,7 @@
2272 2263 if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) {
2273 2264 return propagateFloat64NaN( a, b );
2274 2265 }
2275   - float_raise( float_flag_invalid );
  2266 + roundData->exception |= float_flag_invalid;
2276 2267 return float64_default_nan;
2277 2268 }
2278 2269 if ( bExp == 0x7FF ) {
... ... @@ -2281,7 +2272,7 @@
2281 2272 }
2282 2273 if ( bExp == 0 ) {
2283 2274 if ( bSig == 0 ) {
2284   - float_raise( float_flag_invalid );
  2275 + roundData->exception |= float_flag_invalid;
2285 2276 return float64_default_nan;
2286 2277 }
2287 2278 normalizeFloat64Subnormal( bSig, &bExp, &bSig );
... ... @@ -2329,7 +2320,7 @@
2329 2320 }
2330 2321 zSign = ( (sbits64) aSig < 0 );
2331 2322 if ( zSign ) aSig = - aSig;
2332   - return normalizeRoundAndPackFloat64( aSign ^ zSign, bExp, aSig );
  2323 + return normalizeRoundAndPackFloat64( roundData, aSign ^ zSign, bExp, aSig );
2333 2324  
2334 2325 }
2335 2326  
... ... @@ -2340,7 +2331,7 @@
2340 2331 Floating-point Arithmetic.
2341 2332 -------------------------------------------------------------------------------
2342 2333 */
2343   -float64 float64_sqrt( float64 a )
  2334 +float64 float64_sqrt( struct roundingData *roundData, float64 a )
2344 2335 {
2345 2336 flag aSign;
2346 2337 int16 aExp, zExp;
2347 2338  
... ... @@ -2354,12 +2345,12 @@
2354 2345 if ( aExp == 0x7FF ) {
2355 2346 if ( aSig ) return propagateFloat64NaN( a, a );
2356 2347 if ( ! aSign ) return a;
2357   - float_raise( float_flag_invalid );
  2348 + roundData->exception |= float_flag_invalid;
2358 2349 return float64_default_nan;
2359 2350 }
2360 2351 if ( aSign ) {
2361 2352 if ( ( aExp | aSig ) == 0 ) return a;
2362   - float_raise( float_flag_invalid );
  2353 + roundData->exception |= float_flag_invalid;
2363 2354 return float64_default_nan;
2364 2355 }
2365 2356 if ( aExp == 0 ) {
... ... @@ -2390,7 +2381,7 @@
2390 2381 }
2391 2382 }
2392 2383 shift64RightJamming( zSig, 1, &zSig );
2393   - return roundAndPackFloat64( 0, zExp, zSig );
  2384 + return roundAndPackFloat64( roundData, 0, zExp, zSig );
2394 2385  
2395 2386 }
2396 2387  
... ... @@ -2554,7 +2545,7 @@
2554 2545 overflows, the largest integer with the same sign as `a' is returned.
2555 2546 -------------------------------------------------------------------------------
2556 2547 */
2557   -int32 floatx80_to_int32( floatx80 a )
  2548 +int32 floatx80_to_int32( struct roundingData *roundData, floatx80 a )
2558 2549 {
2559 2550 flag aSign;
2560 2551 int32 aExp, shiftCount;
... ... @@ -2567,7 +2558,7 @@
2567 2558 shiftCount = 0x4037 - aExp;
2568 2559 if ( shiftCount <= 0 ) shiftCount = 1;
2569 2560 shift64RightJamming( aSig, shiftCount, &aSig );
2570   - return roundAndPackInt32( aSign, aSig );
  2561 + return roundAndPackInt32( roundData, aSign, aSig );
2571 2562  
2572 2563 }
2573 2564  
... ... @@ -2598,7 +2589,7 @@
2598 2589 goto invalid;
2599 2590 }
2600 2591 else if ( 63 < shiftCount ) {
2601   - if ( aExp || aSig ) float_exception_flags |= float_flag_inexact;
  2592 + if ( aExp || aSig ) float_raise( float_flag_inexact );
2602 2593 return 0;
2603 2594 }
2604 2595 savedASig = aSig;
2605 2596  
... ... @@ -2607,11 +2598,11 @@
2607 2598 if ( aSign ) z = - z;
2608 2599 if ( ( z < 0 ) ^ aSign ) {
2609 2600 invalid:
2610   - float_exception_flags |= float_flag_invalid;
  2601 + float_raise( float_flag_invalid );
2611 2602 return aSign ? 0x80000000 : 0x7FFFFFFF;
2612 2603 }
2613 2604 if ( ( aSig<<shiftCount ) != savedASig ) {
2614   - float_exception_flags |= float_flag_inexact;
  2605 + float_raise( float_flag_inexact );
2615 2606 }
2616 2607 return z;
2617 2608  
... ... @@ -2625,7 +2616,7 @@
2625 2616 Floating-point Arithmetic.
2626 2617 -------------------------------------------------------------------------------
2627 2618 */
2628   -float32 floatx80_to_float32( floatx80 a )
  2619 +float32 floatx80_to_float32( struct roundingData *roundData, floatx80 a )
2629 2620 {
2630 2621 flag aSign;
2631 2622 int32 aExp;
... ... @@ -2642,7 +2633,7 @@
2642 2633 }
2643 2634 shift64RightJamming( aSig, 33, &aSig );
2644 2635 if ( aExp || aSig ) aExp -= 0x3F81;
2645   - return roundAndPackFloat32( aSign, aExp, aSig );
  2636 + return roundAndPackFloat32( roundData, aSign, aExp, aSig );
2646 2637  
2647 2638 }
2648 2639  
... ... @@ -2654,7 +2645,7 @@
2654 2645 Floating-point Arithmetic.
2655 2646 -------------------------------------------------------------------------------
2656 2647 */
2657   -float64 floatx80_to_float64( floatx80 a )
  2648 +float64 floatx80_to_float64( struct roundingData *roundData, floatx80 a )
2658 2649 {
2659 2650 flag aSign;
2660 2651 int32 aExp;
... ... @@ -2671,7 +2662,7 @@
2671 2662 }
2672 2663 shift64RightJamming( aSig, 1, &zSig );
2673 2664 if ( aExp || aSig ) aExp -= 0x3C01;
2674   - return roundAndPackFloat64( aSign, aExp, zSig );
  2665 + return roundAndPackFloat64( roundData, aSign, aExp, zSig );
2675 2666  
2676 2667 }
2677 2668  
... ... @@ -2683,7 +2674,7 @@
2683 2674 Binary Floating-point Arithmetic.
2684 2675 -------------------------------------------------------------------------------
2685 2676 */
2686   -floatx80 floatx80_round_to_int( floatx80 a )
  2677 +floatx80 floatx80_round_to_int( struct roundingData *roundData, floatx80 a )
2687 2678 {
2688 2679 flag aSign;
2689 2680 int32 aExp;
2690 2681  
... ... @@ -2703,9 +2694,9 @@
2703 2694 && ( (bits64) ( extractFloatx80Frac( a )<<1 ) == 0 ) ) {
2704 2695 return a;
2705 2696 }
2706   - float_exception_flags |= float_flag_inexact;
  2697 + roundData->exception |= float_flag_inexact;
2707 2698 aSign = extractFloatx80Sign( a );
2708   - switch ( float_rounding_mode ) {
  2699 + switch ( roundData->mode ) {
2709 2700 case float_round_nearest_even:
2710 2701 if ( ( aExp == 0x3FFE ) && (bits64) ( extractFloatx80Frac( a )<<1 )
2711 2702 ) {
... ... @@ -2729,7 +2720,7 @@
2729 2720 lastBitMask <<= 0x403E - aExp;
2730 2721 roundBitsMask = lastBitMask - 1;
2731 2722 z = a;
2732   - roundingMode = float_rounding_mode;
  2723 + roundingMode = roundData->mode;
2733 2724 if ( roundingMode == float_round_nearest_even ) {
2734 2725 z.low += lastBitMask>>1;
2735 2726 if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask;
... ... @@ -2744,7 +2735,7 @@
2744 2735 ++z.high;
2745 2736 z.low = LIT64( 0x8000000000000000 );
2746 2737 }
2747   - if ( z.low != a.low ) float_exception_flags |= float_flag_inexact;
  2738 + if ( z.low != a.low ) roundData->exception |= float_flag_inexact;
2748 2739 return z;
2749 2740  
2750 2741 }
... ... @@ -2758,7 +2749,7 @@
2758 2749 Floating-point Arithmetic.
2759 2750 -------------------------------------------------------------------------------
2760 2751 */
2761   -static floatx80 addFloatx80Sigs( floatx80 a, floatx80 b, flag zSign )
  2752 +static floatx80 addFloatx80Sigs( struct roundingData *roundData, floatx80 a, floatx80 b, flag zSign )
2762 2753 {
2763 2754 int32 aExp, bExp, zExp;
2764 2755 bits64 aSig, bSig, zSig0, zSig1;
... ... @@ -2814,7 +2805,7 @@
2814 2805 roundAndPack:
2815 2806 return
2816 2807 roundAndPackFloatx80(
2817   - floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 );
  2808 + roundData, zSign, zExp, zSig0, zSig1 );
2818 2809  
2819 2810 }
2820 2811  
... ... @@ -2827,7 +2818,7 @@
2827 2818 Standard for Binary Floating-point Arithmetic.
2828 2819 -------------------------------------------------------------------------------
2829 2820 */
2830   -static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign )
  2821 +static floatx80 subFloatx80Sigs( struct roundingData *roundData, floatx80 a, floatx80 b, flag zSign )
2831 2822 {
2832 2823 int32 aExp, bExp, zExp;
2833 2824 bits64 aSig, bSig, zSig0, zSig1;
... ... @@ -2845,7 +2836,7 @@
2845 2836 if ( (bits64) ( ( aSig | bSig )<<1 ) ) {
2846 2837 return propagateFloatx80NaN( a, b );
2847 2838 }
2848   - float_raise( float_flag_invalid );
  2839 + roundData->exception |= float_flag_invalid;
2849 2840 z.low = floatx80_default_nan_low;
2850 2841 z.high = floatx80_default_nan_high;
2851 2842 return z;
... ... @@ -2857,7 +2848,7 @@
2857 2848 zSig1 = 0;
2858 2849 if ( bSig < aSig ) goto aBigger;
2859 2850 if ( aSig < bSig ) goto bBigger;
2860   - return packFloatx80( float_rounding_mode == float_round_down, 0, 0 );
  2851 + return packFloatx80( roundData->mode == float_round_down, 0, 0 );
2861 2852 bExpBigger:
2862 2853 if ( bExp == 0x7FFF ) {
2863 2854 if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
... ... @@ -2883,7 +2874,7 @@
2883 2874 normalizeRoundAndPack:
2884 2875 return
2885 2876 normalizeRoundAndPackFloatx80(
2886   - floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 );
  2877 + roundData, zSign, zExp, zSig0, zSig1 );
2887 2878  
2888 2879 }
2889 2880  
2890 2881  
2891 2882  
... ... @@ -2894,17 +2885,17 @@
2894 2885 Standard for Binary Floating-point Arithmetic.
2895 2886 -------------------------------------------------------------------------------
2896 2887 */
2897   -floatx80 floatx80_add( floatx80 a, floatx80 b )
  2888 +floatx80 floatx80_add( struct roundingData *roundData, floatx80 a, floatx80 b )
2898 2889 {
2899 2890 flag aSign, bSign;
2900 2891  
2901 2892 aSign = extractFloatx80Sign( a );
2902 2893 bSign = extractFloatx80Sign( b );
2903 2894 if ( aSign == bSign ) {
2904   - return addFloatx80Sigs( a, b, aSign );
  2895 + return addFloatx80Sigs( roundData, a, b, aSign );
2905 2896 }
2906 2897 else {
2907   - return subFloatx80Sigs( a, b, aSign );
  2898 + return subFloatx80Sigs( roundData, a, b, aSign );
2908 2899 }
2909 2900  
2910 2901 }
2911 2902  
2912 2903  
... ... @@ -2916,17 +2907,17 @@
2916 2907 IEC/IEEE Standard for Binary Floating-point Arithmetic.
2917 2908 -------------------------------------------------------------------------------
2918 2909 */
2919   -floatx80 floatx80_sub( floatx80 a, floatx80 b )
  2910 +floatx80 floatx80_sub( struct roundingData *roundData, floatx80 a, floatx80 b )
2920 2911 {
2921 2912 flag aSign, bSign;
2922 2913  
2923 2914 aSign = extractFloatx80Sign( a );
2924 2915 bSign = extractFloatx80Sign( b );
2925 2916 if ( aSign == bSign ) {
2926   - return subFloatx80Sigs( a, b, aSign );
  2917 + return subFloatx80Sigs( roundData, a, b, aSign );
2927 2918 }
2928 2919 else {
2929   - return addFloatx80Sigs( a, b, aSign );
  2920 + return addFloatx80Sigs( roundData, a, b, aSign );
2930 2921 }
2931 2922  
2932 2923 }
... ... @@ -2938,7 +2929,7 @@
2938 2929 IEC/IEEE Standard for Binary Floating-point Arithmetic.
2939 2930 -------------------------------------------------------------------------------
2940 2931 */
2941   -floatx80 floatx80_mul( floatx80 a, floatx80 b )
  2932 +floatx80 floatx80_mul( struct roundingData *roundData, floatx80 a, floatx80 b )
2942 2933 {
2943 2934 flag aSign, bSign, zSign;
2944 2935 int32 aExp, bExp, zExp;
... ... @@ -2964,7 +2955,7 @@
2964 2955 if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
2965 2956 if ( ( aExp | aSig ) == 0 ) {
2966 2957 invalid:
2967   - float_raise( float_flag_invalid );
  2958 + roundData->exception |= float_flag_invalid;
2968 2959 z.low = floatx80_default_nan_low;
2969 2960 z.high = floatx80_default_nan_high;
2970 2961 return z;
... ... @@ -2987,7 +2978,7 @@
2987 2978 }
2988 2979 return
2989 2980 roundAndPackFloatx80(
2990   - floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 );
  2981 + roundData, zSign, zExp, zSig0, zSig1 );
2991 2982  
2992 2983 }
2993 2984  
... ... @@ -2998,7 +2989,7 @@
2998 2989 according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
2999 2990 -------------------------------------------------------------------------------
3000 2991 */
3001   -floatx80 floatx80_div( floatx80 a, floatx80 b )
  2992 +floatx80 floatx80_div( struct roundingData *roundData, floatx80 a, floatx80 b )
3002 2993 {
3003 2994 flag aSign, bSign, zSign;
3004 2995 int32 aExp, bExp, zExp;
3005 2996  
... ... @@ -3029,12 +3020,12 @@
3029 3020 if ( bSig == 0 ) {
3030 3021 if ( ( aExp | aSig ) == 0 ) {
3031 3022 invalid:
3032   - float_raise( float_flag_invalid );
  3023 + roundData->exception |= float_flag_invalid;
3033 3024 z.low = floatx80_default_nan_low;
3034 3025 z.high = floatx80_default_nan_high;
3035 3026 return z;
3036 3027 }
3037   - float_raise( float_flag_divbyzero );
  3028 + roundData->exception |= float_flag_divbyzero;
3038 3029 return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
3039 3030 }
3040 3031 normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
... ... @@ -3068,7 +3059,7 @@
3068 3059 }
3069 3060 return
3070 3061 roundAndPackFloatx80(
3071   - floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 );
  3062 + roundData, zSign, zExp, zSig0, zSig1 );
3072 3063  
3073 3064 }
3074 3065  
... ... @@ -3079,7 +3070,7 @@
3079 3070 according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
3080 3071 -------------------------------------------------------------------------------
3081 3072 */
3082   -floatx80 floatx80_rem( floatx80 a, floatx80 b )
  3073 +floatx80 floatx80_rem( struct roundingData *roundData, floatx80 a, floatx80 b )
3083 3074 {
3084 3075 flag aSign, bSign, zSign;
3085 3076 int32 aExp, bExp, expDiff;
... ... @@ -3107,7 +3098,7 @@
3107 3098 if ( bExp == 0 ) {
3108 3099 if ( bSig == 0 ) {
3109 3100 invalid:
3110   - float_raise( float_flag_invalid );
  3101 + roundData->exception |= float_flag_invalid;
3111 3102 z.low = floatx80_default_nan_low;
3112 3103 z.high = floatx80_default_nan_high;
3113 3104 return z;
3114 3105  
... ... @@ -3164,9 +3155,10 @@
3164 3155 aSig1 = alternateASig1;
3165 3156 zSign = ! zSign;
3166 3157 }
  3158 +
3167 3159 return
3168 3160 normalizeRoundAndPackFloatx80(
3169   - 80, zSign, bExp + expDiff, aSig0, aSig1 );
  3161 + roundData, zSign, bExp + expDiff, aSig0, aSig1 );
3170 3162  
3171 3163 }
3172 3164  
... ... @@ -3177,7 +3169,7 @@
3177 3169 for Binary Floating-point Arithmetic.
3178 3170 -------------------------------------------------------------------------------
3179 3171 */
3180   -floatx80 floatx80_sqrt( floatx80 a )
  3172 +floatx80 floatx80_sqrt( struct roundingData *roundData, floatx80 a )
3181 3173 {
3182 3174 flag aSign;
3183 3175 int32 aExp, zExp;
... ... @@ -3197,7 +3189,7 @@
3197 3189 if ( aSign ) {
3198 3190 if ( ( aExp | aSig0 ) == 0 ) return a;
3199 3191 invalid:
3200   - float_raise( float_flag_invalid );
  3192 + roundData->exception |= float_flag_invalid;
3201 3193 z.low = floatx80_default_nan_low;
3202 3194 z.high = floatx80_default_nan_high;
3203 3195 return z;
... ... @@ -3242,7 +3234,7 @@
3242 3234 }
3243 3235 return
3244 3236 roundAndPackFloatx80(
3245   - floatx80_rounding_precision, 0, zExp, zSig0, zSig1 );
  3237 + roundData, 0, zExp, zSig0, zSig1 );
3246 3238  
3247 3239 }
3248 3240  
... ... @@ -3264,7 +3256,7 @@
3264 3256 ) {
3265 3257 if ( floatx80_is_signaling_nan( a )
3266 3258 || floatx80_is_signaling_nan( b ) ) {
3267   - float_raise( float_flag_invalid );
  3259 + roundData->exception |= float_flag_invalid;
3268 3260 }
3269 3261 return 0;
3270 3262 }
... ... @@ -3294,7 +3286,7 @@
3294 3286 || ( ( extractFloatx80Exp( b ) == 0x7FFF )
3295 3287 && (bits64) ( extractFloatx80Frac( b )<<1 ) )
3296 3288 ) {
3297   - float_raise( float_flag_invalid );
  3289 + roundData->exception |= float_flag_invalid;
3298 3290 return 0;
3299 3291 }
3300 3292 aSign = extractFloatx80Sign( a );
... ... @@ -3328,7 +3320,7 @@
3328 3320 || ( ( extractFloatx80Exp( b ) == 0x7FFF )
3329 3321 && (bits64) ( extractFloatx80Frac( b )<<1 ) )
3330 3322 ) {
3331   - float_raise( float_flag_invalid );
  3323 + roundData->exception |= float_flag_invalid;
3332 3324 return 0;
3333 3325 }
3334 3326 aSign = extractFloatx80Sign( a );
... ... @@ -3361,7 +3353,7 @@
3361 3353 || ( ( extractFloatx80Exp( b ) == 0x7FFF )
3362 3354 && (bits64) ( extractFloatx80Frac( b )<<1 ) )
3363 3355 ) {
3364   - float_raise( float_flag_invalid );
  3356 + roundData->exception |= float_flag_invalid;
3365 3357 return 0;
3366 3358 }
3367 3359 return
... ... @@ -3392,7 +3384,7 @@
3392 3384 ) {
3393 3385 if ( floatx80_is_signaling_nan( a )
3394 3386 || floatx80_is_signaling_nan( b ) ) {
3395   - float_raise( float_flag_invalid );
  3387 + roundData->exception |= float_flag_invalid;
3396 3388 }
3397 3389 return 0;
3398 3390 }
... ... @@ -3429,7 +3421,7 @@
3429 3421 ) {
3430 3422 if ( floatx80_is_signaling_nan( a )
3431 3423 || floatx80_is_signaling_nan( b ) ) {
3432   - float_raise( float_flag_invalid );
  3424 + roundData->exception |= float_flag_invalid;
3433 3425 }
3434 3426 return 0;
3435 3427 }
arch/arm/nwfpe/softfloat.h
... ... @@ -74,7 +74,7 @@
74 74 Software IEC/IEEE floating-point rounding mode.
75 75 -------------------------------------------------------------------------------
76 76 */
77   -extern signed char float_rounding_mode;
  77 +//extern int8 float_rounding_mode;
78 78 enum {
79 79 float_round_nearest_even = 0,
80 80 float_round_to_zero = 1,
... ... @@ -86,7 +86,6 @@
86 86 -------------------------------------------------------------------------------
87 87 Software IEC/IEEE floating-point exception flags.
88 88 -------------------------------------------------------------------------------
89   -extern signed char float_exception_flags;
90 89 enum {
91 90 float_flag_inexact = 1,
92 91 float_flag_underflow = 2,
... ... @@ -99,7 +98,6 @@
99 98 Changed the enumeration to match the bit order in the FPA11.
100 99 */
101 100  
102   -extern signed char float_exception_flags;
103 101 enum {
104 102 float_flag_invalid = 1,
105 103 float_flag_divbyzero = 2,
... ... @@ -121,7 +119,7 @@
121 119 Software IEC/IEEE integer-to-floating-point conversion routines.
122 120 -------------------------------------------------------------------------------
123 121 */
124   -float32 int32_to_float32( signed int );
  122 +float32 int32_to_float32( struct roundingData *, signed int );
125 123 float64 int32_to_float64( signed int );
126 124 #ifdef FLOATX80
127 125 floatx80 int32_to_floatx80( signed int );
... ... @@ -132,7 +130,7 @@
132 130 Software IEC/IEEE single-precision conversion routines.
133 131 -------------------------------------------------------------------------------
134 132 */
135   -signed int float32_to_int32( float32 );
  133 +signed int float32_to_int32( struct roundingData *, float32 );
136 134 signed int float32_to_int32_round_to_zero( float32 );
137 135 float64 float32_to_float64( float32 );
138 136 #ifdef FLOATX80
... ... @@ -144,13 +142,13 @@
144 142 Software IEC/IEEE single-precision operations.
145 143 -------------------------------------------------------------------------------
146 144 */
147   -float32 float32_round_to_int( float32 );
148   -float32 float32_add( float32, float32 );
149   -float32 float32_sub( float32, float32 );
150   -float32 float32_mul( float32, float32 );
151   -float32 float32_div( float32, float32 );
152   -float32 float32_rem( float32, float32 );
153   -float32 float32_sqrt( float32 );
  145 +float32 float32_round_to_int( struct roundingData*, float32 );
  146 +float32 float32_add( struct roundingData *, float32, float32 );
  147 +float32 float32_sub( struct roundingData *, float32, float32 );
  148 +float32 float32_mul( struct roundingData *, float32, float32 );
  149 +float32 float32_div( struct roundingData *, float32, float32 );
  150 +float32 float32_rem( struct roundingData *, float32, float32 );
  151 +float32 float32_sqrt( struct roundingData*, float32 );
154 152 char float32_eq( float32, float32 );
155 153 char float32_le( float32, float32 );
156 154 char float32_lt( float32, float32 );
157 155  
... ... @@ -164,9 +162,9 @@
164 162 Software IEC/IEEE double-precision conversion routines.
165 163 -------------------------------------------------------------------------------
166 164 */
167   -signed int float64_to_int32( float64 );
  165 +signed int float64_to_int32( struct roundingData *, float64 );
168 166 signed int float64_to_int32_round_to_zero( float64 );
169   -float32 float64_to_float32( float64 );
  167 +float32 float64_to_float32( struct roundingData *, float64 );
170 168 #ifdef FLOATX80
171 169 floatx80 float64_to_floatx80( float64 );
172 170 #endif
... ... @@ -176,13 +174,13 @@
176 174 Software IEC/IEEE double-precision operations.
177 175 -------------------------------------------------------------------------------
178 176 */
179   -float64 float64_round_to_int( float64 );
180   -float64 float64_add( float64, float64 );
181   -float64 float64_sub( float64, float64 );
182   -float64 float64_mul( float64, float64 );
183   -float64 float64_div( float64, float64 );
184   -float64 float64_rem( float64, float64 );
185   -float64 float64_sqrt( float64 );
  177 +float64 float64_round_to_int( struct roundingData *, float64 );
  178 +float64 float64_add( struct roundingData *, float64, float64 );
  179 +float64 float64_sub( struct roundingData *, float64, float64 );
  180 +float64 float64_mul( struct roundingData *, float64, float64 );
  181 +float64 float64_div( struct roundingData *, float64, float64 );
  182 +float64 float64_rem( struct roundingData *, float64, float64 );
  183 +float64 float64_sqrt( struct roundingData *, float64 );
186 184 char float64_eq( float64, float64 );
187 185 char float64_le( float64, float64 );
188 186 char float64_lt( float64, float64 );
189 187  
190 188  
191 189  
... ... @@ -198,31 +196,23 @@
198 196 Software IEC/IEEE extended double-precision conversion routines.
199 197 -------------------------------------------------------------------------------
200 198 */
201   -signed int floatx80_to_int32( floatx80 );
  199 +signed int floatx80_to_int32( struct roundingData *, floatx80 );
202 200 signed int floatx80_to_int32_round_to_zero( floatx80 );
203   -float32 floatx80_to_float32( floatx80 );
204   -float64 floatx80_to_float64( floatx80 );
  201 +float32 floatx80_to_float32( struct roundingData *, floatx80 );
  202 +float64 floatx80_to_float64( struct roundingData *, floatx80 );
205 203  
206 204 /*
207 205 -------------------------------------------------------------------------------
208   -Software IEC/IEEE extended double-precision rounding precision. Valid
209   -values are 32, 64, and 80.
210   --------------------------------------------------------------------------------
211   -*/
212   -extern signed char floatx80_rounding_precision;
213   -
214   -/*
215   --------------------------------------------------------------------------------
216 206 Software IEC/IEEE extended double-precision operations.
217 207 -------------------------------------------------------------------------------
218 208 */
219   -floatx80 floatx80_round_to_int( floatx80 );
220   -floatx80 floatx80_add( floatx80, floatx80 );
221   -floatx80 floatx80_sub( floatx80, floatx80 );
222   -floatx80 floatx80_mul( floatx80, floatx80 );
223   -floatx80 floatx80_div( floatx80, floatx80 );
224   -floatx80 floatx80_rem( floatx80, floatx80 );
225   -floatx80 floatx80_sqrt( floatx80 );
  209 +floatx80 floatx80_round_to_int( struct roundingData *, floatx80 );
  210 +floatx80 floatx80_add( struct roundingData *, floatx80, floatx80 );
  211 +floatx80 floatx80_sub( struct roundingData *, floatx80, floatx80 );
  212 +floatx80 floatx80_mul( struct roundingData *, floatx80, floatx80 );
  213 +floatx80 floatx80_div( struct roundingData *, floatx80, floatx80 );
  214 +floatx80 floatx80_rem( struct roundingData *, floatx80, floatx80 );
  215 +floatx80 floatx80_sqrt( struct roundingData *, floatx80 );
226 216 char floatx80_eq( floatx80, floatx80 );
227 217 char floatx80_le( floatx80, floatx80 );
228 218 char floatx80_lt( floatx80, floatx80 );