glsl: Add "built-in" functions to do fp64_to_int(fp64)
v2: use mix Signed-off-by: Elie Tournier <elie.tournier@collabora.com>
This commit is contained in:
parent
cbf090b809
commit
773190f281
|
@ -880,3 +880,44 @@ __uint_to_fp64(uint a)
|
|||
|
||||
return __packFloat64(0u, 0x432 - shiftDist, aHigh, aLow);
|
||||
}
|
||||
|
||||
/* Returns the result of converting the double-precision floating-point value
|
||||
* `a' to the 32-bit two's complement integer format. The conversion is
|
||||
* performed according to the IEEE Standard for Floating-Point Arithmetic---
|
||||
* which means in particular that the conversion is rounded according to the
|
||||
* current rounding mode. If `a' is a NaN, the largest positive integer is
|
||||
* returned. Otherwise, if the conversion overflows, the largest integer with
|
||||
* the same sign as `a' is returned.
|
||||
*/
|
||||
int
|
||||
__fp64_to_int(uint64_t a)
|
||||
{
|
||||
uint aFracLo = __extractFloat64FracLo(a);
|
||||
uint aFracHi = __extractFloat64FracHi(a);
|
||||
int aExp = __extractFloat64Exp(a);
|
||||
uint aSign = __extractFloat64Sign(a);
|
||||
|
||||
uint absZ = 0u;
|
||||
uint aFracExtra = 0u;
|
||||
int shiftCount = aExp - 0x413;
|
||||
|
||||
if (0 <= shiftCount) {
|
||||
if (0x41E < aExp) {
|
||||
if ((aExp == 0x7FF) && bool(aFracHi | aFracLo))
|
||||
aSign = 0u;
|
||||
return mix(0x7FFFFFFF, 0x80000000, bool(aSign));
|
||||
}
|
||||
__shortShift64Left(aFracHi | 0x00100000u, aFracLo, shiftCount, absZ, aFracExtra);
|
||||
} else {
|
||||
if (aExp < 0x3FF)
|
||||
return 0;
|
||||
|
||||
aFracHi |= 0x00100000u;
|
||||
aFracExtra = ( aFracHi << (shiftCount & 31)) | aFracLo;
|
||||
absZ = aFracHi >> (- shiftCount);
|
||||
}
|
||||
|
||||
int z = mix(int(absZ), -int(absZ), (aSign != 0u));
|
||||
int nan = mix(0x7FFFFFFF, 0x80000000, bool(aSign));
|
||||
return mix(z, nan, bool(aSign ^ uint(z < 0)) && bool(z));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue