nv50: fix build-predicate function

This commit is contained in:
Christoph Bumiller 2010-09-02 18:27:01 +02:00
parent 9f9ae4eee1
commit 443abc80db
4 changed files with 65 additions and 13 deletions

View file

@ -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;
}
@ -507,6 +507,19 @@ nvbb_insert_tail(struct nv_basic_block *b, struct nv_instruction *i)
b->num_instructions++;
}
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)
{

View file

@ -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)
{

View file

@ -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

View file

@ -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;