diff options
author | Matt Turner <[email protected]> | 2013-09-17 21:34:15 -0700 |
---|---|---|
committer | Matt Turner <[email protected]> | 2013-10-07 10:43:19 -0700 |
commit | 06e41a02a3564b00404dd3dd5d6f6b5897df36e9 (patch) | |
tree | c8addcab70dc2f20e65df76fd2570230ff5e64bd /src/glsl | |
parent | 69909c866b6595f80d206c8e2484b1dc6668e7be (diff) |
glsl: Implement [iu]mulExtended() built-ins for ARB_gpu_shader5.
These built-ins have two "out" parameters, which makes implementing them
efficiently with our current compiler infrastructure difficult. Instead,
implement them in terms of the existing ir_binop_mul IR (to return the
low 32-bits) and a new ir_binop_mul64 which returns the high 32-bits.
v2: Rename mul64 -> imul_high as suggested by Ken.
Reviewed-by: Kenneth Graunke <[email protected]>
Diffstat (limited to 'src/glsl')
-rw-r--r-- | src/glsl/builtin_functions.cpp | 31 | ||||
-rw-r--r-- | src/glsl/ir.cpp | 2 | ||||
-rw-r--r-- | src/glsl/ir.h | 3 | ||||
-rw-r--r-- | src/glsl/ir_builder.cpp | 5 | ||||
-rw-r--r-- | src/glsl/ir_builder.h | 1 | ||||
-rw-r--r-- | src/glsl/ir_validate.cpp | 6 |
6 files changed, 47 insertions, 1 deletions
diff --git a/src/glsl/builtin_functions.cpp b/src/glsl/builtin_functions.cpp index 5b1b9c3b7c1..d40888d3819 100644 --- a/src/glsl/builtin_functions.cpp +++ b/src/glsl/builtin_functions.cpp @@ -533,6 +533,7 @@ private: B2(frexp) B1(uaddCarry) B1(usubBorrow) + B1(mulExtended) #undef B0 #undef B1 #undef B2 @@ -1961,6 +1962,18 @@ builtin_builder::create_builtins() _usubBorrow(glsl_type::uvec3_type), _usubBorrow(glsl_type::uvec4_type), NULL); + add_function("imulExtended", + _mulExtended(glsl_type::int_type), + _mulExtended(glsl_type::ivec2_type), + _mulExtended(glsl_type::ivec3_type), + _mulExtended(glsl_type::ivec4_type), + NULL); + add_function("umulExtended", + _mulExtended(glsl_type::uint_type), + _mulExtended(glsl_type::uvec2_type), + _mulExtended(glsl_type::uvec3_type), + _mulExtended(glsl_type::uvec4_type), + NULL); #undef F #undef FI #undef FIU @@ -3762,6 +3775,24 @@ builtin_builder::_usubBorrow(const glsl_type *type) return sig; } + +/** + * For both imulExtended() and umulExtended() built-ins. + */ +ir_function_signature * +builtin_builder::_mulExtended(const glsl_type *type) +{ + ir_variable *x = in_var(type, "x"); + ir_variable *y = in_var(type, "y"); + ir_variable *msb = out_var(type, "msb"); + ir_variable *lsb = out_var(type, "lsb"); + MAKE_SIG(glsl_type::void_type, gpu_shader5, 4, x, y, msb, lsb); + + body.emit(assign(msb, imul_high(x, y))); + body.emit(assign(lsb, mul(x, y))); + + return sig; +} /** @} */ /******************************************************************************/ diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp index 149ddbd5342..ead7456dfcc 100644 --- a/src/glsl/ir.cpp +++ b/src/glsl/ir.cpp @@ -398,6 +398,7 @@ ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1) this->type = glsl_type::uint_type; break; + case ir_binop_imul_high: case ir_binop_carry: case ir_binop_borrow: case ir_binop_lshift: @@ -529,6 +530,7 @@ static const char *const operator_strs[] = { "+", "-", "*", + "imul_high", "/", "carry", "borrow", diff --git a/src/glsl/ir.h b/src/glsl/ir.h index 756ce9c7cd3..9fd5f5a997a 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -1091,7 +1091,8 @@ enum ir_expression_operation { ir_binop_add, ir_binop_sub, - ir_binop_mul, + ir_binop_mul, /**< Floating-point or low 32-bit integer multiply. */ + ir_binop_imul_high, /**< Calculates the high 32-bits of a 64-bit multiply. */ ir_binop_div, /** diff --git a/src/glsl/ir_builder.cpp b/src/glsl/ir_builder.cpp index b6ce889834c..6c49734bef8 100644 --- a/src/glsl/ir_builder.cpp +++ b/src/glsl/ir_builder.cpp @@ -216,6 +216,11 @@ ir_expression *mul(operand a, operand b) return expr(ir_binop_mul, a, b); } +ir_expression *imul_high(operand a, operand b) +{ + return expr(ir_binop_imul_high, a, b); +} + ir_expression *div(operand a, operand b) { return expr(ir_binop_div, a, b); diff --git a/src/glsl/ir_builder.h b/src/glsl/ir_builder.h index 1345788ab13..1f0778870e3 100644 --- a/src/glsl/ir_builder.h +++ b/src/glsl/ir_builder.h @@ -133,6 +133,7 @@ ir_expression *expr(ir_expression_operation op, operand a, operand b, operand c) ir_expression *add(operand a, operand b); ir_expression *sub(operand a, operand b); ir_expression *mul(operand a, operand b); +ir_expression *imul_high(operand a, operand b); ir_expression *div(operand a, operand b); ir_expression *carry(operand a, operand b); ir_expression *borrow(operand a, operand b); diff --git a/src/glsl/ir_validate.cpp b/src/glsl/ir_validate.cpp index 38db8c20677..d6abc8eb5a8 100644 --- a/src/glsl/ir_validate.cpp +++ b/src/glsl/ir_validate.cpp @@ -429,6 +429,12 @@ ir_validate::visit_leave(ir_expression *ir) } break; + case ir_binop_imul_high: + assert(ir->type == ir->operands[0]->type); + assert(ir->type == ir->operands[1]->type); + assert(ir->type->is_integer()); + break; + case ir_binop_carry: case ir_binop_borrow: assert(ir->type == ir->operands[0]->type); |