glsl: add lowering passes for carry/borrow
Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu> Reviewed-by: Matt Turner <mattst88@gmail.com>
This commit is contained in:
parent
f64bfb2e39
commit
31b92aa2fc
|
@ -38,6 +38,8 @@
|
|||
#define INT_DIV_TO_MUL_RCP 0x40
|
||||
#define BITFIELD_INSERT_TO_BFM_BFI 0x80
|
||||
#define LDEXP_TO_ARITH 0x100
|
||||
#define CARRY_TO_ARITH 0x200
|
||||
#define BORROW_TO_ARITH 0x400
|
||||
|
||||
/**
|
||||
* \see class lower_packing_builtins_visitor
|
||||
|
|
|
@ -39,6 +39,8 @@
|
|||
* - MOD_TO_FRACT
|
||||
* - LDEXP_TO_ARITH
|
||||
* - BITFIELD_INSERT_TO_BFM_BFI
|
||||
* - CARRY_TO_ARITH
|
||||
* - BORROW_TO_ARITH
|
||||
*
|
||||
* SUB_TO_ADD_NEG:
|
||||
* ---------------
|
||||
|
@ -94,6 +96,14 @@
|
|||
* Many GPUs implement the bitfieldInsert() built-in from ARB_gpu_shader_5
|
||||
* with a pair of instructions.
|
||||
*
|
||||
* CARRY_TO_ARITH:
|
||||
* ---------------
|
||||
* Converts ir_carry into (x + y) < x.
|
||||
*
|
||||
* BORROW_TO_ARITH:
|
||||
* ----------------
|
||||
* Converts ir_borrow into (x < y).
|
||||
*
|
||||
*/
|
||||
|
||||
#include "main/core.h" /* for M_LOG2E */
|
||||
|
@ -127,6 +137,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 +448,42 @@ 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 +530,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(BORROW_TO_ARITH))
|
||||
borrow_to_arith(ir);
|
||||
break;
|
||||
|
||||
default:
|
||||
return visit_continue;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue