nv50: fix build-predicate function
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>
Thu, 2 Sep 2010 16:27:01 +0000 (18:27 +0200)
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>
Thu, 2 Sep 2010 16:28:47 +0000 (18:28 +0200)
src/gallium/drivers/nv50/nv50_pc.c
src/gallium/drivers/nv50/nv50_pc.h
src/gallium/drivers/nv50/nv50_pc_optimize.c
src/gallium/drivers/nv50/nv50_tgsi_to_nc.c

index c2f2ab3ef30fe7929fea5cacacc5f7a7c641b8f4..e34c0553eb4aff843e6e55b5a71ff760df6687c8 100644 (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)
 {
index adc46dec8dbe5e5bf4fd64490073c087c4fe1376..703d32d334e662622489e9ce1187e43951822a79 100644 (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)
 {
index fb95da30f2349b45aa135fdcfb328f01765ddb26..1ed5032175493294b491dce3786a9f80eadf71fd 100644 (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
index 6bd2de4c744b4070d23cb5c0081beb81efa9dded..e1c6ed87bfe2049decd9453d259ed1c553c6b55a 100644 (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;