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"
257ec681f3Smrg#include "util/half_float.h"
2601e04c3fSmrg#include "compiler/glsl_types.h"
2701e04c3fSmrg#include "glsl_parser_extras.h"
2801e04c3fSmrg
2901e04c3fSmrg
3001e04c3fSmrgir_rvalue::ir_rvalue(enum ir_node_type t)
3101e04c3fSmrg   : ir_instruction(t)
3201e04c3fSmrg{
3301e04c3fSmrg   this->type = glsl_type::error_type;
3401e04c3fSmrg}
3501e04c3fSmrg
3601e04c3fSmrgbool ir_rvalue::is_zero() const
3701e04c3fSmrg{
3801e04c3fSmrg   return false;
3901e04c3fSmrg}
4001e04c3fSmrg
4101e04c3fSmrgbool ir_rvalue::is_one() const
4201e04c3fSmrg{
4301e04c3fSmrg   return false;
4401e04c3fSmrg}
4501e04c3fSmrg
4601e04c3fSmrgbool ir_rvalue::is_negative_one() const
4701e04c3fSmrg{
4801e04c3fSmrg   return false;
4901e04c3fSmrg}
5001e04c3fSmrg
5101e04c3fSmrg/**
5201e04c3fSmrg * Modify the swizzle make to move one component to another
5301e04c3fSmrg *
5401e04c3fSmrg * \param m    IR swizzle to be modified
5501e04c3fSmrg * \param from Component in the RHS that is to be swizzled
5601e04c3fSmrg * \param to   Desired swizzle location of \c from
5701e04c3fSmrg */
5801e04c3fSmrgstatic void
5901e04c3fSmrgupdate_rhs_swizzle(ir_swizzle_mask &m, unsigned from, unsigned to)
6001e04c3fSmrg{
6101e04c3fSmrg   switch (to) {
6201e04c3fSmrg   case 0: m.x = from; break;
6301e04c3fSmrg   case 1: m.y = from; break;
6401e04c3fSmrg   case 2: m.z = from; break;
6501e04c3fSmrg   case 3: m.w = from; break;
6601e04c3fSmrg   default: assert(!"Should not get here.");
6701e04c3fSmrg   }
6801e04c3fSmrg}
6901e04c3fSmrg
7001e04c3fSmrgvoid
7101e04c3fSmrgir_assignment::set_lhs(ir_rvalue *lhs)
7201e04c3fSmrg{
7301e04c3fSmrg   void *mem_ctx = this;
7401e04c3fSmrg   bool swizzled = false;
7501e04c3fSmrg
7601e04c3fSmrg   while (lhs != NULL) {
7701e04c3fSmrg      ir_swizzle *swiz = lhs->as_swizzle();
7801e04c3fSmrg
7901e04c3fSmrg      if (swiz == NULL)
8001e04c3fSmrg	 break;
8101e04c3fSmrg
8201e04c3fSmrg      unsigned write_mask = 0;
8301e04c3fSmrg      ir_swizzle_mask rhs_swiz = { 0, 0, 0, 0, 0, 0 };
8401e04c3fSmrg
8501e04c3fSmrg      for (unsigned i = 0; i < swiz->mask.num_components; i++) {
8601e04c3fSmrg	 unsigned c = 0;
8701e04c3fSmrg
8801e04c3fSmrg	 switch (i) {
8901e04c3fSmrg	 case 0: c = swiz->mask.x; break;
9001e04c3fSmrg	 case 1: c = swiz->mask.y; break;
9101e04c3fSmrg	 case 2: c = swiz->mask.z; break;
9201e04c3fSmrg	 case 3: c = swiz->mask.w; break;
9301e04c3fSmrg	 default: assert(!"Should not get here.");
9401e04c3fSmrg	 }
9501e04c3fSmrg
9601e04c3fSmrg	 write_mask |= (((this->write_mask >> i) & 1) << c);
9701e04c3fSmrg	 update_rhs_swizzle(rhs_swiz, i, c);
9801e04c3fSmrg         rhs_swiz.num_components = swiz->val->type->vector_elements;
9901e04c3fSmrg      }
10001e04c3fSmrg
10101e04c3fSmrg      this->write_mask = write_mask;
10201e04c3fSmrg      lhs = swiz->val;
10301e04c3fSmrg
10401e04c3fSmrg      this->rhs = new(mem_ctx) ir_swizzle(this->rhs, rhs_swiz);
10501e04c3fSmrg      swizzled = true;
10601e04c3fSmrg   }
10701e04c3fSmrg
10801e04c3fSmrg   if (swizzled) {
10901e04c3fSmrg      /* Now, RHS channels line up with the LHS writemask.  Collapse it
11001e04c3fSmrg       * to just the channels that will be written.
11101e04c3fSmrg       */
11201e04c3fSmrg      ir_swizzle_mask rhs_swiz = { 0, 0, 0, 0, 0, 0 };
11301e04c3fSmrg      int rhs_chan = 0;
11401e04c3fSmrg      for (int i = 0; i < 4; i++) {
11501e04c3fSmrg	 if (write_mask & (1 << i))
11601e04c3fSmrg	    update_rhs_swizzle(rhs_swiz, i, rhs_chan++);
11701e04c3fSmrg      }
11801e04c3fSmrg      rhs_swiz.num_components = rhs_chan;
11901e04c3fSmrg      this->rhs = new(mem_ctx) ir_swizzle(this->rhs, rhs_swiz);
12001e04c3fSmrg   }
12101e04c3fSmrg
12201e04c3fSmrg   assert((lhs == NULL) || lhs->as_dereference());
12301e04c3fSmrg
12401e04c3fSmrg   this->lhs = (ir_dereference *) lhs;
12501e04c3fSmrg}
12601e04c3fSmrg
12701e04c3fSmrgir_variable *
12801e04c3fSmrgir_assignment::whole_variable_written()
12901e04c3fSmrg{
13001e04c3fSmrg   ir_variable *v = this->lhs->whole_variable_referenced();
13101e04c3fSmrg
13201e04c3fSmrg   if (v == NULL)
13301e04c3fSmrg      return NULL;
13401e04c3fSmrg
13501e04c3fSmrg   if (v->type->is_scalar())
13601e04c3fSmrg      return v;
13701e04c3fSmrg
13801e04c3fSmrg   if (v->type->is_vector()) {
13901e04c3fSmrg      const unsigned mask = (1U << v->type->vector_elements) - 1;
14001e04c3fSmrg
14101e04c3fSmrg      if (mask != this->write_mask)
14201e04c3fSmrg	 return NULL;
14301e04c3fSmrg   }
14401e04c3fSmrg
14501e04c3fSmrg   /* Either all the vector components are assigned or the variable is some
14601e04c3fSmrg    * composite type (and the whole thing is assigned.
14701e04c3fSmrg    */
14801e04c3fSmrg   return v;
14901e04c3fSmrg}
15001e04c3fSmrg
15101e04c3fSmrgir_assignment::ir_assignment(ir_dereference *lhs, ir_rvalue *rhs,
15201e04c3fSmrg			     ir_rvalue *condition, unsigned write_mask)
15301e04c3fSmrg   : ir_instruction(ir_type_assignment)
15401e04c3fSmrg{
15501e04c3fSmrg   this->condition = condition;
15601e04c3fSmrg   this->rhs = rhs;
15701e04c3fSmrg   this->lhs = lhs;
15801e04c3fSmrg   this->write_mask = write_mask;
15901e04c3fSmrg
16001e04c3fSmrg   if (lhs->type->is_scalar() || lhs->type->is_vector()) {
16101e04c3fSmrg      int lhs_components = 0;
16201e04c3fSmrg      for (int i = 0; i < 4; i++) {
16301e04c3fSmrg	 if (write_mask & (1 << i))
16401e04c3fSmrg	    lhs_components++;
16501e04c3fSmrg      }
16601e04c3fSmrg
16701e04c3fSmrg      assert(lhs_components == this->rhs->type->vector_elements);
16801e04c3fSmrg   }
16901e04c3fSmrg}
17001e04c3fSmrg
17101e04c3fSmrgir_assignment::ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs,
17201e04c3fSmrg			     ir_rvalue *condition)
17301e04c3fSmrg   : ir_instruction(ir_type_assignment)
17401e04c3fSmrg{
17501e04c3fSmrg   this->condition = condition;
17601e04c3fSmrg   this->rhs = rhs;
17701e04c3fSmrg
17801e04c3fSmrg   /* If the RHS is a vector type, assume that all components of the vector
17901e04c3fSmrg    * type are being written to the LHS.  The write mask comes from the RHS
18001e04c3fSmrg    * because we can have a case where the LHS is a vec4 and the RHS is a
18101e04c3fSmrg    * vec3.  In that case, the assignment is:
18201e04c3fSmrg    *
18301e04c3fSmrg    *     (assign (...) (xyz) (var_ref lhs) (var_ref rhs))
18401e04c3fSmrg    */
18501e04c3fSmrg   if (rhs->type->is_vector())
18601e04c3fSmrg      this->write_mask = (1U << rhs->type->vector_elements) - 1;
18701e04c3fSmrg   else if (rhs->type->is_scalar())
18801e04c3fSmrg      this->write_mask = 1;
18901e04c3fSmrg   else
19001e04c3fSmrg      this->write_mask = 0;
19101e04c3fSmrg
19201e04c3fSmrg   this->set_lhs(lhs);
19301e04c3fSmrg}
19401e04c3fSmrg
19501e04c3fSmrgir_expression::ir_expression(int op, const struct glsl_type *type,
19601e04c3fSmrg			     ir_rvalue *op0, ir_rvalue *op1,
19701e04c3fSmrg			     ir_rvalue *op2, ir_rvalue *op3)
19801e04c3fSmrg   : ir_rvalue(ir_type_expression)
19901e04c3fSmrg{
20001e04c3fSmrg   this->type = type;
20101e04c3fSmrg   this->operation = ir_expression_operation(op);
20201e04c3fSmrg   this->operands[0] = op0;
20301e04c3fSmrg   this->operands[1] = op1;
20401e04c3fSmrg   this->operands[2] = op2;
20501e04c3fSmrg   this->operands[3] = op3;
20601e04c3fSmrg   init_num_operands();
20701e04c3fSmrg
20801e04c3fSmrg#ifndef NDEBUG
20901e04c3fSmrg   for (unsigned i = num_operands; i < 4; i++) {
21001e04c3fSmrg      assert(this->operands[i] == NULL);
21101e04c3fSmrg   }
21201e04c3fSmrg
21301e04c3fSmrg   for (unsigned i = 0; i < num_operands; i++) {
21401e04c3fSmrg      assert(this->operands[i] != NULL);
21501e04c3fSmrg   }
21601e04c3fSmrg#endif
21701e04c3fSmrg}
21801e04c3fSmrg
21901e04c3fSmrgir_expression::ir_expression(int op, ir_rvalue *op0)
22001e04c3fSmrg   : ir_rvalue(ir_type_expression)
22101e04c3fSmrg{
22201e04c3fSmrg   this->operation = ir_expression_operation(op);
22301e04c3fSmrg   this->operands[0] = op0;
22401e04c3fSmrg   this->operands[1] = NULL;
22501e04c3fSmrg   this->operands[2] = NULL;
22601e04c3fSmrg   this->operands[3] = NULL;
22701e04c3fSmrg
22801e04c3fSmrg   assert(op <= ir_last_unop);
22901e04c3fSmrg   init_num_operands();
23001e04c3fSmrg   assert(num_operands == 1);
23101e04c3fSmrg   assert(this->operands[0]);
23201e04c3fSmrg
23301e04c3fSmrg   switch (this->operation) {
23401e04c3fSmrg   case ir_unop_bit_not:
23501e04c3fSmrg   case ir_unop_logic_not:
23601e04c3fSmrg   case ir_unop_neg:
23701e04c3fSmrg   case ir_unop_abs:
23801e04c3fSmrg   case ir_unop_sign:
23901e04c3fSmrg   case ir_unop_rcp:
24001e04c3fSmrg   case ir_unop_rsq:
24101e04c3fSmrg   case ir_unop_sqrt:
24201e04c3fSmrg   case ir_unop_exp:
24301e04c3fSmrg   case ir_unop_log:
24401e04c3fSmrg   case ir_unop_exp2:
24501e04c3fSmrg   case ir_unop_log2:
24601e04c3fSmrg   case ir_unop_trunc:
24701e04c3fSmrg   case ir_unop_ceil:
24801e04c3fSmrg   case ir_unop_floor:
24901e04c3fSmrg   case ir_unop_fract:
25001e04c3fSmrg   case ir_unop_round_even:
25101e04c3fSmrg   case ir_unop_sin:
25201e04c3fSmrg   case ir_unop_cos:
25301e04c3fSmrg   case ir_unop_dFdx:
25401e04c3fSmrg   case ir_unop_dFdx_coarse:
25501e04c3fSmrg   case ir_unop_dFdx_fine:
25601e04c3fSmrg   case ir_unop_dFdy:
25701e04c3fSmrg   case ir_unop_dFdy_coarse:
25801e04c3fSmrg   case ir_unop_dFdy_fine:
25901e04c3fSmrg   case ir_unop_bitfield_reverse:
26001e04c3fSmrg   case ir_unop_interpolate_at_centroid:
2617ec681f3Smrg   case ir_unop_clz:
26201e04c3fSmrg   case ir_unop_saturate:
2637ec681f3Smrg   case ir_unop_atan:
26401e04c3fSmrg      this->type = op0->type;
26501e04c3fSmrg      break;
26601e04c3fSmrg
26701e04c3fSmrg   case ir_unop_f2i:
26801e04c3fSmrg   case ir_unop_b2i:
26901e04c3fSmrg   case ir_unop_u2i:
27001e04c3fSmrg   case ir_unop_d2i:
27101e04c3fSmrg   case ir_unop_bitcast_f2i:
27201e04c3fSmrg   case ir_unop_bit_count:
27301e04c3fSmrg   case ir_unop_find_msb:
27401e04c3fSmrg   case ir_unop_find_lsb:
27501e04c3fSmrg   case ir_unop_subroutine_to_int:
27601e04c3fSmrg   case ir_unop_i642i:
27701e04c3fSmrg   case ir_unop_u642i:
27801e04c3fSmrg      this->type = glsl_type::get_instance(GLSL_TYPE_INT,
27901e04c3fSmrg					   op0->type->vector_elements, 1);
28001e04c3fSmrg      break;
28101e04c3fSmrg
28201e04c3fSmrg   case ir_unop_b2f:
28301e04c3fSmrg   case ir_unop_i2f:
28401e04c3fSmrg   case ir_unop_u2f:
28501e04c3fSmrg   case ir_unop_d2f:
2867ec681f3Smrg   case ir_unop_f162f:
28701e04c3fSmrg   case ir_unop_bitcast_i2f:
28801e04c3fSmrg   case ir_unop_bitcast_u2f:
28901e04c3fSmrg   case ir_unop_i642f:
29001e04c3fSmrg   case ir_unop_u642f:
29101e04c3fSmrg      this->type = glsl_type::get_instance(GLSL_TYPE_FLOAT,
29201e04c3fSmrg					   op0->type->vector_elements, 1);
29301e04c3fSmrg      break;
29401e04c3fSmrg
2957ec681f3Smrg   case ir_unop_f2f16:
2967ec681f3Smrg   case ir_unop_f2fmp:
2977ec681f3Smrg   case ir_unop_b2f16:
2987ec681f3Smrg      this->type = glsl_type::get_instance(GLSL_TYPE_FLOAT16,
2997ec681f3Smrg					   op0->type->vector_elements, 1);
3007ec681f3Smrg      break;
3017ec681f3Smrg
3027ec681f3Smrg   case ir_unop_i2imp:
3037ec681f3Smrg      this->type = glsl_type::get_instance(GLSL_TYPE_INT16,
3047ec681f3Smrg					   op0->type->vector_elements, 1);
3057ec681f3Smrg      break;
3067ec681f3Smrg
3077ec681f3Smrg   case ir_unop_i2i:
3087ec681f3Smrg      if (op0->type->base_type == GLSL_TYPE_INT) {
3097ec681f3Smrg         this->type = glsl_type::get_instance(GLSL_TYPE_INT16,
3107ec681f3Smrg                                              op0->type->vector_elements, 1);
3117ec681f3Smrg      } else {
3127ec681f3Smrg         assert(op0->type->base_type == GLSL_TYPE_INT16);
3137ec681f3Smrg         this->type = glsl_type::get_instance(GLSL_TYPE_INT,
3147ec681f3Smrg                                              op0->type->vector_elements, 1);
3157ec681f3Smrg      }
3167ec681f3Smrg      break;
3177ec681f3Smrg
3187ec681f3Smrg   case ir_unop_u2u:
3197ec681f3Smrg      if (op0->type->base_type == GLSL_TYPE_UINT) {
3207ec681f3Smrg         this->type = glsl_type::get_instance(GLSL_TYPE_UINT16,
3217ec681f3Smrg                                              op0->type->vector_elements, 1);
3227ec681f3Smrg      } else {
3237ec681f3Smrg         assert(op0->type->base_type == GLSL_TYPE_UINT16);
3247ec681f3Smrg         this->type = glsl_type::get_instance(GLSL_TYPE_UINT,
3257ec681f3Smrg                                              op0->type->vector_elements, 1);
3267ec681f3Smrg      }
3277ec681f3Smrg      break;
3287ec681f3Smrg
3297ec681f3Smrg   case ir_unop_u2ump:
3307ec681f3Smrg      this->type = glsl_type::get_instance(GLSL_TYPE_UINT16,
3317ec681f3Smrg					   op0->type->vector_elements, 1);
3327ec681f3Smrg      break;
3337ec681f3Smrg
33401e04c3fSmrg   case ir_unop_f2b:
33501e04c3fSmrg   case ir_unop_i2b:
33601e04c3fSmrg   case ir_unop_d2b:
3377ec681f3Smrg   case ir_unop_f162b:
33801e04c3fSmrg   case ir_unop_i642b:
33901e04c3fSmrg      this->type = glsl_type::get_instance(GLSL_TYPE_BOOL,
34001e04c3fSmrg					   op0->type->vector_elements, 1);
34101e04c3fSmrg      break;
34201e04c3fSmrg
34301e04c3fSmrg   case ir_unop_f2d:
34401e04c3fSmrg   case ir_unop_i2d:
34501e04c3fSmrg   case ir_unop_u2d:
34601e04c3fSmrg   case ir_unop_i642d:
34701e04c3fSmrg   case ir_unop_u642d:
34801e04c3fSmrg      this->type = glsl_type::get_instance(GLSL_TYPE_DOUBLE,
34901e04c3fSmrg					   op0->type->vector_elements, 1);
35001e04c3fSmrg      break;
35101e04c3fSmrg
35201e04c3fSmrg   case ir_unop_i2u:
35301e04c3fSmrg   case ir_unop_f2u:
35401e04c3fSmrg   case ir_unop_d2u:
35501e04c3fSmrg   case ir_unop_bitcast_f2u:
35601e04c3fSmrg   case ir_unop_i642u:
35701e04c3fSmrg   case ir_unop_u642u:
35801e04c3fSmrg      this->type = glsl_type::get_instance(GLSL_TYPE_UINT,
35901e04c3fSmrg					   op0->type->vector_elements, 1);
36001e04c3fSmrg      break;
36101e04c3fSmrg
36201e04c3fSmrg   case ir_unop_i2i64:
36301e04c3fSmrg   case ir_unop_u2i64:
36401e04c3fSmrg   case ir_unop_b2i64:
36501e04c3fSmrg   case ir_unop_f2i64:
36601e04c3fSmrg   case ir_unop_d2i64:
36701e04c3fSmrg   case ir_unop_u642i64:
36801e04c3fSmrg      this->type = glsl_type::get_instance(GLSL_TYPE_INT64,
36901e04c3fSmrg					   op0->type->vector_elements, 1);
37001e04c3fSmrg      break;
37101e04c3fSmrg
37201e04c3fSmrg   case ir_unop_i2u64:
37301e04c3fSmrg   case ir_unop_u2u64:
37401e04c3fSmrg   case ir_unop_f2u64:
37501e04c3fSmrg   case ir_unop_d2u64:
37601e04c3fSmrg   case ir_unop_i642u64:
37701e04c3fSmrg      this->type = glsl_type::get_instance(GLSL_TYPE_UINT64,
37801e04c3fSmrg					   op0->type->vector_elements, 1);
37901e04c3fSmrg      break;
38001e04c3fSmrg
38101e04c3fSmrg   case ir_unop_unpack_double_2x32:
38201e04c3fSmrg   case ir_unop_unpack_uint_2x32:
38301e04c3fSmrg      this->type = glsl_type::uvec2_type;
38401e04c3fSmrg      break;
38501e04c3fSmrg
38601e04c3fSmrg   case ir_unop_unpack_int_2x32:
38701e04c3fSmrg      this->type = glsl_type::ivec2_type;
38801e04c3fSmrg      break;
38901e04c3fSmrg
39001e04c3fSmrg   case ir_unop_pack_snorm_2x16:
39101e04c3fSmrg   case ir_unop_pack_snorm_4x8:
39201e04c3fSmrg   case ir_unop_pack_unorm_2x16:
39301e04c3fSmrg   case ir_unop_pack_unorm_4x8:
39401e04c3fSmrg   case ir_unop_pack_half_2x16:
39501e04c3fSmrg      this->type = glsl_type::uint_type;
39601e04c3fSmrg      break;
39701e04c3fSmrg
39801e04c3fSmrg   case ir_unop_pack_double_2x32:
39901e04c3fSmrg      this->type = glsl_type::double_type;
40001e04c3fSmrg      break;
40101e04c3fSmrg
40201e04c3fSmrg   case ir_unop_pack_int_2x32:
40301e04c3fSmrg      this->type = glsl_type::int64_t_type;
40401e04c3fSmrg      break;
40501e04c3fSmrg
40601e04c3fSmrg   case ir_unop_pack_uint_2x32:
40701e04c3fSmrg      this->type = glsl_type::uint64_t_type;
40801e04c3fSmrg      break;
40901e04c3fSmrg
41001e04c3fSmrg   case ir_unop_unpack_snorm_2x16:
41101e04c3fSmrg   case ir_unop_unpack_unorm_2x16:
41201e04c3fSmrg   case ir_unop_unpack_half_2x16:
41301e04c3fSmrg      this->type = glsl_type::vec2_type;
41401e04c3fSmrg      break;
41501e04c3fSmrg
41601e04c3fSmrg   case ir_unop_unpack_snorm_4x8:
41701e04c3fSmrg   case ir_unop_unpack_unorm_4x8:
41801e04c3fSmrg      this->type = glsl_type::vec4_type;
41901e04c3fSmrg      break;
42001e04c3fSmrg
42101e04c3fSmrg   case ir_unop_unpack_sampler_2x32:
42201e04c3fSmrg   case ir_unop_unpack_image_2x32:
42301e04c3fSmrg      this->type = glsl_type::uvec2_type;
42401e04c3fSmrg      break;
42501e04c3fSmrg
42601e04c3fSmrg   case ir_unop_pack_sampler_2x32:
42701e04c3fSmrg   case ir_unop_pack_image_2x32:
42801e04c3fSmrg      this->type = op0->type;
42901e04c3fSmrg      break;
43001e04c3fSmrg
43101e04c3fSmrg   case ir_unop_frexp_sig:
43201e04c3fSmrg      this->type = op0->type;
43301e04c3fSmrg      break;
43401e04c3fSmrg   case ir_unop_frexp_exp:
43501e04c3fSmrg      this->type = glsl_type::get_instance(GLSL_TYPE_INT,
43601e04c3fSmrg					   op0->type->vector_elements, 1);
43701e04c3fSmrg      break;
43801e04c3fSmrg
43901e04c3fSmrg   case ir_unop_get_buffer_size:
44001e04c3fSmrg   case ir_unop_ssbo_unsized_array_length:
4417ec681f3Smrg   case ir_unop_implicitly_sized_array_length:
44201e04c3fSmrg      this->type = glsl_type::int_type;
44301e04c3fSmrg      break;
44401e04c3fSmrg
44501e04c3fSmrg   case ir_unop_bitcast_i642d:
44601e04c3fSmrg   case ir_unop_bitcast_u642d:
44701e04c3fSmrg      this->type = glsl_type::get_instance(GLSL_TYPE_DOUBLE,
44801e04c3fSmrg                                           op0->type->vector_elements, 1);
44901e04c3fSmrg      break;
45001e04c3fSmrg
45101e04c3fSmrg   case ir_unop_bitcast_d2i64:
45201e04c3fSmrg      this->type = glsl_type::get_instance(GLSL_TYPE_INT64,
45301e04c3fSmrg                                           op0->type->vector_elements, 1);
45401e04c3fSmrg      break;
45501e04c3fSmrg   case ir_unop_bitcast_d2u64:
45601e04c3fSmrg      this->type = glsl_type::get_instance(GLSL_TYPE_UINT64,
45701e04c3fSmrg                                           op0->type->vector_elements, 1);
45801e04c3fSmrg      break;
45901e04c3fSmrg
46001e04c3fSmrg   default:
46101e04c3fSmrg      assert(!"not reached: missing automatic type setup for ir_expression");
46201e04c3fSmrg      this->type = op0->type;
46301e04c3fSmrg      break;
46401e04c3fSmrg   }
46501e04c3fSmrg}
46601e04c3fSmrg
46701e04c3fSmrgir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1)
46801e04c3fSmrg   : ir_rvalue(ir_type_expression)
46901e04c3fSmrg{
47001e04c3fSmrg   this->operation = ir_expression_operation(op);
47101e04c3fSmrg   this->operands[0] = op0;
47201e04c3fSmrg   this->operands[1] = op1;
47301e04c3fSmrg   this->operands[2] = NULL;
47401e04c3fSmrg   this->operands[3] = NULL;
47501e04c3fSmrg
47601e04c3fSmrg   assert(op > ir_last_unop);
47701e04c3fSmrg   init_num_operands();
47801e04c3fSmrg   assert(num_operands == 2);
47901e04c3fSmrg   for (unsigned i = 0; i < num_operands; i++) {
48001e04c3fSmrg      assert(this->operands[i] != NULL);
48101e04c3fSmrg   }
48201e04c3fSmrg
48301e04c3fSmrg   switch (this->operation) {
48401e04c3fSmrg   case ir_binop_all_equal:
48501e04c3fSmrg   case ir_binop_any_nequal:
48601e04c3fSmrg      this->type = glsl_type::bool_type;
48701e04c3fSmrg      break;
48801e04c3fSmrg
48901e04c3fSmrg   case ir_binop_add:
49001e04c3fSmrg   case ir_binop_sub:
49101e04c3fSmrg   case ir_binop_min:
49201e04c3fSmrg   case ir_binop_max:
49301e04c3fSmrg   case ir_binop_pow:
49401e04c3fSmrg   case ir_binop_mul:
49501e04c3fSmrg   case ir_binop_div:
49601e04c3fSmrg   case ir_binop_mod:
4977ec681f3Smrg   case ir_binop_atan2:
49801e04c3fSmrg      if (op0->type->is_scalar()) {
49901e04c3fSmrg	 this->type = op1->type;
50001e04c3fSmrg      } else if (op1->type->is_scalar()) {
50101e04c3fSmrg	 this->type = op0->type;
50201e04c3fSmrg      } else {
50301e04c3fSmrg         if (this->operation == ir_binop_mul) {
50401e04c3fSmrg            this->type = glsl_type::get_mul_type(op0->type, op1->type);
50501e04c3fSmrg         } else {
50601e04c3fSmrg            assert(op0->type == op1->type);
50701e04c3fSmrg            this->type = op0->type;
50801e04c3fSmrg         }
50901e04c3fSmrg      }
51001e04c3fSmrg      break;
51101e04c3fSmrg
51201e04c3fSmrg   case ir_binop_logic_and:
51301e04c3fSmrg   case ir_binop_logic_xor:
51401e04c3fSmrg   case ir_binop_logic_or:
51501e04c3fSmrg   case ir_binop_bit_and:
51601e04c3fSmrg   case ir_binop_bit_xor:
51701e04c3fSmrg   case ir_binop_bit_or:
51801e04c3fSmrg       assert(!op0->type->is_matrix());
51901e04c3fSmrg       assert(!op1->type->is_matrix());
52001e04c3fSmrg      if (op0->type->is_scalar()) {
52101e04c3fSmrg         this->type = op1->type;
52201e04c3fSmrg      } else if (op1->type->is_scalar()) {
52301e04c3fSmrg         this->type = op0->type;
52401e04c3fSmrg      } else {
52501e04c3fSmrg          assert(op0->type->vector_elements == op1->type->vector_elements);
52601e04c3fSmrg          this->type = op0->type;
52701e04c3fSmrg      }
52801e04c3fSmrg      break;
52901e04c3fSmrg
53001e04c3fSmrg   case ir_binop_equal:
53101e04c3fSmrg   case ir_binop_nequal:
53201e04c3fSmrg   case ir_binop_gequal:
53301e04c3fSmrg   case ir_binop_less:
53401e04c3fSmrg      assert(op0->type == op1->type);
53501e04c3fSmrg      this->type = glsl_type::get_instance(GLSL_TYPE_BOOL,
53601e04c3fSmrg					   op0->type->vector_elements, 1);
53701e04c3fSmrg      break;
53801e04c3fSmrg
53901e04c3fSmrg   case ir_binop_dot:
54001e04c3fSmrg      this->type = op0->type->get_base_type();
54101e04c3fSmrg      break;
54201e04c3fSmrg
54301e04c3fSmrg   case ir_binop_imul_high:
5447ec681f3Smrg   case ir_binop_mul_32x16:
54501e04c3fSmrg   case ir_binop_carry:
54601e04c3fSmrg   case ir_binop_borrow:
54701e04c3fSmrg   case ir_binop_lshift:
54801e04c3fSmrg   case ir_binop_rshift:
54901e04c3fSmrg   case ir_binop_ldexp:
55001e04c3fSmrg   case ir_binop_interpolate_at_offset:
55101e04c3fSmrg   case ir_binop_interpolate_at_sample:
55201e04c3fSmrg      this->type = op0->type;
55301e04c3fSmrg      break;
55401e04c3fSmrg
5557ec681f3Smrg   case ir_binop_add_sat:
5567ec681f3Smrg   case ir_binop_sub_sat:
5577ec681f3Smrg   case ir_binop_avg:
5587ec681f3Smrg   case ir_binop_avg_round:
5597ec681f3Smrg      assert(op0->type == op1->type);
5607ec681f3Smrg      this->type = op0->type;
5617ec681f3Smrg      break;
5627ec681f3Smrg
5637ec681f3Smrg   case ir_binop_abs_sub: {
5647ec681f3Smrg      enum glsl_base_type base;
5657ec681f3Smrg
5667ec681f3Smrg      assert(op0->type == op1->type);
5677ec681f3Smrg
5687ec681f3Smrg      switch (op0->type->base_type) {
5697ec681f3Smrg      case GLSL_TYPE_UINT:
5707ec681f3Smrg      case GLSL_TYPE_INT:
5717ec681f3Smrg         base = GLSL_TYPE_UINT;
5727ec681f3Smrg         break;
5737ec681f3Smrg      case GLSL_TYPE_UINT8:
5747ec681f3Smrg      case GLSL_TYPE_INT8:
5757ec681f3Smrg         base = GLSL_TYPE_UINT8;
5767ec681f3Smrg         break;
5777ec681f3Smrg      case GLSL_TYPE_UINT16:
5787ec681f3Smrg      case GLSL_TYPE_INT16:
5797ec681f3Smrg         base = GLSL_TYPE_UINT16;
5807ec681f3Smrg         break;
5817ec681f3Smrg      case GLSL_TYPE_UINT64:
5827ec681f3Smrg      case GLSL_TYPE_INT64:
5837ec681f3Smrg         base = GLSL_TYPE_UINT64;
5847ec681f3Smrg         break;
5857ec681f3Smrg      default:
5867ec681f3Smrg         unreachable(!"Invalid base type.");
5877ec681f3Smrg      }
5887ec681f3Smrg
5897ec681f3Smrg      this->type = glsl_type::get_instance(base, op0->type->vector_elements, 1);
5907ec681f3Smrg      break;
5917ec681f3Smrg   }
5927ec681f3Smrg
59301e04c3fSmrg   case ir_binop_vector_extract:
59401e04c3fSmrg      this->type = op0->type->get_scalar_type();
59501e04c3fSmrg      break;
59601e04c3fSmrg
59701e04c3fSmrg   default:
59801e04c3fSmrg      assert(!"not reached: missing automatic type setup for ir_expression");
59901e04c3fSmrg      this->type = glsl_type::float_type;
60001e04c3fSmrg   }
60101e04c3fSmrg}
60201e04c3fSmrg
60301e04c3fSmrgir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1,
60401e04c3fSmrg                             ir_rvalue *op2)
60501e04c3fSmrg   : ir_rvalue(ir_type_expression)
60601e04c3fSmrg{
60701e04c3fSmrg   this->operation = ir_expression_operation(op);
60801e04c3fSmrg   this->operands[0] = op0;
60901e04c3fSmrg   this->operands[1] = op1;
61001e04c3fSmrg   this->operands[2] = op2;
61101e04c3fSmrg   this->operands[3] = NULL;
61201e04c3fSmrg
61301e04c3fSmrg   assert(op > ir_last_binop && op <= ir_last_triop);
61401e04c3fSmrg   init_num_operands();
61501e04c3fSmrg   assert(num_operands == 3);
61601e04c3fSmrg   for (unsigned i = 0; i < num_operands; i++) {
61701e04c3fSmrg      assert(this->operands[i] != NULL);
61801e04c3fSmrg   }
61901e04c3fSmrg
62001e04c3fSmrg   switch (this->operation) {
62101e04c3fSmrg   case ir_triop_fma:
62201e04c3fSmrg   case ir_triop_lrp:
62301e04c3fSmrg   case ir_triop_bitfield_extract:
62401e04c3fSmrg   case ir_triop_vector_insert:
62501e04c3fSmrg      this->type = op0->type;
62601e04c3fSmrg      break;
62701e04c3fSmrg
62801e04c3fSmrg   case ir_triop_csel:
62901e04c3fSmrg      this->type = op1->type;
63001e04c3fSmrg      break;
63101e04c3fSmrg
63201e04c3fSmrg   default:
63301e04c3fSmrg      assert(!"not reached: missing automatic type setup for ir_expression");
63401e04c3fSmrg      this->type = glsl_type::float_type;
63501e04c3fSmrg   }
63601e04c3fSmrg}
63701e04c3fSmrg
63801e04c3fSmrg/**
63901e04c3fSmrg * This is only here for ir_reader to used for testing purposes. Please use
64001e04c3fSmrg * the precomputed num_operands field if you need the number of operands.
64101e04c3fSmrg */
64201e04c3fSmrgunsigned
64301e04c3fSmrgir_expression::get_num_operands(ir_expression_operation op)
64401e04c3fSmrg{
64501e04c3fSmrg   assert(op <= ir_last_opcode);
64601e04c3fSmrg
64701e04c3fSmrg   if (op <= ir_last_unop)
64801e04c3fSmrg      return 1;
64901e04c3fSmrg
65001e04c3fSmrg   if (op <= ir_last_binop)
65101e04c3fSmrg      return 2;
65201e04c3fSmrg
65301e04c3fSmrg   if (op <= ir_last_triop)
65401e04c3fSmrg      return 3;
65501e04c3fSmrg
65601e04c3fSmrg   if (op <= ir_last_quadop)
65701e04c3fSmrg      return 4;
65801e04c3fSmrg
65901e04c3fSmrg   unreachable("Could not calculate number of operands");
66001e04c3fSmrg}
66101e04c3fSmrg
66201e04c3fSmrg#include "ir_expression_operation_strings.h"
66301e04c3fSmrg
66401e04c3fSmrgconst char*
66501e04c3fSmrgdepth_layout_string(ir_depth_layout layout)
66601e04c3fSmrg{
66701e04c3fSmrg   switch(layout) {
66801e04c3fSmrg   case ir_depth_layout_none:      return "";
66901e04c3fSmrg   case ir_depth_layout_any:       return "depth_any";
67001e04c3fSmrg   case ir_depth_layout_greater:   return "depth_greater";
67101e04c3fSmrg   case ir_depth_layout_less:      return "depth_less";
67201e04c3fSmrg   case ir_depth_layout_unchanged: return "depth_unchanged";
67301e04c3fSmrg
67401e04c3fSmrg   default:
67501e04c3fSmrg      assert(0);
67601e04c3fSmrg      return "";
67701e04c3fSmrg   }
67801e04c3fSmrg}
67901e04c3fSmrg
68001e04c3fSmrgir_expression_operation
68101e04c3fSmrgir_expression::get_operator(const char *str)
68201e04c3fSmrg{
68301e04c3fSmrg   for (int op = 0; op <= int(ir_last_opcode); op++) {
68401e04c3fSmrg      if (strcmp(str, ir_expression_operation_strings[op]) == 0)
68501e04c3fSmrg	 return (ir_expression_operation) op;
68601e04c3fSmrg   }
68701e04c3fSmrg   return (ir_expression_operation) -1;
68801e04c3fSmrg}
68901e04c3fSmrg
69001e04c3fSmrgir_variable *
69101e04c3fSmrgir_expression::variable_referenced() const
69201e04c3fSmrg{
69301e04c3fSmrg   switch (operation) {
69401e04c3fSmrg      case ir_binop_vector_extract:
69501e04c3fSmrg      case ir_triop_vector_insert:
69601e04c3fSmrg         /* We get these for things like a[0] where a is a vector type. In these
69701e04c3fSmrg          * cases we want variable_referenced() to return the actual vector
69801e04c3fSmrg          * variable this is wrapping.
69901e04c3fSmrg          */
70001e04c3fSmrg         return operands[0]->variable_referenced();
70101e04c3fSmrg      default:
70201e04c3fSmrg         return ir_rvalue::variable_referenced();
70301e04c3fSmrg   }
70401e04c3fSmrg}
70501e04c3fSmrg
70601e04c3fSmrgir_constant::ir_constant()
70701e04c3fSmrg   : ir_rvalue(ir_type_constant)
70801e04c3fSmrg{
70901e04c3fSmrg   this->const_elements = NULL;
71001e04c3fSmrg}
71101e04c3fSmrg
71201e04c3fSmrgir_constant::ir_constant(const struct glsl_type *type,
71301e04c3fSmrg			 const ir_constant_data *data)
71401e04c3fSmrg   : ir_rvalue(ir_type_constant)
71501e04c3fSmrg{
71601e04c3fSmrg   this->const_elements = NULL;
71701e04c3fSmrg
71801e04c3fSmrg   assert((type->base_type >= GLSL_TYPE_UINT)
71901e04c3fSmrg	  && (type->base_type <= GLSL_TYPE_IMAGE));
72001e04c3fSmrg
72101e04c3fSmrg   this->type = type;
72201e04c3fSmrg   memcpy(& this->value, data, sizeof(this->value));
72301e04c3fSmrg}
72401e04c3fSmrg
7257ec681f3Smrgir_constant::ir_constant(float16_t f16, unsigned vector_elements)
7267ec681f3Smrg   : ir_rvalue(ir_type_constant)
7277ec681f3Smrg{
7287ec681f3Smrg   this->const_elements = NULL;
7297ec681f3Smrg   assert(vector_elements <= 4);
7307ec681f3Smrg   this->type = glsl_type::get_instance(GLSL_TYPE_FLOAT16, vector_elements, 1);
7317ec681f3Smrg   for (unsigned i = 0; i < vector_elements; i++) {
7327ec681f3Smrg      this->value.f16[i] = f16.bits;
7337ec681f3Smrg   }
7347ec681f3Smrg   for (unsigned i = vector_elements; i < 16; i++)  {
7357ec681f3Smrg      this->value.f[i] = 0;
7367ec681f3Smrg   }
7377ec681f3Smrg}
7387ec681f3Smrg
73901e04c3fSmrgir_constant::ir_constant(float f, unsigned vector_elements)
74001e04c3fSmrg   : ir_rvalue(ir_type_constant)
74101e04c3fSmrg{
7427ec681f3Smrg   this->const_elements = NULL;
74301e04c3fSmrg   assert(vector_elements <= 4);
74401e04c3fSmrg   this->type = glsl_type::get_instance(GLSL_TYPE_FLOAT, vector_elements, 1);
74501e04c3fSmrg   for (unsigned i = 0; i < vector_elements; i++) {
74601e04c3fSmrg      this->value.f[i] = f;
74701e04c3fSmrg   }
74801e04c3fSmrg   for (unsigned i = vector_elements; i < 16; i++)  {
74901e04c3fSmrg      this->value.f[i] = 0;
75001e04c3fSmrg   }
75101e04c3fSmrg}
75201e04c3fSmrg
75301e04c3fSmrgir_constant::ir_constant(double d, unsigned vector_elements)
75401e04c3fSmrg   : ir_rvalue(ir_type_constant)
75501e04c3fSmrg{
7567ec681f3Smrg   this->const_elements = NULL;
75701e04c3fSmrg   assert(vector_elements <= 4);
75801e04c3fSmrg   this->type = glsl_type::get_instance(GLSL_TYPE_DOUBLE, vector_elements, 1);
75901e04c3fSmrg   for (unsigned i = 0; i < vector_elements; i++) {
76001e04c3fSmrg      this->value.d[i] = d;
76101e04c3fSmrg   }
76201e04c3fSmrg   for (unsigned i = vector_elements; i < 16; i++)  {
76301e04c3fSmrg      this->value.d[i] = 0.0;
76401e04c3fSmrg   }
76501e04c3fSmrg}
76601e04c3fSmrg
7677ec681f3Smrgir_constant::ir_constant(int16_t i16, unsigned vector_elements)
7687ec681f3Smrg   : ir_rvalue(ir_type_constant)
7697ec681f3Smrg{
7707ec681f3Smrg   this->const_elements = NULL;
7717ec681f3Smrg   assert(vector_elements <= 4);
7727ec681f3Smrg   this->type = glsl_type::get_instance(GLSL_TYPE_INT16, vector_elements, 1);
7737ec681f3Smrg   for (unsigned i = 0; i < vector_elements; i++) {
7747ec681f3Smrg      this->value.i16[i] = i16;
7757ec681f3Smrg   }
7767ec681f3Smrg   for (unsigned i = vector_elements; i < 16; i++) {
7777ec681f3Smrg      this->value.i16[i] = 0;
7787ec681f3Smrg   }
7797ec681f3Smrg}
7807ec681f3Smrg
7817ec681f3Smrgir_constant::ir_constant(uint16_t u16, unsigned vector_elements)
7827ec681f3Smrg   : ir_rvalue(ir_type_constant)
7837ec681f3Smrg{
7847ec681f3Smrg   this->const_elements = NULL;
7857ec681f3Smrg   assert(vector_elements <= 4);
7867ec681f3Smrg   this->type = glsl_type::get_instance(GLSL_TYPE_UINT16, vector_elements, 1);
7877ec681f3Smrg   for (unsigned i = 0; i < vector_elements; i++) {
7887ec681f3Smrg      this->value.u16[i] = u16;
7897ec681f3Smrg   }
7907ec681f3Smrg   for (unsigned i = vector_elements; i < 16; i++) {
7917ec681f3Smrg      this->value.u16[i] = 0;
7927ec681f3Smrg   }
7937ec681f3Smrg}
7947ec681f3Smrg
79501e04c3fSmrgir_constant::ir_constant(unsigned int u, unsigned vector_elements)
79601e04c3fSmrg   : ir_rvalue(ir_type_constant)
79701e04c3fSmrg{
7987ec681f3Smrg   this->const_elements = NULL;
79901e04c3fSmrg   assert(vector_elements <= 4);
80001e04c3fSmrg   this->type = glsl_type::get_instance(GLSL_TYPE_UINT, vector_elements, 1);
80101e04c3fSmrg   for (unsigned i = 0; i < vector_elements; i++) {
80201e04c3fSmrg      this->value.u[i] = u;
80301e04c3fSmrg   }
80401e04c3fSmrg   for (unsigned i = vector_elements; i < 16; i++) {
80501e04c3fSmrg      this->value.u[i] = 0;
80601e04c3fSmrg   }
80701e04c3fSmrg}
80801e04c3fSmrg
80901e04c3fSmrgir_constant::ir_constant(int integer, unsigned vector_elements)
81001e04c3fSmrg   : ir_rvalue(ir_type_constant)
81101e04c3fSmrg{
8127ec681f3Smrg   this->const_elements = NULL;
81301e04c3fSmrg   assert(vector_elements <= 4);
81401e04c3fSmrg   this->type = glsl_type::get_instance(GLSL_TYPE_INT, vector_elements, 1);
81501e04c3fSmrg   for (unsigned i = 0; i < vector_elements; i++) {
81601e04c3fSmrg      this->value.i[i] = integer;
81701e04c3fSmrg   }
81801e04c3fSmrg   for (unsigned i = vector_elements; i < 16; i++) {
81901e04c3fSmrg      this->value.i[i] = 0;
82001e04c3fSmrg   }
82101e04c3fSmrg}
82201e04c3fSmrg
82301e04c3fSmrgir_constant::ir_constant(uint64_t u64, unsigned vector_elements)
82401e04c3fSmrg   : ir_rvalue(ir_type_constant)
82501e04c3fSmrg{
8267ec681f3Smrg   this->const_elements = NULL;
82701e04c3fSmrg   assert(vector_elements <= 4);
82801e04c3fSmrg   this->type = glsl_type::get_instance(GLSL_TYPE_UINT64, vector_elements, 1);
82901e04c3fSmrg   for (unsigned i = 0; i < vector_elements; i++) {
83001e04c3fSmrg      this->value.u64[i] = u64;
83101e04c3fSmrg   }
83201e04c3fSmrg   for (unsigned i = vector_elements; i < 16; i++) {
83301e04c3fSmrg      this->value.u64[i] = 0;
83401e04c3fSmrg   }
83501e04c3fSmrg}
83601e04c3fSmrg
83701e04c3fSmrgir_constant::ir_constant(int64_t int64, unsigned vector_elements)
83801e04c3fSmrg   : ir_rvalue(ir_type_constant)
83901e04c3fSmrg{
8407ec681f3Smrg   this->const_elements = NULL;
84101e04c3fSmrg   assert(vector_elements <= 4);
84201e04c3fSmrg   this->type = glsl_type::get_instance(GLSL_TYPE_INT64, vector_elements, 1);
84301e04c3fSmrg   for (unsigned i = 0; i < vector_elements; i++) {
84401e04c3fSmrg      this->value.i64[i] = int64;
84501e04c3fSmrg   }
84601e04c3fSmrg   for (unsigned i = vector_elements; i < 16; i++) {
84701e04c3fSmrg      this->value.i64[i] = 0;
84801e04c3fSmrg   }
84901e04c3fSmrg}
85001e04c3fSmrg
85101e04c3fSmrgir_constant::ir_constant(bool b, unsigned vector_elements)
85201e04c3fSmrg   : ir_rvalue(ir_type_constant)
85301e04c3fSmrg{
8547ec681f3Smrg   this->const_elements = NULL;
85501e04c3fSmrg   assert(vector_elements <= 4);
85601e04c3fSmrg   this->type = glsl_type::get_instance(GLSL_TYPE_BOOL, vector_elements, 1);
85701e04c3fSmrg   for (unsigned i = 0; i < vector_elements; i++) {
85801e04c3fSmrg      this->value.b[i] = b;
85901e04c3fSmrg   }
86001e04c3fSmrg   for (unsigned i = vector_elements; i < 16; i++) {
86101e04c3fSmrg      this->value.b[i] = false;
86201e04c3fSmrg   }
86301e04c3fSmrg}
86401e04c3fSmrg
86501e04c3fSmrgir_constant::ir_constant(const ir_constant *c, unsigned i)
86601e04c3fSmrg   : ir_rvalue(ir_type_constant)
86701e04c3fSmrg{
86801e04c3fSmrg   this->const_elements = NULL;
86901e04c3fSmrg   this->type = c->type->get_base_type();
87001e04c3fSmrg
8717ec681f3Smrg   /* Section 5.11 (Out-of-Bounds Accesses) of the GLSL 4.60 spec says:
8727ec681f3Smrg    *
8737ec681f3Smrg    *    In the subsections described above for array, vector, matrix and
8747ec681f3Smrg    *    structure accesses, any out-of-bounds access produced undefined
8757ec681f3Smrg    *    behavior....Out-of-bounds reads return undefined values, which
8767ec681f3Smrg    *    include values from other variables of the active program or zero.
8777ec681f3Smrg    *
8787ec681f3Smrg    * GL_KHR_robustness and GL_ARB_robustness encourage us to return zero.
8797ec681f3Smrg    */
8807ec681f3Smrg   if (i >= c->type->vector_elements) {
8817ec681f3Smrg      this->value = { { 0 } };
8827ec681f3Smrg      return;
8837ec681f3Smrg   }
8847ec681f3Smrg
88501e04c3fSmrg   switch (this->type->base_type) {
8867ec681f3Smrg   case GLSL_TYPE_UINT16:  this->value.u16[0] = c->value.u16[i]; break;
8877ec681f3Smrg   case GLSL_TYPE_INT16:  this->value.i16[0] = c->value.i16[i]; break;
88801e04c3fSmrg   case GLSL_TYPE_UINT:  this->value.u[0] = c->value.u[i]; break;
88901e04c3fSmrg   case GLSL_TYPE_INT:   this->value.i[0] = c->value.i[i]; break;
89001e04c3fSmrg   case GLSL_TYPE_FLOAT: this->value.f[0] = c->value.f[i]; break;
8917ec681f3Smrg   case GLSL_TYPE_FLOAT16: this->value.f16[0] = c->value.f16[i]; break;
89201e04c3fSmrg   case GLSL_TYPE_BOOL:  this->value.b[0] = c->value.b[i]; break;
89301e04c3fSmrg   case GLSL_TYPE_DOUBLE: this->value.d[0] = c->value.d[i]; break;
89401e04c3fSmrg   default:              assert(!"Should not get here."); break;
89501e04c3fSmrg   }
89601e04c3fSmrg}
89701e04c3fSmrg
89801e04c3fSmrgir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list)
89901e04c3fSmrg   : ir_rvalue(ir_type_constant)
90001e04c3fSmrg{
90101e04c3fSmrg   this->const_elements = NULL;
90201e04c3fSmrg   this->type = type;
90301e04c3fSmrg
90401e04c3fSmrg   assert(type->is_scalar() || type->is_vector() || type->is_matrix()
9057e102996Smaya	  || type->is_struct() || type->is_array());
90601e04c3fSmrg
90701e04c3fSmrg   /* If the constant is a record, the types of each of the entries in
90801e04c3fSmrg    * value_list must be a 1-for-1 match with the structure components.  Each
90901e04c3fSmrg    * entry must also be a constant.  Just move the nodes from the value_list
91001e04c3fSmrg    * to the list in the ir_constant.
91101e04c3fSmrg    */
9127e102996Smaya   if (type->is_array() || type->is_struct()) {
91301e04c3fSmrg      this->const_elements = ralloc_array(this, ir_constant *, type->length);
91401e04c3fSmrg      unsigned i = 0;
91501e04c3fSmrg      foreach_in_list(ir_constant, value, value_list) {
91601e04c3fSmrg	 assert(value->as_constant() != NULL);
91701e04c3fSmrg
91801e04c3fSmrg	 this->const_elements[i++] = value;
91901e04c3fSmrg      }
92001e04c3fSmrg      return;
92101e04c3fSmrg   }
92201e04c3fSmrg
92301e04c3fSmrg   for (unsigned i = 0; i < 16; i++) {
92401e04c3fSmrg      this->value.u[i] = 0;
92501e04c3fSmrg   }
92601e04c3fSmrg
92701e04c3fSmrg   ir_constant *value = (ir_constant *) (value_list->get_head_raw());
92801e04c3fSmrg
92901e04c3fSmrg   /* Constructors with exactly one scalar argument are special for vectors
93001e04c3fSmrg    * and matrices.  For vectors, the scalar value is replicated to fill all
93101e04c3fSmrg    * the components.  For matrices, the scalar fills the components of the
93201e04c3fSmrg    * diagonal while the rest is filled with 0.
93301e04c3fSmrg    */
93401e04c3fSmrg   if (value->type->is_scalar() && value->next->is_tail_sentinel()) {
93501e04c3fSmrg      if (type->is_matrix()) {
93601e04c3fSmrg	 /* Matrix - fill diagonal (rest is already set to 0) */
93701e04c3fSmrg         for (unsigned i = 0; i < type->matrix_columns; i++) {
9387ec681f3Smrg            switch (type->base_type) {
9397ec681f3Smrg            case GLSL_TYPE_FLOAT:
94001e04c3fSmrg               this->value.f[i * type->vector_elements + i] =
94101e04c3fSmrg                  value->value.f[0];
9427ec681f3Smrg               break;
9437ec681f3Smrg            case GLSL_TYPE_DOUBLE:
94401e04c3fSmrg               this->value.d[i * type->vector_elements + i] =
94501e04c3fSmrg                  value->value.d[0];
9467ec681f3Smrg               break;
9477ec681f3Smrg            case GLSL_TYPE_FLOAT16:
9487ec681f3Smrg               this->value.f16[i * type->vector_elements + i] =
9497ec681f3Smrg                  value->value.f16[0];
9507ec681f3Smrg               break;
9517ec681f3Smrg            default:
9527ec681f3Smrg               assert(!"unexpected matrix base type");
9537ec681f3Smrg            }
95401e04c3fSmrg         }
95501e04c3fSmrg      } else {
95601e04c3fSmrg	 /* Vector or scalar - fill all components */
95701e04c3fSmrg	 switch (type->base_type) {
9587ec681f3Smrg         case GLSL_TYPE_UINT16:
9597ec681f3Smrg	 case GLSL_TYPE_INT16:
9607ec681f3Smrg	    for (unsigned i = 0; i < type->components(); i++)
9617ec681f3Smrg	       this->value.u16[i] = value->value.u16[0];
9627ec681f3Smrg	    break;
96301e04c3fSmrg	 case GLSL_TYPE_UINT:
96401e04c3fSmrg	 case GLSL_TYPE_INT:
96501e04c3fSmrg	    for (unsigned i = 0; i < type->components(); i++)
96601e04c3fSmrg	       this->value.u[i] = value->value.u[0];
96701e04c3fSmrg	    break;
96801e04c3fSmrg	 case GLSL_TYPE_FLOAT:
96901e04c3fSmrg	    for (unsigned i = 0; i < type->components(); i++)
97001e04c3fSmrg	       this->value.f[i] = value->value.f[0];
97101e04c3fSmrg	    break;
9727ec681f3Smrg	 case GLSL_TYPE_FLOAT16:
9737ec681f3Smrg	    for (unsigned i = 0; i < type->components(); i++)
9747ec681f3Smrg	       this->value.f16[i] = value->value.f16[0];
9757ec681f3Smrg	    break;
97601e04c3fSmrg	 case GLSL_TYPE_DOUBLE:
97701e04c3fSmrg	    for (unsigned i = 0; i < type->components(); i++)
97801e04c3fSmrg	       this->value.d[i] = value->value.d[0];
97901e04c3fSmrg	    break;
98001e04c3fSmrg	 case GLSL_TYPE_UINT64:
98101e04c3fSmrg	 case GLSL_TYPE_INT64:
98201e04c3fSmrg	    for (unsigned i = 0; i < type->components(); i++)
98301e04c3fSmrg	       this->value.u64[i] = value->value.u64[0];
98401e04c3fSmrg	    break;
98501e04c3fSmrg	 case GLSL_TYPE_BOOL:
98601e04c3fSmrg	    for (unsigned i = 0; i < type->components(); i++)
98701e04c3fSmrg	       this->value.b[i] = value->value.b[0];
98801e04c3fSmrg	    break;
98901e04c3fSmrg	 case GLSL_TYPE_SAMPLER:
99001e04c3fSmrg	 case GLSL_TYPE_IMAGE:
99101e04c3fSmrg	    this->value.u64[0] = value->value.u64[0];
99201e04c3fSmrg	    break;
99301e04c3fSmrg	 default:
99401e04c3fSmrg	    assert(!"Should not get here.");
99501e04c3fSmrg	    break;
99601e04c3fSmrg	 }
99701e04c3fSmrg      }
99801e04c3fSmrg      return;
99901e04c3fSmrg   }
100001e04c3fSmrg
100101e04c3fSmrg   if (type->is_matrix() && value->type->is_matrix()) {
100201e04c3fSmrg      assert(value->next->is_tail_sentinel());
100301e04c3fSmrg
100401e04c3fSmrg      /* From section 5.4.2 of the GLSL 1.20 spec:
100501e04c3fSmrg       * "If a matrix is constructed from a matrix, then each component
100601e04c3fSmrg       *  (column i, row j) in the result that has a corresponding component
100701e04c3fSmrg       *  (column i, row j) in the argument will be initialized from there."
100801e04c3fSmrg       */
100901e04c3fSmrg      unsigned cols = MIN2(type->matrix_columns, value->type->matrix_columns);
101001e04c3fSmrg      unsigned rows = MIN2(type->vector_elements, value->type->vector_elements);
101101e04c3fSmrg      for (unsigned i = 0; i < cols; i++) {
101201e04c3fSmrg	 for (unsigned j = 0; j < rows; j++) {
101301e04c3fSmrg	    const unsigned src = i * value->type->vector_elements + j;
101401e04c3fSmrg	    const unsigned dst = i * type->vector_elements + j;
101501e04c3fSmrg	    this->value.f[dst] = value->value.f[src];
101601e04c3fSmrg	 }
101701e04c3fSmrg      }
101801e04c3fSmrg
101901e04c3fSmrg      /* "All other components will be initialized to the identity matrix." */
102001e04c3fSmrg      for (unsigned i = cols; i < type->matrix_columns; i++)
102101e04c3fSmrg	 this->value.f[i * type->vector_elements + i] = 1.0;
102201e04c3fSmrg
102301e04c3fSmrg      return;
102401e04c3fSmrg   }
102501e04c3fSmrg
102601e04c3fSmrg   /* Use each component from each entry in the value_list to initialize one
102701e04c3fSmrg    * component of the constant being constructed.
102801e04c3fSmrg    */
102901e04c3fSmrg   unsigned i = 0;
103001e04c3fSmrg   for (;;) {
103101e04c3fSmrg      assert(value->as_constant() != NULL);
103201e04c3fSmrg      assert(!value->is_tail_sentinel());
103301e04c3fSmrg
103401e04c3fSmrg      for (unsigned j = 0; j < value->type->components(); j++) {
103501e04c3fSmrg	 switch (type->base_type) {
10367ec681f3Smrg         case GLSL_TYPE_UINT16:
10377ec681f3Smrg	    this->value.u16[i] = value->get_uint16_component(j);
10387ec681f3Smrg	    break;
10397ec681f3Smrg	 case GLSL_TYPE_INT16:
10407ec681f3Smrg	    this->value.i16[i] = value->get_int16_component(j);
10417ec681f3Smrg	    break;
104201e04c3fSmrg	 case GLSL_TYPE_UINT:
104301e04c3fSmrg	    this->value.u[i] = value->get_uint_component(j);
104401e04c3fSmrg	    break;
104501e04c3fSmrg	 case GLSL_TYPE_INT:
104601e04c3fSmrg	    this->value.i[i] = value->get_int_component(j);
104701e04c3fSmrg	    break;
104801e04c3fSmrg	 case GLSL_TYPE_FLOAT:
104901e04c3fSmrg	    this->value.f[i] = value->get_float_component(j);
105001e04c3fSmrg	    break;
10517ec681f3Smrg	 case GLSL_TYPE_FLOAT16:
10527ec681f3Smrg	    this->value.f16[i] = value->get_float16_component(j);
10537ec681f3Smrg	    break;
105401e04c3fSmrg	 case GLSL_TYPE_BOOL:
105501e04c3fSmrg	    this->value.b[i] = value->get_bool_component(j);
105601e04c3fSmrg	    break;
105701e04c3fSmrg	 case GLSL_TYPE_DOUBLE:
105801e04c3fSmrg	    this->value.d[i] = value->get_double_component(j);
105901e04c3fSmrg	    break;
106001e04c3fSmrg         case GLSL_TYPE_UINT64:
106101e04c3fSmrg	    this->value.u64[i] = value->get_uint64_component(j);
106201e04c3fSmrg	    break;
106301e04c3fSmrg	 case GLSL_TYPE_INT64:
106401e04c3fSmrg	    this->value.i64[i] = value->get_int64_component(j);
106501e04c3fSmrg	    break;
106601e04c3fSmrg	 default:
106701e04c3fSmrg	    /* FINISHME: What to do?  Exceptions are not the answer.
106801e04c3fSmrg	     */
106901e04c3fSmrg	    break;
107001e04c3fSmrg	 }
107101e04c3fSmrg
107201e04c3fSmrg	 i++;
107301e04c3fSmrg	 if (i >= type->components())
107401e04c3fSmrg	    break;
107501e04c3fSmrg      }
107601e04c3fSmrg
107701e04c3fSmrg      if (i >= type->components())
107801e04c3fSmrg	 break; /* avoid downcasting a list sentinel */
107901e04c3fSmrg      value = (ir_constant *) value->next;
108001e04c3fSmrg   }
108101e04c3fSmrg}
108201e04c3fSmrg
108301e04c3fSmrgir_constant *
108401e04c3fSmrgir_constant::zero(void *mem_ctx, const glsl_type *type)
108501e04c3fSmrg{
108601e04c3fSmrg   assert(type->is_scalar() || type->is_vector() || type->is_matrix()
10877e102996Smaya	  || type->is_struct() || type->is_array());
108801e04c3fSmrg
108901e04c3fSmrg   ir_constant *c = new(mem_ctx) ir_constant;
109001e04c3fSmrg   c->type = type;
109101e04c3fSmrg   memset(&c->value, 0, sizeof(c->value));
109201e04c3fSmrg
109301e04c3fSmrg   if (type->is_array()) {
109401e04c3fSmrg      c->const_elements = ralloc_array(c, ir_constant *, type->length);
109501e04c3fSmrg
109601e04c3fSmrg      for (unsigned i = 0; i < type->length; i++)
109701e04c3fSmrg	 c->const_elements[i] = ir_constant::zero(c, type->fields.array);
109801e04c3fSmrg   }
109901e04c3fSmrg
11007e102996Smaya   if (type->is_struct()) {
110101e04c3fSmrg      c->const_elements = ralloc_array(c, ir_constant *, type->length);
110201e04c3fSmrg
110301e04c3fSmrg      for (unsigned i = 0; i < type->length; i++) {
110401e04c3fSmrg         c->const_elements[i] =
110501e04c3fSmrg            ir_constant::zero(mem_ctx, type->fields.structure[i].type);
110601e04c3fSmrg      }
110701e04c3fSmrg   }
110801e04c3fSmrg
110901e04c3fSmrg   return c;
111001e04c3fSmrg}
111101e04c3fSmrg
111201e04c3fSmrgbool
111301e04c3fSmrgir_constant::get_bool_component(unsigned i) const
111401e04c3fSmrg{
111501e04c3fSmrg   switch (this->type->base_type) {
11167ec681f3Smrg   case GLSL_TYPE_UINT16:return this->value.u16[i] != 0;
11177ec681f3Smrg   case GLSL_TYPE_INT16: return this->value.i16[i] != 0;
111801e04c3fSmrg   case GLSL_TYPE_UINT:  return this->value.u[i] != 0;
111901e04c3fSmrg   case GLSL_TYPE_INT:   return this->value.i[i] != 0;
112001e04c3fSmrg   case GLSL_TYPE_FLOAT: return ((int)this->value.f[i]) != 0;
11217ec681f3Smrg   case GLSL_TYPE_FLOAT16: return ((int)_mesa_half_to_float(this->value.f16[i])) != 0;
112201e04c3fSmrg   case GLSL_TYPE_BOOL:  return this->value.b[i];
112301e04c3fSmrg   case GLSL_TYPE_DOUBLE: return this->value.d[i] != 0.0;
112401e04c3fSmrg   case GLSL_TYPE_SAMPLER:
112501e04c3fSmrg   case GLSL_TYPE_IMAGE:
112601e04c3fSmrg   case GLSL_TYPE_UINT64: return this->value.u64[i] != 0;
112701e04c3fSmrg   case GLSL_TYPE_INT64:  return this->value.i64[i] != 0;
112801e04c3fSmrg   default:              assert(!"Should not get here."); break;
112901e04c3fSmrg   }
113001e04c3fSmrg
113101e04c3fSmrg   /* Must return something to make the compiler happy.  This is clearly an
113201e04c3fSmrg    * error case.
113301e04c3fSmrg    */
113401e04c3fSmrg   return false;
113501e04c3fSmrg}
113601e04c3fSmrg
113701e04c3fSmrgfloat
113801e04c3fSmrgir_constant::get_float_component(unsigned i) const
113901e04c3fSmrg{
114001e04c3fSmrg   switch (this->type->base_type) {
11417ec681f3Smrg   case GLSL_TYPE_UINT16:return (float) this->value.u16[i];
11427ec681f3Smrg   case GLSL_TYPE_INT16: return (float) this->value.i16[i];
114301e04c3fSmrg   case GLSL_TYPE_UINT:  return (float) this->value.u[i];
114401e04c3fSmrg   case GLSL_TYPE_INT:   return (float) this->value.i[i];
114501e04c3fSmrg   case GLSL_TYPE_FLOAT: return this->value.f[i];
11467ec681f3Smrg   case GLSL_TYPE_FLOAT16: return _mesa_half_to_float(this->value.f16[i]);
114701e04c3fSmrg   case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1.0f : 0.0f;
114801e04c3fSmrg   case GLSL_TYPE_DOUBLE: return (float) this->value.d[i];
114901e04c3fSmrg   case GLSL_TYPE_SAMPLER:
115001e04c3fSmrg   case GLSL_TYPE_IMAGE:
115101e04c3fSmrg   case GLSL_TYPE_UINT64: return (float) this->value.u64[i];
115201e04c3fSmrg   case GLSL_TYPE_INT64:  return (float) this->value.i64[i];
115301e04c3fSmrg   default:              assert(!"Should not get here."); break;
115401e04c3fSmrg   }
115501e04c3fSmrg
115601e04c3fSmrg   /* Must return something to make the compiler happy.  This is clearly an
115701e04c3fSmrg    * error case.
115801e04c3fSmrg    */
115901e04c3fSmrg   return 0.0;
116001e04c3fSmrg}
116101e04c3fSmrg
11627ec681f3Smrguint16_t
11637ec681f3Smrgir_constant::get_float16_component(unsigned i) const
11647ec681f3Smrg{
11657ec681f3Smrg   if (this->type->base_type == GLSL_TYPE_FLOAT16)
11667ec681f3Smrg      return this->value.f16[i];
11677ec681f3Smrg   else
11687ec681f3Smrg      return _mesa_float_to_half(get_float_component(i));
11697ec681f3Smrg}
11707ec681f3Smrg
117101e04c3fSmrgdouble
117201e04c3fSmrgir_constant::get_double_component(unsigned i) const
117301e04c3fSmrg{
117401e04c3fSmrg   switch (this->type->base_type) {
11757ec681f3Smrg   case GLSL_TYPE_UINT16:return (double) this->value.u16[i];
11767ec681f3Smrg   case GLSL_TYPE_INT16: return (double) this->value.i16[i];
117701e04c3fSmrg   case GLSL_TYPE_UINT:  return (double) this->value.u[i];
117801e04c3fSmrg   case GLSL_TYPE_INT:   return (double) this->value.i[i];
117901e04c3fSmrg   case GLSL_TYPE_FLOAT: return (double) this->value.f[i];
11807ec681f3Smrg   case GLSL_TYPE_FLOAT16: return (double) _mesa_half_to_float(this->value.f16[i]);
118101e04c3fSmrg   case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1.0 : 0.0;
118201e04c3fSmrg   case GLSL_TYPE_DOUBLE: return this->value.d[i];
118301e04c3fSmrg   case GLSL_TYPE_SAMPLER:
118401e04c3fSmrg   case GLSL_TYPE_IMAGE:
118501e04c3fSmrg   case GLSL_TYPE_UINT64: return (double) this->value.u64[i];
118601e04c3fSmrg   case GLSL_TYPE_INT64:  return (double) this->value.i64[i];
118701e04c3fSmrg   default:              assert(!"Should not get here."); break;
118801e04c3fSmrg   }
118901e04c3fSmrg
119001e04c3fSmrg   /* Must return something to make the compiler happy.  This is clearly an
119101e04c3fSmrg    * error case.
119201e04c3fSmrg    */
119301e04c3fSmrg   return 0.0;
119401e04c3fSmrg}
119501e04c3fSmrg
11967ec681f3Smrgint16_t
11977ec681f3Smrgir_constant::get_int16_component(unsigned i) const
11987ec681f3Smrg{
11997ec681f3Smrg   switch (this->type->base_type) {
12007ec681f3Smrg   case GLSL_TYPE_UINT16:return this->value.u16[i];
12017ec681f3Smrg   case GLSL_TYPE_INT16: return this->value.i16[i];
12027ec681f3Smrg   case GLSL_TYPE_UINT:  return this->value.u[i];
12037ec681f3Smrg   case GLSL_TYPE_INT:   return this->value.i[i];
12047ec681f3Smrg   case GLSL_TYPE_FLOAT: return (int16_t) this->value.f[i];
12057ec681f3Smrg   case GLSL_TYPE_FLOAT16: return (int16_t) _mesa_half_to_float(this->value.f16[i]);
12067ec681f3Smrg   case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1 : 0;
12077ec681f3Smrg   case GLSL_TYPE_DOUBLE: return (int16_t) this->value.d[i];
12087ec681f3Smrg   case GLSL_TYPE_SAMPLER:
12097ec681f3Smrg   case GLSL_TYPE_IMAGE:
12107ec681f3Smrg   case GLSL_TYPE_UINT64: return (int16_t) this->value.u64[i];
12117ec681f3Smrg   case GLSL_TYPE_INT64:  return (int16_t) this->value.i64[i];
12127ec681f3Smrg   default:              assert(!"Should not get here."); break;
12137ec681f3Smrg   }
12147ec681f3Smrg
12157ec681f3Smrg   /* Must return something to make the compiler happy.  This is clearly an
12167ec681f3Smrg    * error case.
12177ec681f3Smrg    */
12187ec681f3Smrg   return 0;
12197ec681f3Smrg}
12207ec681f3Smrg
12217ec681f3Smrguint16_t
12227ec681f3Smrgir_constant::get_uint16_component(unsigned i) const
12237ec681f3Smrg{
12247ec681f3Smrg   switch (this->type->base_type) {
12257ec681f3Smrg   case GLSL_TYPE_UINT16:return this->value.u16[i];
12267ec681f3Smrg   case GLSL_TYPE_INT16: return this->value.i16[i];
12277ec681f3Smrg   case GLSL_TYPE_UINT:  return this->value.u[i];
12287ec681f3Smrg   case GLSL_TYPE_INT:   return this->value.i[i];
12297ec681f3Smrg   case GLSL_TYPE_FLOAT: return (uint16_t) this->value.f[i];
12307ec681f3Smrg   case GLSL_TYPE_FLOAT16: return (uint16_t) _mesa_half_to_float(this->value.f16[i]);
12317ec681f3Smrg   case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1 : 0;
12327ec681f3Smrg   case GLSL_TYPE_DOUBLE: return (uint16_t) this->value.d[i];
12337ec681f3Smrg   case GLSL_TYPE_SAMPLER:
12347ec681f3Smrg   case GLSL_TYPE_IMAGE:
12357ec681f3Smrg   case GLSL_TYPE_UINT64: return (uint16_t) this->value.u64[i];
12367ec681f3Smrg   case GLSL_TYPE_INT64:  return (uint16_t) this->value.i64[i];
12377ec681f3Smrg   default:              assert(!"Should not get here."); break;
12387ec681f3Smrg   }
12397ec681f3Smrg
12407ec681f3Smrg   /* Must return something to make the compiler happy.  This is clearly an
12417ec681f3Smrg    * error case.
12427ec681f3Smrg    */
12437ec681f3Smrg   return 0;
12447ec681f3Smrg}
12457ec681f3Smrg
124601e04c3fSmrgint
124701e04c3fSmrgir_constant::get_int_component(unsigned i) const
124801e04c3fSmrg{
124901e04c3fSmrg   switch (this->type->base_type) {
12507ec681f3Smrg   case GLSL_TYPE_UINT16:return this->value.u16[i];
12517ec681f3Smrg   case GLSL_TYPE_INT16: return this->value.i16[i];
125201e04c3fSmrg   case GLSL_TYPE_UINT:  return this->value.u[i];
125301e04c3fSmrg   case GLSL_TYPE_INT:   return this->value.i[i];
125401e04c3fSmrg   case GLSL_TYPE_FLOAT: return (int) this->value.f[i];
12557ec681f3Smrg   case GLSL_TYPE_FLOAT16: return (int) _mesa_half_to_float(this->value.f16[i]);
125601e04c3fSmrg   case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1 : 0;
125701e04c3fSmrg   case GLSL_TYPE_DOUBLE: return (int) this->value.d[i];
125801e04c3fSmrg   case GLSL_TYPE_SAMPLER:
125901e04c3fSmrg   case GLSL_TYPE_IMAGE:
126001e04c3fSmrg   case GLSL_TYPE_UINT64: return (int) this->value.u64[i];
126101e04c3fSmrg   case GLSL_TYPE_INT64:  return (int) this->value.i64[i];
126201e04c3fSmrg   default:              assert(!"Should not get here."); break;
126301e04c3fSmrg   }
126401e04c3fSmrg
126501e04c3fSmrg   /* Must return something to make the compiler happy.  This is clearly an
126601e04c3fSmrg    * error case.
126701e04c3fSmrg    */
126801e04c3fSmrg   return 0;
126901e04c3fSmrg}
127001e04c3fSmrg
127101e04c3fSmrgunsigned
127201e04c3fSmrgir_constant::get_uint_component(unsigned i) const
127301e04c3fSmrg{
127401e04c3fSmrg   switch (this->type->base_type) {
12757ec681f3Smrg   case GLSL_TYPE_UINT16:return this->value.u16[i];
12767ec681f3Smrg   case GLSL_TYPE_INT16: return this->value.i16[i];
127701e04c3fSmrg   case GLSL_TYPE_UINT:  return this->value.u[i];
127801e04c3fSmrg   case GLSL_TYPE_INT:   return this->value.i[i];
127901e04c3fSmrg   case GLSL_TYPE_FLOAT: return (unsigned) this->value.f[i];
12807ec681f3Smrg   case GLSL_TYPE_FLOAT16: return (unsigned) _mesa_half_to_float(this->value.f16[i]);
128101e04c3fSmrg   case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1 : 0;
128201e04c3fSmrg   case GLSL_TYPE_DOUBLE: return (unsigned) this->value.d[i];
128301e04c3fSmrg   case GLSL_TYPE_SAMPLER:
128401e04c3fSmrg   case GLSL_TYPE_IMAGE:
128501e04c3fSmrg   case GLSL_TYPE_UINT64: return (unsigned) this->value.u64[i];
128601e04c3fSmrg   case GLSL_TYPE_INT64:  return (unsigned) this->value.i64[i];
128701e04c3fSmrg   default:              assert(!"Should not get here."); break;
128801e04c3fSmrg   }
128901e04c3fSmrg
129001e04c3fSmrg   /* Must return something to make the compiler happy.  This is clearly an
129101e04c3fSmrg    * error case.
129201e04c3fSmrg    */
129301e04c3fSmrg   return 0;
129401e04c3fSmrg}
129501e04c3fSmrg
129601e04c3fSmrgint64_t
129701e04c3fSmrgir_constant::get_int64_component(unsigned i) const
129801e04c3fSmrg{
129901e04c3fSmrg   switch (this->type->base_type) {
13007ec681f3Smrg   case GLSL_TYPE_UINT16:return this->value.u16[i];
13017ec681f3Smrg   case GLSL_TYPE_INT16: return this->value.i16[i];
130201e04c3fSmrg   case GLSL_TYPE_UINT:  return this->value.u[i];
130301e04c3fSmrg   case GLSL_TYPE_INT:   return this->value.i[i];
130401e04c3fSmrg   case GLSL_TYPE_FLOAT: return (int64_t) this->value.f[i];
13057ec681f3Smrg   case GLSL_TYPE_FLOAT16: return (int64_t) _mesa_half_to_float(this->value.f16[i]);
130601e04c3fSmrg   case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1 : 0;
130701e04c3fSmrg   case GLSL_TYPE_DOUBLE: return (int64_t) this->value.d[i];
130801e04c3fSmrg   case GLSL_TYPE_SAMPLER:
130901e04c3fSmrg   case GLSL_TYPE_IMAGE:
131001e04c3fSmrg   case GLSL_TYPE_UINT64: return (int64_t) this->value.u64[i];
131101e04c3fSmrg   case GLSL_TYPE_INT64:  return this->value.i64[i];
131201e04c3fSmrg   default:              assert(!"Should not get here."); break;
131301e04c3fSmrg   }
131401e04c3fSmrg
131501e04c3fSmrg   /* Must return something to make the compiler happy.  This is clearly an
131601e04c3fSmrg    * error case.
131701e04c3fSmrg    */
131801e04c3fSmrg   return 0;
131901e04c3fSmrg}
132001e04c3fSmrg
132101e04c3fSmrguint64_t
132201e04c3fSmrgir_constant::get_uint64_component(unsigned i) const
132301e04c3fSmrg{
132401e04c3fSmrg   switch (this->type->base_type) {
13257ec681f3Smrg   case GLSL_TYPE_UINT16:return this->value.u16[i];
13267ec681f3Smrg   case GLSL_TYPE_INT16: return this->value.i16[i];
132701e04c3fSmrg   case GLSL_TYPE_UINT:  return this->value.u[i];
132801e04c3fSmrg   case GLSL_TYPE_INT:   return this->value.i[i];
132901e04c3fSmrg   case GLSL_TYPE_FLOAT: return (uint64_t) this->value.f[i];
13307ec681f3Smrg   case GLSL_TYPE_FLOAT16: return (uint64_t) _mesa_half_to_float(this->value.f16[i]);
133101e04c3fSmrg   case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1 : 0;
133201e04c3fSmrg   case GLSL_TYPE_DOUBLE: return (uint64_t) this->value.d[i];
133301e04c3fSmrg   case GLSL_TYPE_SAMPLER:
133401e04c3fSmrg   case GLSL_TYPE_IMAGE:
133501e04c3fSmrg   case GLSL_TYPE_UINT64: return this->value.u64[i];
133601e04c3fSmrg   case GLSL_TYPE_INT64:  return (uint64_t) this->value.i64[i];
133701e04c3fSmrg   default:              assert(!"Should not get here."); break;
133801e04c3fSmrg   }
133901e04c3fSmrg
134001e04c3fSmrg   /* Must return something to make the compiler happy.  This is clearly an
134101e04c3fSmrg    * error case.
134201e04c3fSmrg    */
134301e04c3fSmrg   return 0;
134401e04c3fSmrg}
134501e04c3fSmrg
134601e04c3fSmrgir_constant *
134701e04c3fSmrgir_constant::get_array_element(unsigned i) const
134801e04c3fSmrg{
134901e04c3fSmrg   assert(this->type->is_array());
135001e04c3fSmrg
135101e04c3fSmrg   /* From page 35 (page 41 of the PDF) of the GLSL 1.20 spec:
135201e04c3fSmrg    *
135301e04c3fSmrg    *     "Behavior is undefined if a shader subscripts an array with an index
135401e04c3fSmrg    *     less than 0 or greater than or equal to the size the array was
135501e04c3fSmrg    *     declared with."
135601e04c3fSmrg    *
135701e04c3fSmrg    * Most out-of-bounds accesses are removed before things could get this far.
135801e04c3fSmrg    * There are cases where non-constant array index values can get constant
135901e04c3fSmrg    * folded.
136001e04c3fSmrg    */
136101e04c3fSmrg   if (int(i) < 0)
136201e04c3fSmrg      i = 0;
136301e04c3fSmrg   else if (i >= this->type->length)
136401e04c3fSmrg      i = this->type->length - 1;
136501e04c3fSmrg
136601e04c3fSmrg   return const_elements[i];
136701e04c3fSmrg}
136801e04c3fSmrg
136901e04c3fSmrgir_constant *
137001e04c3fSmrgir_constant::get_record_field(int idx)
137101e04c3fSmrg{
13727e102996Smaya   assert(this->type->is_struct());
137301e04c3fSmrg   assert(idx >= 0 && (unsigned) idx < this->type->length);
137401e04c3fSmrg
137501e04c3fSmrg   return const_elements[idx];
137601e04c3fSmrg}
137701e04c3fSmrg
137801e04c3fSmrgvoid
137901e04c3fSmrgir_constant::copy_offset(ir_constant *src, int offset)
138001e04c3fSmrg{
138101e04c3fSmrg   switch (this->type->base_type) {
13827ec681f3Smrg   case GLSL_TYPE_UINT16:
13837ec681f3Smrg   case GLSL_TYPE_INT16:
138401e04c3fSmrg   case GLSL_TYPE_UINT:
138501e04c3fSmrg   case GLSL_TYPE_INT:
138601e04c3fSmrg   case GLSL_TYPE_FLOAT:
13877ec681f3Smrg   case GLSL_TYPE_FLOAT16:
138801e04c3fSmrg   case GLSL_TYPE_DOUBLE:
138901e04c3fSmrg   case GLSL_TYPE_SAMPLER:
139001e04c3fSmrg   case GLSL_TYPE_IMAGE:
139101e04c3fSmrg   case GLSL_TYPE_UINT64:
139201e04c3fSmrg   case GLSL_TYPE_INT64:
139301e04c3fSmrg   case GLSL_TYPE_BOOL: {
139401e04c3fSmrg      unsigned int size = src->type->components();
139501e04c3fSmrg      assert (size <= this->type->components() - offset);
139601e04c3fSmrg      for (unsigned int i=0; i<size; i++) {
139701e04c3fSmrg	 switch (this->type->base_type) {
13987ec681f3Smrg         case GLSL_TYPE_UINT16:
13997ec681f3Smrg	    value.u16[i+offset] = src->get_uint16_component(i);
14007ec681f3Smrg	    break;
14017ec681f3Smrg	 case GLSL_TYPE_INT16:
14027ec681f3Smrg	    value.i16[i+offset] = src->get_int16_component(i);
14037ec681f3Smrg	    break;
140401e04c3fSmrg	 case GLSL_TYPE_UINT:
140501e04c3fSmrg	    value.u[i+offset] = src->get_uint_component(i);
140601e04c3fSmrg	    break;
140701e04c3fSmrg	 case GLSL_TYPE_INT:
140801e04c3fSmrg	    value.i[i+offset] = src->get_int_component(i);
140901e04c3fSmrg	    break;
141001e04c3fSmrg	 case GLSL_TYPE_FLOAT:
141101e04c3fSmrg	    value.f[i+offset] = src->get_float_component(i);
141201e04c3fSmrg	    break;
14137ec681f3Smrg	 case GLSL_TYPE_FLOAT16:
14147ec681f3Smrg	    value.f16[i+offset] = src->get_float16_component(i);
14157ec681f3Smrg	    break;
141601e04c3fSmrg	 case GLSL_TYPE_BOOL:
141701e04c3fSmrg	    value.b[i+offset] = src->get_bool_component(i);
141801e04c3fSmrg	    break;
141901e04c3fSmrg	 case GLSL_TYPE_DOUBLE:
142001e04c3fSmrg	    value.d[i+offset] = src->get_double_component(i);
142101e04c3fSmrg	    break;
142201e04c3fSmrg	 case GLSL_TYPE_SAMPLER:
142301e04c3fSmrg	 case GLSL_TYPE_IMAGE:
142401e04c3fSmrg	 case GLSL_TYPE_UINT64:
142501e04c3fSmrg	    value.u64[i+offset] = src->get_uint64_component(i);
142601e04c3fSmrg	    break;
142701e04c3fSmrg	 case GLSL_TYPE_INT64:
142801e04c3fSmrg	    value.i64[i+offset] = src->get_int64_component(i);
142901e04c3fSmrg	    break;
143001e04c3fSmrg	 default: // Shut up the compiler
143101e04c3fSmrg	    break;
143201e04c3fSmrg	 }
143301e04c3fSmrg      }
143401e04c3fSmrg      break;
143501e04c3fSmrg   }
143601e04c3fSmrg
143701e04c3fSmrg   case GLSL_TYPE_STRUCT:
143801e04c3fSmrg   case GLSL_TYPE_ARRAY: {
143901e04c3fSmrg      assert (src->type == this->type);
144001e04c3fSmrg      for (unsigned i = 0; i < this->type->length; i++) {
144101e04c3fSmrg	 this->const_elements[i] = src->const_elements[i]->clone(this, NULL);
144201e04c3fSmrg      }
144301e04c3fSmrg      break;
144401e04c3fSmrg   }
144501e04c3fSmrg
144601e04c3fSmrg   default:
144701e04c3fSmrg      assert(!"Should not get here.");
144801e04c3fSmrg      break;
144901e04c3fSmrg   }
145001e04c3fSmrg}
145101e04c3fSmrg
145201e04c3fSmrgvoid
145301e04c3fSmrgir_constant::copy_masked_offset(ir_constant *src, int offset, unsigned int mask)
145401e04c3fSmrg{
14557e102996Smaya   assert (!type->is_array() && !type->is_struct());
145601e04c3fSmrg
145701e04c3fSmrg   if (!type->is_vector() && !type->is_matrix()) {
145801e04c3fSmrg      offset = 0;
145901e04c3fSmrg      mask = 1;
146001e04c3fSmrg   }
146101e04c3fSmrg
146201e04c3fSmrg   int id = 0;
146301e04c3fSmrg   for (int i=0; i<4; i++) {
146401e04c3fSmrg      if (mask & (1 << i)) {
146501e04c3fSmrg	 switch (this->type->base_type) {
14667ec681f3Smrg         case GLSL_TYPE_UINT16:
14677ec681f3Smrg	    value.u16[i+offset] = src->get_uint16_component(id++);
14687ec681f3Smrg	    break;
14697ec681f3Smrg	 case GLSL_TYPE_INT16:
14707ec681f3Smrg	    value.i16[i+offset] = src->get_int16_component(id++);
14717ec681f3Smrg	    break;
147201e04c3fSmrg	 case GLSL_TYPE_UINT:
147301e04c3fSmrg	    value.u[i+offset] = src->get_uint_component(id++);
147401e04c3fSmrg	    break;
147501e04c3fSmrg	 case GLSL_TYPE_INT:
147601e04c3fSmrg	    value.i[i+offset] = src->get_int_component(id++);
147701e04c3fSmrg	    break;
147801e04c3fSmrg	 case GLSL_TYPE_FLOAT:
147901e04c3fSmrg	    value.f[i+offset] = src->get_float_component(id++);
148001e04c3fSmrg	    break;
14817ec681f3Smrg	 case GLSL_TYPE_FLOAT16:
14827ec681f3Smrg	    value.f16[i+offset] = src->get_float16_component(id++);
14837ec681f3Smrg	    break;
148401e04c3fSmrg	 case GLSL_TYPE_BOOL:
148501e04c3fSmrg	    value.b[i+offset] = src->get_bool_component(id++);
148601e04c3fSmrg	    break;
148701e04c3fSmrg	 case GLSL_TYPE_DOUBLE:
148801e04c3fSmrg	    value.d[i+offset] = src->get_double_component(id++);
148901e04c3fSmrg	    break;
149001e04c3fSmrg	 case GLSL_TYPE_SAMPLER:
149101e04c3fSmrg	 case GLSL_TYPE_IMAGE:
149201e04c3fSmrg	 case GLSL_TYPE_UINT64:
149301e04c3fSmrg	    value.u64[i+offset] = src->get_uint64_component(id++);
149401e04c3fSmrg	    break;
149501e04c3fSmrg	 case GLSL_TYPE_INT64:
149601e04c3fSmrg	    value.i64[i+offset] = src->get_int64_component(id++);
149701e04c3fSmrg	    break;
149801e04c3fSmrg	 default:
149901e04c3fSmrg	    assert(!"Should not get here.");
150001e04c3fSmrg	    return;
150101e04c3fSmrg	 }
150201e04c3fSmrg      }
150301e04c3fSmrg   }
150401e04c3fSmrg}
150501e04c3fSmrg
150601e04c3fSmrgbool
150701e04c3fSmrgir_constant::has_value(const ir_constant *c) const
150801e04c3fSmrg{
150901e04c3fSmrg   if (this->type != c->type)
151001e04c3fSmrg      return false;
151101e04c3fSmrg
15127e102996Smaya   if (this->type->is_array() || this->type->is_struct()) {
151301e04c3fSmrg      for (unsigned i = 0; i < this->type->length; i++) {
151401e04c3fSmrg	 if (!this->const_elements[i]->has_value(c->const_elements[i]))
151501e04c3fSmrg	    return false;
151601e04c3fSmrg      }
151701e04c3fSmrg      return true;
151801e04c3fSmrg   }
151901e04c3fSmrg
152001e04c3fSmrg   for (unsigned i = 0; i < this->type->components(); i++) {
152101e04c3fSmrg      switch (this->type->base_type) {
15227ec681f3Smrg      case GLSL_TYPE_UINT16:
15237ec681f3Smrg	 if (this->value.u16[i] != c->value.u16[i])
15247ec681f3Smrg	    return false;
15257ec681f3Smrg	 break;
15267ec681f3Smrg      case GLSL_TYPE_INT16:
15277ec681f3Smrg	 if (this->value.i16[i] != c->value.i16[i])
15287ec681f3Smrg	    return false;
15297ec681f3Smrg	 break;
153001e04c3fSmrg      case GLSL_TYPE_UINT:
153101e04c3fSmrg	 if (this->value.u[i] != c->value.u[i])
153201e04c3fSmrg	    return false;
153301e04c3fSmrg	 break;
153401e04c3fSmrg      case GLSL_TYPE_INT:
153501e04c3fSmrg	 if (this->value.i[i] != c->value.i[i])
153601e04c3fSmrg	    return false;
153701e04c3fSmrg	 break;
153801e04c3fSmrg      case GLSL_TYPE_FLOAT:
153901e04c3fSmrg	 if (this->value.f[i] != c->value.f[i])
154001e04c3fSmrg	    return false;
154101e04c3fSmrg	 break;
15427ec681f3Smrg      case GLSL_TYPE_FLOAT16:
15437ec681f3Smrg	/* Convert to float to make sure NaN and ±0.0 compares correctly */
15447ec681f3Smrg	 if (_mesa_half_to_float(this->value.f16[i]) !=
15457ec681f3Smrg             _mesa_half_to_float(c->value.f16[i]))
15467ec681f3Smrg	    return false;
15477ec681f3Smrg	 break;
154801e04c3fSmrg      case GLSL_TYPE_BOOL:
154901e04c3fSmrg	 if (this->value.b[i] != c->value.b[i])
155001e04c3fSmrg	    return false;
155101e04c3fSmrg	 break;
155201e04c3fSmrg      case GLSL_TYPE_DOUBLE:
155301e04c3fSmrg	 if (this->value.d[i] != c->value.d[i])
155401e04c3fSmrg	    return false;
155501e04c3fSmrg	 break;
155601e04c3fSmrg      case GLSL_TYPE_SAMPLER:
155701e04c3fSmrg      case GLSL_TYPE_IMAGE:
155801e04c3fSmrg      case GLSL_TYPE_UINT64:
155901e04c3fSmrg	 if (this->value.u64[i] != c->value.u64[i])
156001e04c3fSmrg	    return false;
156101e04c3fSmrg	 break;
156201e04c3fSmrg      case GLSL_TYPE_INT64:
156301e04c3fSmrg	 if (this->value.i64[i] != c->value.i64[i])
156401e04c3fSmrg	    return false;
156501e04c3fSmrg	 break;
156601e04c3fSmrg      default:
156701e04c3fSmrg	 assert(!"Should not get here.");
156801e04c3fSmrg	 return false;
156901e04c3fSmrg      }
157001e04c3fSmrg   }
157101e04c3fSmrg
157201e04c3fSmrg   return true;
157301e04c3fSmrg}
157401e04c3fSmrg
157501e04c3fSmrgbool
157601e04c3fSmrgir_constant::is_value(float f, int i) const
157701e04c3fSmrg{
157801e04c3fSmrg   if (!this->type->is_scalar() && !this->type->is_vector())
157901e04c3fSmrg      return false;
158001e04c3fSmrg
158101e04c3fSmrg   /* Only accept boolean values for 0/1. */
158201e04c3fSmrg   if (int(bool(i)) != i && this->type->is_boolean())
158301e04c3fSmrg      return false;
158401e04c3fSmrg
158501e04c3fSmrg   for (unsigned c = 0; c < this->type->vector_elements; c++) {
158601e04c3fSmrg      switch (this->type->base_type) {
158701e04c3fSmrg      case GLSL_TYPE_FLOAT:
158801e04c3fSmrg	 if (this->value.f[c] != f)
158901e04c3fSmrg	    return false;
159001e04c3fSmrg	 break;
15917ec681f3Smrg      case GLSL_TYPE_FLOAT16:
15927ec681f3Smrg         if (_mesa_half_to_float(this->value.f16[c]) != f)
15937ec681f3Smrg            return false;
15947ec681f3Smrg         break;
15957ec681f3Smrg      case GLSL_TYPE_INT16:
15967ec681f3Smrg	 if (this->value.i16[c] != int16_t(i))
15977ec681f3Smrg	    return false;
15987ec681f3Smrg	 break;
15997ec681f3Smrg      case GLSL_TYPE_UINT16:
16007ec681f3Smrg	 if (this->value.u16[c] != uint16_t(i))
16017ec681f3Smrg	    return false;
16027ec681f3Smrg	 break;
160301e04c3fSmrg      case GLSL_TYPE_INT:
160401e04c3fSmrg	 if (this->value.i[c] != i)
160501e04c3fSmrg	    return false;
160601e04c3fSmrg	 break;
160701e04c3fSmrg      case GLSL_TYPE_UINT:
160801e04c3fSmrg	 if (this->value.u[c] != unsigned(i))
160901e04c3fSmrg	    return false;
161001e04c3fSmrg	 break;
161101e04c3fSmrg      case GLSL_TYPE_BOOL:
161201e04c3fSmrg	 if (this->value.b[c] != bool(i))
161301e04c3fSmrg	    return false;
161401e04c3fSmrg	 break;
161501e04c3fSmrg      case GLSL_TYPE_DOUBLE:
161601e04c3fSmrg	 if (this->value.d[c] != double(f))
161701e04c3fSmrg	    return false;
161801e04c3fSmrg	 break;
161901e04c3fSmrg      case GLSL_TYPE_SAMPLER:
162001e04c3fSmrg      case GLSL_TYPE_IMAGE:
162101e04c3fSmrg      case GLSL_TYPE_UINT64:
162201e04c3fSmrg	 if (this->value.u64[c] != uint64_t(i))
162301e04c3fSmrg	    return false;
162401e04c3fSmrg	 break;
162501e04c3fSmrg      case GLSL_TYPE_INT64:
162601e04c3fSmrg	 if (this->value.i64[c] != i)
162701e04c3fSmrg	    return false;
162801e04c3fSmrg	 break;
162901e04c3fSmrg      default:
163001e04c3fSmrg	 /* The only other base types are structures, arrays, and samplers.
163101e04c3fSmrg	  * Samplers cannot be constants, and the others should have been
163201e04c3fSmrg	  * filtered out above.
163301e04c3fSmrg	  */
163401e04c3fSmrg	 assert(!"Should not get here.");
163501e04c3fSmrg	 return false;
163601e04c3fSmrg      }
163701e04c3fSmrg   }
163801e04c3fSmrg
163901e04c3fSmrg   return true;
164001e04c3fSmrg}
164101e04c3fSmrg
164201e04c3fSmrgbool
164301e04c3fSmrgir_constant::is_zero() const
164401e04c3fSmrg{
164501e04c3fSmrg   return is_value(0.0, 0);
164601e04c3fSmrg}
164701e04c3fSmrg
164801e04c3fSmrgbool
164901e04c3fSmrgir_constant::is_one() const
165001e04c3fSmrg{
165101e04c3fSmrg   return is_value(1.0, 1);
165201e04c3fSmrg}
165301e04c3fSmrg
165401e04c3fSmrgbool
165501e04c3fSmrgir_constant::is_negative_one() const
165601e04c3fSmrg{
165701e04c3fSmrg   return is_value(-1.0, -1);
165801e04c3fSmrg}
165901e04c3fSmrg
166001e04c3fSmrgbool
166101e04c3fSmrgir_constant::is_uint16_constant() const
166201e04c3fSmrg{
16637ec681f3Smrg   if (!type->is_integer_32())
166401e04c3fSmrg      return false;
166501e04c3fSmrg
166601e04c3fSmrg   return value.u[0] < (1 << 16);
166701e04c3fSmrg}
166801e04c3fSmrg
166901e04c3fSmrgir_loop::ir_loop()
167001e04c3fSmrg   : ir_instruction(ir_type_loop)
167101e04c3fSmrg{
167201e04c3fSmrg}
167301e04c3fSmrg
167401e04c3fSmrg
167501e04c3fSmrgir_dereference_variable::ir_dereference_variable(ir_variable *var)
167601e04c3fSmrg   : ir_dereference(ir_type_dereference_variable)
167701e04c3fSmrg{
167801e04c3fSmrg   assert(var != NULL);
167901e04c3fSmrg
168001e04c3fSmrg   this->var = var;
168101e04c3fSmrg   this->type = var->type;
168201e04c3fSmrg}
168301e04c3fSmrg
168401e04c3fSmrg
168501e04c3fSmrgir_dereference_array::ir_dereference_array(ir_rvalue *value,
168601e04c3fSmrg					   ir_rvalue *array_index)
168701e04c3fSmrg   : ir_dereference(ir_type_dereference_array)
168801e04c3fSmrg{
168901e04c3fSmrg   this->array_index = array_index;
169001e04c3fSmrg   this->set_array(value);
169101e04c3fSmrg}
169201e04c3fSmrg
169301e04c3fSmrg
169401e04c3fSmrgir_dereference_array::ir_dereference_array(ir_variable *var,
169501e04c3fSmrg					   ir_rvalue *array_index)
169601e04c3fSmrg   : ir_dereference(ir_type_dereference_array)
169701e04c3fSmrg{
169801e04c3fSmrg   void *ctx = ralloc_parent(var);
169901e04c3fSmrg
170001e04c3fSmrg   this->array_index = array_index;
170101e04c3fSmrg   this->set_array(new(ctx) ir_dereference_variable(var));
170201e04c3fSmrg}
170301e04c3fSmrg
170401e04c3fSmrg
170501e04c3fSmrgvoid
170601e04c3fSmrgir_dereference_array::set_array(ir_rvalue *value)
170701e04c3fSmrg{
170801e04c3fSmrg   assert(value != NULL);
170901e04c3fSmrg
171001e04c3fSmrg   this->array = value;
171101e04c3fSmrg
171201e04c3fSmrg   const glsl_type *const vt = this->array->type;
171301e04c3fSmrg
171401e04c3fSmrg   if (vt->is_array()) {
171501e04c3fSmrg      type = vt->fields.array;
171601e04c3fSmrg   } else if (vt->is_matrix()) {
171701e04c3fSmrg      type = vt->column_type();
171801e04c3fSmrg   } else if (vt->is_vector()) {
171901e04c3fSmrg      type = vt->get_base_type();
172001e04c3fSmrg   }
172101e04c3fSmrg}
172201e04c3fSmrg
172301e04c3fSmrg
172401e04c3fSmrgir_dereference_record::ir_dereference_record(ir_rvalue *value,
172501e04c3fSmrg					     const char *field)
172601e04c3fSmrg   : ir_dereference(ir_type_dereference_record)
172701e04c3fSmrg{
172801e04c3fSmrg   assert(value != NULL);
172901e04c3fSmrg
173001e04c3fSmrg   this->record = value;
173101e04c3fSmrg   this->type = this->record->type->field_type(field);
173201e04c3fSmrg   this->field_idx = this->record->type->field_index(field);
173301e04c3fSmrg}
173401e04c3fSmrg
173501e04c3fSmrg
173601e04c3fSmrgir_dereference_record::ir_dereference_record(ir_variable *var,
173701e04c3fSmrg					     const char *field)
173801e04c3fSmrg   : ir_dereference(ir_type_dereference_record)
173901e04c3fSmrg{
174001e04c3fSmrg   void *ctx = ralloc_parent(var);
174101e04c3fSmrg
174201e04c3fSmrg   this->record = new(ctx) ir_dereference_variable(var);
174301e04c3fSmrg   this->type = this->record->type->field_type(field);
174401e04c3fSmrg   this->field_idx = this->record->type->field_index(field);
174501e04c3fSmrg}
174601e04c3fSmrg
174701e04c3fSmrgbool
174801e04c3fSmrgir_dereference::is_lvalue(const struct _mesa_glsl_parse_state *state) const
174901e04c3fSmrg{
175001e04c3fSmrg   ir_variable *var = this->variable_referenced();
175101e04c3fSmrg
17527ec681f3Smrg   /* Every l-value dereference chain eventually ends in a variable.
175301e04c3fSmrg    */
175401e04c3fSmrg   if ((var == NULL) || var->data.read_only)
175501e04c3fSmrg      return false;
175601e04c3fSmrg
175701e04c3fSmrg   /* From section 4.1.7 of the ARB_bindless_texture spec:
175801e04c3fSmrg    *
175901e04c3fSmrg    * "Samplers can be used as l-values, so can be assigned into and used as
176001e04c3fSmrg    *  "out" and "inout" function parameters."
176101e04c3fSmrg    *
176201e04c3fSmrg    * From section 4.1.X of the ARB_bindless_texture spec:
176301e04c3fSmrg    *
176401e04c3fSmrg    * "Images can be used as l-values, so can be assigned into and used as
176501e04c3fSmrg    *  "out" and "inout" function parameters."
176601e04c3fSmrg    */
176701e04c3fSmrg   if ((!state || state->has_bindless()) &&
176801e04c3fSmrg       (this->type->contains_sampler() || this->type->contains_image()))
176901e04c3fSmrg      return true;
177001e04c3fSmrg
177101e04c3fSmrg   /* From section 4.1.7 of the GLSL 4.40 spec:
177201e04c3fSmrg    *
177301e04c3fSmrg    *   "Opaque variables cannot be treated as l-values; hence cannot
177401e04c3fSmrg    *    be used as out or inout function parameters, nor can they be
177501e04c3fSmrg    *    assigned into."
177601e04c3fSmrg    */
177701e04c3fSmrg   if (this->type->contains_opaque())
177801e04c3fSmrg      return false;
177901e04c3fSmrg
178001e04c3fSmrg   return true;
178101e04c3fSmrg}
178201e04c3fSmrg
178301e04c3fSmrg
178401e04c3fSmrgstatic const char * const tex_opcode_strs[] = { "tex", "txb", "txl", "txd", "txf", "txf_ms", "txs", "lod", "tg4", "query_levels", "texture_samples", "samples_identical" };
178501e04c3fSmrg
178601e04c3fSmrgconst char *ir_texture::opcode_string()
178701e04c3fSmrg{
178801e04c3fSmrg   assert((unsigned int) op < ARRAY_SIZE(tex_opcode_strs));
178901e04c3fSmrg   return tex_opcode_strs[op];
179001e04c3fSmrg}
179101e04c3fSmrg
179201e04c3fSmrgir_texture_opcode
179301e04c3fSmrgir_texture::get_opcode(const char *str)
179401e04c3fSmrg{
179501e04c3fSmrg   const int count = sizeof(tex_opcode_strs) / sizeof(tex_opcode_strs[0]);
179601e04c3fSmrg   for (int op = 0; op < count; op++) {
179701e04c3fSmrg      if (strcmp(str, tex_opcode_strs[op]) == 0)
179801e04c3fSmrg	 return (ir_texture_opcode) op;
179901e04c3fSmrg   }
180001e04c3fSmrg   return (ir_texture_opcode) -1;
180101e04c3fSmrg}
180201e04c3fSmrg
180301e04c3fSmrg
180401e04c3fSmrgvoid
180501e04c3fSmrgir_texture::set_sampler(ir_dereference *sampler, const glsl_type *type)
180601e04c3fSmrg{
180701e04c3fSmrg   assert(sampler != NULL);
180801e04c3fSmrg   assert(type != NULL);
180901e04c3fSmrg   this->sampler = sampler;
181001e04c3fSmrg   this->type = type;
181101e04c3fSmrg
181201e04c3fSmrg   if (this->op == ir_txs || this->op == ir_query_levels ||
181301e04c3fSmrg       this->op == ir_texture_samples) {
181401e04c3fSmrg      assert(type->base_type == GLSL_TYPE_INT);
181501e04c3fSmrg   } else if (this->op == ir_lod) {
181601e04c3fSmrg      assert(type->vector_elements == 2);
181701e04c3fSmrg      assert(type->is_float());
181801e04c3fSmrg   } else if (this->op == ir_samples_identical) {
181901e04c3fSmrg      assert(type == glsl_type::bool_type);
182001e04c3fSmrg      assert(sampler->type->is_sampler());
182101e04c3fSmrg      assert(sampler->type->sampler_dimensionality == GLSL_SAMPLER_DIM_MS);
182201e04c3fSmrg   } else {
182301e04c3fSmrg      assert(sampler->type->sampled_type == (int) type->base_type);
182401e04c3fSmrg      if (sampler->type->sampler_shadow)
182501e04c3fSmrg	 assert(type->vector_elements == 4 || type->vector_elements == 1);
182601e04c3fSmrg      else
182701e04c3fSmrg	 assert(type->vector_elements == 4);
182801e04c3fSmrg   }
182901e04c3fSmrg}
183001e04c3fSmrg
183101e04c3fSmrg
183201e04c3fSmrgvoid
183301e04c3fSmrgir_swizzle::init_mask(const unsigned *comp, unsigned count)
183401e04c3fSmrg{
183501e04c3fSmrg   assert((count >= 1) && (count <= 4));
183601e04c3fSmrg
183701e04c3fSmrg   memset(&this->mask, 0, sizeof(this->mask));
183801e04c3fSmrg   this->mask.num_components = count;
183901e04c3fSmrg
184001e04c3fSmrg   unsigned dup_mask = 0;
184101e04c3fSmrg   switch (count) {
184201e04c3fSmrg   case 4:
184301e04c3fSmrg      assert(comp[3] <= 3);
184401e04c3fSmrg      dup_mask |= (1U << comp[3])
184501e04c3fSmrg	 & ((1U << comp[0]) | (1U << comp[1]) | (1U << comp[2]));
184601e04c3fSmrg      this->mask.w = comp[3];
184701e04c3fSmrg
184801e04c3fSmrg   case 3:
184901e04c3fSmrg      assert(comp[2] <= 3);
185001e04c3fSmrg      dup_mask |= (1U << comp[2])
185101e04c3fSmrg	 & ((1U << comp[0]) | (1U << comp[1]));
185201e04c3fSmrg      this->mask.z = comp[2];
185301e04c3fSmrg
185401e04c3fSmrg   case 2:
185501e04c3fSmrg      assert(comp[1] <= 3);
185601e04c3fSmrg      dup_mask |= (1U << comp[1])
185701e04c3fSmrg	 & ((1U << comp[0]));
185801e04c3fSmrg      this->mask.y = comp[1];
185901e04c3fSmrg
186001e04c3fSmrg   case 1:
186101e04c3fSmrg      assert(comp[0] <= 3);
186201e04c3fSmrg      this->mask.x = comp[0];
186301e04c3fSmrg   }
186401e04c3fSmrg
186501e04c3fSmrg   this->mask.has_duplicates = dup_mask != 0;
186601e04c3fSmrg
186701e04c3fSmrg   /* Based on the number of elements in the swizzle and the base type
186801e04c3fSmrg    * (i.e., float, int, unsigned, or bool) of the vector being swizzled,
186901e04c3fSmrg    * generate the type of the resulting value.
187001e04c3fSmrg    */
187101e04c3fSmrg   type = glsl_type::get_instance(val->type->base_type, mask.num_components, 1);
187201e04c3fSmrg}
187301e04c3fSmrg
187401e04c3fSmrgir_swizzle::ir_swizzle(ir_rvalue *val, unsigned x, unsigned y, unsigned z,
187501e04c3fSmrg		       unsigned w, unsigned count)
187601e04c3fSmrg   : ir_rvalue(ir_type_swizzle), val(val)
187701e04c3fSmrg{
187801e04c3fSmrg   const unsigned components[4] = { x, y, z, w };
187901e04c3fSmrg   this->init_mask(components, count);
188001e04c3fSmrg}
188101e04c3fSmrg
188201e04c3fSmrgir_swizzle::ir_swizzle(ir_rvalue *val, const unsigned *comp,
188301e04c3fSmrg		       unsigned count)
188401e04c3fSmrg   : ir_rvalue(ir_type_swizzle), val(val)
188501e04c3fSmrg{
188601e04c3fSmrg   this->init_mask(comp, count);
188701e04c3fSmrg}
188801e04c3fSmrg
188901e04c3fSmrgir_swizzle::ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask)
189001e04c3fSmrg   : ir_rvalue(ir_type_swizzle), val(val), mask(mask)
189101e04c3fSmrg{
189201e04c3fSmrg   this->type = glsl_type::get_instance(val->type->base_type,
189301e04c3fSmrg					mask.num_components, 1);
189401e04c3fSmrg}
189501e04c3fSmrg
189601e04c3fSmrg#define X 1
189701e04c3fSmrg#define R 5
189801e04c3fSmrg#define S 9
189901e04c3fSmrg#define I 13
190001e04c3fSmrg
190101e04c3fSmrgir_swizzle *
190201e04c3fSmrgir_swizzle::create(ir_rvalue *val, const char *str, unsigned vector_length)
190301e04c3fSmrg{
190401e04c3fSmrg   void *ctx = ralloc_parent(val);
190501e04c3fSmrg
190601e04c3fSmrg   /* For each possible swizzle character, this table encodes the value in
190701e04c3fSmrg    * \c idx_map that represents the 0th element of the vector.  For invalid
190801e04c3fSmrg    * swizzle characters (e.g., 'k'), a special value is used that will allow
190901e04c3fSmrg    * detection of errors.
191001e04c3fSmrg    */
191101e04c3fSmrg   static const unsigned char base_idx[26] = {
191201e04c3fSmrg   /* a  b  c  d  e  f  g  h  i  j  k  l  m */
191301e04c3fSmrg      R, R, I, I, I, I, R, I, I, I, I, I, I,
191401e04c3fSmrg   /* n  o  p  q  r  s  t  u  v  w  x  y  z */
191501e04c3fSmrg      I, I, S, S, R, S, S, I, I, X, X, X, X
191601e04c3fSmrg   };
191701e04c3fSmrg
191801e04c3fSmrg   /* Each valid swizzle character has an entry in the previous table.  This
191901e04c3fSmrg    * table encodes the base index encoded in the previous table plus the actual
192001e04c3fSmrg    * index of the swizzle character.  When processing swizzles, the first
192101e04c3fSmrg    * character in the string is indexed in the previous table.  Each character
192201e04c3fSmrg    * in the string is indexed in this table, and the value found there has the
192301e04c3fSmrg    * value form the first table subtracted.  The result must be on the range
192401e04c3fSmrg    * [0,3].
192501e04c3fSmrg    *
192601e04c3fSmrg    * For example, the string "wzyx" will get X from the first table.  Each of
192701e04c3fSmrg    * the charcaters will get X+3, X+2, X+1, and X+0 from this table.  After
192801e04c3fSmrg    * subtraction, the swizzle values are { 3, 2, 1, 0 }.
192901e04c3fSmrg    *
193001e04c3fSmrg    * The string "wzrg" will get X from the first table.  Each of the characters
193101e04c3fSmrg    * will get X+3, X+2, R+0, and R+1 from this table.  After subtraction, the
193201e04c3fSmrg    * swizzle values are { 3, 2, 4, 5 }.  Since 4 and 5 are outside the range
193301e04c3fSmrg    * [0,3], the error is detected.
193401e04c3fSmrg    */
193501e04c3fSmrg   static const unsigned char idx_map[26] = {
193601e04c3fSmrg   /* a    b    c    d    e    f    g    h    i    j    k    l    m */
193701e04c3fSmrg      R+3, R+2, 0,   0,   0,   0,   R+1, 0,   0,   0,   0,   0,   0,
193801e04c3fSmrg   /* n    o    p    q    r    s    t    u    v    w    x    y    z */
193901e04c3fSmrg      0,   0,   S+2, S+3, R+0, S+0, S+1, 0,   0,   X+3, X+0, X+1, X+2
194001e04c3fSmrg   };
194101e04c3fSmrg
194201e04c3fSmrg   int swiz_idx[4] = { 0, 0, 0, 0 };
194301e04c3fSmrg   unsigned i;
194401e04c3fSmrg
194501e04c3fSmrg
194601e04c3fSmrg   /* Validate the first character in the swizzle string and look up the base
194701e04c3fSmrg    * index value as described above.
194801e04c3fSmrg    */
194901e04c3fSmrg   if ((str[0] < 'a') || (str[0] > 'z'))
195001e04c3fSmrg      return NULL;
195101e04c3fSmrg
195201e04c3fSmrg   const unsigned base = base_idx[str[0] - 'a'];
195301e04c3fSmrg
195401e04c3fSmrg
195501e04c3fSmrg   for (i = 0; (i < 4) && (str[i] != '\0'); i++) {
195601e04c3fSmrg      /* Validate the next character, and, as described above, convert it to a
195701e04c3fSmrg       * swizzle index.
195801e04c3fSmrg       */
195901e04c3fSmrg      if ((str[i] < 'a') || (str[i] > 'z'))
196001e04c3fSmrg	 return NULL;
196101e04c3fSmrg
196201e04c3fSmrg      swiz_idx[i] = idx_map[str[i] - 'a'] - base;
196301e04c3fSmrg      if ((swiz_idx[i] < 0) || (swiz_idx[i] >= (int) vector_length))
196401e04c3fSmrg	 return NULL;
196501e04c3fSmrg   }
196601e04c3fSmrg
196701e04c3fSmrg   if (str[i] != '\0')
196801e04c3fSmrg	 return NULL;
196901e04c3fSmrg
197001e04c3fSmrg   return new(ctx) ir_swizzle(val, swiz_idx[0], swiz_idx[1], swiz_idx[2],
197101e04c3fSmrg			      swiz_idx[3], i);
197201e04c3fSmrg}
197301e04c3fSmrg
197401e04c3fSmrg#undef X
197501e04c3fSmrg#undef R
197601e04c3fSmrg#undef S
197701e04c3fSmrg#undef I
197801e04c3fSmrg
197901e04c3fSmrgir_variable *
198001e04c3fSmrgir_swizzle::variable_referenced() const
198101e04c3fSmrg{
198201e04c3fSmrg   return this->val->variable_referenced();
198301e04c3fSmrg}
198401e04c3fSmrg
198501e04c3fSmrg
198601e04c3fSmrgbool ir_variable::temporaries_allocate_names = false;
198701e04c3fSmrg
198801e04c3fSmrgconst char ir_variable::tmp_name[] = "compiler_temp";
198901e04c3fSmrg
199001e04c3fSmrgir_variable::ir_variable(const struct glsl_type *type, const char *name,
199101e04c3fSmrg			 ir_variable_mode mode)
199201e04c3fSmrg   : ir_instruction(ir_type_variable)
199301e04c3fSmrg{
199401e04c3fSmrg   this->type = type;
199501e04c3fSmrg
199601e04c3fSmrg   if (mode == ir_var_temporary && !ir_variable::temporaries_allocate_names)
199701e04c3fSmrg      name = NULL;
199801e04c3fSmrg
199901e04c3fSmrg   /* The ir_variable clone method may call this constructor with name set to
200001e04c3fSmrg    * tmp_name.
200101e04c3fSmrg    */
200201e04c3fSmrg   assert(name != NULL
200301e04c3fSmrg          || mode == ir_var_temporary
200401e04c3fSmrg          || mode == ir_var_function_in
200501e04c3fSmrg          || mode == ir_var_function_out
200601e04c3fSmrg          || mode == ir_var_function_inout);
200701e04c3fSmrg   assert(name != ir_variable::tmp_name
200801e04c3fSmrg          || mode == ir_var_temporary);
200901e04c3fSmrg   if (mode == ir_var_temporary
201001e04c3fSmrg       && (name == NULL || name == ir_variable::tmp_name)) {
201101e04c3fSmrg      this->name = ir_variable::tmp_name;
201201e04c3fSmrg   } else if (name == NULL ||
201301e04c3fSmrg              strlen(name) < ARRAY_SIZE(this->name_storage)) {
201401e04c3fSmrg      strcpy(this->name_storage, name ? name : "");
201501e04c3fSmrg      this->name = this->name_storage;
201601e04c3fSmrg   } else {
201701e04c3fSmrg      this->name = ralloc_strdup(this, name);
201801e04c3fSmrg   }
201901e04c3fSmrg
202001e04c3fSmrg   this->u.max_ifc_array_access = NULL;
202101e04c3fSmrg
202201e04c3fSmrg   this->data.explicit_location = false;
20237ec681f3Smrg   this->data.explicit_index = false;
20247ec681f3Smrg   this->data.explicit_binding = false;
20257ec681f3Smrg   this->data.explicit_component = false;
202601e04c3fSmrg   this->data.has_initializer = false;
20277ec681f3Smrg   this->data.is_implicit_initializer = false;
20287ec681f3Smrg   this->data.is_unmatched_generic_inout = false;
20297ec681f3Smrg   this->data.is_xfb = false;
20307ec681f3Smrg   this->data.is_xfb_only = false;
20317ec681f3Smrg   this->data.explicit_xfb_buffer = false;
20327ec681f3Smrg   this->data.explicit_xfb_offset = false;
20337ec681f3Smrg   this->data.explicit_xfb_stride = false;
203401e04c3fSmrg   this->data.location = -1;
203501e04c3fSmrg   this->data.location_frac = 0;
20367ec681f3Smrg   this->data.matrix_layout = GLSL_MATRIX_LAYOUT_INHERITED;
20377ec681f3Smrg   this->data.from_named_ifc_block = false;
20387ec681f3Smrg   this->data.must_be_shader_input = false;
20397ec681f3Smrg   this->data.index = 0;
204001e04c3fSmrg   this->data.binding = 0;
204101e04c3fSmrg   this->data.warn_extension_index = 0;
204201e04c3fSmrg   this->constant_value = NULL;
204301e04c3fSmrg   this->constant_initializer = NULL;
204401e04c3fSmrg   this->data.depth_layout = ir_depth_layout_none;
204501e04c3fSmrg   this->data.used = false;
20467ec681f3Smrg   this->data.assigned = false;
204701e04c3fSmrg   this->data.always_active_io = false;
204801e04c3fSmrg   this->data.read_only = false;
204901e04c3fSmrg   this->data.centroid = false;
205001e04c3fSmrg   this->data.sample = false;
205101e04c3fSmrg   this->data.patch = false;
2052993e1d59Smrg   this->data.explicit_invariant = false;
205301e04c3fSmrg   this->data.invariant = false;
20547ec681f3Smrg   this->data.precise = false;
205501e04c3fSmrg   this->data.how_declared = ir_var_declared_normally;
205601e04c3fSmrg   this->data.mode = mode;
205701e04c3fSmrg   this->data.interpolation = INTERP_MODE_NONE;
205801e04c3fSmrg   this->data.max_array_access = -1;
205901e04c3fSmrg   this->data.offset = 0;
206001e04c3fSmrg   this->data.precision = GLSL_PRECISION_NONE;
206101e04c3fSmrg   this->data.memory_read_only = false;
206201e04c3fSmrg   this->data.memory_write_only = false;
206301e04c3fSmrg   this->data.memory_coherent = false;
206401e04c3fSmrg   this->data.memory_volatile = false;
206501e04c3fSmrg   this->data.memory_restrict = false;
206601e04c3fSmrg   this->data.from_ssbo_unsized_array = false;
20677ec681f3Smrg   this->data.implicit_sized_array = false;
206801e04c3fSmrg   this->data.fb_fetch_output = false;
206901e04c3fSmrg   this->data.bindless = false;
207001e04c3fSmrg   this->data.bound = false;
20717ec681f3Smrg   this->data.image_format = PIPE_FORMAT_NONE;
20727ec681f3Smrg   this->data._num_state_slots = 0;
20737ec681f3Smrg   this->data.param_index = 0;
20747ec681f3Smrg   this->data.stream = 0;
20757ec681f3Smrg   this->data.xfb_buffer = -1;
20767ec681f3Smrg   this->data.xfb_stride = -1;
20777ec681f3Smrg   this->data.implicit_conversion_prohibited = false;
20787ec681f3Smrg
20797ec681f3Smrg   this->interface_type = NULL;
208001e04c3fSmrg
208101e04c3fSmrg   if (type != NULL) {
208201e04c3fSmrg      if (type->is_interface())
208301e04c3fSmrg         this->init_interface_type(type);
208401e04c3fSmrg      else if (type->without_array()->is_interface())
208501e04c3fSmrg         this->init_interface_type(type->without_array());
208601e04c3fSmrg   }
208701e04c3fSmrg}
208801e04c3fSmrg
208901e04c3fSmrg
209001e04c3fSmrgconst char *
209101e04c3fSmrginterpolation_string(unsigned interpolation)
209201e04c3fSmrg{
209301e04c3fSmrg   switch (interpolation) {
209401e04c3fSmrg   case INTERP_MODE_NONE:          return "no";
209501e04c3fSmrg   case INTERP_MODE_SMOOTH:        return "smooth";
209601e04c3fSmrg   case INTERP_MODE_FLAT:          return "flat";
209701e04c3fSmrg   case INTERP_MODE_NOPERSPECTIVE: return "noperspective";
209801e04c3fSmrg   }
209901e04c3fSmrg
210001e04c3fSmrg   assert(!"Should not get here.");
210101e04c3fSmrg   return "";
210201e04c3fSmrg}
210301e04c3fSmrg
210401e04c3fSmrgconst char *const ir_variable::warn_extension_table[] = {
210501e04c3fSmrg   "",
210601e04c3fSmrg   "GL_ARB_shader_stencil_export",
210701e04c3fSmrg   "GL_AMD_shader_stencil_export",
210801e04c3fSmrg};
210901e04c3fSmrg
211001e04c3fSmrgvoid
211101e04c3fSmrgir_variable::enable_extension_warning(const char *extension)
211201e04c3fSmrg{
211301e04c3fSmrg   for (unsigned i = 0; i < ARRAY_SIZE(warn_extension_table); i++) {
211401e04c3fSmrg      if (strcmp(warn_extension_table[i], extension) == 0) {
211501e04c3fSmrg         this->data.warn_extension_index = i;
211601e04c3fSmrg         return;
211701e04c3fSmrg      }
211801e04c3fSmrg   }
211901e04c3fSmrg
212001e04c3fSmrg   assert(!"Should not get here.");
212101e04c3fSmrg   this->data.warn_extension_index = 0;
212201e04c3fSmrg}
212301e04c3fSmrg
212401e04c3fSmrgconst char *
212501e04c3fSmrgir_variable::get_extension_warning() const
212601e04c3fSmrg{
212701e04c3fSmrg   return this->data.warn_extension_index == 0
212801e04c3fSmrg      ? NULL : warn_extension_table[this->data.warn_extension_index];
212901e04c3fSmrg}
213001e04c3fSmrg
213101e04c3fSmrgir_function_signature::ir_function_signature(const glsl_type *return_type,
213201e04c3fSmrg                                             builtin_available_predicate b)
213301e04c3fSmrg   : ir_instruction(ir_type_function_signature),
213401e04c3fSmrg     return_type(return_type), is_defined(false),
21357ec681f3Smrg     return_precision(GLSL_PRECISION_NONE),
213601e04c3fSmrg     intrinsic_id(ir_intrinsic_invalid), builtin_avail(b), _function(NULL)
213701e04c3fSmrg{
213801e04c3fSmrg   this->origin = NULL;
213901e04c3fSmrg}
214001e04c3fSmrg
214101e04c3fSmrg
214201e04c3fSmrgbool
214301e04c3fSmrgir_function_signature::is_builtin() const
214401e04c3fSmrg{
214501e04c3fSmrg   return builtin_avail != NULL;
214601e04c3fSmrg}
214701e04c3fSmrg
214801e04c3fSmrg
214901e04c3fSmrgbool
215001e04c3fSmrgir_function_signature::is_builtin_available(const _mesa_glsl_parse_state *state) const
215101e04c3fSmrg{
215201e04c3fSmrg   /* We can't call the predicate without a state pointer, so just say that
215301e04c3fSmrg    * the signature is available.  At compile time, we need the filtering,
215401e04c3fSmrg    * but also receive a valid state pointer.  At link time, we're resolving
215501e04c3fSmrg    * imported built-in prototypes to their definitions, which will always
215601e04c3fSmrg    * be an exact match.  So we can skip the filtering.
215701e04c3fSmrg    */
215801e04c3fSmrg   if (state == NULL)
215901e04c3fSmrg      return true;
216001e04c3fSmrg
216101e04c3fSmrg   assert(builtin_avail != NULL);
216201e04c3fSmrg   return builtin_avail(state);
216301e04c3fSmrg}
216401e04c3fSmrg
216501e04c3fSmrg
216601e04c3fSmrgstatic bool
216701e04c3fSmrgmodes_match(unsigned a, unsigned b)
216801e04c3fSmrg{
216901e04c3fSmrg   if (a == b)
217001e04c3fSmrg      return true;
217101e04c3fSmrg
217201e04c3fSmrg   /* Accept "in" vs. "const in" */
217301e04c3fSmrg   if ((a == ir_var_const_in && b == ir_var_function_in) ||
217401e04c3fSmrg       (b == ir_var_const_in && a == ir_var_function_in))
217501e04c3fSmrg      return true;
217601e04c3fSmrg
217701e04c3fSmrg   return false;
217801e04c3fSmrg}
217901e04c3fSmrg
218001e04c3fSmrg
218101e04c3fSmrgconst char *
218201e04c3fSmrgir_function_signature::qualifiers_match(exec_list *params)
218301e04c3fSmrg{
218401e04c3fSmrg   /* check that the qualifiers match. */
218501e04c3fSmrg   foreach_two_lists(a_node, &this->parameters, b_node, params) {
218601e04c3fSmrg      ir_variable *a = (ir_variable *) a_node;
218701e04c3fSmrg      ir_variable *b = (ir_variable *) b_node;
218801e04c3fSmrg
218901e04c3fSmrg      if (a->data.read_only != b->data.read_only ||
219001e04c3fSmrg	  !modes_match(a->data.mode, b->data.mode) ||
219101e04c3fSmrg	  a->data.interpolation != b->data.interpolation ||
219201e04c3fSmrg	  a->data.centroid != b->data.centroid ||
219301e04c3fSmrg          a->data.sample != b->data.sample ||
219401e04c3fSmrg          a->data.patch != b->data.patch ||
219501e04c3fSmrg          a->data.memory_read_only != b->data.memory_read_only ||
219601e04c3fSmrg          a->data.memory_write_only != b->data.memory_write_only ||
219701e04c3fSmrg          a->data.memory_coherent != b->data.memory_coherent ||
219801e04c3fSmrg          a->data.memory_volatile != b->data.memory_volatile ||
219901e04c3fSmrg          a->data.memory_restrict != b->data.memory_restrict) {
220001e04c3fSmrg
220101e04c3fSmrg	 /* parameter a's qualifiers don't match */
220201e04c3fSmrg	 return a->name;
220301e04c3fSmrg      }
220401e04c3fSmrg   }
220501e04c3fSmrg   return NULL;
220601e04c3fSmrg}
220701e04c3fSmrg
220801e04c3fSmrg
220901e04c3fSmrgvoid
221001e04c3fSmrgir_function_signature::replace_parameters(exec_list *new_params)
221101e04c3fSmrg{
221201e04c3fSmrg   /* Destroy all of the previous parameter information.  If the previous
221301e04c3fSmrg    * parameter information comes from the function prototype, it may either
221401e04c3fSmrg    * specify incorrect parameter names or not have names at all.
221501e04c3fSmrg    */
221601e04c3fSmrg   new_params->move_nodes_to(&parameters);
221701e04c3fSmrg}
221801e04c3fSmrg
221901e04c3fSmrg
222001e04c3fSmrgir_function::ir_function(const char *name)
222101e04c3fSmrg   : ir_instruction(ir_type_function)
222201e04c3fSmrg{
222301e04c3fSmrg   this->subroutine_index = -1;
222401e04c3fSmrg   this->name = ralloc_strdup(this, name);
222501e04c3fSmrg}
222601e04c3fSmrg
222701e04c3fSmrg
222801e04c3fSmrgbool
222901e04c3fSmrgir_function::has_user_signature()
223001e04c3fSmrg{
223101e04c3fSmrg   foreach_in_list(ir_function_signature, sig, &this->signatures) {
223201e04c3fSmrg      if (!sig->is_builtin())
223301e04c3fSmrg	 return true;
223401e04c3fSmrg   }
223501e04c3fSmrg   return false;
223601e04c3fSmrg}
223701e04c3fSmrg
223801e04c3fSmrg
223901e04c3fSmrgir_rvalue *
224001e04c3fSmrgir_rvalue::error_value(void *mem_ctx)
224101e04c3fSmrg{
224201e04c3fSmrg   ir_rvalue *v = new(mem_ctx) ir_rvalue(ir_type_unset);
224301e04c3fSmrg
224401e04c3fSmrg   v->type = glsl_type::error_type;
224501e04c3fSmrg   return v;
224601e04c3fSmrg}
224701e04c3fSmrg
224801e04c3fSmrg
224901e04c3fSmrgvoid
225001e04c3fSmrgvisit_exec_list(exec_list *list, ir_visitor *visitor)
225101e04c3fSmrg{
225201e04c3fSmrg   foreach_in_list_safe(ir_instruction, node, list) {
225301e04c3fSmrg      node->accept(visitor);
225401e04c3fSmrg   }
225501e04c3fSmrg}
225601e04c3fSmrg
225701e04c3fSmrg
225801e04c3fSmrgstatic void
225901e04c3fSmrgsteal_memory(ir_instruction *ir, void *new_ctx)
226001e04c3fSmrg{
226101e04c3fSmrg   ir_variable *var = ir->as_variable();
226201e04c3fSmrg   ir_function *fn = ir->as_function();
226301e04c3fSmrg   ir_constant *constant = ir->as_constant();
226401e04c3fSmrg   if (var != NULL && var->constant_value != NULL)
226501e04c3fSmrg      steal_memory(var->constant_value, ir);
226601e04c3fSmrg
226701e04c3fSmrg   if (var != NULL && var->constant_initializer != NULL)
226801e04c3fSmrg      steal_memory(var->constant_initializer, ir);
226901e04c3fSmrg
227001e04c3fSmrg   if (fn != NULL && fn->subroutine_types)
227101e04c3fSmrg      ralloc_steal(new_ctx, fn->subroutine_types);
227201e04c3fSmrg
227301e04c3fSmrg   /* The components of aggregate constants are not visited by the normal
227401e04c3fSmrg    * visitor, so steal their values by hand.
227501e04c3fSmrg    */
227601e04c3fSmrg   if (constant != NULL &&
22777e102996Smaya       (constant->type->is_array() || constant->type->is_struct())) {
227801e04c3fSmrg      for (unsigned int i = 0; i < constant->type->length; i++) {
227901e04c3fSmrg         steal_memory(constant->const_elements[i], ir);
228001e04c3fSmrg      }
228101e04c3fSmrg   }
228201e04c3fSmrg
228301e04c3fSmrg   ralloc_steal(new_ctx, ir);
228401e04c3fSmrg}
228501e04c3fSmrg
228601e04c3fSmrg
228701e04c3fSmrgvoid
228801e04c3fSmrgreparent_ir(exec_list *list, void *mem_ctx)
228901e04c3fSmrg{
229001e04c3fSmrg   foreach_in_list(ir_instruction, node, list) {
229101e04c3fSmrg      visit_tree(node, steal_memory, mem_ctx);
229201e04c3fSmrg   }
229301e04c3fSmrg}
229401e04c3fSmrg
229501e04c3fSmrg
229601e04c3fSmrgstatic ir_rvalue *
229701e04c3fSmrgtry_min_one(ir_rvalue *ir)
229801e04c3fSmrg{
229901e04c3fSmrg   ir_expression *expr = ir->as_expression();
230001e04c3fSmrg
230101e04c3fSmrg   if (!expr || expr->operation != ir_binop_min)
230201e04c3fSmrg      return NULL;
230301e04c3fSmrg
230401e04c3fSmrg   if (expr->operands[0]->is_one())
230501e04c3fSmrg      return expr->operands[1];
230601e04c3fSmrg
230701e04c3fSmrg   if (expr->operands[1]->is_one())
230801e04c3fSmrg      return expr->operands[0];
230901e04c3fSmrg
231001e04c3fSmrg   return NULL;
231101e04c3fSmrg}
231201e04c3fSmrg
231301e04c3fSmrgstatic ir_rvalue *
231401e04c3fSmrgtry_max_zero(ir_rvalue *ir)
231501e04c3fSmrg{
231601e04c3fSmrg   ir_expression *expr = ir->as_expression();
231701e04c3fSmrg
231801e04c3fSmrg   if (!expr || expr->operation != ir_binop_max)
231901e04c3fSmrg      return NULL;
232001e04c3fSmrg
232101e04c3fSmrg   if (expr->operands[0]->is_zero())
232201e04c3fSmrg      return expr->operands[1];
232301e04c3fSmrg
232401e04c3fSmrg   if (expr->operands[1]->is_zero())
232501e04c3fSmrg      return expr->operands[0];
232601e04c3fSmrg
232701e04c3fSmrg   return NULL;
232801e04c3fSmrg}
232901e04c3fSmrg
233001e04c3fSmrgir_rvalue *
233101e04c3fSmrgir_rvalue::as_rvalue_to_saturate()
233201e04c3fSmrg{
233301e04c3fSmrg   ir_expression *expr = this->as_expression();
233401e04c3fSmrg
233501e04c3fSmrg   if (!expr)
233601e04c3fSmrg      return NULL;
233701e04c3fSmrg
233801e04c3fSmrg   ir_rvalue *max_zero = try_max_zero(expr);
233901e04c3fSmrg   if (max_zero) {
234001e04c3fSmrg      return try_min_one(max_zero);
234101e04c3fSmrg   } else {
234201e04c3fSmrg      ir_rvalue *min_one = try_min_one(expr);
234301e04c3fSmrg      if (min_one) {
234401e04c3fSmrg	 return try_max_zero(min_one);
234501e04c3fSmrg      }
234601e04c3fSmrg   }
234701e04c3fSmrg
234801e04c3fSmrg   return NULL;
234901e04c3fSmrg}
235001e04c3fSmrg
235101e04c3fSmrg
235201e04c3fSmrgunsigned
235301e04c3fSmrgvertices_per_prim(GLenum prim)
235401e04c3fSmrg{
235501e04c3fSmrg   switch (prim) {
235601e04c3fSmrg   case GL_POINTS:
235701e04c3fSmrg      return 1;
235801e04c3fSmrg   case GL_LINES:
235901e04c3fSmrg      return 2;
236001e04c3fSmrg   case GL_TRIANGLES:
236101e04c3fSmrg      return 3;
236201e04c3fSmrg   case GL_LINES_ADJACENCY:
236301e04c3fSmrg      return 4;
236401e04c3fSmrg   case GL_TRIANGLES_ADJACENCY:
236501e04c3fSmrg      return 6;
236601e04c3fSmrg   default:
236701e04c3fSmrg      assert(!"Bad primitive");
236801e04c3fSmrg      return 3;
236901e04c3fSmrg   }
237001e04c3fSmrg}
237101e04c3fSmrg
237201e04c3fSmrg/**
237301e04c3fSmrg * Generate a string describing the mode of a variable
237401e04c3fSmrg */
237501e04c3fSmrgconst char *
237601e04c3fSmrgmode_string(const ir_variable *var)
237701e04c3fSmrg{
237801e04c3fSmrg   switch (var->data.mode) {
237901e04c3fSmrg   case ir_var_auto:
238001e04c3fSmrg      return (var->data.read_only) ? "global constant" : "global variable";
238101e04c3fSmrg
238201e04c3fSmrg   case ir_var_uniform:
238301e04c3fSmrg      return "uniform";
238401e04c3fSmrg
238501e04c3fSmrg   case ir_var_shader_storage:
238601e04c3fSmrg      return "buffer";
238701e04c3fSmrg
238801e04c3fSmrg   case ir_var_shader_in:
238901e04c3fSmrg      return "shader input";
239001e04c3fSmrg
239101e04c3fSmrg   case ir_var_shader_out:
239201e04c3fSmrg      return "shader output";
239301e04c3fSmrg
239401e04c3fSmrg   case ir_var_function_in:
239501e04c3fSmrg   case ir_var_const_in:
239601e04c3fSmrg      return "function input";
239701e04c3fSmrg
239801e04c3fSmrg   case ir_var_function_out:
239901e04c3fSmrg      return "function output";
240001e04c3fSmrg
240101e04c3fSmrg   case ir_var_function_inout:
240201e04c3fSmrg      return "function inout";
240301e04c3fSmrg
240401e04c3fSmrg   case ir_var_system_value:
240501e04c3fSmrg      return "shader input";
240601e04c3fSmrg
240701e04c3fSmrg   case ir_var_temporary:
240801e04c3fSmrg      return "compiler temporary";
240901e04c3fSmrg
241001e04c3fSmrg   case ir_var_mode_count:
241101e04c3fSmrg      break;
241201e04c3fSmrg   }
241301e04c3fSmrg
241401e04c3fSmrg   assert(!"Should not get here.");
241501e04c3fSmrg   return "invalid variable";
241601e04c3fSmrg}
2417