struct ir3_register *src_reg = __ssa_src(instr, src, IR3_REG_ARRAY);
src_reg->array = src->regs[0]->array;
} else {
- __ssa_src(instr, src, 0);
+ __ssa_src(instr, src, src->regs[0]->flags & IR3_REG_HIGH);
}
debug_assert(!(src->regs[0]->flags & IR3_REG_RELATIV));
instr->cat1.src_type = type;
{
unsigned bit_size = nir_dest_bit_size(*dst);
+ /* add extra mov if dst value is HIGH reg.. in some cases not all
+ * instructions can read from HIGH regs, in cases where they can
+ * ir3_cp will clean up the extra mov:
+ */
+ for (unsigned i = 0; i < ctx->last_dst_n; i++) {
+ if (ctx->last_dst[i]->regs[0]->flags & IR3_REG_HIGH) {
+ ctx->last_dst[i] = ir3_MOV(ctx->block, ctx->last_dst[i], TYPE_U32);
+ }
+ }
+
if (bit_size < 32) {
for (unsigned i = 0; i < ctx->last_dst_n; i++) {
struct ir3_instruction *dst = ctx->last_dst[i];
ralloc_free(ctx->last_dst);
}
+
ctx->last_dst = NULL;
ctx->last_dst_n = 0;
}
return;
}
+ unsigned flags = src->regs[0]->flags & (IR3_REG_HALF | IR3_REG_HIGH);
+
for (int i = 0, j = 0; i < n; i++) {
struct ir3_instruction *split = ir3_instr_create(block, OPC_META_FO);
- ir3_reg_create(split, 0, IR3_REG_SSA);
- ir3_reg_create(split, 0, IR3_REG_SSA)->instr = src;
+ ir3_reg_create(split, 0, IR3_REG_SSA | flags);
+ ir3_reg_create(split, 0, IR3_REG_SSA | flags)->instr = src;
split->fo.off = i + base;
if (prev) {
#include <math.h>
#include "ir3.h"
+#include "ir3_compiler.h"
#include "ir3_shader.h"
/*
unsigned flags)
{
unsigned valid_flags;
+
+ if ((flags & IR3_REG_HIGH) &&
+ (opc_cat(instr->opc) > 1) &&
+ (instr->block->shader->compiler->gpu_id >= 600))
+ return false;
+
flags = cp_flags(flags);
/* If destination is indirect, then source cannot be.. at least
*dstflags |= srcflags & IR3_REG_IMMED;
*dstflags |= srcflags & IR3_REG_RELATIV;
*dstflags |= srcflags & IR3_REG_ARRAY;
+ *dstflags |= srcflags & IR3_REG_HIGH;
/* if src of the src is boolean we can drop the (abs) since we know
* the source value is already a postitive integer. This cleans
else
printf("\x1b[0;31mr<a0.x + %d>\x1b[0m (%u)", reg->array.offset, reg->size);
} else {
+ if (reg->flags & IR3_REG_HIGH)
+ printf("H");
if (reg->flags & IR3_REG_HALF)
printf("h");
if (reg->flags & IR3_REG_CONST)