freedreno/ir3: array offset can be negative
authorRob Clark <robclark@freedesktop.org>
Fri, 15 Jan 2016 23:22:40 +0000 (18:22 -0500)
committerRob Clark <robclark@freedesktop.org>
Sat, 16 Jan 2016 19:23:20 +0000 (14:23 -0500)
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>
src/gallium/drivers/freedreno/ir3/instr-a3xx.h
src/gallium/drivers/freedreno/ir3/ir3.c
src/gallium/drivers/freedreno/ir3/ir3.h
src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c
src/gallium/drivers/freedreno/ir3/ir3_print.c

index c3fb68d511c83f0f9f16821d383218d440318f8a..1b1f1f0a797f2e4b1203dbd1914f789f92956fd4 100644 (file)
@@ -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;
index be415d8e5fef47c1a7d9709aa73561ef56c9015a..7d89142d7a13148ed805fbc32d0b78f5a26a202e 100644 (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);
index 1e5a1e9ee8bcf4d8b2279e38affc10be016720df..f24acfa95cdc53054ce00211995ae177aef91ef4 100644 (file)
@@ -100,7 +100,7 @@ struct ir3_register {
                /* relative: */
                struct {
                        uint16_t id;
-                       uint16_t offset;
+                       int16_t offset;
                } array;
        };
 
index bd0ee89a1ec18a241343e977a2b50b38ce6642c3..1ea2dd9cbf713e0ba3668d49d874c76be7745942 100644 (file)
@@ -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]));
                        }
index ec832f5d72ae002cfc1fb71cbef96f4b17877f47..ba0c4a57aa34914c653e6dd3e0a8a2e8ea9bdca4 100644 (file)
@@ -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");