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 <jfonseca@vmware.com>
This commit is contained in:
Roland Scheidegger
2013-07-30 17:16:17 +02:00
parent 606132b4de
commit 7a72bef47e
+27 -12
View File
@@ -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