From: Steven Fuerst <svfuerst@gmail.com>
To: dri-devel@lists.freedesktop.org
Cc: Steven Fuerst <svfuerst@gmail.com>
Subject: [Patch v2 1/4] Replace i2f() in r600_blit.c with an optimized version.
Date: Sat, 11 Aug 2012 10:30:19 -0700 [thread overview]
Message-ID: <1344706222-3018-1-git-send-email-svfuerst@gmail.com> (raw)
We use __fls() to find the most significant bit. Using that, the
loop can be avoided. A second trick is to use the behaviour of the
rotate instructions to expand the range of the unsigned int to float
conversion to the full 32 bits in a branchless way.
The routine is now exact up to 2^24. Above that, we truncate which
is equivalent to rounding towards zero.
Signed-off-by: Steven Fuerst <svfuerst@gmail.com>
---
drivers/gpu/drm/radeon/r600_blit.c | 50 ++++++++++++++++++++----------------
1 file changed, 28 insertions(+), 22 deletions(-)
diff --git a/drivers/gpu/drm/radeon/r600_blit.c b/drivers/gpu/drm/radeon/r600_blit.c
index 3c031a4..326a8da 100644
--- a/drivers/gpu/drm/radeon/r600_blit.c
+++ b/drivers/gpu/drm/radeon/r600_blit.c
@@ -489,29 +489,35 @@ set_default_state(drm_radeon_private_t *dev_priv)
ADVANCE_RING();
}
-static uint32_t i2f(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.)
+ */
+static uint32_t i2f(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;
}
--
1.7.10.4
next reply other threads:[~2012-08-11 17:30 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-08-11 17:30 Steven Fuerst [this message]
2012-08-11 17:30 ` [Patch v2 2/4] Replace i2f() in r600_blit_kms.c with an optimized version Steven Fuerst
2012-08-11 17:30 ` [Patch v2 3/4] Rename i2f() to int2float(), and make it global so one copy can be removed Steven Fuerst
2012-08-11 17:30 ` [Patch v2 4/4] Annotate int2float() as being a pure function Steven Fuerst
2012-08-14 10:33 ` [Patch v2 1/4] Replace i2f() in r600_blit.c with an optimized version Michel Dänzer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1344706222-3018-1-git-send-email-svfuerst@gmail.com \
--to=svfuerst@gmail.com \
--cc=dri-devel@lists.freedesktop.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox