summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nv50
diff options
context:
space:
mode:
authorChristoph Bumiller <[email protected]>2010-08-16 18:00:39 +0200
committerChristoph Bumiller <[email protected]>2010-08-17 00:47:47 +0200
commit62f933a6f617050a267079b27360eaae2d0e1a70 (patch)
treea7897c1efe777740babff92409ba515085254ff4 /src/gallium/drivers/nv50
parent6c5c55723d32f8933ffb5fc6b5beb209eca84ca8 (diff)
nv50: generate JOINs for outermost IF clauses
Diffstat (limited to 'src/gallium/drivers/nv50')
-rw-r--r--src/gallium/drivers/nv50/nv50_pc.h3
-rw-r--r--src/gallium/drivers/nv50/nv50_pc_emit.c11
-rw-r--r--src/gallium/drivers/nv50/nv50_pc_optimize.c16
-rw-r--r--src/gallium/drivers/nv50/nv50_pc_print.c1
-rw-r--r--src/gallium/drivers/nv50/nv50_tgsi_to_nc.c11
5 files changed, 31 insertions, 11 deletions
diff --git a/src/gallium/drivers/nv50/nv50_pc.h b/src/gallium/drivers/nv50/nv50_pc.h
index 28208ad247b..d24375100d8 100644
--- a/src/gallium/drivers/nv50/nv50_pc.h
+++ b/src/gallium/drivers/nv50/nv50_pc.h
@@ -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
diff --git a/src/gallium/drivers/nv50/nv50_pc_emit.c b/src/gallium/drivers/nv50/nv50_pc_emit.c
index fe44b327ab1..3a3b277c139 100644
--- a/src/gallium/drivers/nv50/nv50_pc_emit.c
+++ b/src/gallium/drivers/nv50/nv50_pc_emit.c
@@ -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);
}
diff --git a/src/gallium/drivers/nv50/nv50_pc_optimize.c b/src/gallium/drivers/nv50/nv50_pc_optimize.c
index 5d575461ca9..b35dd728417 100644
--- a/src/gallium/drivers/nv50/nv50_pc_optimize.c
+++ b/src/gallium/drivers/nv50/nv50_pc_optimize.c
@@ -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);
diff --git a/src/gallium/drivers/nv50/nv50_pc_print.c b/src/gallium/drivers/nv50/nv50_pc_print.c
index a4f567bde49..7bdeb1c78d4 100644
--- a/src/gallium/drivers/nv50/nv50_pc_print.c
+++ b/src/gallium/drivers/nv50/nv50_pc_print.c
@@ -95,6 +95,7 @@ static const char *nv_opcode_names[NV_OP_COUNT + 1] = {
"nop",
"select",
"export",
+ "join",
"BAD_OP"
};
diff --git a/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c b/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c
index b23c285dc12..d6c5a8d6606 100644
--- a/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c
+++ b/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c
@@ -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;
+ bld_new_block(bld, b);
- new_instruction(bld->pc, NV_OP_NOP)->is_join = TRUE;
+ 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;
}
-
- bld_new_block(bld, b);
}
break;
case TGSI_OPCODE_BGNLOOP: