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(¶meters); 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