diff options
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r-- | src/gallium/drivers/nv50/nv50_pc.c | 15 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_pc.h | 20 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_pc_optimize.c | 9 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_tgsi_to_nc.c | 34 |
4 files changed, 65 insertions, 13 deletions
diff --git a/src/gallium/drivers/nv50/nv50_pc.c b/src/gallium/drivers/nv50/nv50_pc.c index c2f2ab3ef30..e34c0553eb4 100644 --- a/src/gallium/drivers/nv50/nv50_pc.c +++ b/src/gallium/drivers/nv50/nv50_pc.c @@ -121,7 +121,7 @@ nv50_nvi_can_load(struct nv_instruction *nvi, int s, struct nv_value *value) return FALSE; case NV_OP_MOV: assert(s == 0); - return TRUE; + return /* TRUE */ FALSE; /* don't turn MOVs into loads */ default: return FALSE; } @@ -508,6 +508,19 @@ nvbb_insert_tail(struct nv_basic_block *b, struct nv_instruction *i) } void +nvi_insert_after(struct nv_instruction *at, struct nv_instruction *ni) +{ + if (!at->next) { + nvbb_insert_tail(at->bb, ni); + return; + } + ni->next = at->next; + ni->prev = at; + ni->next->prev = ni; + ni->prev->next = ni; +} + +void nv_nvi_delete(struct nv_instruction *nvi) { struct nv_basic_block *b = nvi->bb; diff --git a/src/gallium/drivers/nv50/nv50_pc.h b/src/gallium/drivers/nv50/nv50_pc.h index adc46dec8db..703d32d334e 100644 --- a/src/gallium/drivers/nv50/nv50_pc.h +++ b/src/gallium/drivers/nv50/nv50_pc.h @@ -347,9 +347,10 @@ struct nv_pc { }; void nvbb_insert_tail(struct nv_basic_block *, struct nv_instruction *); +void nvi_insert_after(struct nv_instruction *, struct nv_instruction *); static INLINE struct nv_instruction * -new_instruction(struct nv_pc *pc, uint opcode) +nv_alloc_instruction(struct nv_pc *pc, uint opcode) { struct nv_instruction *insn; @@ -359,10 +360,27 @@ new_instruction(struct nv_pc *pc, uint opcode) insn->cc = NV_CC_TR; insn->opcode = opcode; + return insn; +} + +static INLINE struct nv_instruction * +new_instruction(struct nv_pc *pc, uint opcode) +{ + struct nv_instruction *insn = nv_alloc_instruction(pc, opcode); + nvbb_insert_tail(pc->current_block, insn); return insn; } +static INLINE struct nv_instruction * +new_instruction_at(struct nv_pc *pc, struct nv_instruction *at, uint opcode) +{ + struct nv_instruction *insn = nv_alloc_instruction(pc, opcode); + + nvi_insert_after(at, insn); + return insn; +} + static INLINE struct nv_value * new_value(struct nv_pc *pc, ubyte file, ubyte type) { diff --git a/src/gallium/drivers/nv50/nv50_pc_optimize.c b/src/gallium/drivers/nv50/nv50_pc_optimize.c index fb95da30f23..1ed50321754 100644 --- a/src/gallium/drivers/nv50/nv50_pc_optimize.c +++ b/src/gallium/drivers/nv50/nv50_pc_optimize.c @@ -636,6 +636,15 @@ constant_operand(struct nv_pc *pc, default: break; } + + if (nvi->opcode == NV_OP_MOV && nvi->flags_def) { + struct nv_instruction *cvt = new_instruction_at(pc, nvi, NV_OP_CVT); + + nv_reference(pc, &cvt->src[0], nvi->def[0]); + + cvt->flags_def = nvi->flags_def; + nvi->flags_def = NULL; + } } static int diff --git a/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c b/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c index 6bd2de4c744..e1c6ed87bfe 100644 --- a/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c +++ b/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c @@ -625,23 +625,35 @@ bld_get_address(struct bld_context *bld, int id, struct nv_value *indirect) static struct nv_value * bld_predicate(struct bld_context *bld, struct nv_value *src, boolean bool_only) { - struct nv_instruction *nvi = src->insn; + struct nv_instruction *s0i, *nvi = src->insn; - if (nvi->opcode == NV_OP_LDA || - nvi->opcode == NV_OP_PHI || - nvi->bb != bld->pc->current_block) { - nvi = new_instruction(bld->pc, NV_OP_CVT); - nv_reference(bld->pc, &nvi->src[0], src); + if (!nvi) { + nvi = bld_insn_1(bld, + (src->reg.file == NV_FILE_IMM) ? NV_OP_MOV : NV_OP_LDA, + src)->insn; + src = nvi->def[0]; } else if (bool_only) { - while (nvi->opcode == NV_OP_ABS || nvi->opcode == NV_OP_CVT || - nvi->opcode == NV_OP_NEG) { - /* TGSI SET gets conversion to f32, we only need source 0/~0 */ - if (!nvi->def[0]->insn->flags_src) - nvi = nvi->src[0]->value->insn; + while (nvi->opcode == NV_OP_ABS || nvi->opcode == NV_OP_NEG || + nvi->opcode == NV_OP_CVT) { + s0i = nvi->src[0]->value->insn; + if (!s0i || + s0i->opcode == NV_OP_LDA || + s0i->opcode == NV_OP_MOV || + s0i->opcode == NV_OP_PHI) + break; + nvi = s0i; + assert(!nvi->flags_src); } } + if (nvi->opcode == NV_OP_LDA || + nvi->opcode == NV_OP_MOV || + nvi->opcode == NV_OP_PHI || nvi->bb != bld->pc->current_block) { + nvi = new_instruction(bld->pc, NV_OP_CVT); + nv_reference(bld->pc, &nvi->src[0], src); + } + if (!nvi->flags_def) { nvi->flags_def = new_value(bld->pc, NV_FILE_FLAGS, NV_TYPE_U16); nvi->flags_def->insn = nvi; |