freedreno/ir3: array offset can be negative

It at least happens with some piglit tests, like
$piglit/bin/vp-address-01

  VERT
  DCL IN[0]
  DCL IN[1]
  DCL OUT[0], POSITION
  DCL OUT[1], COLOR
  DCL CONST[0..7]
  DCL ADDR[0]
    0: ARL ADDR[0].x, IN[1].xxxx
    1: MOV_SAT OUT[1], CONST[ADDR[0].x-1]
    2: DP4 OUT[0].x, CONST[4], IN[0]
    3: DP4 OUT[0].y, CONST[5], IN[0]
    4: DP4 OUT[0].z, CONST[6], IN[0]
    5: DP4 OUT[0].w, CONST[7], IN[0]
    6: END

Signed-off-by: Rob Clark <robclark@freedesktop.org>
This commit is contained in:
Rob Clark
2016-01-15 18:22:40 -05:00
parent ddede497b8
commit 6a33c5c0df
5 changed files with 13 additions and 12 deletions
@@ -261,6 +261,7 @@ typedef union PACKED {
/* to make compiler happy: */
uint32_t dummy32;
uint32_t dummy10 : 10;
int32_t idummy10 : 10;
uint32_t dummy11 : 11;
uint32_t dummy12 : 12;
uint32_t dummy13 : 13;
+1 -1
View File
@@ -126,7 +126,7 @@ static uint32_t reg(struct ir3_register *reg, struct ir3_info *info,
if (reg->flags & IR3_REG_RELATIV) {
components = reg->size;
val.dummy10 = reg->array.offset;
val.idummy10 = reg->array.offset;
max = (reg->array.offset + repeat + components - 1) >> 2;
} else {
components = util_last_bit(reg->wrmask);
+1 -1
View File
@@ -100,7 +100,7 @@ struct ir3_register {
/* relative: */
struct {
uint16_t id;
uint16_t offset;
int16_t offset;
} array;
};
@@ -377,7 +377,7 @@ create_uniform(struct ir3_compile *ctx, unsigned n)
}
static struct ir3_instruction *
create_uniform_indirect(struct ir3_compile *ctx, unsigned n,
create_uniform_indirect(struct ir3_compile *ctx, int n,
struct ir3_instruction *address)
{
struct ir3_instruction *mov;
@@ -411,7 +411,7 @@ create_collect(struct ir3_block *block, struct ir3_instruction **arr,
}
static struct ir3_instruction *
create_indirect_load(struct ir3_compile *ctx, unsigned arrsz, unsigned n,
create_indirect_load(struct ir3_compile *ctx, unsigned arrsz, int n,
struct ir3_instruction *address, struct ir3_instruction *collect)
{
struct ir3_block *block = ctx->block;
@@ -434,7 +434,7 @@ create_indirect_load(struct ir3_compile *ctx, unsigned arrsz, unsigned n,
/* relative (indirect) if address!=NULL */
static struct ir3_instruction *
create_var_load(struct ir3_compile *ctx, struct ir3_array *arr, unsigned n,
create_var_load(struct ir3_compile *ctx, struct ir3_array *arr, int n,
struct ir3_instruction *address)
{
struct ir3_block *block = ctx->block;
@@ -462,7 +462,7 @@ create_var_load(struct ir3_compile *ctx, struct ir3_array *arr, unsigned n,
/* relative (indirect) if address!=NULL */
static struct ir3_instruction *
create_var_store(struct ir3_compile *ctx, struct ir3_array *arr, unsigned n,
create_var_store(struct ir3_compile *ctx, struct ir3_array *arr, int n,
struct ir3_instruction *src, struct ir3_instruction *address)
{
struct ir3_block *block = ctx->block;
@@ -1000,7 +1000,7 @@ emit_intrinsic_load_ubo(struct ir3_compile *ctx, nir_intrinsic_instr *intr,
nir_const_value *const_offset;
/* UBO addresses are the first driver params: */
unsigned ubo = regid(ctx->so->first_driver_param + IR3_UBOS_OFF, 0);
unsigned off = intr->const_index[0];
int off = intr->const_index[0];
/* First src is ubo index, which could either be an immed or not: */
src0 = get_src(ctx, &intr->src[0])[0];
@@ -1141,7 +1141,7 @@ emit_intrinsic(struct ir3_compile *ctx, nir_intrinsic_instr *intr)
const nir_intrinsic_info *info = &nir_intrinsic_infos[intr->intrinsic];
struct ir3_instruction **dst, **src;
struct ir3_block *b = ctx->block;
unsigned idx = intr->const_index[0];
int idx = intr->const_index[0];
nir_const_value *const_offset;
if (info->has_dest) {
@@ -1162,7 +1162,7 @@ emit_intrinsic(struct ir3_compile *ctx, nir_intrinsic_instr *intr)
} else {
src = get_src(ctx, &intr->src[0]);
for (int i = 0; i < intr->num_components; i++) {
unsigned n = idx * 4 + i;
int n = idx * 4 + i;
dst[i] = create_uniform_indirect(ctx, n,
get_addr(ctx, src[0]));
}
@@ -107,7 +107,7 @@ static void print_reg_name(struct ir3_register *reg)
if (reg->flags & IR3_REG_IMMED) {
printf("imm[%f,%d,0x%x]", reg->fim_val, reg->iim_val, reg->iim_val);
} else if (reg->flags & IR3_REG_ARRAY) {
printf("arr[id=%u, offset=%u, size=%u", reg->array.id,
printf("arr[id=%u, offset=%d, size=%u", reg->array.id,
reg->array.offset, reg->size);
/* for ARRAY we could have null src, for example first write
* instruction..
@@ -126,9 +126,9 @@ static void print_reg_name(struct ir3_register *reg)
if (reg->flags & IR3_REG_HALF)
printf("h");
if (reg->flags & IR3_REG_CONST)
printf("c<a0.x + %u>", reg->array.offset);
printf("c<a0.x + %d>", reg->array.offset);
else
printf("\x1b[0;31mr<a0.x + %u>\x1b[0m (%u)", reg->array.offset, reg->size);
printf("\x1b[0;31mr<a0.x + %d>\x1b[0m (%u)", reg->array.offset, reg->size);
} else {
if (reg->flags & IR3_REG_HALF)
printf("h");