ir_binop_greater,
ir_binop_lequal,
ir_binop_gequal,
- ir_binop_equal,
- ir_binop_nequal,
+ ir_binop_all_equal,
+ ir_binop_any_nequal,
ir_binop_bit_and,
ir_binop_bit_xor,
ir_binop_bit_or,
2, /* ir_binop_gequal */
2, /* ir_binop_equal */
2, /* ir_binop_nequal */
+ 2, /* ir_binop_all_equal */
+ 2, /* ir_binop_any_nequal */
2, /* ir_binop_lshift */
2, /* ir_binop_rshift */
">=",
"==",
"!=",
+ "all_equal",
+ "any_nequal",
"<<",
">>",
"&",
const char *ir_expression::operator_string(ir_expression_operation op)
{
assert((unsigned int) op < Elements(operator_strs));
+ assert(Elements(operator_strs) == (ir_binop_pow + 1));
return operator_strs[op];
}
ir_binop_greater,
ir_binop_lequal,
ir_binop_gequal,
+ ir_binop_equal,
+ ir_binop_nequal,
/**
* Returns single boolean for whether all components of operands[0]
* equal the components of operands[1].
*/
- ir_binop_equal,
+ ir_binop_all_equal,
/**
* Returns single boolean for whether any component of operands[0]
* is not equal to the corresponding component of operands[1].
*/
- ir_binop_nequal,
+ ir_binop_any_nequal,
/*@}*/
/**
case ir_binop_gequal: new_op = ir_binop_less; break;
case ir_binop_equal: new_op = ir_binop_nequal; break;
case ir_binop_nequal: new_op = ir_binop_equal; break;
+ case ir_binop_all_equal: new_op = ir_binop_any_nequal; break;
+ case ir_binop_any_nequal: new_op = ir_binop_all_equal; break;
default:
/* The default case handler is here to silence a warning from GCC.
if (op[0]->type->is_array()) {
assert(op[1] != NULL && op[1]->type->is_array());
switch (this->operation) {
- case ir_binop_equal:
+ case ir_binop_all_equal:
return new(ctx) ir_constant(op[0]->has_value(op[1]));
- case ir_binop_nequal:
+ case ir_binop_any_nequal:
return new(ctx) ir_constant(!op[0]->has_value(op[1]));
default:
break;
assert(0);
}
break;
-
case ir_binop_equal:
- data.b[0] = op[0]->has_value(op[1]);
+ switch (op[0]->type->base_type) {
+ case GLSL_TYPE_UINT:
+ data.b[0] = op[0]->value.u[0] == op[1]->value.u[0];
+ break;
+ case GLSL_TYPE_INT:
+ data.b[0] = op[0]->value.i[0] == op[1]->value.i[0];
+ break;
+ case GLSL_TYPE_FLOAT:
+ data.b[0] = op[0]->value.f[0] == op[1]->value.f[0];
+ break;
+ default:
+ assert(0);
+ }
break;
case ir_binop_nequal:
+ switch (op[0]->type->base_type) {
+ case GLSL_TYPE_UINT:
+ data.b[0] = op[0]->value.u[0] != op[1]->value.u[0];
+ break;
+ case GLSL_TYPE_INT:
+ data.b[0] = op[0]->value.i[0] != op[1]->value.i[0];
+ break;
+ case GLSL_TYPE_FLOAT:
+ data.b[0] = op[0]->value.f[0] != op[1]->value.f[0];
+ break;
+ default:
+ assert(0);
+ }
+ break;
+
+ case ir_binop_all_equal:
+ data.b[0] = op[0]->has_value(op[1]);
+ break;
+ case ir_binop_any_nequal:
data.b[0] = !op[0]->has_value(op[1]);
break;
ir_dereference *const op1 = get_column(b_var, i);
ir_expression *const cmp =
- new(this->mem_ctx) ir_expression(ir_binop_nequal,
+ new(this->mem_ctx) ir_expression(ir_binop_any_nequal,
glsl_type::bool_type, op0, op1);
ir_rvalue *const swiz =
}
break;
- case ir_binop_equal:
- case ir_binop_nequal:
+ case ir_binop_all_equal:
+ case ir_binop_any_nequal:
do_equal_mat_mat(result_var, op_var[1], op_var[0],
- (orig_expr->operation == ir_binop_equal));
+ (orig_expr->operation == ir_binop_all_equal));
break;
default:
assert(ir->operands[0]->type == ir->type);
}
break;
+
case ir_binop_less:
case ir_binop_greater:
case ir_binop_lequal:
case ir_binop_gequal:
- /* GLSL < > <= >= operators take scalar floats/ints, but in the
- * IR we may want to do them for vectors instead to support the
- * lessEqual() and friends builtins.
+ case ir_binop_equal:
+ case ir_binop_nequal:
+ /* The semantics of the IR operators differ from the GLSL <, >, <=, >=,
+ * ==, and != operators. The IR operators perform a component-wise
+ * comparison on scalar or vector types and return a boolean scalar or
+ * vector type of the same size.
*/
- assert(ir->type == glsl_type::bool_type);
+ assert(ir->type->base_type == GLSL_TYPE_BOOL);
assert(ir->operands[0]->type == ir->operands[1]->type);
+ assert(ir->operands[0]->type->is_vector()
+ || ir->operands[0]->type->is_scalar());
+ assert(ir->operands[0]->type->vector_elements
+ == ir->type->vector_elements);
break;
- case ir_binop_equal:
- case ir_binop_nequal:
- /* GLSL == and != operate on vectors and return a bool, and the
- * IR matches that. We may want to switch up the IR to work on
- * vectors and return a bvec and make the operators break down
- * to ANDing/ORing the results of the vector comparison.
+ case ir_binop_all_equal:
+ case ir_binop_any_nequal:
+ /* GLSL == and != operate on scalars, vectors, matrices and arrays, and
+ * return a scalar boolean. The IR matches that.
*/
assert(ir->type == glsl_type::bool_type);
assert(ir->operands[0]->type == ir->operands[1]->type);
ir_to_mesa_emit_op2(ir, OPCODE_SGE, result_dst, op[0], op[1]);
break;
case ir_binop_equal:
+ ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, op[0], op[1]);
+ break;
+ case ir_binop_nequal:
+ ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]);
+ break;
+ case ir_binop_all_equal:
/* "==" operator producing a scalar boolean. */
if (ir->operands[0]->type->is_vector() ||
ir->operands[1]->type->is_vector()) {
ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, op[0], op[1]);
}
break;
- case ir_binop_nequal:
+ case ir_binop_any_nequal:
/* "!=" operator producing a scalar boolean. */
if (ir->operands[0]->type->is_vector() ||
ir->operands[1]->type->is_vector()) {