From 0bd3a75de9002e73214cde883691da558db7bc70 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 3 Jul 2012 15:51:22 -0600 Subject: [PATCH] svga: fix register collision issue in emit_conditional() MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit If the 'dst' register is the same as the 'pass' register we'll generate invalid code. Use a temporary register in that case. Reviewed-by: José Fonseca --- src/gallium/drivers/svga/svga_tgsi_insn.c | 24 +++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/gallium/drivers/svga/svga_tgsi_insn.c b/src/gallium/drivers/svga/svga_tgsi_insn.c index 64dfa557539..42df4195fcc 100644 --- a/src/gallium/drivers/svga/svga_tgsi_insn.c +++ b/src/gallium/drivers/svga/svga_tgsi_insn.c @@ -1285,6 +1285,20 @@ static boolean emit_kilp(struct svga_shader_emitter *emit, return submit_op0( emit, inst, temp ); } + +/** + * Test if r1 and r2 are the same register. + */ +static boolean +same_register(struct src_register r1, struct src_register r2) +{ + return (r1.base.num == r2.base.num && + r1.base.type_upper == r2.base.type_upper && + r1.base.type_lower == r2.base.type_lower); +} + + + /* Implement conditionals by initializing destination reg to 'fail', * then set predicate reg with UFOP_SETP, then move 'pass' to dest * based on predicate reg. @@ -1335,6 +1349,16 @@ emit_conditional(struct svga_shader_emitter *emit, break; } + if (same_register(src(dst), pass)) { + /* We'll get bad results if the dst and pass registers are the same + * so use a temp register containing pass. + */ + SVGA3dShaderDestToken temp = get_temp(emit); + if (!submit_op1(emit, inst_token(SVGA3DOP_MOV), temp, pass)) + return FALSE; + pass = src(temp); + } + /* SETP src0, COMPOP, src1 */ if (!submit_op2( emit, setp_token, pred_reg, src0, src1 )) -- 2.30.2