ir.cpp revision 01e04c3f
101e04c3fSmrg/*
201e04c3fSmrg * Copyright © 2010 Intel Corporation
301e04c3fSmrg *
401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a
501e04c3fSmrg * copy of this software and associated documentation files (the "Software"),
601e04c3fSmrg * to deal in the Software without restriction, including without limitation
701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the
901e04c3fSmrg * Software is furnished to do so, subject to the following conditions:
1001e04c3fSmrg *
1101e04c3fSmrg * The above copyright notice and this permission notice (including the next
1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the
1301e04c3fSmrg * Software.
1401e04c3fSmrg *
1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2101e04c3fSmrg * DEALINGS IN THE SOFTWARE.
2201e04c3fSmrg */
2301e04c3fSmrg#include <string.h>
2401e04c3fSmrg#include "ir.h"
2501e04c3fSmrg#include "compiler/glsl_types.h"
2601e04c3fSmrg#include "glsl_parser_extras.h"
2701e04c3fSmrg
2801e04c3fSmrg
2901e04c3fSmrgir_rvalue::ir_rvalue(enum ir_node_type t)
3001e04c3fSmrg   : ir_instruction(t)
3101e04c3fSmrg{
3201e04c3fSmrg   this->type = glsl_type::error_type;
3301e04c3fSmrg}
3401e04c3fSmrg
3501e04c3fSmrgbool ir_rvalue::is_zero() const
3601e04c3fSmrg{
3701e04c3fSmrg   return false;
3801e04c3fSmrg}
3901e04c3fSmrg
4001e04c3fSmrgbool ir_rvalue::is_one() const
4101e04c3fSmrg{
4201e04c3fSmrg   return false;
4301e04c3fSmrg}
4401e04c3fSmrg
4501e04c3fSmrgbool ir_rvalue::is_negative_one() const
4601e04c3fSmrg{
4701e04c3fSmrg   return false;
4801e04c3fSmrg}
4901e04c3fSmrg
5001e04c3fSmrg/**
5101e04c3fSmrg * Modify the swizzle make to move one component to another
5201e04c3fSmrg *
5301e04c3fSmrg * \param m    IR swizzle to be modified
5401e04c3fSmrg * \param from Component in the RHS that is to be swizzled
5501e04c3fSmrg * \param to   Desired swizzle location of \c from
5601e04c3fSmrg */
5701e04c3fSmrgstatic void
5801e04c3fSmrgupdate_rhs_swizzle(ir_swizzle_mask &m, unsigned from, unsigned to)
5901e04c3fSmrg{
6001e04c3fSmrg   switch (to) {
6101e04c3fSmrg   case 0: m.x = from; break;
6201e04c3fSmrg   case 1: m.y = from; break;
6301e04c3fSmrg   case 2: m.z = from; break;
6401e04c3fSmrg   case 3: m.w = from; break;
6501e04c3fSmrg   default: assert(!"Should not get here.");
6601e04c3fSmrg   }
6701e04c3fSmrg}
6801e04c3fSmrg
6901e04c3fSmrgvoid
7001e04c3fSmrgir_assignment::set_lhs(ir_rvalue *lhs)
7101e04c3fSmrg{
7201e04c3fSmrg   void *mem_ctx = this;
7301e04c3fSmrg   bool swizzled = false;
7401e04c3fSmrg
7501e04c3fSmrg   while (lhs != NULL) {
7601e04c3fSmrg      ir_swizzle *swiz = lhs->as_swizzle();
7701e04c3fSmrg
7801e04c3fSmrg      if (swiz == NULL)
7901e04c3fSmrg	 break;
8001e04c3fSmrg
8101e04c3fSmrg      unsigned write_mask = 0;
8201e04c3fSmrg      ir_swizzle_mask rhs_swiz = { 0, 0, 0, 0, 0, 0 };
8301e04c3fSmrg
8401e04c3fSmrg      for (unsigned i = 0; i < swiz->mask.num_components; i++) {
8501e04c3fSmrg	 unsigned c = 0;
8601e04c3fSmrg
8701e04c3fSmrg	 switch (i) {
8801e04c3fSmrg	 case 0: c = swiz->mask.x; break;
8901e04c3fSmrg	 case 1: c = swiz->mask.y; break;
9001e04c3fSmrg	 case 2: c = swiz->mask.z; break;
9101e04c3fSmrg	 case 3: c = swiz->mask.w; break;
9201e04c3fSmrg	 default: assert(!"Should not get here.");
9301e04c3fSmrg	 }
9401e04c3fSmrg
9501e04c3fSmrg	 write_mask |= (((this->write_mask >> i) & 1) << c);
9601e04c3fSmrg	 update_rhs_swizzle(rhs_swiz, i, c);
9701e04c3fSmrg         rhs_swiz.num_components = swiz->val->type->vector_elements;
9801e04c3fSmrg      }
9901e04c3fSmrg
10001e04c3fSmrg      this->write_mask = write_mask;
10101e04c3fSmrg      lhs = swiz->val;
10201e04c3fSmrg
10301e04c3fSmrg      this->rhs = new(mem_ctx) ir_swizzle(this->rhs, rhs_swiz);
10401e04c3fSmrg      swizzled = true;
10501e04c3fSmrg   }
10601e04c3fSmrg
10701e04c3fSmrg   if (swizzled) {
10801e04c3fSmrg      /* Now, RHS channels line up with the LHS writemask.  Collapse it
10901e04c3fSmrg       * to just the channels that will be written.
11001e04c3fSmrg       */
11101e04c3fSmrg      ir_swizzle_mask rhs_swiz = { 0, 0, 0, 0, 0, 0 };
11201e04c3fSmrg      int rhs_chan = 0;
11301e04c3fSmrg      for (int i = 0; i < 4; i++) {
11401e04c3fSmrg	 if (write_mask & (1 << i))
11501e04c3fSmrg	    update_rhs_swizzle(rhs_swiz, i, rhs_chan++);
11601e04c3fSmrg      }
11701e04c3fSmrg      rhs_swiz.num_components = rhs_chan;
11801e04c3fSmrg      this->rhs = new(mem_ctx) ir_swizzle(this->rhs, rhs_swiz);
11901e04c3fSmrg   }
12001e04c3fSmrg
12101e04c3fSmrg   assert((lhs == NULL) || lhs->as_dereference());
12201e04c3fSmrg
12301e04c3fSmrg   this->lhs = (ir_dereference *) lhs;
12401e04c3fSmrg}
12501e04c3fSmrg
12601e04c3fSmrgir_variable *
12701e04c3fSmrgir_assignment::whole_variable_written()
12801e04c3fSmrg{
12901e04c3fSmrg   ir_variable *v = this->lhs->whole_variable_referenced();
13001e04c3fSmrg
13101e04c3fSmrg   if (v == NULL)
13201e04c3fSmrg      return NULL;
13301e04c3fSmrg
13401e04c3fSmrg   if (v->type->is_scalar())
13501e04c3fSmrg      return v;
13601e04c3fSmrg
13701e04c3fSmrg   if (v->type->is_vector()) {
13801e04c3fSmrg      const unsigned mask = (1U << v->type->vector_elements) - 1;
13901e04c3fSmrg
14001e04c3fSmrg      if (mask != this->write_mask)
14101e04c3fSmrg	 return NULL;
14201e04c3fSmrg   }
14301e04c3fSmrg
14401e04c3fSmrg   /* Either all the vector components are assigned or the variable is some
14501e04c3fSmrg    * composite type (and the whole thing is assigned.
14601e04c3fSmrg    */
14701e04c3fSmrg   return v;
14801e04c3fSmrg}
14901e04c3fSmrg
15001e04c3fSmrgir_assignment::ir_assignment(ir_dereference *lhs, ir_rvalue *rhs,
15101e04c3fSmrg			     ir_rvalue *condition, unsigned write_mask)
15201e04c3fSmrg   : ir_instruction(ir_type_assignment)
15301e04c3fSmrg{
15401e04c3fSmrg   this->condition = condition;
15501e04c3fSmrg   this->rhs = rhs;
15601e04c3fSmrg   this->lhs = lhs;
15701e04c3fSmrg   this->write_mask = write_mask;
15801e04c3fSmrg
15901e04c3fSmrg   if (lhs->type->is_scalar() || lhs->type->is_vector()) {
16001e04c3fSmrg      int lhs_components = 0;
16101e04c3fSmrg      for (int i = 0; i < 4; i++) {
16201e04c3fSmrg	 if (write_mask & (1 << i))
16301e04c3fSmrg	    lhs_components++;
16401e04c3fSmrg      }
16501e04c3fSmrg
16601e04c3fSmrg      assert(lhs_components == this->rhs->type->vector_elements);
16701e04c3fSmrg   }
16801e04c3fSmrg}
16901e04c3fSmrg
17001e04c3fSmrgir_assignment::ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs,
17101e04c3fSmrg			     ir_rvalue *condition)
17201e04c3fSmrg   : ir_instruction(ir_type_assignment)
17301e04c3fSmrg{
17401e04c3fSmrg   this->condition = condition;
17501e04c3fSmrg   this->rhs = rhs;
17601e04c3fSmrg
17701e04c3fSmrg   /* If the RHS is a vector type, assume that all components of the vector
17801e04c3fSmrg    * type are being written to the LHS.  The write mask comes from the RHS
17901e04c3fSmrg    * because we can have a case where the LHS is a vec4 and the RHS is a
18001e04c3fSmrg    * vec3.  In that case, the assignment is:
18101e04c3fSmrg    *
18201e04c3fSmrg    *     (assign (...) (xyz) (var_ref lhs) (var_ref rhs))
18301e04c3fSmrg    */
18401e04c3fSmrg   if (rhs->type->is_vector())
18501e04c3fSmrg      this->write_mask = (1U << rhs->type->vector_elements) - 1;
18601e04c3fSmrg   else if (rhs->type->is_scalar())
18701e04c3fSmrg      this->write_mask = 1;
18801e04c3fSmrg   else
18901e04c3fSmrg      this->write_mask = 0;
19001e04c3fSmrg
19101e04c3fSmrg   this->set_lhs(lhs);
19201e04c3fSmrg}
19301e04c3fSmrg
19401e04c3fSmrgir_expression::ir_expression(int op, const struct glsl_type *type,
19501e04c3fSmrg			     ir_rvalue *op0, ir_rvalue *op1,
19601e04c3fSmrg			     ir_rvalue *op2, ir_rvalue *op3)
19701e04c3fSmrg   : ir_rvalue(ir_type_expression)
19801e04c3fSmrg{
19901e04c3fSmrg   this->type = type;
20001e04c3fSmrg   this->operation = ir_expression_operation(op);
20101e04c3fSmrg   this->operands[0] = op0;
20201e04c3fSmrg   this->operands[1] = op1;
20301e04c3fSmrg   this->operands[2] = op2;
20401e04c3fSmrg   this->operands[3] = op3;
20501e04c3fSmrg   init_num_operands();
20601e04c3fSmrg
20701e04c3fSmrg#ifndef NDEBUG
20801e04c3fSmrg   for (unsigned i = num_operands; i < 4; i++) {
20901e04c3fSmrg      assert(this->operands[i] == NULL);
21001e04c3fSmrg   }
21101e04c3fSmrg
21201e04c3fSmrg   for (unsigned i = 0; i < num_operands; i++) {
21301e04c3fSmrg      assert(this->operands[i] != NULL);
21401e04c3fSmrg   }
21501e04c3fSmrg#endif
21601e04c3fSmrg}
21701e04c3fSmrg
21801e04c3fSmrgir_expression::ir_expression(int op, ir_rvalue *op0)
21901e04c3fSmrg   : ir_rvalue(ir_type_expression)
22001e04c3fSmrg{
22101e04c3fSmrg   this->operation = ir_expression_operation(op);
22201e04c3fSmrg   this->operands[0] = op0;
22301e04c3fSmrg   this->operands[1] = NULL;
22401e04c3fSmrg   this->operands[2] = NULL;
22501e04c3fSmrg   this->operands[3] = NULL;
22601e04c3fSmrg
22701e04c3fSmrg   assert(op <= ir_last_unop);
22801e04c3fSmrg   init_num_operands();
22901e04c3fSmrg   assert(num_operands == 1);
23001e04c3fSmrg   assert(this->operands[0]);
23101e04c3fSmrg
23201e04c3fSmrg   switch (this->operation) {
23301e04c3fSmrg   case ir_unop_bit_not:
23401e04c3fSmrg   case ir_unop_logic_not:
23501e04c3fSmrg   case ir_unop_neg:
23601e04c3fSmrg   case ir_unop_abs:
23701e04c3fSmrg   case ir_unop_sign:
23801e04c3fSmrg   case ir_unop_rcp:
23901e04c3fSmrg   case ir_unop_rsq:
24001e04c3fSmrg   case ir_unop_sqrt:
24101e04c3fSmrg   case ir_unop_exp:
24201e04c3fSmrg   case ir_unop_log:
24301e04c3fSmrg   case ir_unop_exp2:
24401e04c3fSmrg   case ir_unop_log2:
24501e04c3fSmrg   case ir_unop_trunc:
24601e04c3fSmrg   case ir_unop_ceil:
24701e04c3fSmrg   case ir_unop_floor:
24801e04c3fSmrg   case ir_unop_fract:
24901e04c3fSmrg   case ir_unop_round_even:
25001e04c3fSmrg   case ir_unop_sin:
25101e04c3fSmrg   case ir_unop_cos:
25201e04c3fSmrg   case ir_unop_dFdx:
25301e04c3fSmrg   case ir_unop_dFdx_coarse:
25401e04c3fSmrg   case ir_unop_dFdx_fine:
25501e04c3fSmrg   case ir_unop_dFdy:
25601e04c3fSmrg   case ir_unop_dFdy_coarse:
25701e04c3fSmrg   case ir_unop_dFdy_fine:
25801e04c3fSmrg   case ir_unop_bitfield_reverse:
25901e04c3fSmrg   case ir_unop_interpolate_at_centroid:
26001e04c3fSmrg   case ir_unop_saturate:
26101e04c3fSmrg      this->type = op0->type;
26201e04c3fSmrg      break;
26301e04c3fSmrg
26401e04c3fSmrg   case ir_unop_f2i:
26501e04c3fSmrg   case ir_unop_b2i:
26601e04c3fSmrg   case ir_unop_u2i:
26701e04c3fSmrg   case ir_unop_d2i:
26801e04c3fSmrg   case ir_unop_bitcast_f2i:
26901e04c3fSmrg   case ir_unop_bit_count:
27001e04c3fSmrg   case ir_unop_find_msb:
27101e04c3fSmrg   case ir_unop_find_lsb:
27201e04c3fSmrg   case ir_unop_subroutine_to_int:
27301e04c3fSmrg   case ir_unop_i642i:
27401e04c3fSmrg   case ir_unop_u642i:
27501e04c3fSmrg      this->type = glsl_type::get_instance(GLSL_TYPE_INT,
27601e04c3fSmrg					   op0->type->vector_elements, 1);
27701e04c3fSmrg      break;
27801e04c3fSmrg
27901e04c3fSmrg   case ir_unop_b2f:
28001e04c3fSmrg   case ir_unop_i2f:
28101e04c3fSmrg   case ir_unop_u2f:
28201e04c3fSmrg   case ir_unop_d2f:
28301e04c3fSmrg   case ir_unop_bitcast_i2f:
28401e04c3fSmrg   case ir_unop_bitcast_u2f:
28501e04c3fSmrg   case ir_unop_i642f:
28601e04c3fSmrg   case ir_unop_u642f:
28701e04c3fSmrg      this->type = glsl_type::get_instance(GLSL_TYPE_FLOAT,
28801e04c3fSmrg					   op0->type->vector_elements, 1);
28901e04c3fSmrg      break;
29001e04c3fSmrg
29101e04c3fSmrg   case ir_unop_f2b:
29201e04c3fSmrg   case ir_unop_i2b:
29301e04c3fSmrg   case ir_unop_d2b:
29401e04c3fSmrg   case ir_unop_i642b:
29501e04c3fSmrg      this->type = glsl_type::get_instance(GLSL_TYPE_BOOL,
29601e04c3fSmrg					   op0->type->vector_elements, 1);
29701e04c3fSmrg      break;
29801e04c3fSmrg
29901e04c3fSmrg   case ir_unop_f2d:
30001e04c3fSmrg   case ir_unop_i2d:
30101e04c3fSmrg   case ir_unop_u2d:
30201e04c3fSmrg   case ir_unop_i642d:
30301e04c3fSmrg   case ir_unop_u642d:
30401e04c3fSmrg      this->type = glsl_type::get_instance(GLSL_TYPE_DOUBLE,
30501e04c3fSmrg					   op0->type->vector_elements, 1);
30601e04c3fSmrg      break;
30701e04c3fSmrg
30801e04c3fSmrg   case ir_unop_i2u:
30901e04c3fSmrg   case ir_unop_f2u:
31001e04c3fSmrg   case ir_unop_d2u:
31101e04c3fSmrg   case ir_unop_bitcast_f2u:
31201e04c3fSmrg   case ir_unop_i642u:
31301e04c3fSmrg   case ir_unop_u642u:
31401e04c3fSmrg      this->type = glsl_type::get_instance(GLSL_TYPE_UINT,
31501e04c3fSmrg					   op0->type->vector_elements, 1);
31601e04c3fSmrg      break;
31701e04c3fSmrg
31801e04c3fSmrg   case ir_unop_i2i64:
31901e04c3fSmrg   case ir_unop_u2i64:
32001e04c3fSmrg   case ir_unop_b2i64:
32101e04c3fSmrg   case ir_unop_f2i64:
32201e04c3fSmrg   case ir_unop_d2i64:
32301e04c3fSmrg   case ir_unop_u642i64:
32401e04c3fSmrg      this->type = glsl_type::get_instance(GLSL_TYPE_INT64,
32501e04c3fSmrg					   op0->type->vector_elements, 1);
32601e04c3fSmrg      break;
32701e04c3fSmrg
32801e04c3fSmrg   case ir_unop_i2u64:
32901e04c3fSmrg   case ir_unop_u2u64:
33001e04c3fSmrg   case ir_unop_f2u64:
33101e04c3fSmrg   case ir_unop_d2u64:
33201e04c3fSmrg   case ir_unop_i642u64:
33301e04c3fSmrg      this->type = glsl_type::get_instance(GLSL_TYPE_UINT64,
33401e04c3fSmrg					   op0->type->vector_elements, 1);
33501e04c3fSmrg      break;
33601e04c3fSmrg   case ir_unop_noise:
33701e04c3fSmrg      this->type = glsl_type::float_type;
33801e04c3fSmrg      break;
33901e04c3fSmrg
34001e04c3fSmrg   case ir_unop_unpack_double_2x32:
34101e04c3fSmrg   case ir_unop_unpack_uint_2x32:
34201e04c3fSmrg      this->type = glsl_type::uvec2_type;
34301e04c3fSmrg      break;
34401e04c3fSmrg
34501e04c3fSmrg   case ir_unop_unpack_int_2x32:
34601e04c3fSmrg      this->type = glsl_type::ivec2_type;
34701e04c3fSmrg      break;
34801e04c3fSmrg
34901e04c3fSmrg   case ir_unop_pack_snorm_2x16:
35001e04c3fSmrg   case ir_unop_pack_snorm_4x8:
35101e04c3fSmrg   case ir_unop_pack_unorm_2x16:
35201e04c3fSmrg   case ir_unop_pack_unorm_4x8:
35301e04c3fSmrg   case ir_unop_pack_half_2x16:
35401e04c3fSmrg      this->type = glsl_type::uint_type;
35501e04c3fSmrg      break;
35601e04c3fSmrg
35701e04c3fSmrg   case ir_unop_pack_double_2x32:
35801e04c3fSmrg      this->type = glsl_type::double_type;
35901e04c3fSmrg      break;
36001e04c3fSmrg
36101e04c3fSmrg   case ir_unop_pack_int_2x32:
36201e04c3fSmrg      this->type = glsl_type::int64_t_type;
36301e04c3fSmrg      break;
36401e04c3fSmrg
36501e04c3fSmrg   case ir_unop_pack_uint_2x32:
36601e04c3fSmrg      this->type = glsl_type::uint64_t_type;
36701e04c3fSmrg      break;
36801e04c3fSmrg
36901e04c3fSmrg   case ir_unop_unpack_snorm_2x16:
37001e04c3fSmrg   case ir_unop_unpack_unorm_2x16:
37101e04c3fSmrg   case ir_unop_unpack_half_2x16:
37201e04c3fSmrg      this->type = glsl_type::vec2_type;
37301e04c3fSmrg      break;
37401e04c3fSmrg
37501e04c3fSmrg   case ir_unop_unpack_snorm_4x8:
37601e04c3fSmrg   case ir_unop_unpack_unorm_4x8:
37701e04c3fSmrg      this->type = glsl_type::vec4_type;
37801e04c3fSmrg      break;
37901e04c3fSmrg
38001e04c3fSmrg   case ir_unop_unpack_sampler_2x32:
38101e04c3fSmrg   case ir_unop_unpack_image_2x32:
38201e04c3fSmrg      this->type = glsl_type::uvec2_type;
38301e04c3fSmrg      break;
38401e04c3fSmrg
38501e04c3fSmrg   case ir_unop_pack_sampler_2x32:
38601e04c3fSmrg   case ir_unop_pack_image_2x32:
38701e04c3fSmrg      this->type = op0->type;
38801e04c3fSmrg      break;
38901e04c3fSmrg
39001e04c3fSmrg   case ir_unop_frexp_sig:
39101e04c3fSmrg      this->type = op0->type;
39201e04c3fSmrg      break;
39301e04c3fSmrg   case ir_unop_frexp_exp:
39401e04c3fSmrg      this->type = glsl_type::get_instance(GLSL_TYPE_INT,
39501e04c3fSmrg					   op0->type->vector_elements, 1);
39601e04c3fSmrg      break;
39701e04c3fSmrg
39801e04c3fSmrg   case ir_unop_get_buffer_size:
39901e04c3fSmrg   case ir_unop_ssbo_unsized_array_length:
40001e04c3fSmrg      this->type = glsl_type::int_type;
40101e04c3fSmrg      break;
40201e04c3fSmrg
40301e04c3fSmrg   case ir_unop_bitcast_i642d:
40401e04c3fSmrg   case ir_unop_bitcast_u642d:
40501e04c3fSmrg      this->type = glsl_type::get_instance(GLSL_TYPE_DOUBLE,
40601e04c3fSmrg                                           op0->type->vector_elements, 1);
40701e04c3fSmrg      break;
40801e04c3fSmrg
40901e04c3fSmrg   case ir_unop_bitcast_d2i64:
41001e04c3fSmrg      this->type = glsl_type::get_instance(GLSL_TYPE_INT64,
41101e04c3fSmrg                                           op0->type->vector_elements, 1);
41201e04c3fSmrg      break;
41301e04c3fSmrg   case ir_unop_bitcast_d2u64:
41401e04c3fSmrg      this->type = glsl_type::get_instance(GLSL_TYPE_UINT64,
41501e04c3fSmrg                                           op0->type->vector_elements, 1);
41601e04c3fSmrg      break;
41701e04c3fSmrg
41801e04c3fSmrg   default:
41901e04c3fSmrg      assert(!"not reached: missing automatic type setup for ir_expression");
42001e04c3fSmrg      this->type = op0->type;
42101e04c3fSmrg      break;
42201e04c3fSmrg   }
42301e04c3fSmrg}
42401e04c3fSmrg
42501e04c3fSmrgir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1)
42601e04c3fSmrg   : ir_rvalue(ir_type_expression)
42701e04c3fSmrg{
42801e04c3fSmrg   this->operation = ir_expression_operation(op);
42901e04c3fSmrg   this->operands[0] = op0;
43001e04c3fSmrg   this->operands[1] = op1;
43101e04c3fSmrg   this->operands[2] = NULL;
43201e04c3fSmrg   this->operands[3] = NULL;
43301e04c3fSmrg
43401e04c3fSmrg   assert(op > ir_last_unop);
43501e04c3fSmrg   init_num_operands();
43601e04c3fSmrg   assert(num_operands == 2);
43701e04c3fSmrg   for (unsigned i = 0; i < num_operands; i++) {
43801e04c3fSmrg      assert(this->operands[i] != NULL);
43901e04c3fSmrg   }
44001e04c3fSmrg
44101e04c3fSmrg   switch (this->operation) {
44201e04c3fSmrg   case ir_binop_all_equal:
44301e04c3fSmrg   case ir_binop_any_nequal:
44401e04c3fSmrg      this->type = glsl_type::bool_type;
44501e04c3fSmrg      break;
44601e04c3fSmrg
44701e04c3fSmrg   case ir_binop_add:
44801e04c3fSmrg   case ir_binop_sub:
44901e04c3fSmrg   case ir_binop_min:
45001e04c3fSmrg   case ir_binop_max:
45101e04c3fSmrg   case ir_binop_pow:
45201e04c3fSmrg   case ir_binop_mul:
45301e04c3fSmrg   case ir_binop_div:
45401e04c3fSmrg   case ir_binop_mod:
45501e04c3fSmrg      if (op0->type->is_scalar()) {
45601e04c3fSmrg	 this->type = op1->type;
45701e04c3fSmrg      } else if (op1->type->is_scalar()) {
45801e04c3fSmrg	 this->type = op0->type;
45901e04c3fSmrg      } else {
46001e04c3fSmrg         if (this->operation == ir_binop_mul) {
46101e04c3fSmrg            this->type = glsl_type::get_mul_type(op0->type, op1->type);
46201e04c3fSmrg         } else {
46301e04c3fSmrg            assert(op0->type == op1->type);
46401e04c3fSmrg            this->type = op0->type;
46501e04c3fSmrg         }
46601e04c3fSmrg      }
46701e04c3fSmrg      break;
46801e04c3fSmrg
46901e04c3fSmrg   case ir_binop_logic_and:
47001e04c3fSmrg   case ir_binop_logic_xor:
47101e04c3fSmrg   case ir_binop_logic_or:
47201e04c3fSmrg   case ir_binop_bit_and:
47301e04c3fSmrg   case ir_binop_bit_xor:
47401e04c3fSmrg   case ir_binop_bit_or:
47501e04c3fSmrg       assert(!op0->type->is_matrix());
47601e04c3fSmrg       assert(!op1->type->is_matrix());
47701e04c3fSmrg      if (op0->type->is_scalar()) {
47801e04c3fSmrg         this->type = op1->type;
47901e04c3fSmrg      } else if (op1->type->is_scalar()) {
48001e04c3fSmrg         this->type = op0->type;
48101e04c3fSmrg      } else {
48201e04c3fSmrg          assert(op0->type->vector_elements == op1->type->vector_elements);
48301e04c3fSmrg          this->type = op0->type;
48401e04c3fSmrg      }
48501e04c3fSmrg      break;
48601e04c3fSmrg
48701e04c3fSmrg   case ir_binop_equal:
48801e04c3fSmrg   case ir_binop_nequal:
48901e04c3fSmrg   case ir_binop_gequal:
49001e04c3fSmrg   case ir_binop_less:
49101e04c3fSmrg      assert(op0->type == op1->type);
49201e04c3fSmrg      this->type = glsl_type::get_instance(GLSL_TYPE_BOOL,
49301e04c3fSmrg					   op0->type->vector_elements, 1);
49401e04c3fSmrg      break;
49501e04c3fSmrg
49601e04c3fSmrg   case ir_binop_dot:
49701e04c3fSmrg      this->type = op0->type->get_base_type();
49801e04c3fSmrg      break;
49901e04c3fSmrg
50001e04c3fSmrg   case ir_binop_imul_high:
50101e04c3fSmrg   case ir_binop_carry:
50201e04c3fSmrg   case ir_binop_borrow:
50301e04c3fSmrg   case ir_binop_lshift:
50401e04c3fSmrg   case ir_binop_rshift:
50501e04c3fSmrg   case ir_binop_ldexp:
50601e04c3fSmrg   case ir_binop_interpolate_at_offset:
50701e04c3fSmrg   case ir_binop_interpolate_at_sample:
50801e04c3fSmrg      this->type = op0->type;
50901e04c3fSmrg      break;
51001e04c3fSmrg
51101e04c3fSmrg   case ir_binop_vector_extract:
51201e04c3fSmrg      this->type = op0->type->get_scalar_type();
51301e04c3fSmrg      break;
51401e04c3fSmrg
51501e04c3fSmrg   default:
51601e04c3fSmrg      assert(!"not reached: missing automatic type setup for ir_expression");
51701e04c3fSmrg      this->type = glsl_type::float_type;
51801e04c3fSmrg   }
51901e04c3fSmrg}
52001e04c3fSmrg
52101e04c3fSmrgir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1,
52201e04c3fSmrg                             ir_rvalue *op2)
52301e04c3fSmrg   : ir_rvalue(ir_type_expression)
52401e04c3fSmrg{
52501e04c3fSmrg   this->operation = ir_expression_operation(op);
52601e04c3fSmrg   this->operands[0] = op0;
52701e04c3fSmrg   this->operands[1] = op1;
52801e04c3fSmrg   this->operands[2] = op2;
52901e04c3fSmrg   this->operands[3] = NULL;
53001e04c3fSmrg
53101e04c3fSmrg   assert(op > ir_last_binop && op <= ir_last_triop);
53201e04c3fSmrg   init_num_operands();
53301e04c3fSmrg   assert(num_operands == 3);
53401e04c3fSmrg   for (unsigned i = 0; i < num_operands; i++) {
53501e04c3fSmrg      assert(this->operands[i] != NULL);
53601e04c3fSmrg   }
53701e04c3fSmrg
53801e04c3fSmrg   switch (this->operation) {
53901e04c3fSmrg   case ir_triop_fma:
54001e04c3fSmrg   case ir_triop_lrp:
54101e04c3fSmrg   case ir_triop_bitfield_extract:
54201e04c3fSmrg   case ir_triop_vector_insert:
54301e04c3fSmrg      this->type = op0->type;
54401e04c3fSmrg      break;
54501e04c3fSmrg
54601e04c3fSmrg   case ir_triop_csel:
54701e04c3fSmrg      this->type = op1->type;
54801e04c3fSmrg      break;
54901e04c3fSmrg
55001e04c3fSmrg   default:
55101e04c3fSmrg      assert(!"not reached: missing automatic type setup for ir_expression");
55201e04c3fSmrg      this->type = glsl_type::float_type;
55301e04c3fSmrg   }
55401e04c3fSmrg}
55501e04c3fSmrg
55601e04c3fSmrg/**
55701e04c3fSmrg * This is only here for ir_reader to used for testing purposes. Please use
55801e04c3fSmrg * the precomputed num_operands field if you need the number of operands.
55901e04c3fSmrg */
56001e04c3fSmrgunsigned
56101e04c3fSmrgir_expression::get_num_operands(ir_expression_operation op)
56201e04c3fSmrg{
56301e04c3fSmrg   assert(op <= ir_last_opcode);
56401e04c3fSmrg
56501e04c3fSmrg   if (op <= ir_last_unop)
56601e04c3fSmrg      return 1;
56701e04c3fSmrg
56801e04c3fSmrg   if (op <= ir_last_binop)
56901e04c3fSmrg      return 2;
57001e04c3fSmrg
57101e04c3fSmrg   if (op <= ir_last_triop)
57201e04c3fSmrg      return 3;
57301e04c3fSmrg
57401e04c3fSmrg   if (op <= ir_last_quadop)
57501e04c3fSmrg      return 4;
57601e04c3fSmrg
57701e04c3fSmrg   unreachable("Could not calculate number of operands");
57801e04c3fSmrg}
57901e04c3fSmrg
58001e04c3fSmrg#include "ir_expression_operation_strings.h"
58101e04c3fSmrg
58201e04c3fSmrgconst char*
58301e04c3fSmrgdepth_layout_string(ir_depth_layout layout)
58401e04c3fSmrg{
58501e04c3fSmrg   switch(layout) {
58601e04c3fSmrg   case ir_depth_layout_none:      return "";
58701e04c3fSmrg   case ir_depth_layout_any:       return "depth_any";
58801e04c3fSmrg   case ir_depth_layout_greater:   return "depth_greater";
58901e04c3fSmrg   case ir_depth_layout_less:      return "depth_less";
59001e04c3fSmrg   case ir_depth_layout_unchanged: return "depth_unchanged";
59101e04c3fSmrg
59201e04c3fSmrg   default:
59301e04c3fSmrg      assert(0);
59401e04c3fSmrg      return "";
59501e04c3fSmrg   }
59601e04c3fSmrg}
59701e04c3fSmrg
59801e04c3fSmrgir_expression_operation
59901e04c3fSmrgir_expression::get_operator(const char *str)
60001e04c3fSmrg{
60101e04c3fSmrg   for (int op = 0; op <= int(ir_last_opcode); op++) {
60201e04c3fSmrg      if (strcmp(str, ir_expression_operation_strings[op]) == 0)
60301e04c3fSmrg	 return (ir_expression_operation) op;
60401e04c3fSmrg   }
60501e04c3fSmrg   return (ir_expression_operation) -1;
60601e04c3fSmrg}
60701e04c3fSmrg
60801e04c3fSmrgir_variable *
60901e04c3fSmrgir_expression::variable_referenced() const
61001e04c3fSmrg{
61101e04c3fSmrg   switch (operation) {
61201e04c3fSmrg      case ir_binop_vector_extract:
61301e04c3fSmrg      case ir_triop_vector_insert:
61401e04c3fSmrg         /* We get these for things like a[0] where a is a vector type. In these
61501e04c3fSmrg          * cases we want variable_referenced() to return the actual vector
61601e04c3fSmrg          * variable this is wrapping.
61701e04c3fSmrg          */
61801e04c3fSmrg         return operands[0]->variable_referenced();
61901e04c3fSmrg      default:
62001e04c3fSmrg         return ir_rvalue::variable_referenced();
62101e04c3fSmrg   }
62201e04c3fSmrg}
62301e04c3fSmrg
62401e04c3fSmrgir_constant::ir_constant()
62501e04c3fSmrg   : ir_rvalue(ir_type_constant)
62601e04c3fSmrg{
62701e04c3fSmrg   this->const_elements = NULL;
62801e04c3fSmrg}
62901e04c3fSmrg
63001e04c3fSmrgir_constant::ir_constant(const struct glsl_type *type,
63101e04c3fSmrg			 const ir_constant_data *data)
63201e04c3fSmrg   : ir_rvalue(ir_type_constant)
63301e04c3fSmrg{
63401e04c3fSmrg   this->const_elements = NULL;
63501e04c3fSmrg
63601e04c3fSmrg   assert((type->base_type >= GLSL_TYPE_UINT)
63701e04c3fSmrg	  && (type->base_type <= GLSL_TYPE_IMAGE));
63801e04c3fSmrg
63901e04c3fSmrg   this->type = type;
64001e04c3fSmrg   memcpy(& this->value, data, sizeof(this->value));
64101e04c3fSmrg}
64201e04c3fSmrg
64301e04c3fSmrgir_constant::ir_constant(float f, unsigned vector_elements)
64401e04c3fSmrg   : ir_rvalue(ir_type_constant)
64501e04c3fSmrg{
64601e04c3fSmrg   assert(vector_elements <= 4);
64701e04c3fSmrg   this->type = glsl_type::get_instance(GLSL_TYPE_FLOAT, vector_elements, 1);
64801e04c3fSmrg   for (unsigned i = 0; i < vector_elements; i++) {
64901e04c3fSmrg      this->value.f[i] = f;
65001e04c3fSmrg   }
65101e04c3fSmrg   for (unsigned i = vector_elements; i < 16; i++)  {
65201e04c3fSmrg      this->value.f[i] = 0;
65301e04c3fSmrg   }
65401e04c3fSmrg}
65501e04c3fSmrg
65601e04c3fSmrgir_constant::ir_constant(double d, unsigned vector_elements)
65701e04c3fSmrg   : ir_rvalue(ir_type_constant)
65801e04c3fSmrg{
65901e04c3fSmrg   assert(vector_elements <= 4);
66001e04c3fSmrg   this->type = glsl_type::get_instance(GLSL_TYPE_DOUBLE, vector_elements, 1);
66101e04c3fSmrg   for (unsigned i = 0; i < vector_elements; i++) {
66201e04c3fSmrg      this->value.d[i] = d;
66301e04c3fSmrg   }
66401e04c3fSmrg   for (unsigned i = vector_elements; i < 16; i++)  {
66501e04c3fSmrg      this->value.d[i] = 0.0;
66601e04c3fSmrg   }
66701e04c3fSmrg}
66801e04c3fSmrg
66901e04c3fSmrgir_constant::ir_constant(unsigned int u, unsigned vector_elements)
67001e04c3fSmrg   : ir_rvalue(ir_type_constant)
67101e04c3fSmrg{
67201e04c3fSmrg   assert(vector_elements <= 4);
67301e04c3fSmrg   this->type = glsl_type::get_instance(GLSL_TYPE_UINT, vector_elements, 1);
67401e04c3fSmrg   for (unsigned i = 0; i < vector_elements; i++) {
67501e04c3fSmrg      this->value.u[i] = u;
67601e04c3fSmrg   }
67701e04c3fSmrg   for (unsigned i = vector_elements; i < 16; i++) {
67801e04c3fSmrg      this->value.u[i] = 0;
67901e04c3fSmrg   }
68001e04c3fSmrg}
68101e04c3fSmrg
68201e04c3fSmrgir_constant::ir_constant(int integer, unsigned vector_elements)
68301e04c3fSmrg   : ir_rvalue(ir_type_constant)
68401e04c3fSmrg{
68501e04c3fSmrg   assert(vector_elements <= 4);
68601e04c3fSmrg   this->type = glsl_type::get_instance(GLSL_TYPE_INT, vector_elements, 1);
68701e04c3fSmrg   for (unsigned i = 0; i < vector_elements; i++) {
68801e04c3fSmrg      this->value.i[i] = integer;
68901e04c3fSmrg   }
69001e04c3fSmrg   for (unsigned i = vector_elements; i < 16; i++) {
69101e04c3fSmrg      this->value.i[i] = 0;
69201e04c3fSmrg   }
69301e04c3fSmrg}
69401e04c3fSmrg
69501e04c3fSmrgir_constant::ir_constant(uint64_t u64, unsigned vector_elements)
69601e04c3fSmrg   : ir_rvalue(ir_type_constant)
69701e04c3fSmrg{
69801e04c3fSmrg   assert(vector_elements <= 4);
69901e04c3fSmrg   this->type = glsl_type::get_instance(GLSL_TYPE_UINT64, vector_elements, 1);
70001e04c3fSmrg   for (unsigned i = 0; i < vector_elements; i++) {
70101e04c3fSmrg      this->value.u64[i] = u64;
70201e04c3fSmrg   }
70301e04c3fSmrg   for (unsigned i = vector_elements; i < 16; i++) {
70401e04c3fSmrg      this->value.u64[i] = 0;
70501e04c3fSmrg   }
70601e04c3fSmrg}
70701e04c3fSmrg
70801e04c3fSmrgir_constant::ir_constant(int64_t int64, unsigned vector_elements)
70901e04c3fSmrg   : ir_rvalue(ir_type_constant)
71001e04c3fSmrg{
71101e04c3fSmrg   assert(vector_elements <= 4);
71201e04c3fSmrg   this->type = glsl_type::get_instance(GLSL_TYPE_INT64, vector_elements, 1);
71301e04c3fSmrg   for (unsigned i = 0; i < vector_elements; i++) {
71401e04c3fSmrg      this->value.i64[i] = int64;
71501e04c3fSmrg   }
71601e04c3fSmrg   for (unsigned i = vector_elements; i < 16; i++) {
71701e04c3fSmrg      this->value.i64[i] = 0;
71801e04c3fSmrg   }
71901e04c3fSmrg}
72001e04c3fSmrg
72101e04c3fSmrgir_constant::ir_constant(bool b, unsigned vector_elements)
72201e04c3fSmrg   : ir_rvalue(ir_type_constant)
72301e04c3fSmrg{
72401e04c3fSmrg   assert(vector_elements <= 4);
72501e04c3fSmrg   this->type = glsl_type::get_instance(GLSL_TYPE_BOOL, vector_elements, 1);
72601e04c3fSmrg   for (unsigned i = 0; i < vector_elements; i++) {
72701e04c3fSmrg      this->value.b[i] = b;
72801e04c3fSmrg   }
72901e04c3fSmrg   for (unsigned i = vector_elements; i < 16; i++) {
73001e04c3fSmrg      this->value.b[i] = false;
73101e04c3fSmrg   }
73201e04c3fSmrg}
73301e04c3fSmrg
73401e04c3fSmrgir_constant::ir_constant(const ir_constant *c, unsigned i)
73501e04c3fSmrg   : ir_rvalue(ir_type_constant)
73601e04c3fSmrg{
73701e04c3fSmrg   this->const_elements = NULL;
73801e04c3fSmrg   this->type = c->type->get_base_type();
73901e04c3fSmrg
74001e04c3fSmrg   switch (this->type->base_type) {
74101e04c3fSmrg   case GLSL_TYPE_UINT:  this->value.u[0] = c->value.u[i]; break;
74201e04c3fSmrg   case GLSL_TYPE_INT:   this->value.i[0] = c->value.i[i]; break;
74301e04c3fSmrg   case GLSL_TYPE_FLOAT: this->value.f[0] = c->value.f[i]; break;
74401e04c3fSmrg   case GLSL_TYPE_BOOL:  this->value.b[0] = c->value.b[i]; break;
74501e04c3fSmrg   case GLSL_TYPE_DOUBLE: this->value.d[0] = c->value.d[i]; break;
74601e04c3fSmrg   default:              assert(!"Should not get here."); break;
74701e04c3fSmrg   }
74801e04c3fSmrg}
74901e04c3fSmrg
75001e04c3fSmrgir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list)
75101e04c3fSmrg   : ir_rvalue(ir_type_constant)
75201e04c3fSmrg{
75301e04c3fSmrg   this->const_elements = NULL;
75401e04c3fSmrg   this->type = type;
75501e04c3fSmrg
75601e04c3fSmrg   assert(type->is_scalar() || type->is_vector() || type->is_matrix()
75701e04c3fSmrg	  || type->is_record() || type->is_array());
75801e04c3fSmrg
75901e04c3fSmrg   /* If the constant is a record, the types of each of the entries in
76001e04c3fSmrg    * value_list must be a 1-for-1 match with the structure components.  Each
76101e04c3fSmrg    * entry must also be a constant.  Just move the nodes from the value_list
76201e04c3fSmrg    * to the list in the ir_constant.
76301e04c3fSmrg    */
76401e04c3fSmrg   if (type->is_array() || type->is_record()) {
76501e04c3fSmrg      this->const_elements = ralloc_array(this, ir_constant *, type->length);
76601e04c3fSmrg      unsigned i = 0;
76701e04c3fSmrg      foreach_in_list(ir_constant, value, value_list) {
76801e04c3fSmrg	 assert(value->as_constant() != NULL);
76901e04c3fSmrg
77001e04c3fSmrg	 this->const_elements[i++] = value;
77101e04c3fSmrg      }
77201e04c3fSmrg      return;
77301e04c3fSmrg   }
77401e04c3fSmrg
77501e04c3fSmrg   for (unsigned i = 0; i < 16; i++) {
77601e04c3fSmrg      this->value.u[i] = 0;
77701e04c3fSmrg   }
77801e04c3fSmrg
77901e04c3fSmrg   ir_constant *value = (ir_constant *) (value_list->get_head_raw());
78001e04c3fSmrg
78101e04c3fSmrg   /* Constructors with exactly one scalar argument are special for vectors
78201e04c3fSmrg    * and matrices.  For vectors, the scalar value is replicated to fill all
78301e04c3fSmrg    * the components.  For matrices, the scalar fills the components of the
78401e04c3fSmrg    * diagonal while the rest is filled with 0.
78501e04c3fSmrg    */
78601e04c3fSmrg   if (value->type->is_scalar() && value->next->is_tail_sentinel()) {
78701e04c3fSmrg      if (type->is_matrix()) {
78801e04c3fSmrg	 /* Matrix - fill diagonal (rest is already set to 0) */
78901e04c3fSmrg         assert(type->is_float() || type->is_double());
79001e04c3fSmrg         for (unsigned i = 0; i < type->matrix_columns; i++) {
79101e04c3fSmrg            if (type->is_float())
79201e04c3fSmrg               this->value.f[i * type->vector_elements + i] =
79301e04c3fSmrg                  value->value.f[0];
79401e04c3fSmrg            else
79501e04c3fSmrg               this->value.d[i * type->vector_elements + i] =
79601e04c3fSmrg                  value->value.d[0];
79701e04c3fSmrg         }
79801e04c3fSmrg      } else {
79901e04c3fSmrg	 /* Vector or scalar - fill all components */
80001e04c3fSmrg	 switch (type->base_type) {
80101e04c3fSmrg	 case GLSL_TYPE_UINT:
80201e04c3fSmrg	 case GLSL_TYPE_INT:
80301e04c3fSmrg	    for (unsigned i = 0; i < type->components(); i++)
80401e04c3fSmrg	       this->value.u[i] = value->value.u[0];
80501e04c3fSmrg	    break;
80601e04c3fSmrg	 case GLSL_TYPE_FLOAT:
80701e04c3fSmrg	    for (unsigned i = 0; i < type->components(); i++)
80801e04c3fSmrg	       this->value.f[i] = value->value.f[0];
80901e04c3fSmrg	    break;
81001e04c3fSmrg	 case GLSL_TYPE_DOUBLE:
81101e04c3fSmrg	    for (unsigned i = 0; i < type->components(); i++)
81201e04c3fSmrg	       this->value.d[i] = value->value.d[0];
81301e04c3fSmrg	    break;
81401e04c3fSmrg	 case GLSL_TYPE_UINT64:
81501e04c3fSmrg	 case GLSL_TYPE_INT64:
81601e04c3fSmrg	    for (unsigned i = 0; i < type->components(); i++)
81701e04c3fSmrg	       this->value.u64[i] = value->value.u64[0];
81801e04c3fSmrg	    break;
81901e04c3fSmrg	 case GLSL_TYPE_BOOL:
82001e04c3fSmrg	    for (unsigned i = 0; i < type->components(); i++)
82101e04c3fSmrg	       this->value.b[i] = value->value.b[0];
82201e04c3fSmrg	    break;
82301e04c3fSmrg	 case GLSL_TYPE_SAMPLER:
82401e04c3fSmrg	 case GLSL_TYPE_IMAGE:
82501e04c3fSmrg	    this->value.u64[0] = value->value.u64[0];
82601e04c3fSmrg	    break;
82701e04c3fSmrg	 default:
82801e04c3fSmrg	    assert(!"Should not get here.");
82901e04c3fSmrg	    break;
83001e04c3fSmrg	 }
83101e04c3fSmrg      }
83201e04c3fSmrg      return;
83301e04c3fSmrg   }
83401e04c3fSmrg
83501e04c3fSmrg   if (type->is_matrix() && value->type->is_matrix()) {
83601e04c3fSmrg      assert(value->next->is_tail_sentinel());
83701e04c3fSmrg
83801e04c3fSmrg      /* From section 5.4.2 of the GLSL 1.20 spec:
83901e04c3fSmrg       * "If a matrix is constructed from a matrix, then each component
84001e04c3fSmrg       *  (column i, row j) in the result that has a corresponding component
84101e04c3fSmrg       *  (column i, row j) in the argument will be initialized from there."
84201e04c3fSmrg       */
84301e04c3fSmrg      unsigned cols = MIN2(type->matrix_columns, value->type->matrix_columns);
84401e04c3fSmrg      unsigned rows = MIN2(type->vector_elements, value->type->vector_elements);
84501e04c3fSmrg      for (unsigned i = 0; i < cols; i++) {
84601e04c3fSmrg	 for (unsigned j = 0; j < rows; j++) {
84701e04c3fSmrg	    const unsigned src = i * value->type->vector_elements + j;
84801e04c3fSmrg	    const unsigned dst = i * type->vector_elements + j;
84901e04c3fSmrg	    this->value.f[dst] = value->value.f[src];
85001e04c3fSmrg	 }
85101e04c3fSmrg      }
85201e04c3fSmrg
85301e04c3fSmrg      /* "All other components will be initialized to the identity matrix." */
85401e04c3fSmrg      for (unsigned i = cols; i < type->matrix_columns; i++)
85501e04c3fSmrg	 this->value.f[i * type->vector_elements + i] = 1.0;
85601e04c3fSmrg
85701e04c3fSmrg      return;
85801e04c3fSmrg   }
85901e04c3fSmrg
86001e04c3fSmrg   /* Use each component from each entry in the value_list to initialize one
86101e04c3fSmrg    * component of the constant being constructed.
86201e04c3fSmrg    */
86301e04c3fSmrg   unsigned i = 0;
86401e04c3fSmrg   for (;;) {
86501e04c3fSmrg      assert(value->as_constant() != NULL);
86601e04c3fSmrg      assert(!value->is_tail_sentinel());
86701e04c3fSmrg
86801e04c3fSmrg      for (unsigned j = 0; j < value->type->components(); j++) {
86901e04c3fSmrg	 switch (type->base_type) {
87001e04c3fSmrg	 case GLSL_TYPE_UINT:
87101e04c3fSmrg	    this->value.u[i] = value->get_uint_component(j);
87201e04c3fSmrg	    break;
87301e04c3fSmrg	 case GLSL_TYPE_INT:
87401e04c3fSmrg	    this->value.i[i] = value->get_int_component(j);
87501e04c3fSmrg	    break;
87601e04c3fSmrg	 case GLSL_TYPE_FLOAT:
87701e04c3fSmrg	    this->value.f[i] = value->get_float_component(j);
87801e04c3fSmrg	    break;
87901e04c3fSmrg	 case GLSL_TYPE_BOOL:
88001e04c3fSmrg	    this->value.b[i] = value->get_bool_component(j);
88101e04c3fSmrg	    break;
88201e04c3fSmrg	 case GLSL_TYPE_DOUBLE:
88301e04c3fSmrg	    this->value.d[i] = value->get_double_component(j);
88401e04c3fSmrg	    break;
88501e04c3fSmrg         case GLSL_TYPE_UINT64:
88601e04c3fSmrg	    this->value.u64[i] = value->get_uint64_component(j);
88701e04c3fSmrg	    break;
88801e04c3fSmrg	 case GLSL_TYPE_INT64:
88901e04c3fSmrg	    this->value.i64[i] = value->get_int64_component(j);
89001e04c3fSmrg	    break;
89101e04c3fSmrg	 default:
89201e04c3fSmrg	    /* FINISHME: What to do?  Exceptions are not the answer.
89301e04c3fSmrg	     */
89401e04c3fSmrg	    break;
89501e04c3fSmrg	 }
89601e04c3fSmrg
89701e04c3fSmrg	 i++;
89801e04c3fSmrg	 if (i >= type->components())
89901e04c3fSmrg	    break;
90001e04c3fSmrg      }
90101e04c3fSmrg
90201e04c3fSmrg      if (i >= type->components())
90301e04c3fSmrg	 break; /* avoid downcasting a list sentinel */
90401e04c3fSmrg      value = (ir_constant *) value->next;
90501e04c3fSmrg   }
90601e04c3fSmrg}
90701e04c3fSmrg
90801e04c3fSmrgir_constant *
90901e04c3fSmrgir_constant::zero(void *mem_ctx, const glsl_type *type)
91001e04c3fSmrg{
91101e04c3fSmrg   assert(type->is_scalar() || type->is_vector() || type->is_matrix()
91201e04c3fSmrg	  || type->is_record() || type->is_array());
91301e04c3fSmrg
91401e04c3fSmrg   ir_constant *c = new(mem_ctx) ir_constant;
91501e04c3fSmrg   c->type = type;
91601e04c3fSmrg   memset(&c->value, 0, sizeof(c->value));
91701e04c3fSmrg
91801e04c3fSmrg   if (type->is_array()) {
91901e04c3fSmrg      c->const_elements = ralloc_array(c, ir_constant *, type->length);
92001e04c3fSmrg
92101e04c3fSmrg      for (unsigned i = 0; i < type->length; i++)
92201e04c3fSmrg	 c->const_elements[i] = ir_constant::zero(c, type->fields.array);
92301e04c3fSmrg   }
92401e04c3fSmrg
92501e04c3fSmrg   if (type->is_record()) {
92601e04c3fSmrg      c->const_elements = ralloc_array(c, ir_constant *, type->length);
92701e04c3fSmrg
92801e04c3fSmrg      for (unsigned i = 0; i < type->length; i++) {
92901e04c3fSmrg         c->const_elements[i] =
93001e04c3fSmrg            ir_constant::zero(mem_ctx, type->fields.structure[i].type);
93101e04c3fSmrg      }
93201e04c3fSmrg   }
93301e04c3fSmrg
93401e04c3fSmrg   return c;
93501e04c3fSmrg}
93601e04c3fSmrg
93701e04c3fSmrgbool
93801e04c3fSmrgir_constant::get_bool_component(unsigned i) const
93901e04c3fSmrg{
94001e04c3fSmrg   switch (this->type->base_type) {
94101e04c3fSmrg   case GLSL_TYPE_UINT:  return this->value.u[i] != 0;
94201e04c3fSmrg   case GLSL_TYPE_INT:   return this->value.i[i] != 0;
94301e04c3fSmrg   case GLSL_TYPE_FLOAT: return ((int)this->value.f[i]) != 0;
94401e04c3fSmrg   case GLSL_TYPE_BOOL:  return this->value.b[i];
94501e04c3fSmrg   case GLSL_TYPE_DOUBLE: return this->value.d[i] != 0.0;
94601e04c3fSmrg   case GLSL_TYPE_SAMPLER:
94701e04c3fSmrg   case GLSL_TYPE_IMAGE:
94801e04c3fSmrg   case GLSL_TYPE_UINT64: return this->value.u64[i] != 0;
94901e04c3fSmrg   case GLSL_TYPE_INT64:  return this->value.i64[i] != 0;
95001e04c3fSmrg   default:              assert(!"Should not get here."); break;
95101e04c3fSmrg   }
95201e04c3fSmrg
95301e04c3fSmrg   /* Must return something to make the compiler happy.  This is clearly an
95401e04c3fSmrg    * error case.
95501e04c3fSmrg    */
95601e04c3fSmrg   return false;
95701e04c3fSmrg}
95801e04c3fSmrg
95901e04c3fSmrgfloat
96001e04c3fSmrgir_constant::get_float_component(unsigned i) const
96101e04c3fSmrg{
96201e04c3fSmrg   switch (this->type->base_type) {
96301e04c3fSmrg   case GLSL_TYPE_UINT:  return (float) this->value.u[i];
96401e04c3fSmrg   case GLSL_TYPE_INT:   return (float) this->value.i[i];
96501e04c3fSmrg   case GLSL_TYPE_FLOAT: return this->value.f[i];
96601e04c3fSmrg   case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1.0f : 0.0f;
96701e04c3fSmrg   case GLSL_TYPE_DOUBLE: return (float) this->value.d[i];
96801e04c3fSmrg   case GLSL_TYPE_SAMPLER:
96901e04c3fSmrg   case GLSL_TYPE_IMAGE:
97001e04c3fSmrg   case GLSL_TYPE_UINT64: return (float) this->value.u64[i];
97101e04c3fSmrg   case GLSL_TYPE_INT64:  return (float) this->value.i64[i];
97201e04c3fSmrg   default:              assert(!"Should not get here."); break;
97301e04c3fSmrg   }
97401e04c3fSmrg
97501e04c3fSmrg   /* Must return something to make the compiler happy.  This is clearly an
97601e04c3fSmrg    * error case.
97701e04c3fSmrg    */
97801e04c3fSmrg   return 0.0;
97901e04c3fSmrg}
98001e04c3fSmrg
98101e04c3fSmrgdouble
98201e04c3fSmrgir_constant::get_double_component(unsigned i) const
98301e04c3fSmrg{
98401e04c3fSmrg   switch (this->type->base_type) {
98501e04c3fSmrg   case GLSL_TYPE_UINT:  return (double) this->value.u[i];
98601e04c3fSmrg   case GLSL_TYPE_INT:   return (double) this->value.i[i];
98701e04c3fSmrg   case GLSL_TYPE_FLOAT: return (double) this->value.f[i];
98801e04c3fSmrg   case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1.0 : 0.0;
98901e04c3fSmrg   case GLSL_TYPE_DOUBLE: return this->value.d[i];
99001e04c3fSmrg   case GLSL_TYPE_SAMPLER:
99101e04c3fSmrg   case GLSL_TYPE_IMAGE:
99201e04c3fSmrg   case GLSL_TYPE_UINT64: return (double) this->value.u64[i];
99301e04c3fSmrg   case GLSL_TYPE_INT64:  return (double) this->value.i64[i];
99401e04c3fSmrg   default:              assert(!"Should not get here."); break;
99501e04c3fSmrg   }
99601e04c3fSmrg
99701e04c3fSmrg   /* Must return something to make the compiler happy.  This is clearly an
99801e04c3fSmrg    * error case.
99901e04c3fSmrg    */
100001e04c3fSmrg   return 0.0;
100101e04c3fSmrg}
100201e04c3fSmrg
100301e04c3fSmrgint
100401e04c3fSmrgir_constant::get_int_component(unsigned i) const
100501e04c3fSmrg{
100601e04c3fSmrg   switch (this->type->base_type) {
100701e04c3fSmrg   case GLSL_TYPE_UINT:  return this->value.u[i];
100801e04c3fSmrg   case GLSL_TYPE_INT:   return this->value.i[i];
100901e04c3fSmrg   case GLSL_TYPE_FLOAT: return (int) this->value.f[i];
101001e04c3fSmrg   case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1 : 0;
101101e04c3fSmrg   case GLSL_TYPE_DOUBLE: return (int) this->value.d[i];
101201e04c3fSmrg   case GLSL_TYPE_SAMPLER:
101301e04c3fSmrg   case GLSL_TYPE_IMAGE:
101401e04c3fSmrg   case GLSL_TYPE_UINT64: return (int) this->value.u64[i];
101501e04c3fSmrg   case GLSL_TYPE_INT64:  return (int) this->value.i64[i];
101601e04c3fSmrg   default:              assert(!"Should not get here."); break;
101701e04c3fSmrg   }
101801e04c3fSmrg
101901e04c3fSmrg   /* Must return something to make the compiler happy.  This is clearly an
102001e04c3fSmrg    * error case.
102101e04c3fSmrg    */
102201e04c3fSmrg   return 0;
102301e04c3fSmrg}
102401e04c3fSmrg
102501e04c3fSmrgunsigned
102601e04c3fSmrgir_constant::get_uint_component(unsigned i) const
102701e04c3fSmrg{
102801e04c3fSmrg   switch (this->type->base_type) {
102901e04c3fSmrg   case GLSL_TYPE_UINT:  return this->value.u[i];
103001e04c3fSmrg   case GLSL_TYPE_INT:   return this->value.i[i];
103101e04c3fSmrg   case GLSL_TYPE_FLOAT: return (unsigned) this->value.f[i];
103201e04c3fSmrg   case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1 : 0;
103301e04c3fSmrg   case GLSL_TYPE_DOUBLE: return (unsigned) this->value.d[i];
103401e04c3fSmrg   case GLSL_TYPE_SAMPLER:
103501e04c3fSmrg   case GLSL_TYPE_IMAGE:
103601e04c3fSmrg   case GLSL_TYPE_UINT64: return (unsigned) this->value.u64[i];
103701e04c3fSmrg   case GLSL_TYPE_INT64:  return (unsigned) this->value.i64[i];
103801e04c3fSmrg   default:              assert(!"Should not get here."); break;
103901e04c3fSmrg   }
104001e04c3fSmrg
104101e04c3fSmrg   /* Must return something to make the compiler happy.  This is clearly an
104201e04c3fSmrg    * error case.
104301e04c3fSmrg    */
104401e04c3fSmrg   return 0;
104501e04c3fSmrg}
104601e04c3fSmrg
104701e04c3fSmrgint64_t
104801e04c3fSmrgir_constant::get_int64_component(unsigned i) const
104901e04c3fSmrg{
105001e04c3fSmrg   switch (this->type->base_type) {
105101e04c3fSmrg   case GLSL_TYPE_UINT:  return this->value.u[i];
105201e04c3fSmrg   case GLSL_TYPE_INT:   return this->value.i[i];
105301e04c3fSmrg   case GLSL_TYPE_FLOAT: return (int64_t) this->value.f[i];
105401e04c3fSmrg   case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1 : 0;
105501e04c3fSmrg   case GLSL_TYPE_DOUBLE: return (int64_t) this->value.d[i];
105601e04c3fSmrg   case GLSL_TYPE_SAMPLER:
105701e04c3fSmrg   case GLSL_TYPE_IMAGE:
105801e04c3fSmrg   case GLSL_TYPE_UINT64: return (int64_t) this->value.u64[i];
105901e04c3fSmrg   case GLSL_TYPE_INT64:  return this->value.i64[i];
106001e04c3fSmrg   default:              assert(!"Should not get here."); break;
106101e04c3fSmrg   }
106201e04c3fSmrg
106301e04c3fSmrg   /* Must return something to make the compiler happy.  This is clearly an
106401e04c3fSmrg    * error case.
106501e04c3fSmrg    */
106601e04c3fSmrg   return 0;
106701e04c3fSmrg}
106801e04c3fSmrg
106901e04c3fSmrguint64_t
107001e04c3fSmrgir_constant::get_uint64_component(unsigned i) const
107101e04c3fSmrg{
107201e04c3fSmrg   switch (this->type->base_type) {
107301e04c3fSmrg   case GLSL_TYPE_UINT:  return this->value.u[i];
107401e04c3fSmrg   case GLSL_TYPE_INT:   return this->value.i[i];
107501e04c3fSmrg   case GLSL_TYPE_FLOAT: return (uint64_t) this->value.f[i];
107601e04c3fSmrg   case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1 : 0;
107701e04c3fSmrg   case GLSL_TYPE_DOUBLE: return (uint64_t) this->value.d[i];
107801e04c3fSmrg   case GLSL_TYPE_SAMPLER:
107901e04c3fSmrg   case GLSL_TYPE_IMAGE:
108001e04c3fSmrg   case GLSL_TYPE_UINT64: return this->value.u64[i];
108101e04c3fSmrg   case GLSL_TYPE_INT64:  return (uint64_t) this->value.i64[i];
108201e04c3fSmrg   default:              assert(!"Should not get here."); break;
108301e04c3fSmrg   }
108401e04c3fSmrg
108501e04c3fSmrg   /* Must return something to make the compiler happy.  This is clearly an
108601e04c3fSmrg    * error case.
108701e04c3fSmrg    */
108801e04c3fSmrg   return 0;
108901e04c3fSmrg}
109001e04c3fSmrg
109101e04c3fSmrgir_constant *
109201e04c3fSmrgir_constant::get_array_element(unsigned i) const
109301e04c3fSmrg{
109401e04c3fSmrg   assert(this->type->is_array());
109501e04c3fSmrg
109601e04c3fSmrg   /* From page 35 (page 41 of the PDF) of the GLSL 1.20 spec:
109701e04c3fSmrg    *
109801e04c3fSmrg    *     "Behavior is undefined if a shader subscripts an array with an index
109901e04c3fSmrg    *     less than 0 or greater than or equal to the size the array was
110001e04c3fSmrg    *     declared with."
110101e04c3fSmrg    *
110201e04c3fSmrg    * Most out-of-bounds accesses are removed before things could get this far.
110301e04c3fSmrg    * There are cases where non-constant array index values can get constant
110401e04c3fSmrg    * folded.
110501e04c3fSmrg    */
110601e04c3fSmrg   if (int(i) < 0)
110701e04c3fSmrg      i = 0;
110801e04c3fSmrg   else if (i >= this->type->length)
110901e04c3fSmrg      i = this->type->length - 1;
111001e04c3fSmrg
111101e04c3fSmrg   return const_elements[i];
111201e04c3fSmrg}
111301e04c3fSmrg
111401e04c3fSmrgir_constant *
111501e04c3fSmrgir_constant::get_record_field(int idx)
111601e04c3fSmrg{
111701e04c3fSmrg   assert(this->type->is_record());
111801e04c3fSmrg   assert(idx >= 0 && (unsigned) idx < this->type->length);
111901e04c3fSmrg
112001e04c3fSmrg   return const_elements[idx];
112101e04c3fSmrg}
112201e04c3fSmrg
112301e04c3fSmrgvoid
112401e04c3fSmrgir_constant::copy_offset(ir_constant *src, int offset)
112501e04c3fSmrg{
112601e04c3fSmrg   switch (this->type->base_type) {
112701e04c3fSmrg   case GLSL_TYPE_UINT:
112801e04c3fSmrg   case GLSL_TYPE_INT:
112901e04c3fSmrg   case GLSL_TYPE_FLOAT:
113001e04c3fSmrg   case GLSL_TYPE_DOUBLE:
113101e04c3fSmrg   case GLSL_TYPE_SAMPLER:
113201e04c3fSmrg   case GLSL_TYPE_IMAGE:
113301e04c3fSmrg   case GLSL_TYPE_UINT64:
113401e04c3fSmrg   case GLSL_TYPE_INT64:
113501e04c3fSmrg   case GLSL_TYPE_BOOL: {
113601e04c3fSmrg      unsigned int size = src->type->components();
113701e04c3fSmrg      assert (size <= this->type->components() - offset);
113801e04c3fSmrg      for (unsigned int i=0; i<size; i++) {
113901e04c3fSmrg	 switch (this->type->base_type) {
114001e04c3fSmrg	 case GLSL_TYPE_UINT:
114101e04c3fSmrg	    value.u[i+offset] = src->get_uint_component(i);
114201e04c3fSmrg	    break;
114301e04c3fSmrg	 case GLSL_TYPE_INT:
114401e04c3fSmrg	    value.i[i+offset] = src->get_int_component(i);
114501e04c3fSmrg	    break;
114601e04c3fSmrg	 case GLSL_TYPE_FLOAT:
114701e04c3fSmrg	    value.f[i+offset] = src->get_float_component(i);
114801e04c3fSmrg	    break;
114901e04c3fSmrg	 case GLSL_TYPE_BOOL:
115001e04c3fSmrg	    value.b[i+offset] = src->get_bool_component(i);
115101e04c3fSmrg	    break;
115201e04c3fSmrg	 case GLSL_TYPE_DOUBLE:
115301e04c3fSmrg	    value.d[i+offset] = src->get_double_component(i);
115401e04c3fSmrg	    break;
115501e04c3fSmrg	 case GLSL_TYPE_SAMPLER:
115601e04c3fSmrg	 case GLSL_TYPE_IMAGE:
115701e04c3fSmrg	 case GLSL_TYPE_UINT64:
115801e04c3fSmrg	    value.u64[i+offset] = src->get_uint64_component(i);
115901e04c3fSmrg	    break;
116001e04c3fSmrg	 case GLSL_TYPE_INT64:
116101e04c3fSmrg	    value.i64[i+offset] = src->get_int64_component(i);
116201e04c3fSmrg	    break;
116301e04c3fSmrg	 default: // Shut up the compiler
116401e04c3fSmrg	    break;
116501e04c3fSmrg	 }
116601e04c3fSmrg      }
116701e04c3fSmrg      break;
116801e04c3fSmrg   }
116901e04c3fSmrg
117001e04c3fSmrg   case GLSL_TYPE_STRUCT:
117101e04c3fSmrg   case GLSL_TYPE_ARRAY: {
117201e04c3fSmrg      assert (src->type == this->type);
117301e04c3fSmrg      for (unsigned i = 0; i < this->type->length; i++) {
117401e04c3fSmrg	 this->const_elements[i] = src->const_elements[i]->clone(this, NULL);
117501e04c3fSmrg      }
117601e04c3fSmrg      break;
117701e04c3fSmrg   }
117801e04c3fSmrg
117901e04c3fSmrg   default:
118001e04c3fSmrg      assert(!"Should not get here.");
118101e04c3fSmrg      break;
118201e04c3fSmrg   }
118301e04c3fSmrg}
118401e04c3fSmrg
118501e04c3fSmrgvoid
118601e04c3fSmrgir_constant::copy_masked_offset(ir_constant *src, int offset, unsigned int mask)
118701e04c3fSmrg{
118801e04c3fSmrg   assert (!type->is_array() && !type->is_record());
118901e04c3fSmrg
119001e04c3fSmrg   if (!type->is_vector() && !type->is_matrix()) {
119101e04c3fSmrg      offset = 0;
119201e04c3fSmrg      mask = 1;
119301e04c3fSmrg   }
119401e04c3fSmrg
119501e04c3fSmrg   int id = 0;
119601e04c3fSmrg   for (int i=0; i<4; i++) {
119701e04c3fSmrg      if (mask & (1 << i)) {
119801e04c3fSmrg	 switch (this->type->base_type) {
119901e04c3fSmrg	 case GLSL_TYPE_UINT:
120001e04c3fSmrg	    value.u[i+offset] = src->get_uint_component(id++);
120101e04c3fSmrg	    break;
120201e04c3fSmrg	 case GLSL_TYPE_INT:
120301e04c3fSmrg	    value.i[i+offset] = src->get_int_component(id++);
120401e04c3fSmrg	    break;
120501e04c3fSmrg	 case GLSL_TYPE_FLOAT:
120601e04c3fSmrg	    value.f[i+offset] = src->get_float_component(id++);
120701e04c3fSmrg	    break;
120801e04c3fSmrg	 case GLSL_TYPE_BOOL:
120901e04c3fSmrg	    value.b[i+offset] = src->get_bool_component(id++);
121001e04c3fSmrg	    break;
121101e04c3fSmrg	 case GLSL_TYPE_DOUBLE:
121201e04c3fSmrg	    value.d[i+offset] = src->get_double_component(id++);
121301e04c3fSmrg	    break;
121401e04c3fSmrg	 case GLSL_TYPE_SAMPLER:
121501e04c3fSmrg	 case GLSL_TYPE_IMAGE:
121601e04c3fSmrg	 case GLSL_TYPE_UINT64:
121701e04c3fSmrg	    value.u64[i+offset] = src->get_uint64_component(id++);
121801e04c3fSmrg	    break;
121901e04c3fSmrg	 case GLSL_TYPE_INT64:
122001e04c3fSmrg	    value.i64[i+offset] = src->get_int64_component(id++);
122101e04c3fSmrg	    break;
122201e04c3fSmrg	 default:
122301e04c3fSmrg	    assert(!"Should not get here.");
122401e04c3fSmrg	    return;
122501e04c3fSmrg	 }
122601e04c3fSmrg      }
122701e04c3fSmrg   }
122801e04c3fSmrg}
122901e04c3fSmrg
123001e04c3fSmrgbool
123101e04c3fSmrgir_constant::has_value(const ir_constant *c) const
123201e04c3fSmrg{
123301e04c3fSmrg   if (this->type != c->type)
123401e04c3fSmrg      return false;
123501e04c3fSmrg
123601e04c3fSmrg   if (this->type->is_array() || this->type->is_record()) {
123701e04c3fSmrg      for (unsigned i = 0; i < this->type->length; i++) {
123801e04c3fSmrg	 if (!this->const_elements[i]->has_value(c->const_elements[i]))
123901e04c3fSmrg	    return false;
124001e04c3fSmrg      }
124101e04c3fSmrg      return true;
124201e04c3fSmrg   }
124301e04c3fSmrg
124401e04c3fSmrg   for (unsigned i = 0; i < this->type->components(); i++) {
124501e04c3fSmrg      switch (this->type->base_type) {
124601e04c3fSmrg      case GLSL_TYPE_UINT:
124701e04c3fSmrg	 if (this->value.u[i] != c->value.u[i])
124801e04c3fSmrg	    return false;
124901e04c3fSmrg	 break;
125001e04c3fSmrg      case GLSL_TYPE_INT:
125101e04c3fSmrg	 if (this->value.i[i] != c->value.i[i])
125201e04c3fSmrg	    return false;
125301e04c3fSmrg	 break;
125401e04c3fSmrg      case GLSL_TYPE_FLOAT:
125501e04c3fSmrg	 if (this->value.f[i] != c->value.f[i])
125601e04c3fSmrg	    return false;
125701e04c3fSmrg	 break;
125801e04c3fSmrg      case GLSL_TYPE_BOOL:
125901e04c3fSmrg	 if (this->value.b[i] != c->value.b[i])
126001e04c3fSmrg	    return false;
126101e04c3fSmrg	 break;
126201e04c3fSmrg      case GLSL_TYPE_DOUBLE:
126301e04c3fSmrg	 if (this->value.d[i] != c->value.d[i])
126401e04c3fSmrg	    return false;
126501e04c3fSmrg	 break;
126601e04c3fSmrg      case GLSL_TYPE_SAMPLER:
126701e04c3fSmrg      case GLSL_TYPE_IMAGE:
126801e04c3fSmrg      case GLSL_TYPE_UINT64:
126901e04c3fSmrg	 if (this->value.u64[i] != c->value.u64[i])
127001e04c3fSmrg	    return false;
127101e04c3fSmrg	 break;
127201e04c3fSmrg      case GLSL_TYPE_INT64:
127301e04c3fSmrg	 if (this->value.i64[i] != c->value.i64[i])
127401e04c3fSmrg	    return false;
127501e04c3fSmrg	 break;
127601e04c3fSmrg      default:
127701e04c3fSmrg	 assert(!"Should not get here.");
127801e04c3fSmrg	 return false;
127901e04c3fSmrg      }
128001e04c3fSmrg   }
128101e04c3fSmrg
128201e04c3fSmrg   return true;
128301e04c3fSmrg}
128401e04c3fSmrg
128501e04c3fSmrgbool
128601e04c3fSmrgir_constant::is_value(float f, int i) const
128701e04c3fSmrg{
128801e04c3fSmrg   if (!this->type->is_scalar() && !this->type->is_vector())
128901e04c3fSmrg      return false;
129001e04c3fSmrg
129101e04c3fSmrg   /* Only accept boolean values for 0/1. */
129201e04c3fSmrg   if (int(bool(i)) != i && this->type->is_boolean())
129301e04c3fSmrg      return false;
129401e04c3fSmrg
129501e04c3fSmrg   for (unsigned c = 0; c < this->type->vector_elements; c++) {
129601e04c3fSmrg      switch (this->type->base_type) {
129701e04c3fSmrg      case GLSL_TYPE_FLOAT:
129801e04c3fSmrg	 if (this->value.f[c] != f)
129901e04c3fSmrg	    return false;
130001e04c3fSmrg	 break;
130101e04c3fSmrg      case GLSL_TYPE_INT:
130201e04c3fSmrg	 if (this->value.i[c] != i)
130301e04c3fSmrg	    return false;
130401e04c3fSmrg	 break;
130501e04c3fSmrg      case GLSL_TYPE_UINT:
130601e04c3fSmrg	 if (this->value.u[c] != unsigned(i))
130701e04c3fSmrg	    return false;
130801e04c3fSmrg	 break;
130901e04c3fSmrg      case GLSL_TYPE_BOOL:
131001e04c3fSmrg	 if (this->value.b[c] != bool(i))
131101e04c3fSmrg	    return false;
131201e04c3fSmrg	 break;
131301e04c3fSmrg      case GLSL_TYPE_DOUBLE:
131401e04c3fSmrg	 if (this->value.d[c] != double(f))
131501e04c3fSmrg	    return false;
131601e04c3fSmrg	 break;
131701e04c3fSmrg      case GLSL_TYPE_SAMPLER:
131801e04c3fSmrg      case GLSL_TYPE_IMAGE:
131901e04c3fSmrg      case GLSL_TYPE_UINT64:
132001e04c3fSmrg	 if (this->value.u64[c] != uint64_t(i))
132101e04c3fSmrg	    return false;
132201e04c3fSmrg	 break;
132301e04c3fSmrg      case GLSL_TYPE_INT64:
132401e04c3fSmrg	 if (this->value.i64[c] != i)
132501e04c3fSmrg	    return false;
132601e04c3fSmrg	 break;
132701e04c3fSmrg      default:
132801e04c3fSmrg	 /* The only other base types are structures, arrays, and samplers.
132901e04c3fSmrg	  * Samplers cannot be constants, and the others should have been
133001e04c3fSmrg	  * filtered out above.
133101e04c3fSmrg	  */
133201e04c3fSmrg	 assert(!"Should not get here.");
133301e04c3fSmrg	 return false;
133401e04c3fSmrg      }
133501e04c3fSmrg   }
133601e04c3fSmrg
133701e04c3fSmrg   return true;
133801e04c3fSmrg}
133901e04c3fSmrg
134001e04c3fSmrgbool
134101e04c3fSmrgir_constant::is_zero() const
134201e04c3fSmrg{
134301e04c3fSmrg   return is_value(0.0, 0);
134401e04c3fSmrg}
134501e04c3fSmrg
134601e04c3fSmrgbool
134701e04c3fSmrgir_constant::is_one() const
134801e04c3fSmrg{
134901e04c3fSmrg   return is_value(1.0, 1);
135001e04c3fSmrg}
135101e04c3fSmrg
135201e04c3fSmrgbool
135301e04c3fSmrgir_constant::is_negative_one() const
135401e04c3fSmrg{
135501e04c3fSmrg   return is_value(-1.0, -1);
135601e04c3fSmrg}
135701e04c3fSmrg
135801e04c3fSmrgbool
135901e04c3fSmrgir_constant::is_uint16_constant() const
136001e04c3fSmrg{
136101e04c3fSmrg   if (!type->is_integer())
136201e04c3fSmrg      return false;
136301e04c3fSmrg
136401e04c3fSmrg   return value.u[0] < (1 << 16);
136501e04c3fSmrg}
136601e04c3fSmrg
136701e04c3fSmrgir_loop::ir_loop()
136801e04c3fSmrg   : ir_instruction(ir_type_loop)
136901e04c3fSmrg{
137001e04c3fSmrg}
137101e04c3fSmrg
137201e04c3fSmrg
137301e04c3fSmrgir_dereference_variable::ir_dereference_variable(ir_variable *var)
137401e04c3fSmrg   : ir_dereference(ir_type_dereference_variable)
137501e04c3fSmrg{
137601e04c3fSmrg   assert(var != NULL);
137701e04c3fSmrg
137801e04c3fSmrg   this->var = var;
137901e04c3fSmrg   this->type = var->type;
138001e04c3fSmrg}
138101e04c3fSmrg
138201e04c3fSmrg
138301e04c3fSmrgir_dereference_array::ir_dereference_array(ir_rvalue *value,
138401e04c3fSmrg					   ir_rvalue *array_index)
138501e04c3fSmrg   : ir_dereference(ir_type_dereference_array)
138601e04c3fSmrg{
138701e04c3fSmrg   this->array_index = array_index;
138801e04c3fSmrg   this->set_array(value);
138901e04c3fSmrg}
139001e04c3fSmrg
139101e04c3fSmrg
139201e04c3fSmrgir_dereference_array::ir_dereference_array(ir_variable *var,
139301e04c3fSmrg					   ir_rvalue *array_index)
139401e04c3fSmrg   : ir_dereference(ir_type_dereference_array)
139501e04c3fSmrg{
139601e04c3fSmrg   void *ctx = ralloc_parent(var);
139701e04c3fSmrg
139801e04c3fSmrg   this->array_index = array_index;
139901e04c3fSmrg   this->set_array(new(ctx) ir_dereference_variable(var));
140001e04c3fSmrg}
140101e04c3fSmrg
140201e04c3fSmrg
140301e04c3fSmrgvoid
140401e04c3fSmrgir_dereference_array::set_array(ir_rvalue *value)
140501e04c3fSmrg{
140601e04c3fSmrg   assert(value != NULL);
140701e04c3fSmrg
140801e04c3fSmrg   this->array = value;
140901e04c3fSmrg
141001e04c3fSmrg   const glsl_type *const vt = this->array->type;
141101e04c3fSmrg
141201e04c3fSmrg   if (vt->is_array()) {
141301e04c3fSmrg      type = vt->fields.array;
141401e04c3fSmrg   } else if (vt->is_matrix()) {
141501e04c3fSmrg      type = vt->column_type();
141601e04c3fSmrg   } else if (vt->is_vector()) {
141701e04c3fSmrg      type = vt->get_base_type();
141801e04c3fSmrg   }
141901e04c3fSmrg}
142001e04c3fSmrg
142101e04c3fSmrg
142201e04c3fSmrgir_dereference_record::ir_dereference_record(ir_rvalue *value,
142301e04c3fSmrg					     const char *field)
142401e04c3fSmrg   : ir_dereference(ir_type_dereference_record)
142501e04c3fSmrg{
142601e04c3fSmrg   assert(value != NULL);
142701e04c3fSmrg
142801e04c3fSmrg   this->record = value;
142901e04c3fSmrg   this->type = this->record->type->field_type(field);
143001e04c3fSmrg   this->field_idx = this->record->type->field_index(field);
143101e04c3fSmrg}
143201e04c3fSmrg
143301e04c3fSmrg
143401e04c3fSmrgir_dereference_record::ir_dereference_record(ir_variable *var,
143501e04c3fSmrg					     const char *field)
143601e04c3fSmrg   : ir_dereference(ir_type_dereference_record)
143701e04c3fSmrg{
143801e04c3fSmrg   void *ctx = ralloc_parent(var);
143901e04c3fSmrg
144001e04c3fSmrg   this->record = new(ctx) ir_dereference_variable(var);
144101e04c3fSmrg   this->type = this->record->type->field_type(field);
144201e04c3fSmrg   this->field_idx = this->record->type->field_index(field);
144301e04c3fSmrg}
144401e04c3fSmrg
144501e04c3fSmrgbool
144601e04c3fSmrgir_dereference::is_lvalue(const struct _mesa_glsl_parse_state *state) const
144701e04c3fSmrg{
144801e04c3fSmrg   ir_variable *var = this->variable_referenced();
144901e04c3fSmrg
145001e04c3fSmrg   /* Every l-value derference chain eventually ends in a variable.
145101e04c3fSmrg    */
145201e04c3fSmrg   if ((var == NULL) || var->data.read_only)
145301e04c3fSmrg      return false;
145401e04c3fSmrg
145501e04c3fSmrg   /* From section 4.1.7 of the ARB_bindless_texture spec:
145601e04c3fSmrg    *
145701e04c3fSmrg    * "Samplers can be used as l-values, so can be assigned into and used as
145801e04c3fSmrg    *  "out" and "inout" function parameters."
145901e04c3fSmrg    *
146001e04c3fSmrg    * From section 4.1.X of the ARB_bindless_texture spec:
146101e04c3fSmrg    *
146201e04c3fSmrg    * "Images can be used as l-values, so can be assigned into and used as
146301e04c3fSmrg    *  "out" and "inout" function parameters."
146401e04c3fSmrg    */
146501e04c3fSmrg   if ((!state || state->has_bindless()) &&
146601e04c3fSmrg       (this->type->contains_sampler() || this->type->contains_image()))
146701e04c3fSmrg      return true;
146801e04c3fSmrg
146901e04c3fSmrg   /* From section 4.1.7 of the GLSL 4.40 spec:
147001e04c3fSmrg    *
147101e04c3fSmrg    *   "Opaque variables cannot be treated as l-values; hence cannot
147201e04c3fSmrg    *    be used as out or inout function parameters, nor can they be
147301e04c3fSmrg    *    assigned into."
147401e04c3fSmrg    */
147501e04c3fSmrg   if (this->type->contains_opaque())
147601e04c3fSmrg      return false;
147701e04c3fSmrg
147801e04c3fSmrg   return true;
147901e04c3fSmrg}
148001e04c3fSmrg
148101e04c3fSmrg
148201e04c3fSmrgstatic const char * const tex_opcode_strs[] = { "tex", "txb", "txl", "txd", "txf", "txf_ms", "txs", "lod", "tg4", "query_levels", "texture_samples", "samples_identical" };
148301e04c3fSmrg
148401e04c3fSmrgconst char *ir_texture::opcode_string()
148501e04c3fSmrg{
148601e04c3fSmrg   assert((unsigned int) op < ARRAY_SIZE(tex_opcode_strs));
148701e04c3fSmrg   return tex_opcode_strs[op];
148801e04c3fSmrg}
148901e04c3fSmrg
149001e04c3fSmrgir_texture_opcode
149101e04c3fSmrgir_texture::get_opcode(const char *str)
149201e04c3fSmrg{
149301e04c3fSmrg   const int count = sizeof(tex_opcode_strs) / sizeof(tex_opcode_strs[0]);
149401e04c3fSmrg   for (int op = 0; op < count; op++) {
149501e04c3fSmrg      if (strcmp(str, tex_opcode_strs[op]) == 0)
149601e04c3fSmrg	 return (ir_texture_opcode) op;
149701e04c3fSmrg   }
149801e04c3fSmrg   return (ir_texture_opcode) -1;
149901e04c3fSmrg}
150001e04c3fSmrg
150101e04c3fSmrg
150201e04c3fSmrgvoid
150301e04c3fSmrgir_texture::set_sampler(ir_dereference *sampler, const glsl_type *type)
150401e04c3fSmrg{
150501e04c3fSmrg   assert(sampler != NULL);
150601e04c3fSmrg   assert(type != NULL);
150701e04c3fSmrg   this->sampler = sampler;
150801e04c3fSmrg   this->type = type;
150901e04c3fSmrg
151001e04c3fSmrg   if (this->op == ir_txs || this->op == ir_query_levels ||
151101e04c3fSmrg       this->op == ir_texture_samples) {
151201e04c3fSmrg      assert(type->base_type == GLSL_TYPE_INT);
151301e04c3fSmrg   } else if (this->op == ir_lod) {
151401e04c3fSmrg      assert(type->vector_elements == 2);
151501e04c3fSmrg      assert(type->is_float());
151601e04c3fSmrg   } else if (this->op == ir_samples_identical) {
151701e04c3fSmrg      assert(type == glsl_type::bool_type);
151801e04c3fSmrg      assert(sampler->type->is_sampler());
151901e04c3fSmrg      assert(sampler->type->sampler_dimensionality == GLSL_SAMPLER_DIM_MS);
152001e04c3fSmrg   } else {
152101e04c3fSmrg      assert(sampler->type->sampled_type == (int) type->base_type);
152201e04c3fSmrg      if (sampler->type->sampler_shadow)
152301e04c3fSmrg	 assert(type->vector_elements == 4 || type->vector_elements == 1);
152401e04c3fSmrg      else
152501e04c3fSmrg	 assert(type->vector_elements == 4);
152601e04c3fSmrg   }
152701e04c3fSmrg}
152801e04c3fSmrg
152901e04c3fSmrg
153001e04c3fSmrgvoid
153101e04c3fSmrgir_swizzle::init_mask(const unsigned *comp, unsigned count)
153201e04c3fSmrg{
153301e04c3fSmrg   assert((count >= 1) && (count <= 4));
153401e04c3fSmrg
153501e04c3fSmrg   memset(&this->mask, 0, sizeof(this->mask));
153601e04c3fSmrg   this->mask.num_components = count;
153701e04c3fSmrg
153801e04c3fSmrg   unsigned dup_mask = 0;
153901e04c3fSmrg   switch (count) {
154001e04c3fSmrg   case 4:
154101e04c3fSmrg      assert(comp[3] <= 3);
154201e04c3fSmrg      dup_mask |= (1U << comp[3])
154301e04c3fSmrg	 & ((1U << comp[0]) | (1U << comp[1]) | (1U << comp[2]));
154401e04c3fSmrg      this->mask.w = comp[3];
154501e04c3fSmrg
154601e04c3fSmrg   case 3:
154701e04c3fSmrg      assert(comp[2] <= 3);
154801e04c3fSmrg      dup_mask |= (1U << comp[2])
154901e04c3fSmrg	 & ((1U << comp[0]) | (1U << comp[1]));
155001e04c3fSmrg      this->mask.z = comp[2];
155101e04c3fSmrg
155201e04c3fSmrg   case 2:
155301e04c3fSmrg      assert(comp[1] <= 3);
155401e04c3fSmrg      dup_mask |= (1U << comp[1])
155501e04c3fSmrg	 & ((1U << comp[0]));
155601e04c3fSmrg      this->mask.y = comp[1];
155701e04c3fSmrg
155801e04c3fSmrg   case 1:
155901e04c3fSmrg      assert(comp[0] <= 3);
156001e04c3fSmrg      this->mask.x = comp[0];
156101e04c3fSmrg   }
156201e04c3fSmrg
156301e04c3fSmrg   this->mask.has_duplicates = dup_mask != 0;
156401e04c3fSmrg
156501e04c3fSmrg   /* Based on the number of elements in the swizzle and the base type
156601e04c3fSmrg    * (i.e., float, int, unsigned, or bool) of the vector being swizzled,
156701e04c3fSmrg    * generate the type of the resulting value.
156801e04c3fSmrg    */
156901e04c3fSmrg   type = glsl_type::get_instance(val->type->base_type, mask.num_components, 1);
157001e04c3fSmrg}
157101e04c3fSmrg
157201e04c3fSmrgir_swizzle::ir_swizzle(ir_rvalue *val, unsigned x, unsigned y, unsigned z,
157301e04c3fSmrg		       unsigned w, unsigned count)
157401e04c3fSmrg   : ir_rvalue(ir_type_swizzle), val(val)
157501e04c3fSmrg{
157601e04c3fSmrg   const unsigned components[4] = { x, y, z, w };
157701e04c3fSmrg   this->init_mask(components, count);
157801e04c3fSmrg}
157901e04c3fSmrg
158001e04c3fSmrgir_swizzle::ir_swizzle(ir_rvalue *val, const unsigned *comp,
158101e04c3fSmrg		       unsigned count)
158201e04c3fSmrg   : ir_rvalue(ir_type_swizzle), val(val)
158301e04c3fSmrg{
158401e04c3fSmrg   this->init_mask(comp, count);
158501e04c3fSmrg}
158601e04c3fSmrg
158701e04c3fSmrgir_swizzle::ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask)
158801e04c3fSmrg   : ir_rvalue(ir_type_swizzle), val(val), mask(mask)
158901e04c3fSmrg{
159001e04c3fSmrg   this->type = glsl_type::get_instance(val->type->base_type,
159101e04c3fSmrg					mask.num_components, 1);
159201e04c3fSmrg}
159301e04c3fSmrg
159401e04c3fSmrg#define X 1
159501e04c3fSmrg#define R 5
159601e04c3fSmrg#define S 9
159701e04c3fSmrg#define I 13
159801e04c3fSmrg
159901e04c3fSmrgir_swizzle *
160001e04c3fSmrgir_swizzle::create(ir_rvalue *val, const char *str, unsigned vector_length)
160101e04c3fSmrg{
160201e04c3fSmrg   void *ctx = ralloc_parent(val);
160301e04c3fSmrg
160401e04c3fSmrg   /* For each possible swizzle character, this table encodes the value in
160501e04c3fSmrg    * \c idx_map that represents the 0th element of the vector.  For invalid
160601e04c3fSmrg    * swizzle characters (e.g., 'k'), a special value is used that will allow
160701e04c3fSmrg    * detection of errors.
160801e04c3fSmrg    */
160901e04c3fSmrg   static const unsigned char base_idx[26] = {
161001e04c3fSmrg   /* a  b  c  d  e  f  g  h  i  j  k  l  m */
161101e04c3fSmrg      R, R, I, I, I, I, R, I, I, I, I, I, I,
161201e04c3fSmrg   /* n  o  p  q  r  s  t  u  v  w  x  y  z */
161301e04c3fSmrg      I, I, S, S, R, S, S, I, I, X, X, X, X
161401e04c3fSmrg   };
161501e04c3fSmrg
161601e04c3fSmrg   /* Each valid swizzle character has an entry in the previous table.  This
161701e04c3fSmrg    * table encodes the base index encoded in the previous table plus the actual
161801e04c3fSmrg    * index of the swizzle character.  When processing swizzles, the first
161901e04c3fSmrg    * character in the string is indexed in the previous table.  Each character
162001e04c3fSmrg    * in the string is indexed in this table, and the value found there has the
162101e04c3fSmrg    * value form the first table subtracted.  The result must be on the range
162201e04c3fSmrg    * [0,3].
162301e04c3fSmrg    *
162401e04c3fSmrg    * For example, the string "wzyx" will get X from the first table.  Each of
162501e04c3fSmrg    * the charcaters will get X+3, X+2, X+1, and X+0 from this table.  After
162601e04c3fSmrg    * subtraction, the swizzle values are { 3, 2, 1, 0 }.
162701e04c3fSmrg    *
162801e04c3fSmrg    * The string "wzrg" will get X from the first table.  Each of the characters
162901e04c3fSmrg    * will get X+3, X+2, R+0, and R+1 from this table.  After subtraction, the
163001e04c3fSmrg    * swizzle values are { 3, 2, 4, 5 }.  Since 4 and 5 are outside the range
163101e04c3fSmrg    * [0,3], the error is detected.
163201e04c3fSmrg    */
163301e04c3fSmrg   static const unsigned char idx_map[26] = {
163401e04c3fSmrg   /* a    b    c    d    e    f    g    h    i    j    k    l    m */
163501e04c3fSmrg      R+3, R+2, 0,   0,   0,   0,   R+1, 0,   0,   0,   0,   0,   0,
163601e04c3fSmrg   /* n    o    p    q    r    s    t    u    v    w    x    y    z */
163701e04c3fSmrg      0,   0,   S+2, S+3, R+0, S+0, S+1, 0,   0,   X+3, X+0, X+1, X+2
163801e04c3fSmrg   };
163901e04c3fSmrg
164001e04c3fSmrg   int swiz_idx[4] = { 0, 0, 0, 0 };
164101e04c3fSmrg   unsigned i;
164201e04c3fSmrg
164301e04c3fSmrg
164401e04c3fSmrg   /* Validate the first character in the swizzle string and look up the base
164501e04c3fSmrg    * index value as described above.
164601e04c3fSmrg    */
164701e04c3fSmrg   if ((str[0] < 'a') || (str[0] > 'z'))
164801e04c3fSmrg      return NULL;
164901e04c3fSmrg
165001e04c3fSmrg   const unsigned base = base_idx[str[0] - 'a'];
165101e04c3fSmrg
165201e04c3fSmrg
165301e04c3fSmrg   for (i = 0; (i < 4) && (str[i] != '\0'); i++) {
165401e04c3fSmrg      /* Validate the next character, and, as described above, convert it to a
165501e04c3fSmrg       * swizzle index.
165601e04c3fSmrg       */
165701e04c3fSmrg      if ((str[i] < 'a') || (str[i] > 'z'))
165801e04c3fSmrg	 return NULL;
165901e04c3fSmrg
166001e04c3fSmrg      swiz_idx[i] = idx_map[str[i] - 'a'] - base;
166101e04c3fSmrg      if ((swiz_idx[i] < 0) || (swiz_idx[i] >= (int) vector_length))
166201e04c3fSmrg	 return NULL;
166301e04c3fSmrg   }
166401e04c3fSmrg
166501e04c3fSmrg   if (str[i] != '\0')
166601e04c3fSmrg	 return NULL;
166701e04c3fSmrg
166801e04c3fSmrg   return new(ctx) ir_swizzle(val, swiz_idx[0], swiz_idx[1], swiz_idx[2],
166901e04c3fSmrg			      swiz_idx[3], i);
167001e04c3fSmrg}
167101e04c3fSmrg
167201e04c3fSmrg#undef X
167301e04c3fSmrg#undef R
167401e04c3fSmrg#undef S
167501e04c3fSmrg#undef I
167601e04c3fSmrg
167701e04c3fSmrgir_variable *
167801e04c3fSmrgir_swizzle::variable_referenced() const
167901e04c3fSmrg{
168001e04c3fSmrg   return this->val->variable_referenced();
168101e04c3fSmrg}
168201e04c3fSmrg
168301e04c3fSmrg
168401e04c3fSmrgbool ir_variable::temporaries_allocate_names = false;
168501e04c3fSmrg
168601e04c3fSmrgconst char ir_variable::tmp_name[] = "compiler_temp";
168701e04c3fSmrg
168801e04c3fSmrgir_variable::ir_variable(const struct glsl_type *type, const char *name,
168901e04c3fSmrg			 ir_variable_mode mode)
169001e04c3fSmrg   : ir_instruction(ir_type_variable)
169101e04c3fSmrg{
169201e04c3fSmrg   this->type = type;
169301e04c3fSmrg
169401e04c3fSmrg   if (mode == ir_var_temporary && !ir_variable::temporaries_allocate_names)
169501e04c3fSmrg      name = NULL;
169601e04c3fSmrg
169701e04c3fSmrg   /* The ir_variable clone method may call this constructor with name set to
169801e04c3fSmrg    * tmp_name.
169901e04c3fSmrg    */
170001e04c3fSmrg   assert(name != NULL
170101e04c3fSmrg          || mode == ir_var_temporary
170201e04c3fSmrg          || mode == ir_var_function_in
170301e04c3fSmrg          || mode == ir_var_function_out
170401e04c3fSmrg          || mode == ir_var_function_inout);
170501e04c3fSmrg   assert(name != ir_variable::tmp_name
170601e04c3fSmrg          || mode == ir_var_temporary);
170701e04c3fSmrg   if (mode == ir_var_temporary
170801e04c3fSmrg       && (name == NULL || name == ir_variable::tmp_name)) {
170901e04c3fSmrg      this->name = ir_variable::tmp_name;
171001e04c3fSmrg   } else if (name == NULL ||
171101e04c3fSmrg              strlen(name) < ARRAY_SIZE(this->name_storage)) {
171201e04c3fSmrg      strcpy(this->name_storage, name ? name : "");
171301e04c3fSmrg      this->name = this->name_storage;
171401e04c3fSmrg   } else {
171501e04c3fSmrg      this->name = ralloc_strdup(this, name);
171601e04c3fSmrg   }
171701e04c3fSmrg
171801e04c3fSmrg   this->u.max_ifc_array_access = NULL;
171901e04c3fSmrg
172001e04c3fSmrg   this->data.explicit_location = false;
172101e04c3fSmrg   this->data.has_initializer = false;
172201e04c3fSmrg   this->data.location = -1;
172301e04c3fSmrg   this->data.location_frac = 0;
172401e04c3fSmrg   this->data.binding = 0;
172501e04c3fSmrg   this->data.warn_extension_index = 0;
172601e04c3fSmrg   this->constant_value = NULL;
172701e04c3fSmrg   this->constant_initializer = NULL;
172801e04c3fSmrg   this->data.origin_upper_left = false;
172901e04c3fSmrg   this->data.pixel_center_integer = false;
173001e04c3fSmrg   this->data.depth_layout = ir_depth_layout_none;
173101e04c3fSmrg   this->data.used = false;
173201e04c3fSmrg   this->data.always_active_io = false;
173301e04c3fSmrg   this->data.read_only = false;
173401e04c3fSmrg   this->data.centroid = false;
173501e04c3fSmrg   this->data.sample = false;
173601e04c3fSmrg   this->data.patch = false;
173701e04c3fSmrg   this->data.invariant = false;
173801e04c3fSmrg   this->data.how_declared = ir_var_declared_normally;
173901e04c3fSmrg   this->data.mode = mode;
174001e04c3fSmrg   this->data.interpolation = INTERP_MODE_NONE;
174101e04c3fSmrg   this->data.max_array_access = -1;
174201e04c3fSmrg   this->data.offset = 0;
174301e04c3fSmrg   this->data.precision = GLSL_PRECISION_NONE;
174401e04c3fSmrg   this->data.memory_read_only = false;
174501e04c3fSmrg   this->data.memory_write_only = false;
174601e04c3fSmrg   this->data.memory_coherent = false;
174701e04c3fSmrg   this->data.memory_volatile = false;
174801e04c3fSmrg   this->data.memory_restrict = false;
174901e04c3fSmrg   this->data.from_ssbo_unsized_array = false;
175001e04c3fSmrg   this->data.fb_fetch_output = false;
175101e04c3fSmrg   this->data.bindless = false;
175201e04c3fSmrg   this->data.bound = false;
175301e04c3fSmrg
175401e04c3fSmrg   if (type != NULL) {
175501e04c3fSmrg      if (type->is_interface())
175601e04c3fSmrg         this->init_interface_type(type);
175701e04c3fSmrg      else if (type->without_array()->is_interface())
175801e04c3fSmrg         this->init_interface_type(type->without_array());
175901e04c3fSmrg   }
176001e04c3fSmrg}
176101e04c3fSmrg
176201e04c3fSmrg
176301e04c3fSmrgconst char *
176401e04c3fSmrginterpolation_string(unsigned interpolation)
176501e04c3fSmrg{
176601e04c3fSmrg   switch (interpolation) {
176701e04c3fSmrg   case INTERP_MODE_NONE:          return "no";
176801e04c3fSmrg   case INTERP_MODE_SMOOTH:        return "smooth";
176901e04c3fSmrg   case INTERP_MODE_FLAT:          return "flat";
177001e04c3fSmrg   case INTERP_MODE_NOPERSPECTIVE: return "noperspective";
177101e04c3fSmrg   }
177201e04c3fSmrg
177301e04c3fSmrg   assert(!"Should not get here.");
177401e04c3fSmrg   return "";
177501e04c3fSmrg}
177601e04c3fSmrg
177701e04c3fSmrgconst char *const ir_variable::warn_extension_table[] = {
177801e04c3fSmrg   "",
177901e04c3fSmrg   "GL_ARB_shader_stencil_export",
178001e04c3fSmrg   "GL_AMD_shader_stencil_export",
178101e04c3fSmrg};
178201e04c3fSmrg
178301e04c3fSmrgvoid
178401e04c3fSmrgir_variable::enable_extension_warning(const char *extension)
178501e04c3fSmrg{
178601e04c3fSmrg   for (unsigned i = 0; i < ARRAY_SIZE(warn_extension_table); i++) {
178701e04c3fSmrg      if (strcmp(warn_extension_table[i], extension) == 0) {
178801e04c3fSmrg         this->data.warn_extension_index = i;
178901e04c3fSmrg         return;
179001e04c3fSmrg      }
179101e04c3fSmrg   }
179201e04c3fSmrg
179301e04c3fSmrg   assert(!"Should not get here.");
179401e04c3fSmrg   this->data.warn_extension_index = 0;
179501e04c3fSmrg}
179601e04c3fSmrg
179701e04c3fSmrgconst char *
179801e04c3fSmrgir_variable::get_extension_warning() const
179901e04c3fSmrg{
180001e04c3fSmrg   return this->data.warn_extension_index == 0
180101e04c3fSmrg      ? NULL : warn_extension_table[this->data.warn_extension_index];
180201e04c3fSmrg}
180301e04c3fSmrg
180401e04c3fSmrgir_function_signature::ir_function_signature(const glsl_type *return_type,
180501e04c3fSmrg                                             builtin_available_predicate b)
180601e04c3fSmrg   : ir_instruction(ir_type_function_signature),
180701e04c3fSmrg     return_type(return_type), is_defined(false),
180801e04c3fSmrg     intrinsic_id(ir_intrinsic_invalid), builtin_avail(b), _function(NULL)
180901e04c3fSmrg{
181001e04c3fSmrg   this->origin = NULL;
181101e04c3fSmrg}
181201e04c3fSmrg
181301e04c3fSmrg
181401e04c3fSmrgbool
181501e04c3fSmrgir_function_signature::is_builtin() const
181601e04c3fSmrg{
181701e04c3fSmrg   return builtin_avail != NULL;
181801e04c3fSmrg}
181901e04c3fSmrg
182001e04c3fSmrg
182101e04c3fSmrgbool
182201e04c3fSmrgir_function_signature::is_builtin_available(const _mesa_glsl_parse_state *state) const
182301e04c3fSmrg{
182401e04c3fSmrg   /* We can't call the predicate without a state pointer, so just say that
182501e04c3fSmrg    * the signature is available.  At compile time, we need the filtering,
182601e04c3fSmrg    * but also receive a valid state pointer.  At link time, we're resolving
182701e04c3fSmrg    * imported built-in prototypes to their definitions, which will always
182801e04c3fSmrg    * be an exact match.  So we can skip the filtering.
182901e04c3fSmrg    */
183001e04c3fSmrg   if (state == NULL)
183101e04c3fSmrg      return true;
183201e04c3fSmrg
183301e04c3fSmrg   assert(builtin_avail != NULL);
183401e04c3fSmrg   return builtin_avail(state);
183501e04c3fSmrg}
183601e04c3fSmrg
183701e04c3fSmrg
183801e04c3fSmrgstatic bool
183901e04c3fSmrgmodes_match(unsigned a, unsigned b)
184001e04c3fSmrg{
184101e04c3fSmrg   if (a == b)
184201e04c3fSmrg      return true;
184301e04c3fSmrg
184401e04c3fSmrg   /* Accept "in" vs. "const in" */
184501e04c3fSmrg   if ((a == ir_var_const_in && b == ir_var_function_in) ||
184601e04c3fSmrg       (b == ir_var_const_in && a == ir_var_function_in))
184701e04c3fSmrg      return true;
184801e04c3fSmrg
184901e04c3fSmrg   return false;
185001e04c3fSmrg}
185101e04c3fSmrg
185201e04c3fSmrg
185301e04c3fSmrgconst char *
185401e04c3fSmrgir_function_signature::qualifiers_match(exec_list *params)
185501e04c3fSmrg{
185601e04c3fSmrg   /* check that the qualifiers match. */
185701e04c3fSmrg   foreach_two_lists(a_node, &this->parameters, b_node, params) {
185801e04c3fSmrg      ir_variable *a = (ir_variable *) a_node;
185901e04c3fSmrg      ir_variable *b = (ir_variable *) b_node;
186001e04c3fSmrg
186101e04c3fSmrg      if (a->data.read_only != b->data.read_only ||
186201e04c3fSmrg	  !modes_match(a->data.mode, b->data.mode) ||
186301e04c3fSmrg	  a->data.interpolation != b->data.interpolation ||
186401e04c3fSmrg	  a->data.centroid != b->data.centroid ||
186501e04c3fSmrg          a->data.sample != b->data.sample ||
186601e04c3fSmrg          a->data.patch != b->data.patch ||
186701e04c3fSmrg          a->data.memory_read_only != b->data.memory_read_only ||
186801e04c3fSmrg          a->data.memory_write_only != b->data.memory_write_only ||
186901e04c3fSmrg          a->data.memory_coherent != b->data.memory_coherent ||
187001e04c3fSmrg          a->data.memory_volatile != b->data.memory_volatile ||
187101e04c3fSmrg          a->data.memory_restrict != b->data.memory_restrict) {
187201e04c3fSmrg
187301e04c3fSmrg	 /* parameter a's qualifiers don't match */
187401e04c3fSmrg	 return a->name;
187501e04c3fSmrg      }
187601e04c3fSmrg   }
187701e04c3fSmrg   return NULL;
187801e04c3fSmrg}
187901e04c3fSmrg
188001e04c3fSmrg
188101e04c3fSmrgvoid
188201e04c3fSmrgir_function_signature::replace_parameters(exec_list *new_params)
188301e04c3fSmrg{
188401e04c3fSmrg   /* Destroy all of the previous parameter information.  If the previous
188501e04c3fSmrg    * parameter information comes from the function prototype, it may either
188601e04c3fSmrg    * specify incorrect parameter names or not have names at all.
188701e04c3fSmrg    */
188801e04c3fSmrg   new_params->move_nodes_to(&parameters);
188901e04c3fSmrg}
189001e04c3fSmrg
189101e04c3fSmrg
189201e04c3fSmrgir_function::ir_function(const char *name)
189301e04c3fSmrg   : ir_instruction(ir_type_function)
189401e04c3fSmrg{
189501e04c3fSmrg   this->subroutine_index = -1;
189601e04c3fSmrg   this->name = ralloc_strdup(this, name);
189701e04c3fSmrg}
189801e04c3fSmrg
189901e04c3fSmrg
190001e04c3fSmrgbool
190101e04c3fSmrgir_function::has_user_signature()
190201e04c3fSmrg{
190301e04c3fSmrg   foreach_in_list(ir_function_signature, sig, &this->signatures) {
190401e04c3fSmrg      if (!sig->is_builtin())
190501e04c3fSmrg	 return true;
190601e04c3fSmrg   }
190701e04c3fSmrg   return false;
190801e04c3fSmrg}
190901e04c3fSmrg
191001e04c3fSmrg
191101e04c3fSmrgir_rvalue *
191201e04c3fSmrgir_rvalue::error_value(void *mem_ctx)
191301e04c3fSmrg{
191401e04c3fSmrg   ir_rvalue *v = new(mem_ctx) ir_rvalue(ir_type_unset);
191501e04c3fSmrg
191601e04c3fSmrg   v->type = glsl_type::error_type;
191701e04c3fSmrg   return v;
191801e04c3fSmrg}
191901e04c3fSmrg
192001e04c3fSmrg
192101e04c3fSmrgvoid
192201e04c3fSmrgvisit_exec_list(exec_list *list, ir_visitor *visitor)
192301e04c3fSmrg{
192401e04c3fSmrg   foreach_in_list_safe(ir_instruction, node, list) {
192501e04c3fSmrg      node->accept(visitor);
192601e04c3fSmrg   }
192701e04c3fSmrg}
192801e04c3fSmrg
192901e04c3fSmrg
193001e04c3fSmrgstatic void
193101e04c3fSmrgsteal_memory(ir_instruction *ir, void *new_ctx)
193201e04c3fSmrg{
193301e04c3fSmrg   ir_variable *var = ir->as_variable();
193401e04c3fSmrg   ir_function *fn = ir->as_function();
193501e04c3fSmrg   ir_constant *constant = ir->as_constant();
193601e04c3fSmrg   if (var != NULL && var->constant_value != NULL)
193701e04c3fSmrg      steal_memory(var->constant_value, ir);
193801e04c3fSmrg
193901e04c3fSmrg   if (var != NULL && var->constant_initializer != NULL)
194001e04c3fSmrg      steal_memory(var->constant_initializer, ir);
194101e04c3fSmrg
194201e04c3fSmrg   if (fn != NULL && fn->subroutine_types)
194301e04c3fSmrg      ralloc_steal(new_ctx, fn->subroutine_types);
194401e04c3fSmrg
194501e04c3fSmrg   /* The components of aggregate constants are not visited by the normal
194601e04c3fSmrg    * visitor, so steal their values by hand.
194701e04c3fSmrg    */
194801e04c3fSmrg   if (constant != NULL &&
194901e04c3fSmrg       (constant->type->is_array() || constant->type->is_record())) {
195001e04c3fSmrg      for (unsigned int i = 0; i < constant->type->length; i++) {
195101e04c3fSmrg         steal_memory(constant->const_elements[i], ir);
195201e04c3fSmrg      }
195301e04c3fSmrg   }
195401e04c3fSmrg
195501e04c3fSmrg   ralloc_steal(new_ctx, ir);
195601e04c3fSmrg}
195701e04c3fSmrg
195801e04c3fSmrg
195901e04c3fSmrgvoid
196001e04c3fSmrgreparent_ir(exec_list *list, void *mem_ctx)
196101e04c3fSmrg{
196201e04c3fSmrg   foreach_in_list(ir_instruction, node, list) {
196301e04c3fSmrg      visit_tree(node, steal_memory, mem_ctx);
196401e04c3fSmrg   }
196501e04c3fSmrg}
196601e04c3fSmrg
196701e04c3fSmrg
196801e04c3fSmrgstatic ir_rvalue *
196901e04c3fSmrgtry_min_one(ir_rvalue *ir)
197001e04c3fSmrg{
197101e04c3fSmrg   ir_expression *expr = ir->as_expression();
197201e04c3fSmrg
197301e04c3fSmrg   if (!expr || expr->operation != ir_binop_min)
197401e04c3fSmrg      return NULL;
197501e04c3fSmrg
197601e04c3fSmrg   if (expr->operands[0]->is_one())
197701e04c3fSmrg      return expr->operands[1];
197801e04c3fSmrg
197901e04c3fSmrg   if (expr->operands[1]->is_one())
198001e04c3fSmrg      return expr->operands[0];
198101e04c3fSmrg
198201e04c3fSmrg   return NULL;
198301e04c3fSmrg}
198401e04c3fSmrg
198501e04c3fSmrgstatic ir_rvalue *
198601e04c3fSmrgtry_max_zero(ir_rvalue *ir)
198701e04c3fSmrg{
198801e04c3fSmrg   ir_expression *expr = ir->as_expression();
198901e04c3fSmrg
199001e04c3fSmrg   if (!expr || expr->operation != ir_binop_max)
199101e04c3fSmrg      return NULL;
199201e04c3fSmrg
199301e04c3fSmrg   if (expr->operands[0]->is_zero())
199401e04c3fSmrg      return expr->operands[1];
199501e04c3fSmrg
199601e04c3fSmrg   if (expr->operands[1]->is_zero())
199701e04c3fSmrg      return expr->operands[0];
199801e04c3fSmrg
199901e04c3fSmrg   return NULL;
200001e04c3fSmrg}
200101e04c3fSmrg
200201e04c3fSmrgir_rvalue *
200301e04c3fSmrgir_rvalue::as_rvalue_to_saturate()
200401e04c3fSmrg{
200501e04c3fSmrg   ir_expression *expr = this->as_expression();
200601e04c3fSmrg
200701e04c3fSmrg   if (!expr)
200801e04c3fSmrg      return NULL;
200901e04c3fSmrg
201001e04c3fSmrg   ir_rvalue *max_zero = try_max_zero(expr);
201101e04c3fSmrg   if (max_zero) {
201201e04c3fSmrg      return try_min_one(max_zero);
201301e04c3fSmrg   } else {
201401e04c3fSmrg      ir_rvalue *min_one = try_min_one(expr);
201501e04c3fSmrg      if (min_one) {
201601e04c3fSmrg	 return try_max_zero(min_one);
201701e04c3fSmrg      }
201801e04c3fSmrg   }
201901e04c3fSmrg
202001e04c3fSmrg   return NULL;
202101e04c3fSmrg}
202201e04c3fSmrg
202301e04c3fSmrg
202401e04c3fSmrgunsigned
202501e04c3fSmrgvertices_per_prim(GLenum prim)
202601e04c3fSmrg{
202701e04c3fSmrg   switch (prim) {
202801e04c3fSmrg   case GL_POINTS:
202901e04c3fSmrg      return 1;
203001e04c3fSmrg   case GL_LINES:
203101e04c3fSmrg      return 2;
203201e04c3fSmrg   case GL_TRIANGLES:
203301e04c3fSmrg      return 3;
203401e04c3fSmrg   case GL_LINES_ADJACENCY:
203501e04c3fSmrg      return 4;
203601e04c3fSmrg   case GL_TRIANGLES_ADJACENCY:
203701e04c3fSmrg      return 6;
203801e04c3fSmrg   default:
203901e04c3fSmrg      assert(!"Bad primitive");
204001e04c3fSmrg      return 3;
204101e04c3fSmrg   }
204201e04c3fSmrg}
204301e04c3fSmrg
204401e04c3fSmrg/**
204501e04c3fSmrg * Generate a string describing the mode of a variable
204601e04c3fSmrg */
204701e04c3fSmrgconst char *
204801e04c3fSmrgmode_string(const ir_variable *var)
204901e04c3fSmrg{
205001e04c3fSmrg   switch (var->data.mode) {
205101e04c3fSmrg   case ir_var_auto:
205201e04c3fSmrg      return (var->data.read_only) ? "global constant" : "global variable";
205301e04c3fSmrg
205401e04c3fSmrg   case ir_var_uniform:
205501e04c3fSmrg      return "uniform";
205601e04c3fSmrg
205701e04c3fSmrg   case ir_var_shader_storage:
205801e04c3fSmrg      return "buffer";
205901e04c3fSmrg
206001e04c3fSmrg   case ir_var_shader_in:
206101e04c3fSmrg      return "shader input";
206201e04c3fSmrg
206301e04c3fSmrg   case ir_var_shader_out:
206401e04c3fSmrg      return "shader output";
206501e04c3fSmrg
206601e04c3fSmrg   case ir_var_function_in:
206701e04c3fSmrg   case ir_var_const_in:
206801e04c3fSmrg      return "function input";
206901e04c3fSmrg
207001e04c3fSmrg   case ir_var_function_out:
207101e04c3fSmrg      return "function output";
207201e04c3fSmrg
207301e04c3fSmrg   case ir_var_function_inout:
207401e04c3fSmrg      return "function inout";
207501e04c3fSmrg
207601e04c3fSmrg   case ir_var_system_value:
207701e04c3fSmrg      return "shader input";
207801e04c3fSmrg
207901e04c3fSmrg   case ir_var_temporary:
208001e04c3fSmrg      return "compiler temporary";
208101e04c3fSmrg
208201e04c3fSmrg   case ir_var_mode_count:
208301e04c3fSmrg      break;
208401e04c3fSmrg   }
208501e04c3fSmrg
208601e04c3fSmrg   assert(!"Should not get here.");
208701e04c3fSmrg   return "invalid variable";
208801e04c3fSmrg}
2089