commit 0bd93153d45bec1616a40b81af28d0c5a1536539 Author: chr Date: Sat May 16 16:30:59 2009 +0200 Rewrite emit_set. diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 95e3bdf..c3185a9 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -833,38 +833,45 @@ emit_cvt(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src, } static void -emit_set(struct nv50_pc *pc, unsigned c_op, struct nv50_reg *dst, +emit_set(struct nv50_pc *pc, unsigned c_op, struct nv50_reg *dst, int wp, struct nv50_reg *src0, struct nv50_reg *src1) { struct nv50_program_exec *e = exec(pc); - unsigned inv_cop[8] = { 0, 4, 2, 6, 1, 5, 3, 7 }; struct nv50_reg *rdst; - assert(c_op <= 7); + /* This maps TGSI_CC_GT/EQ/LT/GE/LE/NE to condition codes for SET. + * Note that conditional execution prefixes are probably different, + * and for SET, code 0xE seems to mean 'output condition code'. + * XXX: maybe verify these again + */ + static unsigned cop_map[16] = { 0x4, 0x2, 0x1, 0x6, 0x3, 0xd, 0, 0, + 0x3, 0xd, 0x6, 0x1, 0x4, 0x2, 0, 0 }; if (check_swap_src_0_1(pc, &src0, &src1)) - c_op = inv_cop[c_op]; + c_op += 8; rdst = dst; if (dst->type != P_TEMP) dst = alloc_temp(pc, NULL); - /* set.u32 */ set_long(pc, e); e->inst[0] |= 0xb0000000; - e->inst[1] |= (3 << 29); - e->inst[1] |= (c_op << 14); - /*XXX: breaks things, .u32 by default? - * decuda will disasm as .u16 and use .lo/.hi regs, but this - * doesn't seem to match what the hw actually does. - inst[1] |= 0x04000000; << breaks things.. .u32 by default? - */ - set_dst(pc, dst, e); - set_src_0(pc, src0, e); - set_src_1(pc, src1, e); + e->inst[1] |= 0x60000000; + e->inst[1] |= ((c_op < 16) ? cop_map[c_op] : 0xe) << 14; + + if (dst) + set_dst(pc, dst, e); + else { + e->inst[0] |= 0x000001fc; + e->inst[1] |= 0x00000008; + } + if (wp >= 0) + set_pred_wr(pc, 1, wp, e); + emit(pc, e); - emit_cvt(pc, rdst, dst, -1, CVTOP_RN, CVT_F32_U32); - + if (dst) + emit_cvt(pc, rdst, dst, -1, CVTOP_RN | CVTOP_ABS, CVT_F32_S32); + if (dst != rdst) free_temp(pc, dst); } @@ -1478,7 +1485,7 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) for (c = 0; c < 4; c++) { if (!(mask & (1 << c))) continue; - emit_set(pc, 6, dst[c], src[0][c], src[1][c]); + emit_set(pc, TGSI_CC_GE, dst[c], -1, src[0][c], src[1][c]); } break; case TGSI_OPCODE_SIN: @@ -1490,7 +1497,7 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) for (c = 0; c < 4; c++) { if (!(mask & (1 << c))) continue; - emit_set(pc, 1, dst[c], src[0][c], src[1][c]); + emit_set(pc, TGSI_CC_LT, dst[c], -1, src[0][c], src[1][c]); } break; case TGSI_OPCODE_SUB: