13a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt/*
23a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt * Copyright © 2010 Intel Corporation
33a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt *
43a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt * Permission is hereby granted, free of charge, to any person obtaining a
53a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt * copy of this software and associated documentation files (the "Software"),
63a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt * to deal in the Software without restriction, including without limitation
73a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt * the rights to use, copy, modify, merge, publish, distribute, sublicense,
83a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt * and/or sell copies of the Software, and to permit persons to whom the
93a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt * Software is furnished to do so, subject to the following conditions:
103a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt *
113a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt * The above copyright notice and this permission notice (including the next
123a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt * paragraph) shall be included in all copies or substantial portions of the
133a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt * Software.
143a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt *
153a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
163a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
173a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
183a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
193a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
203a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
213a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt * DEALINGS IN THE SOFTWARE.
223a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt */
233a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
243a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt/**
253a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt * \file brw_wm_channel_expressions.cpp
263a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt *
273a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt * Breaks vector operations down into operations on each component.
283a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt *
293a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt * The 965 fragment shader receives 8 or 16 pixels at a time, so each
303a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt * channel of a vector is laid out as 1 or 2 8-float registers.  Each
313a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt * ALU operation operates on one of those channel registers.  As a
323a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt * result, there is no value to the 965 fragment shader in tracking
333a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt * "vector" expressions in the sense of GLSL fragment shaders, when
343a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt * doing a channel at a time may help in constant folding, algebraic
353a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt * simplification, and reducing the liveness of channel registers.
363a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt *
373a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt * The exception to the desire to break everything down to floats is
383a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt * texturing.  The texture sampler returns a writemasked masked
393a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt * 4/8-register sequence containing the texture values.  We don't want
403a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt * to dispatch to the sampler separately for each channel we need, so
413a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt * we do retain the vector types in that case.
423a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt */
433a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
443a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholtextern "C" {
453a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt#include "main/core.h"
463a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt#include "brw_wm.h"
473a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt}
482f0edc60f4bd2ae5999a6afa656e3bb3f181bf0fChad Versace#include "glsl/ir.h"
492f0edc60f4bd2ae5999a6afa656e3bb3f181bf0fChad Versace#include "glsl/ir_expression_flattening.h"
502f0edc60f4bd2ae5999a6afa656e3bb3f181bf0fChad Versace#include "glsl/glsl_types.h"
513a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
523a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholtclass ir_channel_expressions_visitor : public ir_hierarchical_visitor {
533a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholtpublic:
543a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   ir_channel_expressions_visitor()
553a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   {
563a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      this->progress = false;
573a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      this->mem_ctx = NULL;
583a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   }
593a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
603a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   ir_visitor_status visit_leave(ir_assignment *);
613a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
623a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   ir_rvalue *get_element(ir_variable *var, unsigned int element);
633a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   void assign(ir_assignment *ir, int elem, ir_rvalue *val);
643a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
653a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   bool progress;
663a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   void *mem_ctx;
673a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt};
683a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
693a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholtstatic bool
703a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholtchannel_expressions_predicate(ir_instruction *ir)
713a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt{
723a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   ir_expression *expr = ir->as_expression();
733a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   unsigned int i;
743a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
753a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   if (!expr)
763a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      return false;
773a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
783a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   for (i = 0; i < expr->get_num_operands(); i++) {
793a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      if (expr->operands[i]->type->is_vector())
803a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt	 return true;
813a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   }
823a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
833a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   return false;
843a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt}
853a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
862e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunkebool
873a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholtbrw_do_channel_expressions(exec_list *instructions)
883a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt{
893a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   ir_channel_expressions_visitor v;
903a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
913a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   /* Pull out any matrix expression to a separate assignment to a
923a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt    * temp.  This will make our handling of the breakdown to
933a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt    * operations on the matrix's vector components much easier.
943a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt    */
953a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   do_expression_flattening(instructions, channel_expressions_predicate);
963a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
973a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   visit_list_elements(&v, instructions);
983a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
993a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   return v.progress;
1003a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt}
1013a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
1023a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholtir_rvalue *
1033a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholtir_channel_expressions_visitor::get_element(ir_variable *var, unsigned int elem)
1043a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt{
1053a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   ir_dereference *deref;
1063a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
1073a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   if (var->type->is_scalar())
1083a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      return new(mem_ctx) ir_dereference_variable(var);
1093a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
1103a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   assert(elem < var->type->components());
1113a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   deref = new(mem_ctx) ir_dereference_variable(var);
1123a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   return new(mem_ctx) ir_swizzle(deref, elem, 0, 0, 0, 1);
1133a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt}
1143a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
1153a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholtvoid
1163a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholtir_channel_expressions_visitor::assign(ir_assignment *ir, int elem, ir_rvalue *val)
1173a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt{
1183a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   ir_dereference *lhs = ir->lhs->clone(mem_ctx, NULL);
1193a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   ir_assignment *assign;
1203a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
1213a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   /* This assign-of-expression should have been generated by the
1223a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt    * expression flattening visitor (since we never short circit to
1233a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt    * not flatten, even for plain assignments of variables), so the
1243a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt    * writemask is always full.
1253a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt    */
1263a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   assert(ir->write_mask == (1 << ir->lhs->type->components()) - 1);
1273a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
128d74bab1fb67fe1334fd80eaf0d4e224fc6d96f22Eric Anholt   assign = new(mem_ctx) ir_assignment(lhs, val, NULL, (1 << elem));
1293a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   ir->insert_before(assign);
1303a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt}
1313a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
1323a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholtir_visitor_status
1333a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholtir_channel_expressions_visitor::visit_leave(ir_assignment *ir)
1343a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt{
1353a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   ir_expression *expr = ir->rhs->as_expression();
1363a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   bool found_vector = false;
1373a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   unsigned int i, vector_elements = 1;
1383a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   ir_variable *op_var[2];
1393a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
1403a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   if (!expr)
1413a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      return visit_continue;
1423a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
1433a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   if (!this->mem_ctx)
144d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke      this->mem_ctx = ralloc_parent(ir);
1453a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
1463a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   for (i = 0; i < expr->get_num_operands(); i++) {
1473a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      if (expr->operands[i]->type->is_vector()) {
1483a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt	 found_vector = true;
1493a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt	 vector_elements = expr->operands[i]->type->vector_elements;
1503a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt	 break;
1513a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      }
1523a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   }
1533a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   if (!found_vector)
1543a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      return visit_continue;
1553a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
1563a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   /* Store the expression operands in temps so we can use them
1573a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt    * multiple times.
1583a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt    */
1593a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   for (i = 0; i < expr->get_num_operands(); i++) {
1603a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      ir_assignment *assign;
1613a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      ir_dereference *deref;
1623a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
1633a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      assert(!expr->operands[i]->type->is_matrix());
1643a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
1653a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      op_var[i] = new(mem_ctx) ir_variable(expr->operands[i]->type,
1663a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt					   "channel_expressions",
1673a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt					   ir_var_temporary);
1683a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      ir->insert_before(op_var[i]);
1693a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
1703a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      deref = new(mem_ctx) ir_dereference_variable(op_var[i]);
1713a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      assign = new(mem_ctx) ir_assignment(deref,
1723a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt					  expr->operands[i],
1733a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt					  NULL);
1743a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      ir->insert_before(assign);
1753a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   }
1763a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
1773a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   const glsl_type *element_type = glsl_type::get_instance(ir->lhs->type->base_type,
1783a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt							   1, 1);
1793a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
1803a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   /* OK, time to break down this vector operation. */
1813a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   switch (expr->operation) {
1823a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_unop_bit_not:
1833a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_unop_logic_not:
1843a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_unop_neg:
1853a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_unop_abs:
1863a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_unop_sign:
1873a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_unop_rcp:
1883a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_unop_rsq:
1893a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_unop_sqrt:
1903a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_unop_exp:
1913a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_unop_log:
1923a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_unop_exp2:
1933a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_unop_log2:
194529476b5e4cd0591e0ec777b9bc2b5bec136822bKenneth Graunke   case ir_unop_bitcast_i2f:
195529476b5e4cd0591e0ec777b9bc2b5bec136822bKenneth Graunke   case ir_unop_bitcast_f2i:
196529476b5e4cd0591e0ec777b9bc2b5bec136822bKenneth Graunke   case ir_unop_bitcast_f2u:
197529476b5e4cd0591e0ec777b9bc2b5bec136822bKenneth Graunke   case ir_unop_bitcast_u2f:
198b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke   case ir_unop_i2u:
199b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke   case ir_unop_u2i:
2003a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_unop_f2i:
20111a7b93592c22c8165f8fde6395f76778fca452ePaul Berry   case ir_unop_f2u:
2023a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_unop_i2f:
2033a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_unop_f2b:
2043a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_unop_b2f:
2053a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_unop_i2b:
2063a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_unop_b2i:
2073a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_unop_u2f:
2083a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_unop_trunc:
2093a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_unop_ceil:
2103a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_unop_floor:
2113a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_unop_fract:
21233c4b2370f7546013e67e39ab9ec8ab2125e7597Eric Anholt   case ir_unop_round_even:
2133a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_unop_sin:
2143a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_unop_cos:
215afb80c531530d0ff4c0efbc9f728f99a87165d8eEric Anholt   case ir_unop_sin_reduced:
216afb80c531530d0ff4c0efbc9f728f99a87165d8eEric Anholt   case ir_unop_cos_reduced:
2173a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_unop_dFdx:
2183a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_unop_dFdy:
2193a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      for (i = 0; i < vector_elements; i++) {
2203a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt	 ir_rvalue *op0 = get_element(op_var[0], i);
2213a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
2223a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt	 assign(ir, i, new(mem_ctx) ir_expression(expr->operation,
2233a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt						  element_type,
2243a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt						  op0,
2253a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt						  NULL));
2263a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      }
2273a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      break;
2283a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
2293a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_binop_add:
2303a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_binop_sub:
2313a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_binop_mul:
2323a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_binop_div:
2333a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_binop_mod:
2343a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_binop_min:
2353a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_binop_max:
2363a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_binop_pow:
2373a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_binop_lshift:
2383a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_binop_rshift:
2393a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_binop_bit_and:
2403a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_binop_bit_xor:
2413a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_binop_bit_or:
242bb70bd55596fa19f5775bac98bffb567f3ba1d9fEric Anholt   case ir_binop_less:
243bb70bd55596fa19f5775bac98bffb567f3ba1d9fEric Anholt   case ir_binop_greater:
244bb70bd55596fa19f5775bac98bffb567f3ba1d9fEric Anholt   case ir_binop_lequal:
245bb70bd55596fa19f5775bac98bffb567f3ba1d9fEric Anholt   case ir_binop_gequal:
246bb70bd55596fa19f5775bac98bffb567f3ba1d9fEric Anholt   case ir_binop_equal:
247bb70bd55596fa19f5775bac98bffb567f3ba1d9fEric Anholt   case ir_binop_nequal:
2483a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      for (i = 0; i < vector_elements; i++) {
2493a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt	 ir_rvalue *op0 = get_element(op_var[0], i);
2503a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt	 ir_rvalue *op1 = get_element(op_var[1], i);
2513a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
2523a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt	 assign(ir, i, new(mem_ctx) ir_expression(expr->operation,
2533a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt						  element_type,
2543a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt						  op0,
2553a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt						  op1));
2563a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      }
2573a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      break;
2583a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
2593a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_unop_any: {
2603a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      ir_expression *temp;
2613a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      temp = new(mem_ctx) ir_expression(ir_binop_logic_or,
2623a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt					element_type,
2633a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt					get_element(op_var[0], 0),
2643a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt					get_element(op_var[0], 1));
2653a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
2663a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      for (i = 2; i < vector_elements; i++) {
2673a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt	 temp = new(mem_ctx) ir_expression(ir_binop_logic_or,
2683a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt					   element_type,
2693a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt					   get_element(op_var[0], i),
2703a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt					   temp);
2713a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      }
2723a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      assign(ir, 0, temp);
2733a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      break;
2743a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   }
2753a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
2763a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_binop_dot: {
2773a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      ir_expression *last = NULL;
2783a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      for (i = 0; i < vector_elements; i++) {
2793a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt	 ir_rvalue *op0 = get_element(op_var[0], i);
2803a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt	 ir_rvalue *op1 = get_element(op_var[1], i);
2813a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt	 ir_expression *temp;
2823a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
2833a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt	 temp = new(mem_ctx) ir_expression(ir_binop_mul,
2843a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt					   element_type,
2853a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt					   op0,
2863a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt					   op1);
2873a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt	 if (last) {
2883a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt	    last = new(mem_ctx) ir_expression(ir_binop_add,
2893a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt					      element_type,
2903a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt					      temp,
2913a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt					      last);
2923a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt	 } else {
2933a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt	    last = temp;
2943a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt	 }
2953a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      }
2963a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      assign(ir, 0, last);
2973a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      break;
2983a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   }
2993a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
3003a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_binop_logic_and:
3013a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_binop_logic_xor:
3023a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   case ir_binop_logic_or:
3033a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      ir->print();
3043a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      printf("\n");
3053a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      assert(!"not reached: expression operates on scalars only");
3063a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      break;
307bb70bd55596fa19f5775bac98bffb567f3ba1d9fEric Anholt   case ir_binop_all_equal:
308bb70bd55596fa19f5775bac98bffb567f3ba1d9fEric Anholt   case ir_binop_any_nequal: {
3093a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      ir_expression *last = NULL;
3103a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      for (i = 0; i < vector_elements; i++) {
3113a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt	 ir_rvalue *op0 = get_element(op_var[0], i);
3123a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt	 ir_rvalue *op1 = get_element(op_var[1], i);
3133a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt	 ir_expression *temp;
3143a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt	 ir_expression_operation join;
3153a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
316bb70bd55596fa19f5775bac98bffb567f3ba1d9fEric Anholt	 if (expr->operation == ir_binop_all_equal)
3173a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt	    join = ir_binop_logic_and;
3183a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt	 else
3193a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt	    join = ir_binop_logic_or;
3203a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
3213a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt	 temp = new(mem_ctx) ir_expression(expr->operation,
3223a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt					   element_type,
3233a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt					   op0,
3243a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt					   op1);
3253a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt	 if (last) {
3263a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt	    last = new(mem_ctx) ir_expression(join,
3273a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt					      element_type,
3283a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt					      temp,
3293a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt					      last);
3303a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt	 } else {
3313a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt	    last = temp;
3323a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt	 }
3333a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      }
3343a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      assign(ir, 0, last);
3353a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt      break;
3363a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   }
3376ef5f212343c0557c4fca272d8236226c1a7c87aEric Anholt   case ir_unop_noise:
3386ef5f212343c0557c4fca272d8236226c1a7c87aEric Anholt      assert(!"noise should have been broken down to function call");
3396ef5f212343c0557c4fca272d8236226c1a7c87aEric Anholt      break;
3402ea3ab14f2182978f471674c9dfce029d37f70a7Eric Anholt
3412ea3ab14f2182978f471674c9dfce029d37f70a7Eric Anholt   case ir_binop_ubo_load:
3422ea3ab14f2182978f471674c9dfce029d37f70a7Eric Anholt      assert(!"not yet supported");
3432ea3ab14f2182978f471674c9dfce029d37f70a7Eric Anholt      break;
3442ea3ab14f2182978f471674c9dfce029d37f70a7Eric Anholt
345afb80c531530d0ff4c0efbc9f728f99a87165d8eEric Anholt   case ir_quadop_vector:
346afb80c531530d0ff4c0efbc9f728f99a87165d8eEric Anholt      assert(!"should have been lowered");
347afb80c531530d0ff4c0efbc9f728f99a87165d8eEric Anholt      break;
3483a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   }
3493a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
3503a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   ir->remove();
3513a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   this->progress = true;
3523a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt
3533a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt   return visit_continue;
3543a8ad33dde2f059b82ebf09f5cffa66c86f2e734Eric Anholt}
355