Signed-off-by: Ilia Mirkin <imir...@alum.mit.edu> --- It didn't seem useful to add 2 separate lowering flags. I can't really imagine wanting to lower one but not the other.
Also, this is my first foray into the GLSL compiler, so please look out for noob mistakes. This did pass piglit tests though. src/glsl/ir_optimization.h | 1 + src/glsl/lower_instructions.cpp | 55 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/src/glsl/ir_optimization.h b/src/glsl/ir_optimization.h index 40bb613..5f0267d 100644 --- a/src/glsl/ir_optimization.h +++ b/src/glsl/ir_optimization.h @@ -38,6 +38,7 @@ #define INT_DIV_TO_MUL_RCP 0x40 #define BITFIELD_INSERT_TO_BFM_BFI 0x80 #define LDEXP_TO_ARITH 0x100 +#define CARRY_TO_ARITH 0x200 /** * \see class lower_packing_builtins_visitor diff --git a/src/glsl/lower_instructions.cpp b/src/glsl/lower_instructions.cpp index 49316d0..ecbda96 100644 --- a/src/glsl/lower_instructions.cpp +++ b/src/glsl/lower_instructions.cpp @@ -39,6 +39,7 @@ * - MOD_TO_FRACT * - LDEXP_TO_ARITH * - BITFIELD_INSERT_TO_BFM_BFI + * - CARRY_TO_ARITH * * SUB_TO_ADD_NEG: * --------------- @@ -91,6 +92,10 @@ * Breaks ir_quadop_bitfield_insert into ir_binop_bfm (bitfield mask) and * ir_triop_bfi (bitfield insert). * + * CARRY_TO_ARITH: + * --------------- + * Converts ir_carry and ir_borrow into (x + y) > x and (x < y) + * * Many GPUs implement the bitfieldInsert() built-in from ARB_gpu_shader_5 * with a pair of instructions. * @@ -127,6 +132,8 @@ private: void log_to_log2(ir_expression *); void bitfield_insert_to_bfm_bfi(ir_expression *); void ldexp_to_arith(ir_expression *); + void carry_to_arith(ir_expression *); + void borrow_to_arith(ir_expression *); }; } /* anonymous namespace */ @@ -436,6 +443,44 @@ lower_instructions_visitor::ldexp_to_arith(ir_expression *ir) this->progress = true; } +void +lower_instructions_visitor::carry_to_arith(ir_expression *ir) +{ + /* Translates + * ir_binop_carry x y + * into + * sum = ir_binop_add x y + * bcarry = ir_binop_less sum x + * carry = ir_unop_b2i bcarry + */ + + ir_rvalue *x_clone = ir->operands[0]->clone(ir, NULL); + ir->operation = ir_unop_i2u; + ir->operands[0] = b2i(less( + add(ir->operands[0], ir->operands[1]), + x_clone)); + ir->operands[1] = NULL; + + this->progress = true; +} + +void +lower_instructions_visitor::borrow_to_arith(ir_expression *ir) +{ + /* Translates + * ir_binop_borrow x y + * into + * bcarry = ir_binop_less x y + * carry = ir_unop_b2i bcarry + */ + + ir->operation = ir_unop_i2u; + ir->operands[0] = b2i(less(ir->operands[0], ir->operands[1])); + ir->operands[1] = NULL; + + this->progress = true; +} + ir_visitor_status lower_instructions_visitor::visit_leave(ir_expression *ir) { @@ -482,6 +527,16 @@ lower_instructions_visitor::visit_leave(ir_expression *ir) ldexp_to_arith(ir); break; + case ir_binop_carry: + if (lowering(CARRY_TO_ARITH)) + carry_to_arith(ir); + break; + + case ir_binop_borrow: + if (lowering(CARRY_TO_ARITH)) + borrow_to_arith(ir); + break; + default: return visit_continue; } -- 1.8.3.2 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev