diff options
author | Christoph Bumiller <e0425955@student.tuwien.ac.at> | 2010-08-16 18:00:39 +0200 |
---|---|---|
committer | Christoph Bumiller <e0425955@student.tuwien.ac.at> | 2010-08-17 00:47:47 +0200 |
commit | 62f933a6f617050a267079b27360eaae2d0e1a70 (patch) | |
tree | a7897c1efe777740babff92409ba515085254ff4 /src | |
parent | 6c5c55723d32f8933ffb5fc6b5beb209eca84ca8 (diff) |
nv50: generate JOINs for outermost IF clauses
Diffstat (limited to 'src')
-rw-r--r-- | src/gallium/drivers/nv50/nv50_pc.h | 3 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_pc_emit.c | 11 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_pc_optimize.c | 16 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_pc_print.c | 1 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_tgsi_to_nc.c | 11 |
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 28208ad247..d24375100d 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 fe44b327ab..3a3b277c13 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 5d575461ca..b35dd72841 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 a4f567bde4..7bdeb1c78d 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 b23c285dc1..d6c5a8d660 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: |