|
@@ -489,31 +489,36 @@ set_default_state(drm_radeon_private_t *dev_priv)
|
|
|
ADVANCE_RING();
|
|
|
}
|
|
|
|
|
|
-uint32_t int2float(uint32_t input)
|
|
|
+/* 23 bits of float fractional data */
|
|
|
+#define I2F_FRAC_BITS 23
|
|
|
+#define I2F_MASK ((1 << I2F_FRAC_BITS) - 1)
|
|
|
+
|
|
|
+/*
|
|
|
+ * Converts unsigned integer into 32-bit IEEE floating point representation.
|
|
|
+ * Will be exact from 0 to 2^24. Above that, we round towards zero
|
|
|
+ * as the fractional bits will not fit in a float. (It would be better to
|
|
|
+ * round towards even as the fpu does, but that is slower.)
|
|
|
+ */
|
|
|
+uint32_t int2float(uint32_t x)
|
|
|
{
|
|
|
- u32 result, i, exponent, fraction;
|
|
|
-
|
|
|
- if ((input & 0x3fff) == 0)
|
|
|
- result = 0; /* 0 is a special case */
|
|
|
- else {
|
|
|
- exponent = 140; /* exponent biased by 127; */
|
|
|
- fraction = (input & 0x3fff) << 10; /* cheat and only
|
|
|
- handle numbers below 2^^15 */
|
|
|
- for (i = 0; i < 14; i++) {
|
|
|
- if (fraction & 0x800000)
|
|
|
- break;
|
|
|
- else {
|
|
|
- fraction = fraction << 1; /* keep
|
|
|
- shifting left until top bit = 1 */
|
|
|
- exponent = exponent - 1;
|
|
|
- }
|
|
|
- }
|
|
|
- result = exponent << 23 | (fraction & 0x7fffff); /* mask
|
|
|
- off top bit; assumed 1 */
|
|
|
- }
|
|
|
- return result;
|
|
|
-}
|
|
|
+ uint32_t msb, exponent, fraction;
|
|
|
+
|
|
|
+ /* Zero is special */
|
|
|
+ if (!x) return 0;
|
|
|
+
|
|
|
+ /* Get location of the most significant bit */
|
|
|
+ msb = __fls(x);
|
|
|
|
|
|
+ /*
|
|
|
+ * Use a rotate instead of a shift because that works both leftwards
|
|
|
+ * and rightwards due to the mod(32) behaviour. This means we don't
|
|
|
+ * need to check to see if we are above 2^24 or not.
|
|
|
+ */
|
|
|
+ fraction = ror32(x, (msb - I2F_FRAC_BITS) & 0x1f) & I2F_MASK;
|
|
|
+ exponent = (127 + msb) << I2F_FRAC_BITS;
|
|
|
+
|
|
|
+ return fraction + exponent;
|
|
|
+}
|
|
|
|
|
|
static int r600_nomm_get_vb(struct drm_device *dev)
|
|
|
{
|