[Mesa-dev] [PATCH 2/3] tgsi: obey clarified shift behavior

sroland at vmware.com sroland at vmware.com
Tue Jul 30 09:13:05 PDT 2013


From: Roland Scheidegger <sroland at vmware.com>

c shifts are undefined for shift counts exceeding (or matching) bit width,
so need to apply a mask (on x86 it actually would usually probably work as
shifts do masking on int domain shifts - unless some auto-vectorizer would
come along at last as simd domain does not mask the shift count).
---
 src/gallium/auxiliary/tgsi/tgsi_exec.c |   39 ++++++++++++++++++++++----------
 1 file changed, 27 insertions(+), 12 deletions(-)

diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
index 3ac6901..d991d4b 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
@@ -3198,10 +3198,15 @@ micro_shl(union tgsi_exec_channel *dst,
           const union tgsi_exec_channel *src0,
           const union tgsi_exec_channel *src1)
 {
-   dst->u[0] = src0->u[0] << src1->u[0];
-   dst->u[1] = src0->u[1] << src1->u[1];
-   dst->u[2] = src0->u[2] << src1->u[2];
-   dst->u[3] = src0->u[3] << src1->u[3];
+   unsigned masked_count;
+   masked_count = src1->u[0] & 0x1f;
+   dst->u[0] = src0->u[0] << masked_count;
+   masked_count = src1->u[1] & 0x1f;
+   dst->u[1] = src0->u[1] << masked_count;
+   masked_count = src1->u[2] & 0x1f;
+   dst->u[2] = src0->u[2] << masked_count;
+   masked_count = src1->u[3] & 0x1f;
+   dst->u[3] = src0->u[3] << masked_count;
 }
 
 static void
@@ -3307,10 +3312,15 @@ micro_ishr(union tgsi_exec_channel *dst,
            const union tgsi_exec_channel *src0,
            const union tgsi_exec_channel *src1)
 {
-   dst->i[0] = src0->i[0] >> src1->i[0];
-   dst->i[1] = src0->i[1] >> src1->i[1];
-   dst->i[2] = src0->i[2] >> src1->i[2];
-   dst->i[3] = src0->i[3] >> src1->i[3];
+   unsigned masked_count;
+   masked_count = src1->i[0] & 0x1f;
+   dst->i[0] = src0->i[0] >> masked_count;
+   masked_count = src1->i[1] & 0x1f;
+   dst->i[1] = src0->i[1] >> masked_count;
+   masked_count = src1->i[2] & 0x1f;
+   dst->i[2] = src0->i[2] >> masked_count;
+   masked_count = src1->i[3] & 0x1f;
+   dst->i[3] = src0->i[3] >> masked_count;
 }
 
 static void
@@ -3449,10 +3459,15 @@ micro_ushr(union tgsi_exec_channel *dst,
            const union tgsi_exec_channel *src0,
            const union tgsi_exec_channel *src1)
 {
-   dst->u[0] = src0->u[0] >> src1->u[0];
-   dst->u[1] = src0->u[1] >> src1->u[1];
-   dst->u[2] = src0->u[2] >> src1->u[2];
-   dst->u[3] = src0->u[3] >> src1->u[3];
+   unsigned masked_count;
+   masked_count = src1->u[0] & 0x1f;
+   dst->u[0] = src0->u[0] >> masked_count;
+   masked_count = src1->u[1] & 0x1f;
+   dst->u[1] = src0->u[1] >> masked_count;
+   masked_count = src1->u[2] & 0x1f;
+   dst->u[2] = src0->u[2] >> masked_count;
+   masked_count = src1->u[3] & 0x1f;
+   dst->u[3] = src0->u[3] >> masked_count;
 }
 
 static void
-- 
1.7.9.5


More information about the mesa-dev mailing list