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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user