diff options
author | Roland Scheidegger <[email protected]> | 2013-07-30 17:16:17 +0200 |
---|---|---|
committer | Roland Scheidegger <[email protected]> | 2013-08-02 03:49:57 +0200 |
commit | 7a72bef47e8731276ac4ca0b8c4d6d50366c1ec2 (patch) | |
tree | e078857748b65edd5236726536ced66110b21319 | |
parent | 606132b4def69f7c5fa0fa436259e2fd163b0768 (diff) |
tgsi: obey clarified shift behavior
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).
Reviewed-by: Jose Fonseca <[email protected]>
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_exec.c | 39 |
1 files changed, 27 insertions, 12 deletions
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index 3ac69017a80..d991d4b5cdf 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 |