nv50: be more cautious about using reg_instance

Trying to free part of nv50_pc->reg_instances[] for an
nv50_reg representing an indirect constant resulted in
a segmentation fault.
This commit is contained in:
Christoph Bumiller 2009-12-14 18:39:13 +01:00
parent c14be63c56
commit 2677f199a5
1 changed files with 10 additions and 17 deletions

View File

@ -156,14 +156,15 @@ struct nv50_pc {
static INLINE struct nv50_reg * static INLINE struct nv50_reg *
reg_instance(struct nv50_pc *pc, struct nv50_reg *reg) reg_instance(struct nv50_pc *pc, struct nv50_reg *reg)
{ {
struct nv50_reg *dup = NULL; struct nv50_reg *ri;
assert(pc->reg_instance_nr < 16);
ri = &pc->reg_instances[pc->reg_instance_nr++];
if (reg) { if (reg) {
assert(pc->reg_instance_nr < 16); *ri = *reg;
dup = &pc->reg_instances[pc->reg_instance_nr++];
*dup = *reg;
reg->mod = 0; reg->mod = 0;
} }
return dup; return ri;
} }
static INLINE void static INLINE void
@ -1886,7 +1887,7 @@ tgsi_src(struct nv50_pc *pc, int chan, const struct tgsi_full_src_register *src,
/* Indicate indirection by setting r->acc < 0 and /* Indicate indirection by setting r->acc < 0 and
* use the index field to select the address reg. * use the index field to select the address reg.
*/ */
r = MALLOC_STRUCT(nv50_reg); r = reg_instance(pc, NULL);
swz = tgsi_util_get_src_register_swizzle( swz = tgsi_util_get_src_register_swizzle(
&src->Indirect, 0); &src->Indirect, 0);
ctor_reg(r, P_CONST, ctor_reg(r, P_CONST,
@ -1940,6 +1941,8 @@ tgsi_src(struct nv50_pc *pc, int chan, const struct tgsi_full_src_register *src,
break; break;
} }
if (r && r->acc >= 0 && r != temp)
return reg_instance(pc, r);
return r; return r;
} }
@ -2094,8 +2097,7 @@ nv50_program_tx_insn(struct nv50_pc *pc,
for (c = 0; c < 4; c++) for (c = 0; c < 4; c++)
if (src_mask & (1 << c)) if (src_mask & (1 << c))
src[i][c] = reg_instance(pc, src[i][c] = tgsi_src(pc, c, fs, neg_supp);
tgsi_src(pc, c, fs, neg_supp));
} }
brdc = temp = pc->r_brdc; brdc = temp = pc->r_brdc;
@ -2466,15 +2468,6 @@ nv50_program_tx_insn(struct nv50_pc *pc,
} }
} }
for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
for (c = 0; c < 4; c++) {
if (!src[i][c])
continue;
if (src[i][c]->acc < 0 && src[i][c]->type == P_CONST)
FREE(src[i][c]); /* indirect constant */
}
}
kill_temp_temp(pc); kill_temp_temp(pc);
pc->reg_instance_nr = 0; pc->reg_instance_nr = 0;