return block;
}
-struct ir3_instruction * ir3_instr_create(struct ir3_block *block,
- int category, opc_t opc)
+static struct ir3_instruction *instr_create(struct ir3_block *block, int nreg)
+{
+ struct ir3_instruction *instr;
+ unsigned sz = sizeof(*instr) + (nreg * sizeof(instr->regs[0]));
+ char *ptr = ir3_alloc(block->shader, sz);
+
+ instr = (struct ir3_instruction *)ptr;
+ ptr += sizeof(*instr);
+ instr->regs = (struct ir3_register **)ptr;
+
+#ifdef DEBUG
+ instr->regs_max = nreg;
+#endif
+
+ return instr;
+}
+
+struct ir3_instruction * ir3_instr_create2(struct ir3_block *block,
+ int category, opc_t opc, int nreg)
{
- struct ir3_instruction *instr =
- ir3_alloc(block->shader, sizeof(struct ir3_instruction));
+ struct ir3_instruction *instr = instr_create(block, nreg);
instr->block = block;
instr->category = category;
instr->opc = opc;
return instr;
}
+struct ir3_instruction * ir3_instr_create(struct ir3_block *block,
+ int category, opc_t opc)
+{
+ /* NOTE: we could be slightly more clever, at least for non-meta,
+ * and choose # of regs based on category.
+ */
+ return ir3_instr_create2(block, category, opc, 4);
+}
+
+/* only used by old compiler: */
struct ir3_instruction * ir3_instr_clone(struct ir3_instruction *instr)
{
- struct ir3_instruction *new_instr =
- ir3_alloc(instr->block->shader, sizeof(struct ir3_instruction));
+ struct ir3_instruction *new_instr = instr_create(instr->block,
+ instr->regs_count);
+ struct ir3_register **regs;
unsigned i;
+ regs = new_instr->regs;
*new_instr = *instr;
+ new_instr->regs = regs;
+
insert_instr(instr->block->shader, new_instr);
/* clone registers: */
int num, int flags)
{
struct ir3_register *reg = reg_create(instr->block->shader, num, flags);
- assert(instr->regs_count < ARRAY_SIZE(instr->regs));
+#ifdef DEBUG
+ debug_assert(instr->regs_count < instr->regs_max);
+#endif
instr->regs[instr->regs_count++] = reg;
return reg;
}
};
};
-#define IR3_INSTR_SRCS 10
-
struct ir3_instruction {
struct ir3_block *block;
int category;
IR3_INSTR_MARK = 0x1000,
} flags;
int repeat;
+#ifdef DEBUG
+ unsigned regs_max;
+#endif
unsigned regs_count;
- struct ir3_register *regs[1 + IR3_INSTR_SRCS];
+ struct ir3_register **regs;
union {
struct {
char inv;
struct ir3_instruction * ir3_instr_create(struct ir3_block *block,
int category, opc_t opc);
+struct ir3_instruction * ir3_instr_create2(struct ir3_block *block,
+ int category, opc_t opc, int nreg);
struct ir3_instruction * ir3_instr_clone(struct ir3_instruction *instr);
const char *ir3_instr_name(struct ir3_instruction *instr);
reg = ir3_reg_create(instr, 0, IR3_REG_SSA);
- collect = ir3_instr_create(ctx->block, -1, OPC_META_FI);
+ collect = ir3_instr_create2(ctx->block, -1, OPC_META_FI, 12);
ir3_reg_create(collect, 0, 0);
for (i = 0; i < 4; i++) {
if (tinf.src_wrmask & (1 << i))
reg = ir3_reg_create(instr, 0, IR3_REG_SSA);
- collect = ir3_instr_create(ctx->block, -1, OPC_META_FI);
+ collect = ir3_instr_create2(ctx->block, -1, OPC_META_FI, 5);
ir3_reg_create(collect, 0, 0);
if (inst->Texture.NumOffsets) {
static int trysched(struct ir3_sched_ctx *ctx,
struct ir3_instruction *instr)
{
- struct ir3_instruction *srcs[ARRAY_SIZE(instr->regs) - 1];
+ struct ir3_instruction *srcs[64];
struct ir3_instruction *src;
unsigned i, delay, nsrcs = 0;
if (instr->flags & IR3_INSTR_MARK)
return 0;
+ debug_assert(instr->regs_count < ARRAY_SIZE(srcs));
+
/* figure out our src's: */
for (i = 1; i < instr->regs_count; i++) {
struct ir3_register *reg = instr->regs[i];