summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2010-11-03 10:21:07 -0700
committerIan Romanick <ian.d.romanick@intel.com>2010-12-16 16:56:51 -0800
commit573c78803d91225c51abb593c204fcee5628d49b (patch)
treeac43e45118b293b4ce3a1aa004f7fb3a5fb1d2b2
parent5650cc462d693ee9a6443918d2357f0bfb8e921f (diff)
downloadmesa-573c78803d91225c51abb593c204fcee5628d49b.tar.gz
glsl: Add a helper constructor for expressions that works out result type.
This doesn't cover all expressions or all operand types, but it will complain if you overreach and it allows for much greater slack on the programmer's part. (cherry picked from commit 6b937465d4aeab72fabcfe5250d477cf6790a521) The new constructors required some changes because the ir_quadop_vector changes were not cherry picked over from master. Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
-rw-r--r--src/glsl/ir.cpp97
-rw-r--r--src/glsl/ir.h2
2 files changed, 99 insertions, 0 deletions
diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp
index 844f847bd56..ad57079dcec 100644
--- a/src/glsl/ir.cpp
+++ b/src/glsl/ir.cpp
@@ -199,6 +199,103 @@ ir_expression::ir_expression(int op, const struct glsl_type *type,
this->operands[1] = op1;
}
+ir_expression::ir_expression(int op, ir_rvalue *op0)
+{
+ this->ir_type = ir_type_expression;
+
+ this->operation = ir_expression_operation(op);
+ this->operands[0] = op0;
+ this->operands[1] = NULL;
+
+ assert(op <= ir_last_unop);
+
+ switch (this->operation) {
+ case ir_unop_bit_not:
+ case ir_unop_logic_not:
+ case ir_unop_neg:
+ case ir_unop_abs:
+ case ir_unop_sign:
+ case ir_unop_rcp:
+ case ir_unop_rsq:
+ case ir_unop_sqrt:
+ case ir_unop_exp:
+ case ir_unop_log:
+ case ir_unop_exp2:
+ case ir_unop_log2:
+ case ir_unop_trunc:
+ case ir_unop_ceil:
+ case ir_unop_floor:
+ case ir_unop_fract:
+ case ir_unop_cos:
+ case ir_unop_dFdx:
+ case ir_unop_dFdy:
+ this->type = op0->type;
+ break;
+
+ case ir_unop_any:
+ this->type = glsl_type::bool_type;
+ break;
+
+ default:
+ assert(!"not reached: missing automatic type setup for ir_expression");
+ this->type = op0->type;
+ break;
+ }
+}
+
+ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1)
+{
+ this->ir_type = ir_type_expression;
+
+ this->operation = ir_expression_operation(op);
+ this->operands[0] = op0;
+ this->operands[1] = op1;
+
+ assert(op > ir_last_unop);
+
+ switch (this->operation) {
+ case ir_binop_all_equal:
+ case ir_binop_any_nequal:
+ this->type = glsl_type::bool_type;
+ break;
+
+ case ir_binop_add:
+ case ir_binop_sub:
+ case ir_binop_min:
+ case ir_binop_max:
+ case ir_binop_pow:
+ case ir_binop_mul:
+ if (op0->type->is_scalar()) {
+ this->type = op1->type;
+ } else if (op1->type->is_scalar()) {
+ this->type = op0->type;
+ } else {
+ /* FINISHME: matrix types */
+ assert(!op0->type->is_matrix() && !op1->type->is_matrix());
+ assert(op0->type == op1->type);
+ this->type = op0->type;
+ }
+ break;
+
+ case ir_binop_logic_and:
+ case ir_binop_logic_or:
+ if (op0->type->is_scalar()) {
+ this->type = op1->type;
+ } else if (op1->type->is_scalar()) {
+ this->type = op0->type;
+ }
+ break;
+
+ case ir_binop_dot:
+ this->type = glsl_type::float_type;
+ break;
+
+ default:
+ assert(!"not reached: missing automatic type setup for ir_expression");
+ this->type = glsl_type::float_type;
+ }
+}
+
unsigned int
ir_expression::get_num_operands(ir_expression_operation op)
{
diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index 7b2fe771cb8..0a520b420ba 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -794,12 +794,14 @@ public:
* Constructor for unary operation expressions
*/
ir_expression(int op, const struct glsl_type *type, ir_rvalue *);
+ ir_expression(int op, ir_rvalue *);
/**
* Constructor for binary operation expressions
*/
ir_expression(int op, const struct glsl_type *type,
ir_rvalue *, ir_rvalue *);
+ ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1);
virtual ir_expression *as_expression()
{