From 6a33c5c0dffce136bdc95daa2db2d3e9d3c1741f Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 15 Jan 2016 18:22:40 -0500 Subject: [PATCH] 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 --- src/gallium/drivers/freedreno/ir3/instr-a3xx.h | 1 + src/gallium/drivers/freedreno/ir3/ir3.c | 2 +- src/gallium/drivers/freedreno/ir3/ir3.h | 2 +- .../drivers/freedreno/ir3/ir3_compiler_nir.c | 14 +++++++------- src/gallium/drivers/freedreno/ir3/ir3_print.c | 6 +++--- 5 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/gallium/drivers/freedreno/ir3/instr-a3xx.h b/src/gallium/drivers/freedreno/ir3/instr-a3xx.h index c3fb68d511c..1b1f1f0a797 100644 --- a/src/gallium/drivers/freedreno/ir3/instr-a3xx.h +++ b/src/gallium/drivers/freedreno/ir3/instr-a3xx.h @@ -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; diff --git a/src/gallium/drivers/freedreno/ir3/ir3.c b/src/gallium/drivers/freedreno/ir3/ir3.c index be415d8e5fe..7d89142d7a1 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3.c +++ b/src/gallium/drivers/freedreno/ir3/ir3.c @@ -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); diff --git a/src/gallium/drivers/freedreno/ir3/ir3.h b/src/gallium/drivers/freedreno/ir3/ir3.h index 1e5a1e9ee8b..f24acfa95cd 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3.h +++ b/src/gallium/drivers/freedreno/ir3/ir3.h @@ -100,7 +100,7 @@ struct ir3_register { /* relative: */ struct { uint16_t id; - uint16_t offset; + int16_t offset; } array; }; diff --git a/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c b/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c index bd0ee89a1ec..1ea2dd9cbf7 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c @@ -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])); } diff --git a/src/gallium/drivers/freedreno/ir3/ir3_print.c b/src/gallium/drivers/freedreno/ir3/ir3_print.c index ec832f5d72a..ba0c4a57aa3 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_print.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_print.c @@ -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", reg->array.offset); + printf("c", reg->array.offset); else - printf("\x1b[0;31mr\x1b[0m (%u)", reg->array.offset, reg->size); + printf("\x1b[0;31mr\x1b[0m (%u)", reg->array.offset, reg->size); } else { if (reg->flags & IR3_REG_HALF) printf("h"); -- 2.30.2