summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/nv50/nv50_pc.c15
-rw-r--r--src/gallium/drivers/nv50/nv50_pc.h20
-rw-r--r--src/gallium/drivers/nv50/nv50_pc_optimize.c9
-rw-r--r--src/gallium/drivers/nv50/nv50_tgsi_to_nc.c34
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;