nv50: generate JOINs for outermost IF clauses
This commit is contained in:
@@ -83,7 +83,8 @@
|
||||
#define NV_OP_NOP 53
|
||||
#define NV_OP_SELECT 54
|
||||
#define NV_OP_EXPORT 55
|
||||
#define NV_OP_COUNT 56
|
||||
#define NV_OP_JOIN 56
|
||||
#define NV_OP_COUNT 57
|
||||
|
||||
#define NV_FILE_GPR 0
|
||||
#define NV_FILE_OUT 1
|
||||
|
||||
@@ -38,7 +38,7 @@ const ubyte nv50_inst_min_size_tab[NV_OP_COUNT] =
|
||||
0, 0, 0, 8, 8, 4, 4, 4, 8, 4, 4, 8, 8, 8, 8, 8, /* 15 */
|
||||
8, 8, 8, 4, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, /* 31 */
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, /* 47 */
|
||||
4, 8, 8, 8, 8, 8, 0, 0
|
||||
4, 8, 8, 8, 8, 8, 0, 0, 8
|
||||
};
|
||||
|
||||
/* XXX: silence, you ! */
|
||||
@@ -71,6 +71,9 @@ nv50_inst_min_size(struct nv_instruction *i)
|
||||
if (i->flags_def || i->flags_src || i->src[4])
|
||||
return 8;
|
||||
|
||||
if (i->is_join)
|
||||
return 8;
|
||||
|
||||
if (i->src[2]) {
|
||||
if (i->saturate || i->src[2]->mod)
|
||||
return 8;
|
||||
@@ -1126,6 +1129,7 @@ nv50_emit_instruction(struct nv_pc *pc, struct nv_instruction *i)
|
||||
emit_flow(pc, i, 0xa);
|
||||
break;
|
||||
case NV_OP_NOP:
|
||||
case NV_OP_JOIN:
|
||||
pc->emit[0] = 0xf0000001;
|
||||
pc->emit[1] = 0xe0000000;
|
||||
break;
|
||||
@@ -1141,5 +1145,10 @@ nv50_emit_instruction(struct nv_pc *pc, struct nv_instruction *i)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i->is_join) {
|
||||
assert(i->is_long && !(pc->emit[1] & 1));
|
||||
pc->emit[1] |= 2;
|
||||
}
|
||||
|
||||
assert((pc->emit[0] & 1) == i->is_long);
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ inst_commutation_legal(struct nv_instruction *a,
|
||||
static INLINE boolean
|
||||
inst_cullable(struct nv_instruction *nvi)
|
||||
{
|
||||
return (!(nvi->is_terminator ||
|
||||
return (!(nvi->is_terminator || nvi->is_join ||
|
||||
nvi->target ||
|
||||
nvi->fixed ||
|
||||
nv_nvi_refcount(nvi)));
|
||||
@@ -95,7 +95,8 @@ nvi_isnop(struct nv_instruction *nvi)
|
||||
if (nvi->fixed ||
|
||||
nvi->is_terminator ||
|
||||
nvi->flags_src ||
|
||||
nvi->flags_def)
|
||||
nvi->flags_def ||
|
||||
nvi->is_join)
|
||||
return FALSE;
|
||||
|
||||
if (nvi->def[0]->join->reg.id < 0)
|
||||
@@ -934,7 +935,7 @@ nv_pass_flatten(struct nv_pass *ctx, struct nv_basic_block *b)
|
||||
|
||||
if (bb_is_if_else_endif(b)) {
|
||||
|
||||
debug_printf("nv_pass_flatten: IF/ELSE/ENDIF construct at BB:%i\n", b->id);
|
||||
debug_printf("pass_flatten: IF/ELSE/ENDIF construct at BB:%i\n", b->id);
|
||||
|
||||
for (n0 = 0, nvi = b->out[0]->entry; nvi; nvi = nvi->next, ++n0)
|
||||
if (!nv50_nvi_can_predicate(nvi))
|
||||
@@ -959,6 +960,15 @@ nv_pass_flatten(struct nv_pass *ctx, struct nv_basic_block *b)
|
||||
|
||||
assert(b->exit && b->exit->opcode == NV_OP_BRA);
|
||||
nv_nvi_delete(b->exit);
|
||||
|
||||
if (b->exit && b->exit->opcode == NV_OP_JOINAT)
|
||||
nv_nvi_delete(b->exit);
|
||||
|
||||
if ((nvi = b->out[0]->out[0]->entry)) {
|
||||
nvi->is_join = 0;
|
||||
if (nvi->opcode == NV_OP_JOIN)
|
||||
nv_nvi_delete(nvi);
|
||||
}
|
||||
}
|
||||
}
|
||||
DESCEND_ARBITRARY(i, nv_pass_flatten);
|
||||
|
||||
@@ -95,6 +95,7 @@ static const char *nv_opcode_names[NV_OP_COUNT + 1] = {
|
||||
"nop",
|
||||
"select",
|
||||
"export",
|
||||
"join",
|
||||
"BAD_OP"
|
||||
};
|
||||
|
||||
|
||||
@@ -1314,7 +1314,7 @@ bld_instruction(struct bld_context *bld,
|
||||
|
||||
src1 = bld_predicate(bld, emit_fetch(bld, insn, 0, 0), TRUE);
|
||||
|
||||
bld_flow(bld, NV_OP_BRA, NV_CC_EQ, src1, NULL, FALSE);
|
||||
bld_flow(bld, NV_OP_BRA, NV_CC_EQ, src1, NULL, (bld->cond_lvl == 0));
|
||||
|
||||
++bld->cond_lvl;
|
||||
bld_new_block(bld, b);
|
||||
@@ -1346,13 +1346,12 @@ bld_instruction(struct bld_context *bld,
|
||||
|
||||
bld->cond_bb[bld->cond_lvl]->exit->target = b;
|
||||
|
||||
if (0 && bld->join_bb[bld->cond_lvl]) {
|
||||
bld->join_bb[bld->cond_lvl]->exit->prev->target = b;
|
||||
|
||||
new_instruction(bld->pc, NV_OP_NOP)->is_join = TRUE;
|
||||
}
|
||||
|
||||
bld_new_block(bld, b);
|
||||
|
||||
if (!bld->cond_lvl && bld->join_bb[bld->cond_lvl]) {
|
||||
bld->join_bb[bld->cond_lvl]->exit->prev->target = b;
|
||||
new_instruction(bld->pc, NV_OP_JOIN)->is_join = TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TGSI_OPCODE_BGNLOOP:
|
||||
|
||||
Reference in New Issue
Block a user