From: Rob Clark Date: Mon, 1 Jun 2015 16:35:19 +0000 (-0400) Subject: freedreno/ir3: a4xx encodes larger immed offset X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=660d5c1646f5d63f9626b24beabc9cfc318849d4;p=mesa.git freedreno/ir3: a4xx encodes larger immed offset Without this, negative branch/jump offsets look like very large positive offsets. Signed-off-by: Rob Clark --- diff --git a/src/gallium/drivers/freedreno/ir3/disasm-a3xx.c b/src/gallium/drivers/freedreno/ir3/disasm-a3xx.c index a5136c6bd3d..48ae7c71b9f 100644 --- a/src/gallium/drivers/freedreno/ir3/disasm-a3xx.c +++ b/src/gallium/drivers/freedreno/ir3/disasm-a3xx.c @@ -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) diff --git a/src/gallium/drivers/freedreno/ir3/instr-a3xx.h b/src/gallium/drivers/freedreno/ir3/instr-a3xx.h index 5ead0c86999..efb07ea479e 100644 --- a/src/gallium/drivers/freedreno/ir3/instr-a3xx.h +++ b/src/gallium/drivers/freedreno/ir3/instr-a3xx.h @@ -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; diff --git a/src/gallium/drivers/freedreno/ir3/ir3.c b/src/gallium/drivers/freedreno/ir3/ir3.c index 7515b79b0c9..ba5851c6c82 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3.c +++ b/src/gallium/drivers/freedreno/ir3/ir3.c @@ -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; diff --git a/src/gallium/drivers/freedreno/ir3/ir3.h b/src/gallium/drivers/freedreno/ir3/ir3.h index 38912aa3bd4..95b866988b8 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3.h +++ b/src/gallium/drivers/freedreno/ir3/ir3.h @@ -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