freedreno/ir3: a4xx encodes larger immed offset
authorRob Clark <robclark@freedesktop.org>
Mon, 1 Jun 2015 16:35:19 +0000 (12:35 -0400)
committerRob Clark <robclark@freedesktop.org>
Sun, 21 Jun 2015 11:54:31 +0000 (07:54 -0400)
Without this, negative branch/jump offsets look like very large positive
offsets.

Signed-off-by: Rob Clark <robclark@freedesktop.org>
src/gallium/drivers/freedreno/ir3/disasm-a3xx.c
src/gallium/drivers/freedreno/ir3/instr-a3xx.h
src/gallium/drivers/freedreno/ir3/ir3.c
src/gallium/drivers/freedreno/ir3/ir3.h

index a5136c6bd3d9ca0bebdfb117905b0d6058faeea6..48ae7c71b9f16e3d5b4f0b479cffe7985fe847f8 100644 (file)
@@ -133,16 +133,16 @@ static void print_instr_cat0(instr_t *instr)
                break;
        case OPC_BR:
                printf(" %sp0.%c, #%d", cat0->inv ? "!" : "",
-                               component[cat0->comp], cat0->immed);
+                               component[cat0->comp], cat0->a3xx.immed);
                break;
        case OPC_JUMP:
        case OPC_CALL:
-               printf(" #%d", cat0->immed);
+               printf(" #%d", cat0->a3xx.immed);
                break;
        }
 
-       if ((debug & PRINT_VERBOSE) && (cat0->dummy1|cat0->dummy2|cat0->dummy3|cat0->dummy4))
-               printf("\t{0: %x,%x,%x,%x}", cat0->dummy1, cat0->dummy2, cat0->dummy3, cat0->dummy4);
+       if ((debug & PRINT_VERBOSE) && (cat0->a3xx.dummy1|cat0->dummy2|cat0->dummy3|cat0->dummy4))
+               printf("\t{0: %x,%x,%x,%x}", cat0->a3xx.dummy1, cat0->dummy2, cat0->dummy3, cat0->dummy4);
 }
 
 static void print_instr_cat1(instr_t *instr)
index 5ead0c869990b68296ae0eee8ee8635db4e9c015..efb07ea479e0c8043199684c3644c70eb7d80ccb 100644 (file)
@@ -278,8 +278,16 @@ static inline int reg_special(reg_t reg)
 
 typedef struct PACKED {
        /* dword0: */
-       int16_t  immed    : 16;
-       uint32_t dummy1   : 16;
+       union PACKED {
+               struct PACKED {
+                       int16_t  immed    : 16;
+                       uint32_t dummy1   : 16;
+               } a3xx;
+               struct PACKED {
+                       int32_t  immed    : 20;
+                       uint32_t dummy1   : 12;
+               } a4xx;
+       };
 
        /* dword1: */
        uint32_t dummy2   : 8;
index 7515b79b0c98c44fcb7ece16abf50e8e0073bb78..ba5851c6c820ae1285bce078ecf53fb3c46064a7 100644 (file)
@@ -152,7 +152,11 @@ static int emit_cat0(struct ir3_instruction *instr, void *ptr,
 {
        instr_cat0_t *cat0 = ptr;
 
-       cat0->immed    = instr->cat0.immed;
+       if (info->gpu_id >= 400) {
+               cat0->a4xx.immed = instr->cat0.immed;
+       } else {
+               cat0->a3xx.immed = instr->cat0.immed;
+       }
        cat0->repeat   = instr->repeat;
        cat0->ss       = !!(instr->flags & IR3_INSTR_SS);
        cat0->inv      = instr->cat0.inv;
@@ -547,6 +551,7 @@ void * ir3_assemble(struct ir3 *shader, struct ir3_info *info,
        struct ir3_block *block = shader->block;
        uint32_t *ptr, *dwords;
 
+       info->gpu_id        = gpu_id;
        info->max_reg       = -1;
        info->max_half_reg  = -1;
        info->max_const     = -1;
index 38912aa3bd4f05c388b92d1ed17f184e09e30588..95b866988b85839b93ec859770a6626372e6aafe 100644 (file)
@@ -41,6 +41,7 @@ struct ir3_instruction;
 struct ir3_block;
 
 struct ir3_info {
+       uint32_t gpu_id;
        uint16_t sizedwords;
        uint16_t instrs_count;   /* expanded to account for rpt's */
        /* NOTE: max_reg, etc, does not include registers not touched