Commit 75d62a585629cdc1ae0d530189653cb1d8d9c53c
1 parent
b1e341eb
Add missing softfloat helpers.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2518 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
158 additions
and
0 deletions
fpu/softfloat-native.c
| ... | ... | @@ -59,11 +59,21 @@ float32 int32_to_float32(int v STATUS_PARAM) |
| 59 | 59 | return (float32)v; |
| 60 | 60 | } |
| 61 | 61 | |
| 62 | +float32 uint32_to_float32(unsigned int v STATUS_PARAM) | |
| 63 | +{ | |
| 64 | + return (float32)v; | |
| 65 | +} | |
| 66 | + | |
| 62 | 67 | float64 int32_to_float64(int v STATUS_PARAM) |
| 63 | 68 | { |
| 64 | 69 | return (float64)v; |
| 65 | 70 | } |
| 66 | 71 | |
| 72 | +float64 uint32_to_float64(unsigned int v STATUS_PARAM) | |
| 73 | +{ | |
| 74 | + return (float64)v; | |
| 75 | +} | |
| 76 | + | |
| 67 | 77 | #ifdef FLOATX80 |
| 68 | 78 | floatx80 int32_to_floatx80(int v STATUS_PARAM) |
| 69 | 79 | { |
| ... | ... | @@ -74,10 +84,18 @@ float32 int64_to_float32( int64_t v STATUS_PARAM) |
| 74 | 84 | { |
| 75 | 85 | return (float32)v; |
| 76 | 86 | } |
| 87 | +float32 uint64_to_float32( uint64_t v STATUS_PARAM) | |
| 88 | +{ | |
| 89 | + return (float32)v; | |
| 90 | +} | |
| 77 | 91 | float64 int64_to_float64( int64_t v STATUS_PARAM) |
| 78 | 92 | { |
| 79 | 93 | return (float64)v; |
| 80 | 94 | } |
| 95 | +float64 uint64_to_float64( uint64_t v STATUS_PARAM) | |
| 96 | +{ | |
| 97 | + return (float64)v; | |
| 98 | +} | |
| 81 | 99 | #ifdef FLOATX80 |
| 82 | 100 | floatx80 int64_to_floatx80( int64_t v STATUS_PARAM) |
| 83 | 101 | { |
| ... | ... | @@ -132,6 +150,37 @@ floatx80 float32_to_floatx80( float32 a STATUS_PARAM) |
| 132 | 150 | } |
| 133 | 151 | #endif |
| 134 | 152 | |
| 153 | +unsigned int float32_to_uint32( float32 a STATUS_PARAM) | |
| 154 | +{ | |
| 155 | + int64_t v; | |
| 156 | + unsigned int res; | |
| 157 | + | |
| 158 | + v = llrintf(a); | |
| 159 | + if (v < 0) { | |
| 160 | + res = 0; | |
| 161 | + } else if (v > 0xffffffff) { | |
| 162 | + res = 0xffffffff; | |
| 163 | + } else { | |
| 164 | + res = v; | |
| 165 | + } | |
| 166 | + return res; | |
| 167 | +} | |
| 168 | +unsigned int float32_to_uint32_round_to_zero( float32 a STATUS_PARAM) | |
| 169 | +{ | |
| 170 | + int64_t v; | |
| 171 | + unsigned int res; | |
| 172 | + | |
| 173 | + v = (int64_t)a; | |
| 174 | + if (v < 0) { | |
| 175 | + res = 0; | |
| 176 | + } else if (v > 0xffffffff) { | |
| 177 | + res = 0xffffffff; | |
| 178 | + } else { | |
| 179 | + res = v; | |
| 180 | + } | |
| 181 | + return res; | |
| 182 | +} | |
| 183 | + | |
| 135 | 184 | /*---------------------------------------------------------------------------- |
| 136 | 185 | | Software IEC/IEEE single-precision operations. |
| 137 | 186 | *----------------------------------------------------------------------------*/ |
| ... | ... | @@ -218,6 +267,53 @@ float128 float64_to_float128( float64 a STATUS_PARAM) |
| 218 | 267 | } |
| 219 | 268 | #endif |
| 220 | 269 | |
| 270 | +unsigned int float64_to_uint32( float64 a STATUS_PARAM) | |
| 271 | +{ | |
| 272 | + int64_t v; | |
| 273 | + unsigned int res; | |
| 274 | + | |
| 275 | + v = llrint(a); | |
| 276 | + if (v < 0) { | |
| 277 | + res = 0; | |
| 278 | + } else if (v > 0xffffffff) { | |
| 279 | + res = 0xffffffff; | |
| 280 | + } else { | |
| 281 | + res = v; | |
| 282 | + } | |
| 283 | + return res; | |
| 284 | +} | |
| 285 | +unsigned int float64_to_uint32_round_to_zero( float64 a STATUS_PARAM) | |
| 286 | +{ | |
| 287 | + int64_t v; | |
| 288 | + unsigned int res; | |
| 289 | + | |
| 290 | + v = (int64_t)a; | |
| 291 | + if (v < 0) { | |
| 292 | + res = 0; | |
| 293 | + } else if (v > 0xffffffff) { | |
| 294 | + res = 0xffffffff; | |
| 295 | + } else { | |
| 296 | + res = v; | |
| 297 | + } | |
| 298 | + return res; | |
| 299 | +} | |
| 300 | +uint64_t float64_to_uint64 (float64 a STATUS_PARAM) | |
| 301 | +{ | |
| 302 | + int64_t v; | |
| 303 | + | |
| 304 | + v = llrint(a + (float64)INT64_MIN); | |
| 305 | + | |
| 306 | + return v - INT64_MIN; | |
| 307 | +} | |
| 308 | +uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM) | |
| 309 | +{ | |
| 310 | + int64_t v; | |
| 311 | + | |
| 312 | + v = (int64_t)(a + (float64)INT64_MIN); | |
| 313 | + | |
| 314 | + return v - INT64_MIN; | |
| 315 | +} | |
| 316 | + | |
| 221 | 317 | /*---------------------------------------------------------------------------- |
| 222 | 318 | | Software IEC/IEEE double-precision operations. |
| 223 | 319 | *----------------------------------------------------------------------------*/ | ... | ... |
fpu/softfloat-native.h
| ... | ... | @@ -99,7 +99,9 @@ void set_floatx80_rounding_precision(int val STATUS_PARAM); |
| 99 | 99 | | Software IEC/IEEE integer-to-floating-point conversion routines. |
| 100 | 100 | *----------------------------------------------------------------------------*/ |
| 101 | 101 | float32 int32_to_float32( int STATUS_PARAM); |
| 102 | +float32 uint32_to_float32( unsigned int STATUS_PARAM); | |
| 102 | 103 | float64 int32_to_float64( int STATUS_PARAM); |
| 104 | +float64 uint32_to_float64( unsigned int STATUS_PARAM); | |
| 103 | 105 | #ifdef FLOATX80 |
| 104 | 106 | floatx80 int32_to_floatx80( int STATUS_PARAM); |
| 105 | 107 | #endif |
| ... | ... | @@ -107,7 +109,9 @@ floatx80 int32_to_floatx80( int STATUS_PARAM); |
| 107 | 109 | float128 int32_to_float128( int STATUS_PARAM); |
| 108 | 110 | #endif |
| 109 | 111 | float32 int64_to_float32( int64_t STATUS_PARAM); |
| 112 | +float32 uint64_to_float32( uint64_t STATUS_PARAM); | |
| 110 | 113 | float64 int64_to_float64( int64_t STATUS_PARAM); |
| 114 | +float64 uint64_to_float64( uint64_t v STATUS_PARAM); | |
| 111 | 115 | #ifdef FLOATX80 |
| 112 | 116 | floatx80 int64_to_floatx80( int64_t STATUS_PARAM); |
| 113 | 117 | #endif |
| ... | ... | @@ -120,6 +124,8 @@ float128 int64_to_float128( int64_t STATUS_PARAM); |
| 120 | 124 | *----------------------------------------------------------------------------*/ |
| 121 | 125 | int float32_to_int32( float32 STATUS_PARAM); |
| 122 | 126 | int float32_to_int32_round_to_zero( float32 STATUS_PARAM); |
| 127 | +unsigned int float32_to_uint32( float32 a STATUS_PARAM); | |
| 128 | +unsigned int float32_to_uint32_round_to_zero( float32 a STATUS_PARAM); | |
| 123 | 129 | int64_t float32_to_int64( float32 STATUS_PARAM); |
| 124 | 130 | int64_t float32_to_int64_round_to_zero( float32 STATUS_PARAM); |
| 125 | 131 | float64 float32_to_float64( float32 STATUS_PARAM); |
| ... | ... | @@ -200,8 +206,12 @@ INLINE float32 float32_chs(float32 a) |
| 200 | 206 | *----------------------------------------------------------------------------*/ |
| 201 | 207 | int float64_to_int32( float64 STATUS_PARAM ); |
| 202 | 208 | int float64_to_int32_round_to_zero( float64 STATUS_PARAM ); |
| 209 | +unsigned int float64_to_uint32( float64 STATUS_PARAM ); | |
| 210 | +unsigned int float64_to_uint32_round_to_zero( float64 STATUS_PARAM ); | |
| 203 | 211 | int64_t float64_to_int64( float64 STATUS_PARAM ); |
| 204 | 212 | int64_t float64_to_int64_round_to_zero( float64 STATUS_PARAM ); |
| 213 | +uint64_t float64_to_uint64( float64 STATUS_PARAM ); | |
| 214 | +uint64_t float64_to_uint64_round_to_zero( float64 STATUS_PARAM ); | |
| 205 | 215 | float32 float64_to_float32( float64 STATUS_PARAM ); |
| 206 | 216 | #ifdef FLOATX80 |
| 207 | 217 | floatx80 float64_to_floatx80( float64 STATUS_PARAM ); | ... | ... |
fpu/softfloat.c
| ... | ... | @@ -1164,6 +1164,27 @@ float32 int64_to_float32( int64 a STATUS_PARAM ) |
| 1164 | 1164 | |
| 1165 | 1165 | } |
| 1166 | 1166 | |
| 1167 | +float64 uint64_to_float32( uint64 a STATUS_PARAM ) | |
| 1168 | +{ | |
| 1169 | + int8 shiftCount; | |
| 1170 | + | |
| 1171 | + if ( a == 0 ) return 0; | |
| 1172 | + shiftCount = countLeadingZeros64( a ) - 40; | |
| 1173 | + if ( 0 <= shiftCount ) { | |
| 1174 | + return packFloat32( 1 > 0, 0x95 - shiftCount, a<<shiftCount ); | |
| 1175 | + } | |
| 1176 | + else { | |
| 1177 | + shiftCount += 7; | |
| 1178 | + if ( shiftCount < 0 ) { | |
| 1179 | + shift64RightJamming( a, - shiftCount, &a ); | |
| 1180 | + } | |
| 1181 | + else { | |
| 1182 | + a <<= shiftCount; | |
| 1183 | + } | |
| 1184 | + return roundAndPackFloat32( 1 > 0, 0x9C - shiftCount, a STATUS_VAR ); | |
| 1185 | + } | |
| 1186 | +} | |
| 1187 | + | |
| 1167 | 1188 | /*---------------------------------------------------------------------------- |
| 1168 | 1189 | | Returns the result of converting the 64-bit two's complement integer `a' |
| 1169 | 1190 | | to the double-precision floating-point format. The conversion is performed |
| ... | ... | @@ -1183,6 +1204,13 @@ float64 int64_to_float64( int64 a STATUS_PARAM ) |
| 1183 | 1204 | |
| 1184 | 1205 | } |
| 1185 | 1206 | |
| 1207 | +float64 uint64_to_float64( uint64 a STATUS_PARAM ) | |
| 1208 | +{ | |
| 1209 | + if ( a == 0 ) return 0; | |
| 1210 | + return normalizeRoundAndPackFloat64( 0, 0x43C, a STATUS_VAR ); | |
| 1211 | + | |
| 1212 | +} | |
| 1213 | + | |
| 1186 | 1214 | #ifdef FLOATX80 |
| 1187 | 1215 | |
| 1188 | 1216 | /*---------------------------------------------------------------------------- |
| ... | ... | @@ -5282,6 +5310,26 @@ unsigned int float64_to_uint32_round_to_zero( float64 a STATUS_PARAM ) |
| 5282 | 5310 | return res; |
| 5283 | 5311 | } |
| 5284 | 5312 | |
| 5313 | +uint64_t float64_to_uint64 (float64 a STATUS_PARAM) | |
| 5314 | +{ | |
| 5315 | + int64_t v; | |
| 5316 | + | |
| 5317 | + v = int64_to_float64(INT64_MIN STATUS_VAR); | |
| 5318 | + v = float64_to_int64((a + v) STATUS_VAR); | |
| 5319 | + | |
| 5320 | + return v - INT64_MIN; | |
| 5321 | +} | |
| 5322 | + | |
| 5323 | +uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM) | |
| 5324 | +{ | |
| 5325 | + int64_t v; | |
| 5326 | + | |
| 5327 | + v = int64_to_float64(INT64_MIN STATUS_VAR); | |
| 5328 | + v = float64_to_int64_round_to_zero((a + v) STATUS_VAR); | |
| 5329 | + | |
| 5330 | + return v - INT64_MIN; | |
| 5331 | +} | |
| 5332 | + | |
| 5285 | 5333 | #define COMPARE(s, nan_exp) \ |
| 5286 | 5334 | INLINE int float ## s ## _compare_internal( float ## s a, float ## s b, \ |
| 5287 | 5335 | int is_quiet STATUS_PARAM ) \ | ... | ... |
fpu/softfloat.h
| ... | ... | @@ -193,7 +193,9 @@ floatx80 int32_to_floatx80( int STATUS_PARAM ); |
| 193 | 193 | float128 int32_to_float128( int STATUS_PARAM ); |
| 194 | 194 | #endif |
| 195 | 195 | float32 int64_to_float32( int64_t STATUS_PARAM ); |
| 196 | +float32 uint64_to_float32( uint64_t STATUS_PARAM ); | |
| 196 | 197 | float64 int64_to_float64( int64_t STATUS_PARAM ); |
| 198 | +float64 uint64_to_float64( uint64_t STATUS_PARAM ); | |
| 197 | 199 | #ifdef FLOATX80 |
| 198 | 200 | floatx80 int64_to_floatx80( int64_t STATUS_PARAM ); |
| 199 | 201 | #endif |
| ... | ... | @@ -258,6 +260,8 @@ unsigned int float64_to_uint32( float64 STATUS_PARAM ); |
| 258 | 260 | unsigned int float64_to_uint32_round_to_zero( float64 STATUS_PARAM ); |
| 259 | 261 | int64_t float64_to_int64( float64 STATUS_PARAM ); |
| 260 | 262 | int64_t float64_to_int64_round_to_zero( float64 STATUS_PARAM ); |
| 263 | +uint64_t float64_to_uint64 (float64 a STATUS_PARAM); | |
| 264 | +uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM); | |
| 261 | 265 | float32 float64_to_float32( float64 STATUS_PARAM ); |
| 262 | 266 | #ifdef FLOATX80 |
| 263 | 267 | floatx80 float64_to_floatx80( float64 STATUS_PARAM ); | ... | ... |