On a6xx+ with half-regs conflicting with full-regs, the legalize pass needs to set appropriate sync bits, such as (sy), on writes to full regs that conflict with half regs, and visa-versa. Signed-off-by: Rob Clark <robdclark@gmail.com>tags/19.1-branchpoint
@@ -35,6 +35,7 @@ | |||
#include "util/u_math.h" | |||
#include "instr-a3xx.h" | |||
#include "ir3_compiler.h" | |||
/* simple allocator to carve allocations out of an up-front allocated heap, | |||
* so that we can free everything easily in one shot. | |||
@@ -899,6 +900,8 @@ static struct ir3_register * reg_create(struct ir3 *shader, | |||
reg->wrmask = 1; | |||
reg->flags = flags; | |||
reg->num = num; | |||
if (shader->compiler->gpu_id >= 600) | |||
reg->merged = true; | |||
return reg; | |||
} | |||
@@ -98,11 +98,13 @@ struct ir3_register { | |||
} flags; | |||
bool merged : 1; /* half-regs conflict with full regs (ie >= a6xx) */ | |||
/* normal registers: | |||
* the component is in the low two bits of the reg #, so | |||
* rN.x becomes: (N << 2) | x | |||
*/ | |||
int num; | |||
uint16_t num; | |||
union { | |||
/* immediate: */ | |||
int32_t iim_val; | |||
@@ -1426,8 +1428,13 @@ static inline unsigned regmask_idx(struct ir3_register *reg) | |||
{ | |||
unsigned num = (reg->flags & IR3_REG_RELATIV) ? reg->array.offset : reg->num; | |||
debug_assert(num < MAX_REG); | |||
if (reg->flags & IR3_REG_HALF) | |||
num += MAX_REG; | |||
if (reg->flags & IR3_REG_HALF) { | |||
if (reg->merged) { | |||
num /= 2; | |||
} else { | |||
num += MAX_REG; | |||
} | |||
} | |||
return num; | |||
} | |||