<div>Replace i2f() in r600_blit.c with an optimized version.</div><div><br></div><div>We use __fls() to find the most significant bit. Using that, the</div><div>loop can be avoided. A second trick is to use the mod(32)</div>
<div>behaviour of the rotate instructions on x86 to expand the range</div><div>of the unsigned int to float conversion to the full 32 bits.</div><div><br></div><div>The routine is now exact up to 2^24. Above that, we truncate which</div>
<div>is equivalent to rounding towards zero.</div><div><br></div><div>Signed-off-by: Steven Fuerst <<a href="mailto:svfuerst@gmail.com">svfuerst@gmail.com</a>></div><div>---</div><div> drivers/gpu/drm/radeon/r600_blit.c | 52 +++++++++++++++++++++---------------</div>
<div> 1 file changed, 30 insertions(+), 22 deletions(-)</div><div><br></div><div>diff --git a/drivers/gpu/drm/radeon/r600_blit.c b/drivers/gpu/drm/radeon/r600_blit.c</div><div>index 3c031a4..f0ce441 100644</div><div>--- a/drivers/gpu/drm/radeon/r600_blit.c</div>
<div>+++ b/drivers/gpu/drm/radeon/r600_blit.c</div><div>@@ -489,29 +489,37 @@ set_default_state(drm_radeon_private_t *dev_priv)</div><div> <span class="Apple-tab-span" style="white-space:pre"> </span>ADVANCE_RING();</div>
<div> }</div><div> </div><div>-static uint32_t i2f(uint32_t input)</div><div>+/* 23 bits of float fractional data */</div><div>+#define I2F_FRAC_BITS<span class="Apple-tab-span" style="white-space:pre"> </span>23</div><div>
+#define I2F_MASK ((1 << I2F_FRAC_BITS) - 1)</div><div>+</div><div>+/*</div><div>+ * Converts unsigned integer into 32-bit IEEE floating point representation.</div><div>+ * Will be exact from 0 to 2^24. Above that, we round towards zero</div>
<div>+ * as the fractional bits will not fit in a float. (It would be better to</div><div>+ * round towards even as the fpu does, but that is slower.)</div><div>+ * This routine depends on the mod(32) behaviour of the rotate instructions</div>
<div>+ * on x86.</div><div>+ */</div><div>+static uint32_t i2f(uint32_t x)</div><div> {</div><div>-<span class="Apple-tab-span" style="white-space:pre"> </span>u32 result, i, exponent, fraction;</div><div>-</div><div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if ((input & 0x3fff) == 0)</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>result = 0; /* 0 is a special case */</div><div>-<span class="Apple-tab-span" style="white-space:pre"> </span>else {</div><div>-<span class="Apple-tab-span" style="white-space:pre"> </span>exponent = 140; /* exponent biased by 127; */</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>fraction = (input & 0x3fff) << 10; /* cheat and only</div><div>-<span class="Apple-tab-span" style="white-space:pre"> </span> handle numbers below 2^^15 */</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>for (i = 0; i < 14; i++) {</div><div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if (fraction & 0x800000)</div><div>-<span class="Apple-tab-span" style="white-space:pre"> </span>break;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>else {</div><div>-<span class="Apple-tab-span" style="white-space:pre"> </span>fraction = fraction << 1; /* keep</div><div>-<span class="Apple-tab-span" style="white-space:pre"> </span> shifting left until top bit = 1 */</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>exponent = exponent - 1;</div><div>-<span class="Apple-tab-span" style="white-space:pre"> </span>}</div><div>-<span class="Apple-tab-span" style="white-space:pre"> </span>}</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>result = exponent << 23 | (fraction & 0x7fffff); /* mask</div><div>-<span class="Apple-tab-span" style="white-space:pre"> </span> off top bit; assumed 1 */</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>}</div><div>-<span class="Apple-tab-span" style="white-space:pre"> </span>return result;</div><div>+<span class="Apple-tab-span" style="white-space:pre"> </span>uint32_t msb, exponent, fraction;</div>
<div>+</div><div>+<span class="Apple-tab-span" style="white-space:pre"> </span>/* Zero is special */</div><div>+<span class="Apple-tab-span" style="white-space:pre"> </span>if (!x) return 0;</div><div>+</div><div>+<span class="Apple-tab-span" style="white-space:pre"> </span>/* Get location of the most significant bit */</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>msb = __fls(x);</div><div>+</div><div>+<span class="Apple-tab-span" style="white-space:pre"> </span>/*</div><div>+<span class="Apple-tab-span" style="white-space:pre"> </span> * Use a rotate instead of a shift because that works both leftwards</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span> * and rightwards due to the mod(32) beahviour. This means we don't</div><div>+<span class="Apple-tab-span" style="white-space:pre"> </span> * need to check to see if we are above 2^24 or not.</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span> */</div><div>+<span class="Apple-tab-span" style="white-space:pre"> </span>fraction = ror32(x, msb - I2F_FRAC_BITS) & I2F_MASK;</div><div>+<span class="Apple-tab-span" style="white-space:pre"> </span>exponent = (127 + msb) << I2F_FRAC_BITS;</div>
<div>+</div><div>+<span class="Apple-tab-span" style="white-space:pre"> </span>return fraction + exponent;</div><div> }</div><div> </div><div> </div>