nv50: Silence uninitialized variable warning.
[mesa.git] / src / gallium / drivers / nv50 / nv50_tgsi_to_nc.c
index 4168bbbc9547bb8ad8a9d48353f6371ee2b19ceb..012d100e7aae2764d65ea7f20ed1c343e13129d0 100644 (file)
@@ -31,7 +31,6 @@
 #include "tgsi/tgsi_parse.h"
 #include "tgsi/tgsi_util.h"
 
-#include "util/u_simple_list.h"
 #include "tgsi/tgsi_dump.h"
 
 #define BLD_MAX_TEMPS 64
@@ -39,7 +38,7 @@
 #define BLD_MAX_PREDS 4
 #define BLD_MAX_IMMDS 128
 
-#define BLD_MAX_COND_NESTING 4
+#define BLD_MAX_COND_NESTING 8
 #define BLD_MAX_LOOP_NESTING 4
 #define BLD_MAX_CALL_NESTING 2
 
@@ -70,14 +69,14 @@ bld_vals_del_val(struct bld_value_stack *stk, struct nv_value *val)
 {
    unsigned i;
 
-   for (i = stk->size - 1; i >= 0; --i)
-      if (stk->body[i] == val)
+   for (i = stk->size; i > 0; --i)
+      if (stk->body[i - 1] == val)
          break;
-   if (i < 0)
+   if (!i)
       return FALSE;
 
-   if (i != stk->size - 1)
-      stk->body[i] = stk->body[stk->size - 1];
+   if (i != stk->size)
+      stk->body[i - 1] = stk->body[stk->size - 1];
 
    --stk->size; /* XXX: old size in REALLOC */
    return TRUE;
@@ -125,7 +124,7 @@ struct bld_context {
    struct bld_value_stack pvs[BLD_MAX_PREDS][4]; /* TGSI_FILE_PREDICATE */
    struct bld_value_stack ovs[PIPE_MAX_SHADER_OUTPUTS][4];
 
-   uint32_t outputs_written[(PIPE_MAX_SHADER_OUTPUTS + 31) / 32];
+   uint32_t outputs_written[(PIPE_MAX_SHADER_OUTPUTS + 7) / 8];
 
    struct nv_value *frgcrd[4];
    struct nv_value *sysval[4];
@@ -214,6 +213,7 @@ static INLINE void
 bld_warn_uninitialized(struct bld_context *bld, int kind,
                        struct bld_value_stack *stk, struct nv_basic_block *b)
 {
+#ifdef NV50_TGSI2NC_DEBUG
    long i = (stk - &bld->tvs[0][0]) / 4;
    long c = (stk - &bld->tvs[0][0]) & 3;
 
@@ -222,6 +222,7 @@ bld_warn_uninitialized(struct bld_context *bld, int kind,
 
    debug_printf("WARNING: TEMP[%li].%c %s used uninitialized in BB:%i\n",
                 i, (int)('x' + c), kind ? "may be" : "is", b->id);
+#endif
 }
 
 static INLINE struct nv_value *
@@ -288,7 +289,8 @@ bld_phi(struct bld_context *bld, struct nv_basic_block *b,
         struct bld_value_stack *stack)
 {
    struct nv_basic_block *in;
-   struct nv_value *vals[16], *val;
+   struct nv_value *vals[16] = { 0 };
+   struct nv_value *val;
    struct nv_instruction *phi;
    int i, j, n;
 
@@ -646,7 +648,10 @@ bld_pow(struct bld_context *bld, struct nv_value *x, struct nv_value *e)
 static INLINE struct nv_value *
 bld_load_imm_f32(struct bld_context *bld, float f)
 {
-   return bld_insn_1(bld, NV_OP_MOV, bld_imm_f32(bld, f));
+   struct nv_value *imm = bld_insn_1(bld, NV_OP_MOV, bld_imm_f32(bld, f));
+
+   SET_TYPE(imm, NV_TYPE_F32);
+   return imm;
 }
 
 static INLINE struct nv_value *
@@ -660,6 +665,7 @@ bld_get_address(struct bld_context *bld, int id, struct nv_value *indirect)
 {
    int i;
    struct nv_instruction *nvi;
+   struct nv_value *val;
 
    for (i = 0; i < 4; ++i) {
       if (!bld->saved_addr[i][0])
@@ -672,8 +678,15 @@ bld_get_address(struct bld_context *bld, int id, struct nv_value *indirect)
    }
    i &= 3;
 
-   bld->saved_addr[i][0] = bld_load_imm_u32(bld, id);
+   val = bld_imm_u32(bld, id);
+   if (indirect)
+      val = bld_insn_2(bld, NV_OP_ADD, indirect, val);
+   else
+      val = bld_insn_1(bld, NV_OP_MOV, val);
+
+   bld->saved_addr[i][0] = val;
    bld->saved_addr[i][0]->reg.file = NV_FILE_ADDR;
+   bld->saved_addr[i][0]->reg.type = NV_TYPE_U16;
    bld->saved_addr[i][1] = indirect;
    return bld->saved_addr[i][0];
 }
@@ -694,19 +707,15 @@ bld_predicate(struct bld_context *bld, struct nv_value *src, boolean bool_only)
       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)
+         if (!s0i || !nv50_op_can_write_flags(s0i->opcode))
             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) {
+   if (!nv50_op_can_write_flags(nvi->opcode) ||
+       nvi->bb != bld->pc->current_block) {
       nvi = new_instruction(bld->pc, NV_OP_CVT);
       nv_reference(bld->pc, &nvi->src[0], src);
    }
@@ -943,6 +952,8 @@ emit_store(struct bld_context *bld, const struct tgsi_full_instruction *inst,
 
    switch (reg->Register.File) {
    case TGSI_FILE_OUTPUT:
+      if (!value->insn && (bld->ti->output_file == NV_FILE_OUT))
+         value = bld_insn_1(bld, NV_OP_MOV, value);
       value = bld_insn_1(bld, NV_OP_MOV, value);
       value->reg.file = bld->ti->output_file;
 
@@ -955,9 +966,9 @@ emit_store(struct bld_context *bld, const struct tgsi_full_instruction *inst,
       break;
    case TGSI_FILE_TEMPORARY:
       assert(reg->Register.Index < BLD_MAX_TEMPS);
-      value->reg.file = NV_FILE_GPR;
-      if (value->insn->bb != bld->pc->current_block)
+      if (!value->insn || (value->insn->bb != bld->pc->current_block))
          value = bld_insn_1(bld, NV_OP_MOV, value);
+      value->reg.file = NV_FILE_GPR;
 
       if (bld->ti->store_to_memory)
          bld_lmem_store(bld, ptr, reg->Register.Index * 4 + chan, value);
@@ -967,6 +978,7 @@ emit_store(struct bld_context *bld, const struct tgsi_full_instruction *inst,
    case TGSI_FILE_ADDRESS:
       assert(reg->Register.Index < BLD_MAX_ADDRS);
       value->reg.file = NV_FILE_ADDR;
+      value->reg.type = NV_TYPE_U16;
       STORE_ADDR(reg->Register.Index, chan, value);
       break;
    }
@@ -1070,7 +1082,7 @@ emit_fetch(struct bld_context *bld, const struct tgsi_full_instruction *insn,
    const struct tgsi_full_src_register *src = &insn->Src[s];
    struct nv_value *res;
    struct nv_value *ptr = NULL;
-   unsigned idx, swz, dim_idx, ind_idx, ind_swz;
+   unsigned idx, swz, dim_idx, ind_idx, ind_swz, sgn;
    ubyte type = infer_src_type(insn->Instruction.Opcode);
 
    idx = src->Register.Index;
@@ -1152,10 +1164,15 @@ emit_fetch(struct bld_context *bld, const struct tgsi_full_instruction *insn,
    if (!res)
       return bld_undef(bld, NV_FILE_GPR);
 
+   sgn = tgsi_util_get_full_src_register_sign_mode(src, chan);
+
    if (insn->Instruction.Opcode != TGSI_OPCODE_MOV)
       res->reg.as_type = type;
+   else
+   if (sgn != TGSI_UTIL_SIGN_KEEP) /* apparently "MOV A, -B" assumes float */
+      res->reg.as_type = NV_TYPE_F32;
 
-   switch (tgsi_util_get_full_src_register_sign_mode(src, chan)) {
+   switch (sgn) {
    case TGSI_UTIL_SIGN_KEEP:
       break;
    case TGSI_UTIL_SIGN_CLEAR:
@@ -1252,10 +1269,14 @@ get_tex_dim(const struct tgsi_full_instruction *insn, int *dim, int *arg)
 
 static void
 load_proj_tex_coords(struct bld_context *bld,
-                     struct nv_value *t[4], int dim,
+                     struct nv_value *t[4], int dim, int arg,
                      const struct tgsi_full_instruction *insn)
 {
-   int c, mask = 0;
+   int c, mask;
+
+   mask = (1 << dim) - 1;
+   if (arg != dim)
+      mask |= 4; /* depth comparison value */
 
    t[3] = emit_fetch(bld, insn, 0, 3);
 
@@ -1267,17 +1288,19 @@ load_proj_tex_coords(struct bld_context *bld,
 
    t[3] = bld_insn_1(bld, NV_OP_RCP, t[3]);
 
-   for (c = 0; c < dim; ++c) {
+   for (c = 0; c < 4; ++c) {
+      if (!(mask & (1 << c)))
+         continue;
       t[c] = emit_fetch(bld, insn, 0, c);
 
-      if (t[c]->insn->opcode == NV_OP_LINTERP ||
-          t[c]->insn->opcode == NV_OP_PINTERP) {
-         t[c] = bld_duplicate_insn(bld, t[c]->insn);
-         t[c]->insn->opcode = NV_OP_PINTERP;
-         nv_reference(bld->pc, &t[c]->insn->src[1], t[3]);
-      } else {
-         mask |= 1 << c;
-      }
+      if (t[c]->insn->opcode != NV_OP_LINTERP &&
+          t[c]->insn->opcode != NV_OP_PINTERP)
+         continue;
+      t[c] = bld_duplicate_insn(bld, t[c]->insn);
+      t[c]->insn->opcode = NV_OP_PINTERP;
+      nv_reference(bld->pc, &t[c]->insn->src[1], t[3]);
+
+      mask &= ~(1 << c);
    }
 
    for (c = 0; mask; ++c, mask >>= 1) {
@@ -1450,10 +1473,13 @@ bld_tex(struct bld_context *bld, struct nv_value *dst0[4],
    get_tex_dim(insn, &dim, &arg);
 
    if (!cube && insn->Instruction.Opcode == TGSI_OPCODE_TXP)
-      load_proj_tex_coords(bld, t, dim, insn);
-   else
+      load_proj_tex_coords(bld, t, dim, arg, insn);
+   else {
       for (c = 0; c < dim; ++c)
          t[c] = emit_fetch(bld, insn, 0, c);
+      if (arg != dim)
+         t[dim] = emit_fetch(bld, insn, 0, 2);
+   }
 
    if (cube) {
       assert(dim >= 3);
@@ -1468,9 +1494,6 @@ bld_tex(struct bld_context *bld, struct nv_value *dst0[4],
          t[c] = bld_insn_2(bld, NV_OP_MUL, t[c], s[0]);
    }
 
-   if (arg != dim)
-      t[dim] = emit_fetch(bld, insn, 0, 2);
-
    if (opcode == NV_OP_TXB || opcode == NV_OP_TXL) {
       t[arg++] = emit_fetch(bld, insn, 0, 3);
 
@@ -1517,7 +1540,7 @@ bld_instruction(struct bld_context *bld,
    struct nv_value *src0;
    struct nv_value *src1;
    struct nv_value *src2;
-   struct nv_value *dst0[4];
+   struct nv_value *dst0[4] = { 0 };
    struct nv_value *temp;
    int c;
    uint opcode = translate_opcode(insn->Instruction.Opcode);
@@ -1614,6 +1637,23 @@ bld_instruction(struct bld_context *bld,
       if (insn->Dst[0].Register.WriteMask & 8)
          dst0[3] = emit_fetch(bld, insn, 1, 3);
       break;
+   case TGSI_OPCODE_EXP:
+      src0 = emit_fetch(bld, insn, 0, 0);
+      temp = bld_insn_1(bld, NV_OP_FLOOR, src0);
+
+      if (insn->Dst[0].Register.WriteMask & 2)
+         dst0[1] = bld_insn_2(bld, NV_OP_SUB, src0, temp);
+      if (insn->Dst[0].Register.WriteMask & 1) {
+         temp = bld_insn_1(bld, NV_OP_PREEX2, temp);
+         dst0[0] = bld_insn_1(bld, NV_OP_EX2, temp);
+      }
+      if (insn->Dst[0].Register.WriteMask & 4) {
+         temp = bld_insn_1(bld, NV_OP_PREEX2, src0);
+         dst0[2] = bld_insn_1(bld, NV_OP_EX2, temp);
+      }
+      if (insn->Dst[0].Register.WriteMask & 8)
+         dst0[3] = bld_imm_f32(bld, 1.0f);
+      break;
    case TGSI_OPCODE_EX2:
       src0 = emit_fetch(bld, insn, 0, 0);
       temp = bld_insn_1(bld, NV_OP_PREEX2, src0);
@@ -1641,6 +1681,8 @@ bld_instruction(struct bld_context *bld,
    {
       struct nv_basic_block *b = new_basic_block(bld->pc);
 
+      assert(bld->cond_lvl < BLD_MAX_COND_NESTING);
+
       nvbb_attach_block(bld->pc->current_block, b, CFG_EDGE_FORWARD);
 
       bld->join_bb[bld->cond_lvl] = bld->pc->current_block;
@@ -1693,6 +1735,8 @@ bld_instruction(struct bld_context *bld,
       struct nv_basic_block *bl = new_basic_block(bld->pc);
       struct nv_basic_block *bb = new_basic_block(bld->pc);
 
+      assert(bld->loop_lvl < BLD_MAX_LOOP_NESTING);
+
       bld->loop_bb[bld->loop_lvl] = bl;
       bld->brkt_bb[bld->loop_lvl] = bb;
 
@@ -1792,6 +1836,24 @@ bld_instruction(struct bld_context *bld,
       FOR_EACH_DST0_ENABLED_CHANNEL(c, insn)
          dst0[c] = temp;
       break;
+   case TGSI_OPCODE_LOG:
+      src0 = emit_fetch(bld, insn, 0, 0);
+      src0 = bld_insn_1(bld, NV_OP_ABS, src0);
+      temp = bld_insn_1(bld, NV_OP_LG2, src0);
+      dst0[2] = temp;
+      if (insn->Dst[0].Register.WriteMask & 3) {
+         temp = bld_insn_1(bld, NV_OP_FLOOR, temp);
+         dst0[0] = temp;
+      }
+      if (insn->Dst[0].Register.WriteMask & 2) {
+         temp = bld_insn_1(bld, NV_OP_PREEX2, temp);
+         temp = bld_insn_1(bld, NV_OP_EX2, temp);
+         temp = bld_insn_1(bld, NV_OP_RCP, temp);
+         dst0[1] = bld_insn_2(bld, NV_OP_MUL, src0, temp);
+      }
+      if (insn->Dst[0].Register.WriteMask & 8)
+         dst0[3] = bld_imm_f32(bld, 1.0f);
+      break;
    case TGSI_OPCODE_RCP:
    case TGSI_OPCODE_LG2:
       src0 = emit_fetch(bld, insn, 0, 0);