nv50: fix indirect CONST access with large or negative offsets
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>
Sun, 12 Sep 2010 22:59:38 +0000 (00:59 +0200)
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>
Mon, 13 Sep 2010 15:26:41 +0000 (17:26 +0200)
src/gallium/drivers/nv50/nv50_pc_emit.c
src/gallium/drivers/nv50/nv50_tgsi_to_nc.c

index 8c64b198756986c114c32d12e6234c8292c0a992..1eb44741f16465f49b0a3fdd9a7efcf25f4ff6f8 100644 (file)
@@ -696,7 +696,9 @@ emit_add_b32(struct nv_pc *pc, struct nv_instruction *i)
 static void
 emit_add_a16(struct nv_pc *pc, struct nv_instruction *i)
 {
-   pc->emit[0] = 0xd0000001 | (get_immd_u32(i->src[0]) << 9);
+   int s = (i->opcode == NV_OP_MOV) ? 0 : 1;
+
+   pc->emit[0] = 0xd0000001 | ((uint16_t)get_immd_u32(i->src[s]) << 9);
    pc->emit[1] = 0x20000000;
 
    pc->emit[0] |= (DREG(i->def[0])->id + 1) << 2;
@@ -704,7 +706,7 @@ emit_add_a16(struct nv_pc *pc, struct nv_instruction *i)
    set_pred(pc, i);
 
    if (i->src[1])
-      set_a16_bits(pc, SREG(i->src[1])->id);
+      set_a16_bits(pc, SREG(i->src[1])->id + 1);
 }
 
 static void
index 54d6fb960f8ccfcdbcf1b1eef856d246c691ef15..a2b6901c81e93e7649e6f91657834b7ece633fcc 100644 (file)
@@ -665,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])
@@ -677,7 +678,13 @@ 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;