1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright © 2010 Intel Corporation
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"),
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software is furnished to do so, subject to the following conditions:
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the next
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * paragraph) shall be included in all copies or substantial portions of the
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software.
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * DEALINGS IN THE SOFTWARE.
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \file lower_mat_op_to_vec.cpp
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Breaks matrix operation expressions down to a series of vector operations.
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Generally this is how we have to codegen matrix operations for a
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * GPU, so this gives us the chance to constant fold operations on a
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * column or row.
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "ir.h"
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "ir_expression_flattening.h"
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "glsl_types.h"
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass ir_mat_op_to_vec_visitor : public ir_hierarchical_visitor {
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic:
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_mat_op_to_vec_visitor()
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->made_progress = false;
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->mem_ctx = NULL;
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_visitor_status visit_leave(ir_assignment *);
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_dereference *get_column(ir_dereference *val, int col);
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_rvalue *get_element(ir_dereference *val, int col, int row);
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void do_mul_mat_mat(ir_dereference *result,
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       ir_dereference *a, ir_dereference *b);
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void do_mul_mat_vec(ir_dereference *result,
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       ir_dereference *a, ir_dereference *b);
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void do_mul_vec_mat(ir_dereference *result,
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       ir_dereference *a, ir_dereference *b);
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void do_mul_mat_scalar(ir_dereference *result,
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  ir_dereference *a, ir_dereference *b);
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void do_equal_mat_mat(ir_dereference *result, ir_dereference *a,
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			 ir_dereference *b, bool test_equal);
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void *mem_ctx;
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   bool made_progress;
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic bool
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgmat_op_to_vec_predicate(ir_instruction *ir)
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_expression *expr = ir->as_expression();
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned int i;
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!expr)
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return false;
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < expr->get_num_operands(); i++) {
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (expr->operands[i]->type->is_matrix())
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 return true;
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return false;
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdo_mat_op_to_vec(exec_list *instructions)
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_mat_op_to_vec_visitor v;
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Pull out any matrix expression to a separate assignment to a
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * temp.  This will make our handling of the breakdown to
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * operations on the matrix's vector components much easier.
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   do_expression_flattening(instructions, mat_op_to_vec_predicate);
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   visit_list_elements(&v, instructions);
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return v.made_progress;
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue *
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_mat_op_to_vec_visitor::get_element(ir_dereference *val, int col, int row)
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   val = get_column(val, col);
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return new(mem_ctx) ir_swizzle(val, row, 0, 0, 0, 1);
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_dereference *
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_mat_op_to_vec_visitor::get_column(ir_dereference *val, int row)
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   val = val->clone(mem_ctx, NULL);
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (val->type->is_matrix()) {
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      val = new(mem_ctx) ir_dereference_array(val,
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					      new(mem_ctx) ir_constant(row));
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return val;
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_mat_op_to_vec_visitor::do_mul_mat_mat(ir_dereference *result,
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					 ir_dereference *a,
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					 ir_dereference *b)
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int b_col, i;
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_assignment *assign;
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_expression *expr;
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (b_col = 0; b_col < b->type->matrix_columns; b_col++) {
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* first column */
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      expr = new(mem_ctx) ir_expression(ir_binop_mul,
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					get_column(a, 0),
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					get_element(b, b_col, 0));
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* following columns */
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 1; i < a->type->matrix_columns; i++) {
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_expression *mul_expr;
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 mul_expr = new(mem_ctx) ir_expression(ir_binop_mul,
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					       get_column(a, i),
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					       get_element(b, b_col, i));
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 expr = new(mem_ctx) ir_expression(ir_binop_add,
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					   expr,
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					   mul_expr);
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assign = new(mem_ctx) ir_assignment(get_column(result, b_col), expr);
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      base_ir->insert_before(assign);
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_mat_op_to_vec_visitor::do_mul_mat_vec(ir_dereference *result,
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					 ir_dereference *a,
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					 ir_dereference *b)
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i;
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_assignment *assign;
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_expression *expr;
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* first column */
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   expr = new(mem_ctx) ir_expression(ir_binop_mul,
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				     get_column(a, 0),
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				     get_element(b, 0, 0));
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* following columns */
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 1; i < a->type->matrix_columns; i++) {
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_expression *mul_expr;
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      mul_expr = new(mem_ctx) ir_expression(ir_binop_mul,
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					    get_column(a, i),
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					    get_element(b, 0, i));
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      expr = new(mem_ctx) ir_expression(ir_binop_add, expr, mul_expr);
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   result = result->clone(mem_ctx, NULL);
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assign = new(mem_ctx) ir_assignment(result, expr);
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   base_ir->insert_before(assign);
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_mat_op_to_vec_visitor::do_mul_vec_mat(ir_dereference *result,
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					 ir_dereference *a,
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					 ir_dereference *b)
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i;
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < b->type->matrix_columns; i++) {
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_rvalue *column_result;
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_expression *column_expr;
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_assignment *column_assign;
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      column_result = result->clone(mem_ctx, NULL);
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      column_result = new(mem_ctx) ir_swizzle(column_result, i, 0, 0, 0, 1);
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      column_expr = new(mem_ctx) ir_expression(ir_binop_dot,
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					       a->clone(mem_ctx, NULL),
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					       get_column(b, i));
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      column_assign = new(mem_ctx) ir_assignment(column_result,
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						 column_expr);
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      base_ir->insert_before(column_assign);
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_mat_op_to_vec_visitor::do_mul_mat_scalar(ir_dereference *result,
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					    ir_dereference *a,
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					    ir_dereference *b)
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i;
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < a->type->matrix_columns; i++) {
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_expression *column_expr;
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_assignment *column_assign;
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      column_expr = new(mem_ctx) ir_expression(ir_binop_mul,
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					       get_column(a, i),
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					       b->clone(mem_ctx, NULL));
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      column_assign = new(mem_ctx) ir_assignment(get_column(result, i),
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						 column_expr);
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      base_ir->insert_before(column_assign);
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_mat_op_to_vec_visitor::do_equal_mat_mat(ir_dereference *result,
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					   ir_dereference *a,
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					   ir_dereference *b,
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					   bool test_equal)
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* This essentially implements the following GLSL:
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * bool equal(mat4 a, mat4 b)
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * {
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *   return !any(bvec4(a[0] != b[0],
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *                     a[1] != b[1],
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *                     a[2] != b[2],
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *                     a[3] != b[3]);
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * }
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * bool nequal(mat4 a, mat4 b)
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * {
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *   return any(bvec4(a[0] != b[0],
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *                    a[1] != b[1],
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *                    a[2] != b[2],
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *                    a[3] != b[3]);
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * }
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const unsigned columns = a->type->matrix_columns;
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const glsl_type *const bvec_type =
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      glsl_type::get_instance(GLSL_TYPE_BOOL, columns, 1);
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_variable *const tmp_bvec =
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      new(this->mem_ctx) ir_variable(bvec_type, "mat_cmp_bvec",
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				     ir_var_temporary);
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->base_ir->insert_before(tmp_bvec);
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (unsigned i = 0; i < columns; i++) {
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_expression *const cmp =
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 new(this->mem_ctx) ir_expression(ir_binop_any_nequal,
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					  get_column(a, i),
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					  get_column(b, i));
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_dereference *const lhs =
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 new(this->mem_ctx) ir_dereference_variable(tmp_bvec);
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_assignment *const assign =
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 new(this->mem_ctx) ir_assignment(lhs, cmp, NULL, (1U << i));
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->base_ir->insert_before(assign);
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_rvalue *const val = new(this->mem_ctx) ir_dereference_variable(tmp_bvec);
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_expression *any = new(this->mem_ctx) ir_expression(ir_unop_any, val);
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (test_equal)
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      any = new(this->mem_ctx) ir_expression(ir_unop_logic_not, any);
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_assignment *const assign =
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      new(mem_ctx) ir_assignment(result->clone(mem_ctx, NULL), any);
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   base_ir->insert_before(assign);
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic bool
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orghas_matrix_operand(const ir_expression *expr, unsigned &columns)
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (unsigned i = 0; i < expr->get_num_operands(); i++) {
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (expr->operands[i]->type->is_matrix()) {
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 columns = expr->operands[i]->type->matrix_columns;
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 return true;
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return false;
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_visitor_status
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign)
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_expression *orig_expr = orig_assign->rhs->as_expression();
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned int i, matrix_columns = 1;
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_dereference *op[2];
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!orig_expr)
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return visit_continue;
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!has_matrix_operand(orig_expr, matrix_columns))
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return visit_continue;
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(orig_expr->get_num_operands() <= 2);
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   mem_ctx = ralloc_parent(orig_assign);
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_dereference_variable *result =
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      orig_assign->lhs->as_dereference_variable();
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(result);
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Store the expression operands in temps so we can use them
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * multiple times.
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < orig_expr->get_num_operands(); i++) {
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_assignment *assign;
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_dereference *deref = orig_expr->operands[i]->as_dereference();
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Avoid making a temporary if we don't need to to avoid aliasing. */
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (deref &&
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  deref->variable_referenced() != result->variable_referenced()) {
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 op[i] = deref;
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 continue;
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Otherwise, store the operand in a temporary generally if it's
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * not a dereference.
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_variable *var = new(mem_ctx) ir_variable(orig_expr->operands[i]->type,
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						  "mat_op_to_vec",
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						  ir_var_temporary);
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      base_ir->insert_before(var);
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Note that we use this dereference for the assignment.  That means
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * that others that want to use op[i] have to clone the deref.
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[i] = new(mem_ctx) ir_dereference_variable(var);
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assign = new(mem_ctx) ir_assignment(op[i], orig_expr->operands[i]);
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      base_ir->insert_before(assign);
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* OK, time to break down this matrix operation. */
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (orig_expr->operation) {
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_neg: {
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Apply the operation to each column.*/
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < matrix_columns; i++) {
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_expression *column_expr;
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_assignment *column_assign;
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 column_expr = new(mem_ctx) ir_expression(orig_expr->operation,
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						  get_column(op[0], i));
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 column_assign = new(mem_ctx) ir_assignment(get_column(result, i),
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						    column_expr);
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(column_assign->write_mask != 0);
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 base_ir->insert_before(column_assign);
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_add:
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_sub:
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_div:
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_mod: {
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* For most operations, the matrix version is just going
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * column-wise through and applying the operation to each column
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * if available.
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < matrix_columns; i++) {
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_expression *column_expr;
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_assignment *column_assign;
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 column_expr = new(mem_ctx) ir_expression(orig_expr->operation,
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						  get_column(op[0], i),
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						  get_column(op[1], i));
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 column_assign = new(mem_ctx) ir_assignment(get_column(result, i),
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						    column_expr);
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(column_assign->write_mask != 0);
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 base_ir->insert_before(column_assign);
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_mul:
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (op[0]->type->is_matrix()) {
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (op[1]->type->is_matrix()) {
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    do_mul_mat_mat(result, op[0], op[1]);
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 } else if (op[1]->type->is_vector()) {
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    do_mul_mat_vec(result, op[0], op[1]);
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 } else {
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    assert(op[1]->type->is_scalar());
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    do_mul_mat_scalar(result, op[0], op[1]);
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(op[1]->type->is_matrix());
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (op[0]->type->is_vector()) {
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    do_mul_vec_mat(result, op[0], op[1]);
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 } else {
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    assert(op[0]->type->is_scalar());
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    do_mul_mat_scalar(result, op[1], op[0]);
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_all_equal:
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_any_nequal:
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      do_equal_mat_mat(result, op[1], op[0],
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       (orig_expr->operation == ir_binop_all_equal));
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      printf("FINISHME: Handle matrix operation for %s\n",
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     orig_expr->operator_string());
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      abort();
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   orig_assign->remove();
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->made_progress = true;
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return visit_continue;
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
429