1b8e80941Smrg/* 2b8e80941Smrg * Copyright © 2010 Intel Corporation 3b8e80941Smrg * 4b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a 5b8e80941Smrg * copy of this software and associated documentation files (the "Software"), 6b8e80941Smrg * to deal in the Software without restriction, including without limitation 7b8e80941Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8b8e80941Smrg * and/or sell copies of the Software, and to permit persons to whom the 9b8e80941Smrg * Software is furnished to do so, subject to the following conditions: 10b8e80941Smrg * 11b8e80941Smrg * The above copyright notice and this permission notice (including the next 12b8e80941Smrg * paragraph) shall be included in all copies or substantial portions of the 13b8e80941Smrg * Software. 14b8e80941Smrg * 15b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16b8e80941Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18b8e80941Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19b8e80941Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20b8e80941Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21b8e80941Smrg * DEALINGS IN THE SOFTWARE. 22b8e80941Smrg */ 23b8e80941Smrg#include <string.h> 24b8e80941Smrg#include "ir.h" 25b8e80941Smrg#include "compiler/glsl_types.h" 26b8e80941Smrg#include "glsl_parser_extras.h" 27b8e80941Smrg 28b8e80941Smrg 29b8e80941Smrgir_rvalue::ir_rvalue(enum ir_node_type t) 30b8e80941Smrg : ir_instruction(t) 31b8e80941Smrg{ 32b8e80941Smrg this->type = glsl_type::error_type; 33b8e80941Smrg} 34b8e80941Smrg 35b8e80941Smrgbool ir_rvalue::is_zero() const 36b8e80941Smrg{ 37b8e80941Smrg return false; 38b8e80941Smrg} 39b8e80941Smrg 40b8e80941Smrgbool ir_rvalue::is_one() const 41b8e80941Smrg{ 42b8e80941Smrg return false; 43b8e80941Smrg} 44b8e80941Smrg 45b8e80941Smrgbool ir_rvalue::is_negative_one() const 46b8e80941Smrg{ 47b8e80941Smrg return false; 48b8e80941Smrg} 49b8e80941Smrg 50b8e80941Smrg/** 51b8e80941Smrg * Modify the swizzle make to move one component to another 52b8e80941Smrg * 53b8e80941Smrg * \param m IR swizzle to be modified 54b8e80941Smrg * \param from Component in the RHS that is to be swizzled 55b8e80941Smrg * \param to Desired swizzle location of \c from 56b8e80941Smrg */ 57b8e80941Smrgstatic void 58b8e80941Smrgupdate_rhs_swizzle(ir_swizzle_mask &m, unsigned from, unsigned to) 59b8e80941Smrg{ 60b8e80941Smrg switch (to) { 61b8e80941Smrg case 0: m.x = from; break; 62b8e80941Smrg case 1: m.y = from; break; 63b8e80941Smrg case 2: m.z = from; break; 64b8e80941Smrg case 3: m.w = from; break; 65b8e80941Smrg default: assert(!"Should not get here."); 66b8e80941Smrg } 67b8e80941Smrg} 68b8e80941Smrg 69b8e80941Smrgvoid 70b8e80941Smrgir_assignment::set_lhs(ir_rvalue *lhs) 71b8e80941Smrg{ 72b8e80941Smrg void *mem_ctx = this; 73b8e80941Smrg bool swizzled = false; 74b8e80941Smrg 75b8e80941Smrg while (lhs != NULL) { 76b8e80941Smrg ir_swizzle *swiz = lhs->as_swizzle(); 77b8e80941Smrg 78b8e80941Smrg if (swiz == NULL) 79b8e80941Smrg break; 80b8e80941Smrg 81b8e80941Smrg unsigned write_mask = 0; 82b8e80941Smrg ir_swizzle_mask rhs_swiz = { 0, 0, 0, 0, 0, 0 }; 83b8e80941Smrg 84b8e80941Smrg for (unsigned i = 0; i < swiz->mask.num_components; i++) { 85b8e80941Smrg unsigned c = 0; 86b8e80941Smrg 87b8e80941Smrg switch (i) { 88b8e80941Smrg case 0: c = swiz->mask.x; break; 89b8e80941Smrg case 1: c = swiz->mask.y; break; 90b8e80941Smrg case 2: c = swiz->mask.z; break; 91b8e80941Smrg case 3: c = swiz->mask.w; break; 92b8e80941Smrg default: assert(!"Should not get here."); 93b8e80941Smrg } 94b8e80941Smrg 95b8e80941Smrg write_mask |= (((this->write_mask >> i) & 1) << c); 96b8e80941Smrg update_rhs_swizzle(rhs_swiz, i, c); 97b8e80941Smrg rhs_swiz.num_components = swiz->val->type->vector_elements; 98b8e80941Smrg } 99b8e80941Smrg 100b8e80941Smrg this->write_mask = write_mask; 101b8e80941Smrg lhs = swiz->val; 102b8e80941Smrg 103b8e80941Smrg this->rhs = new(mem_ctx) ir_swizzle(this->rhs, rhs_swiz); 104b8e80941Smrg swizzled = true; 105b8e80941Smrg } 106b8e80941Smrg 107b8e80941Smrg if (swizzled) { 108b8e80941Smrg /* Now, RHS channels line up with the LHS writemask. Collapse it 109b8e80941Smrg * to just the channels that will be written. 110b8e80941Smrg */ 111b8e80941Smrg ir_swizzle_mask rhs_swiz = { 0, 0, 0, 0, 0, 0 }; 112b8e80941Smrg int rhs_chan = 0; 113b8e80941Smrg for (int i = 0; i < 4; i++) { 114b8e80941Smrg if (write_mask & (1 << i)) 115b8e80941Smrg update_rhs_swizzle(rhs_swiz, i, rhs_chan++); 116b8e80941Smrg } 117b8e80941Smrg rhs_swiz.num_components = rhs_chan; 118b8e80941Smrg this->rhs = new(mem_ctx) ir_swizzle(this->rhs, rhs_swiz); 119b8e80941Smrg } 120b8e80941Smrg 121b8e80941Smrg assert((lhs == NULL) || lhs->as_dereference()); 122b8e80941Smrg 123b8e80941Smrg this->lhs = (ir_dereference *) lhs; 124b8e80941Smrg} 125b8e80941Smrg 126b8e80941Smrgir_variable * 127b8e80941Smrgir_assignment::whole_variable_written() 128b8e80941Smrg{ 129b8e80941Smrg ir_variable *v = this->lhs->whole_variable_referenced(); 130b8e80941Smrg 131b8e80941Smrg if (v == NULL) 132b8e80941Smrg return NULL; 133b8e80941Smrg 134b8e80941Smrg if (v->type->is_scalar()) 135b8e80941Smrg return v; 136b8e80941Smrg 137b8e80941Smrg if (v->type->is_vector()) { 138b8e80941Smrg const unsigned mask = (1U << v->type->vector_elements) - 1; 139b8e80941Smrg 140b8e80941Smrg if (mask != this->write_mask) 141b8e80941Smrg return NULL; 142b8e80941Smrg } 143b8e80941Smrg 144b8e80941Smrg /* Either all the vector components are assigned or the variable is some 145b8e80941Smrg * composite type (and the whole thing is assigned. 146b8e80941Smrg */ 147b8e80941Smrg return v; 148b8e80941Smrg} 149b8e80941Smrg 150b8e80941Smrgir_assignment::ir_assignment(ir_dereference *lhs, ir_rvalue *rhs, 151b8e80941Smrg ir_rvalue *condition, unsigned write_mask) 152b8e80941Smrg : ir_instruction(ir_type_assignment) 153b8e80941Smrg{ 154b8e80941Smrg this->condition = condition; 155b8e80941Smrg this->rhs = rhs; 156b8e80941Smrg this->lhs = lhs; 157b8e80941Smrg this->write_mask = write_mask; 158b8e80941Smrg 159b8e80941Smrg if (lhs->type->is_scalar() || lhs->type->is_vector()) { 160b8e80941Smrg int lhs_components = 0; 161b8e80941Smrg for (int i = 0; i < 4; i++) { 162b8e80941Smrg if (write_mask & (1 << i)) 163b8e80941Smrg lhs_components++; 164b8e80941Smrg } 165b8e80941Smrg 166b8e80941Smrg assert(lhs_components == this->rhs->type->vector_elements); 167b8e80941Smrg } 168b8e80941Smrg} 169b8e80941Smrg 170b8e80941Smrgir_assignment::ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, 171b8e80941Smrg ir_rvalue *condition) 172b8e80941Smrg : ir_instruction(ir_type_assignment) 173b8e80941Smrg{ 174b8e80941Smrg this->condition = condition; 175b8e80941Smrg this->rhs = rhs; 176b8e80941Smrg 177b8e80941Smrg /* If the RHS is a vector type, assume that all components of the vector 178b8e80941Smrg * type are being written to the LHS. The write mask comes from the RHS 179b8e80941Smrg * because we can have a case where the LHS is a vec4 and the RHS is a 180b8e80941Smrg * vec3. In that case, the assignment is: 181b8e80941Smrg * 182b8e80941Smrg * (assign (...) (xyz) (var_ref lhs) (var_ref rhs)) 183b8e80941Smrg */ 184b8e80941Smrg if (rhs->type->is_vector()) 185b8e80941Smrg this->write_mask = (1U << rhs->type->vector_elements) - 1; 186b8e80941Smrg else if (rhs->type->is_scalar()) 187b8e80941Smrg this->write_mask = 1; 188b8e80941Smrg else 189b8e80941Smrg this->write_mask = 0; 190b8e80941Smrg 191b8e80941Smrg this->set_lhs(lhs); 192b8e80941Smrg} 193b8e80941Smrg 194b8e80941Smrgir_expression::ir_expression(int op, const struct glsl_type *type, 195b8e80941Smrg ir_rvalue *op0, ir_rvalue *op1, 196b8e80941Smrg ir_rvalue *op2, ir_rvalue *op3) 197b8e80941Smrg : ir_rvalue(ir_type_expression) 198b8e80941Smrg{ 199b8e80941Smrg this->type = type; 200b8e80941Smrg this->operation = ir_expression_operation(op); 201b8e80941Smrg this->operands[0] = op0; 202b8e80941Smrg this->operands[1] = op1; 203b8e80941Smrg this->operands[2] = op2; 204b8e80941Smrg this->operands[3] = op3; 205b8e80941Smrg init_num_operands(); 206b8e80941Smrg 207b8e80941Smrg#ifndef NDEBUG 208b8e80941Smrg for (unsigned i = num_operands; i < 4; i++) { 209b8e80941Smrg assert(this->operands[i] == NULL); 210b8e80941Smrg } 211b8e80941Smrg 212b8e80941Smrg for (unsigned i = 0; i < num_operands; i++) { 213b8e80941Smrg assert(this->operands[i] != NULL); 214b8e80941Smrg } 215b8e80941Smrg#endif 216b8e80941Smrg} 217b8e80941Smrg 218b8e80941Smrgir_expression::ir_expression(int op, ir_rvalue *op0) 219b8e80941Smrg : ir_rvalue(ir_type_expression) 220b8e80941Smrg{ 221b8e80941Smrg this->operation = ir_expression_operation(op); 222b8e80941Smrg this->operands[0] = op0; 223b8e80941Smrg this->operands[1] = NULL; 224b8e80941Smrg this->operands[2] = NULL; 225b8e80941Smrg this->operands[3] = NULL; 226b8e80941Smrg 227b8e80941Smrg assert(op <= ir_last_unop); 228b8e80941Smrg init_num_operands(); 229b8e80941Smrg assert(num_operands == 1); 230b8e80941Smrg assert(this->operands[0]); 231b8e80941Smrg 232b8e80941Smrg switch (this->operation) { 233b8e80941Smrg case ir_unop_bit_not: 234b8e80941Smrg case ir_unop_logic_not: 235b8e80941Smrg case ir_unop_neg: 236b8e80941Smrg case ir_unop_abs: 237b8e80941Smrg case ir_unop_sign: 238b8e80941Smrg case ir_unop_rcp: 239b8e80941Smrg case ir_unop_rsq: 240b8e80941Smrg case ir_unop_sqrt: 241b8e80941Smrg case ir_unop_exp: 242b8e80941Smrg case ir_unop_log: 243b8e80941Smrg case ir_unop_exp2: 244b8e80941Smrg case ir_unop_log2: 245b8e80941Smrg case ir_unop_trunc: 246b8e80941Smrg case ir_unop_ceil: 247b8e80941Smrg case ir_unop_floor: 248b8e80941Smrg case ir_unop_fract: 249b8e80941Smrg case ir_unop_round_even: 250b8e80941Smrg case ir_unop_sin: 251b8e80941Smrg case ir_unop_cos: 252b8e80941Smrg case ir_unop_dFdx: 253b8e80941Smrg case ir_unop_dFdx_coarse: 254b8e80941Smrg case ir_unop_dFdx_fine: 255b8e80941Smrg case ir_unop_dFdy: 256b8e80941Smrg case ir_unop_dFdy_coarse: 257b8e80941Smrg case ir_unop_dFdy_fine: 258b8e80941Smrg case ir_unop_bitfield_reverse: 259b8e80941Smrg case ir_unop_interpolate_at_centroid: 260b8e80941Smrg case ir_unop_saturate: 261b8e80941Smrg this->type = op0->type; 262b8e80941Smrg break; 263b8e80941Smrg 264b8e80941Smrg case ir_unop_f2i: 265b8e80941Smrg case ir_unop_b2i: 266b8e80941Smrg case ir_unop_u2i: 267b8e80941Smrg case ir_unop_d2i: 268b8e80941Smrg case ir_unop_bitcast_f2i: 269b8e80941Smrg case ir_unop_bit_count: 270b8e80941Smrg case ir_unop_find_msb: 271b8e80941Smrg case ir_unop_find_lsb: 272b8e80941Smrg case ir_unop_subroutine_to_int: 273b8e80941Smrg case ir_unop_i642i: 274b8e80941Smrg case ir_unop_u642i: 275b8e80941Smrg this->type = glsl_type::get_instance(GLSL_TYPE_INT, 276b8e80941Smrg op0->type->vector_elements, 1); 277b8e80941Smrg break; 278b8e80941Smrg 279b8e80941Smrg case ir_unop_b2f: 280b8e80941Smrg case ir_unop_i2f: 281b8e80941Smrg case ir_unop_u2f: 282b8e80941Smrg case ir_unop_d2f: 283b8e80941Smrg case ir_unop_bitcast_i2f: 284b8e80941Smrg case ir_unop_bitcast_u2f: 285b8e80941Smrg case ir_unop_i642f: 286b8e80941Smrg case ir_unop_u642f: 287b8e80941Smrg this->type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 288b8e80941Smrg op0->type->vector_elements, 1); 289b8e80941Smrg break; 290b8e80941Smrg 291b8e80941Smrg case ir_unop_f2b: 292b8e80941Smrg case ir_unop_i2b: 293b8e80941Smrg case ir_unop_d2b: 294b8e80941Smrg case ir_unop_i642b: 295b8e80941Smrg this->type = glsl_type::get_instance(GLSL_TYPE_BOOL, 296b8e80941Smrg op0->type->vector_elements, 1); 297b8e80941Smrg break; 298b8e80941Smrg 299b8e80941Smrg case ir_unop_f2d: 300b8e80941Smrg case ir_unop_i2d: 301b8e80941Smrg case ir_unop_u2d: 302b8e80941Smrg case ir_unop_i642d: 303b8e80941Smrg case ir_unop_u642d: 304b8e80941Smrg this->type = glsl_type::get_instance(GLSL_TYPE_DOUBLE, 305b8e80941Smrg op0->type->vector_elements, 1); 306b8e80941Smrg break; 307b8e80941Smrg 308b8e80941Smrg case ir_unop_i2u: 309b8e80941Smrg case ir_unop_f2u: 310b8e80941Smrg case ir_unop_d2u: 311b8e80941Smrg case ir_unop_bitcast_f2u: 312b8e80941Smrg case ir_unop_i642u: 313b8e80941Smrg case ir_unop_u642u: 314b8e80941Smrg this->type = glsl_type::get_instance(GLSL_TYPE_UINT, 315b8e80941Smrg op0->type->vector_elements, 1); 316b8e80941Smrg break; 317b8e80941Smrg 318b8e80941Smrg case ir_unop_i2i64: 319b8e80941Smrg case ir_unop_u2i64: 320b8e80941Smrg case ir_unop_b2i64: 321b8e80941Smrg case ir_unop_f2i64: 322b8e80941Smrg case ir_unop_d2i64: 323b8e80941Smrg case ir_unop_u642i64: 324b8e80941Smrg this->type = glsl_type::get_instance(GLSL_TYPE_INT64, 325b8e80941Smrg op0->type->vector_elements, 1); 326b8e80941Smrg break; 327b8e80941Smrg 328b8e80941Smrg case ir_unop_i2u64: 329b8e80941Smrg case ir_unop_u2u64: 330b8e80941Smrg case ir_unop_f2u64: 331b8e80941Smrg case ir_unop_d2u64: 332b8e80941Smrg case ir_unop_i642u64: 333b8e80941Smrg this->type = glsl_type::get_instance(GLSL_TYPE_UINT64, 334b8e80941Smrg op0->type->vector_elements, 1); 335b8e80941Smrg break; 336b8e80941Smrg case ir_unop_noise: 337b8e80941Smrg this->type = glsl_type::float_type; 338b8e80941Smrg break; 339b8e80941Smrg 340b8e80941Smrg case ir_unop_unpack_double_2x32: 341b8e80941Smrg case ir_unop_unpack_uint_2x32: 342b8e80941Smrg this->type = glsl_type::uvec2_type; 343b8e80941Smrg break; 344b8e80941Smrg 345b8e80941Smrg case ir_unop_unpack_int_2x32: 346b8e80941Smrg this->type = glsl_type::ivec2_type; 347b8e80941Smrg break; 348b8e80941Smrg 349b8e80941Smrg case ir_unop_pack_snorm_2x16: 350b8e80941Smrg case ir_unop_pack_snorm_4x8: 351b8e80941Smrg case ir_unop_pack_unorm_2x16: 352b8e80941Smrg case ir_unop_pack_unorm_4x8: 353b8e80941Smrg case ir_unop_pack_half_2x16: 354b8e80941Smrg this->type = glsl_type::uint_type; 355b8e80941Smrg break; 356b8e80941Smrg 357b8e80941Smrg case ir_unop_pack_double_2x32: 358b8e80941Smrg this->type = glsl_type::double_type; 359b8e80941Smrg break; 360b8e80941Smrg 361b8e80941Smrg case ir_unop_pack_int_2x32: 362b8e80941Smrg this->type = glsl_type::int64_t_type; 363b8e80941Smrg break; 364b8e80941Smrg 365b8e80941Smrg case ir_unop_pack_uint_2x32: 366b8e80941Smrg this->type = glsl_type::uint64_t_type; 367b8e80941Smrg break; 368b8e80941Smrg 369b8e80941Smrg case ir_unop_unpack_snorm_2x16: 370b8e80941Smrg case ir_unop_unpack_unorm_2x16: 371b8e80941Smrg case ir_unop_unpack_half_2x16: 372b8e80941Smrg this->type = glsl_type::vec2_type; 373b8e80941Smrg break; 374b8e80941Smrg 375b8e80941Smrg case ir_unop_unpack_snorm_4x8: 376b8e80941Smrg case ir_unop_unpack_unorm_4x8: 377b8e80941Smrg this->type = glsl_type::vec4_type; 378b8e80941Smrg break; 379b8e80941Smrg 380b8e80941Smrg case ir_unop_unpack_sampler_2x32: 381b8e80941Smrg case ir_unop_unpack_image_2x32: 382b8e80941Smrg this->type = glsl_type::uvec2_type; 383b8e80941Smrg break; 384b8e80941Smrg 385b8e80941Smrg case ir_unop_pack_sampler_2x32: 386b8e80941Smrg case ir_unop_pack_image_2x32: 387b8e80941Smrg this->type = op0->type; 388b8e80941Smrg break; 389b8e80941Smrg 390b8e80941Smrg case ir_unop_frexp_sig: 391b8e80941Smrg this->type = op0->type; 392b8e80941Smrg break; 393b8e80941Smrg case ir_unop_frexp_exp: 394b8e80941Smrg this->type = glsl_type::get_instance(GLSL_TYPE_INT, 395b8e80941Smrg op0->type->vector_elements, 1); 396b8e80941Smrg break; 397b8e80941Smrg 398b8e80941Smrg case ir_unop_get_buffer_size: 399b8e80941Smrg case ir_unop_ssbo_unsized_array_length: 400b8e80941Smrg this->type = glsl_type::int_type; 401b8e80941Smrg break; 402b8e80941Smrg 403b8e80941Smrg case ir_unop_bitcast_i642d: 404b8e80941Smrg case ir_unop_bitcast_u642d: 405b8e80941Smrg this->type = glsl_type::get_instance(GLSL_TYPE_DOUBLE, 406b8e80941Smrg op0->type->vector_elements, 1); 407b8e80941Smrg break; 408b8e80941Smrg 409b8e80941Smrg case ir_unop_bitcast_d2i64: 410b8e80941Smrg this->type = glsl_type::get_instance(GLSL_TYPE_INT64, 411b8e80941Smrg op0->type->vector_elements, 1); 412b8e80941Smrg break; 413b8e80941Smrg case ir_unop_bitcast_d2u64: 414b8e80941Smrg this->type = glsl_type::get_instance(GLSL_TYPE_UINT64, 415b8e80941Smrg op0->type->vector_elements, 1); 416b8e80941Smrg break; 417b8e80941Smrg 418b8e80941Smrg default: 419b8e80941Smrg assert(!"not reached: missing automatic type setup for ir_expression"); 420b8e80941Smrg this->type = op0->type; 421b8e80941Smrg break; 422b8e80941Smrg } 423b8e80941Smrg} 424b8e80941Smrg 425b8e80941Smrgir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1) 426b8e80941Smrg : ir_rvalue(ir_type_expression) 427b8e80941Smrg{ 428b8e80941Smrg this->operation = ir_expression_operation(op); 429b8e80941Smrg this->operands[0] = op0; 430b8e80941Smrg this->operands[1] = op1; 431b8e80941Smrg this->operands[2] = NULL; 432b8e80941Smrg this->operands[3] = NULL; 433b8e80941Smrg 434b8e80941Smrg assert(op > ir_last_unop); 435b8e80941Smrg init_num_operands(); 436b8e80941Smrg assert(num_operands == 2); 437b8e80941Smrg for (unsigned i = 0; i < num_operands; i++) { 438b8e80941Smrg assert(this->operands[i] != NULL); 439b8e80941Smrg } 440b8e80941Smrg 441b8e80941Smrg switch (this->operation) { 442b8e80941Smrg case ir_binop_all_equal: 443b8e80941Smrg case ir_binop_any_nequal: 444b8e80941Smrg this->type = glsl_type::bool_type; 445b8e80941Smrg break; 446b8e80941Smrg 447b8e80941Smrg case ir_binop_add: 448b8e80941Smrg case ir_binop_sub: 449b8e80941Smrg case ir_binop_min: 450b8e80941Smrg case ir_binop_max: 451b8e80941Smrg case ir_binop_pow: 452b8e80941Smrg case ir_binop_mul: 453b8e80941Smrg case ir_binop_div: 454b8e80941Smrg case ir_binop_mod: 455b8e80941Smrg if (op0->type->is_scalar()) { 456b8e80941Smrg this->type = op1->type; 457b8e80941Smrg } else if (op1->type->is_scalar()) { 458b8e80941Smrg this->type = op0->type; 459b8e80941Smrg } else { 460b8e80941Smrg if (this->operation == ir_binop_mul) { 461b8e80941Smrg this->type = glsl_type::get_mul_type(op0->type, op1->type); 462b8e80941Smrg } else { 463b8e80941Smrg assert(op0->type == op1->type); 464b8e80941Smrg this->type = op0->type; 465b8e80941Smrg } 466b8e80941Smrg } 467b8e80941Smrg break; 468b8e80941Smrg 469b8e80941Smrg case ir_binop_logic_and: 470b8e80941Smrg case ir_binop_logic_xor: 471b8e80941Smrg case ir_binop_logic_or: 472b8e80941Smrg case ir_binop_bit_and: 473b8e80941Smrg case ir_binop_bit_xor: 474b8e80941Smrg case ir_binop_bit_or: 475b8e80941Smrg assert(!op0->type->is_matrix()); 476b8e80941Smrg assert(!op1->type->is_matrix()); 477b8e80941Smrg if (op0->type->is_scalar()) { 478b8e80941Smrg this->type = op1->type; 479b8e80941Smrg } else if (op1->type->is_scalar()) { 480b8e80941Smrg this->type = op0->type; 481b8e80941Smrg } else { 482b8e80941Smrg assert(op0->type->vector_elements == op1->type->vector_elements); 483b8e80941Smrg this->type = op0->type; 484b8e80941Smrg } 485b8e80941Smrg break; 486b8e80941Smrg 487b8e80941Smrg case ir_binop_equal: 488b8e80941Smrg case ir_binop_nequal: 489b8e80941Smrg case ir_binop_gequal: 490b8e80941Smrg case ir_binop_less: 491b8e80941Smrg assert(op0->type == op1->type); 492b8e80941Smrg this->type = glsl_type::get_instance(GLSL_TYPE_BOOL, 493b8e80941Smrg op0->type->vector_elements, 1); 494b8e80941Smrg break; 495b8e80941Smrg 496b8e80941Smrg case ir_binop_dot: 497b8e80941Smrg this->type = op0->type->get_base_type(); 498b8e80941Smrg break; 499b8e80941Smrg 500b8e80941Smrg case ir_binop_imul_high: 501b8e80941Smrg case ir_binop_carry: 502b8e80941Smrg case ir_binop_borrow: 503b8e80941Smrg case ir_binop_lshift: 504b8e80941Smrg case ir_binop_rshift: 505b8e80941Smrg case ir_binop_ldexp: 506b8e80941Smrg case ir_binop_interpolate_at_offset: 507b8e80941Smrg case ir_binop_interpolate_at_sample: 508b8e80941Smrg this->type = op0->type; 509b8e80941Smrg break; 510b8e80941Smrg 511b8e80941Smrg case ir_binop_vector_extract: 512b8e80941Smrg this->type = op0->type->get_scalar_type(); 513b8e80941Smrg break; 514b8e80941Smrg 515b8e80941Smrg default: 516b8e80941Smrg assert(!"not reached: missing automatic type setup for ir_expression"); 517b8e80941Smrg this->type = glsl_type::float_type; 518b8e80941Smrg } 519b8e80941Smrg} 520b8e80941Smrg 521b8e80941Smrgir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1, 522b8e80941Smrg ir_rvalue *op2) 523b8e80941Smrg : ir_rvalue(ir_type_expression) 524b8e80941Smrg{ 525b8e80941Smrg this->operation = ir_expression_operation(op); 526b8e80941Smrg this->operands[0] = op0; 527b8e80941Smrg this->operands[1] = op1; 528b8e80941Smrg this->operands[2] = op2; 529b8e80941Smrg this->operands[3] = NULL; 530b8e80941Smrg 531b8e80941Smrg assert(op > ir_last_binop && op <= ir_last_triop); 532b8e80941Smrg init_num_operands(); 533b8e80941Smrg assert(num_operands == 3); 534b8e80941Smrg for (unsigned i = 0; i < num_operands; i++) { 535b8e80941Smrg assert(this->operands[i] != NULL); 536b8e80941Smrg } 537b8e80941Smrg 538b8e80941Smrg switch (this->operation) { 539b8e80941Smrg case ir_triop_fma: 540b8e80941Smrg case ir_triop_lrp: 541b8e80941Smrg case ir_triop_bitfield_extract: 542b8e80941Smrg case ir_triop_vector_insert: 543b8e80941Smrg this->type = op0->type; 544b8e80941Smrg break; 545b8e80941Smrg 546b8e80941Smrg case ir_triop_csel: 547b8e80941Smrg this->type = op1->type; 548b8e80941Smrg break; 549b8e80941Smrg 550b8e80941Smrg default: 551b8e80941Smrg assert(!"not reached: missing automatic type setup for ir_expression"); 552b8e80941Smrg this->type = glsl_type::float_type; 553b8e80941Smrg } 554b8e80941Smrg} 555b8e80941Smrg 556b8e80941Smrg/** 557b8e80941Smrg * This is only here for ir_reader to used for testing purposes. Please use 558b8e80941Smrg * the precomputed num_operands field if you need the number of operands. 559b8e80941Smrg */ 560b8e80941Smrgunsigned 561b8e80941Smrgir_expression::get_num_operands(ir_expression_operation op) 562b8e80941Smrg{ 563b8e80941Smrg assert(op <= ir_last_opcode); 564b8e80941Smrg 565b8e80941Smrg if (op <= ir_last_unop) 566b8e80941Smrg return 1; 567b8e80941Smrg 568b8e80941Smrg if (op <= ir_last_binop) 569b8e80941Smrg return 2; 570b8e80941Smrg 571b8e80941Smrg if (op <= ir_last_triop) 572b8e80941Smrg return 3; 573b8e80941Smrg 574b8e80941Smrg if (op <= ir_last_quadop) 575b8e80941Smrg return 4; 576b8e80941Smrg 577b8e80941Smrg unreachable("Could not calculate number of operands"); 578b8e80941Smrg} 579b8e80941Smrg 580b8e80941Smrg#include "ir_expression_operation_strings.h" 581b8e80941Smrg 582b8e80941Smrgconst char* 583b8e80941Smrgdepth_layout_string(ir_depth_layout layout) 584b8e80941Smrg{ 585b8e80941Smrg switch(layout) { 586b8e80941Smrg case ir_depth_layout_none: return ""; 587b8e80941Smrg case ir_depth_layout_any: return "depth_any"; 588b8e80941Smrg case ir_depth_layout_greater: return "depth_greater"; 589b8e80941Smrg case ir_depth_layout_less: return "depth_less"; 590b8e80941Smrg case ir_depth_layout_unchanged: return "depth_unchanged"; 591b8e80941Smrg 592b8e80941Smrg default: 593b8e80941Smrg assert(0); 594b8e80941Smrg return ""; 595b8e80941Smrg } 596b8e80941Smrg} 597b8e80941Smrg 598b8e80941Smrgir_expression_operation 599b8e80941Smrgir_expression::get_operator(const char *str) 600b8e80941Smrg{ 601b8e80941Smrg for (int op = 0; op <= int(ir_last_opcode); op++) { 602b8e80941Smrg if (strcmp(str, ir_expression_operation_strings[op]) == 0) 603b8e80941Smrg return (ir_expression_operation) op; 604b8e80941Smrg } 605b8e80941Smrg return (ir_expression_operation) -1; 606b8e80941Smrg} 607b8e80941Smrg 608b8e80941Smrgir_variable * 609b8e80941Smrgir_expression::variable_referenced() const 610b8e80941Smrg{ 611b8e80941Smrg switch (operation) { 612b8e80941Smrg case ir_binop_vector_extract: 613b8e80941Smrg case ir_triop_vector_insert: 614b8e80941Smrg /* We get these for things like a[0] where a is a vector type. In these 615b8e80941Smrg * cases we want variable_referenced() to return the actual vector 616b8e80941Smrg * variable this is wrapping. 617b8e80941Smrg */ 618b8e80941Smrg return operands[0]->variable_referenced(); 619b8e80941Smrg default: 620b8e80941Smrg return ir_rvalue::variable_referenced(); 621b8e80941Smrg } 622b8e80941Smrg} 623b8e80941Smrg 624b8e80941Smrgir_constant::ir_constant() 625b8e80941Smrg : ir_rvalue(ir_type_constant) 626b8e80941Smrg{ 627b8e80941Smrg this->const_elements = NULL; 628b8e80941Smrg} 629b8e80941Smrg 630b8e80941Smrgir_constant::ir_constant(const struct glsl_type *type, 631b8e80941Smrg const ir_constant_data *data) 632b8e80941Smrg : ir_rvalue(ir_type_constant) 633b8e80941Smrg{ 634b8e80941Smrg this->const_elements = NULL; 635b8e80941Smrg 636b8e80941Smrg assert((type->base_type >= GLSL_TYPE_UINT) 637b8e80941Smrg && (type->base_type <= GLSL_TYPE_IMAGE)); 638b8e80941Smrg 639b8e80941Smrg this->type = type; 640b8e80941Smrg memcpy(& this->value, data, sizeof(this->value)); 641b8e80941Smrg} 642b8e80941Smrg 643b8e80941Smrgir_constant::ir_constant(float f, unsigned vector_elements) 644b8e80941Smrg : ir_rvalue(ir_type_constant) 645b8e80941Smrg{ 646b8e80941Smrg assert(vector_elements <= 4); 647b8e80941Smrg this->type = glsl_type::get_instance(GLSL_TYPE_FLOAT, vector_elements, 1); 648b8e80941Smrg for (unsigned i = 0; i < vector_elements; i++) { 649b8e80941Smrg this->value.f[i] = f; 650b8e80941Smrg } 651b8e80941Smrg for (unsigned i = vector_elements; i < 16; i++) { 652b8e80941Smrg this->value.f[i] = 0; 653b8e80941Smrg } 654b8e80941Smrg} 655b8e80941Smrg 656b8e80941Smrgir_constant::ir_constant(double d, unsigned vector_elements) 657b8e80941Smrg : ir_rvalue(ir_type_constant) 658b8e80941Smrg{ 659b8e80941Smrg assert(vector_elements <= 4); 660b8e80941Smrg this->type = glsl_type::get_instance(GLSL_TYPE_DOUBLE, vector_elements, 1); 661b8e80941Smrg for (unsigned i = 0; i < vector_elements; i++) { 662b8e80941Smrg this->value.d[i] = d; 663b8e80941Smrg } 664b8e80941Smrg for (unsigned i = vector_elements; i < 16; i++) { 665b8e80941Smrg this->value.d[i] = 0.0; 666b8e80941Smrg } 667b8e80941Smrg} 668b8e80941Smrg 669b8e80941Smrgir_constant::ir_constant(unsigned int u, unsigned vector_elements) 670b8e80941Smrg : ir_rvalue(ir_type_constant) 671b8e80941Smrg{ 672b8e80941Smrg assert(vector_elements <= 4); 673b8e80941Smrg this->type = glsl_type::get_instance(GLSL_TYPE_UINT, vector_elements, 1); 674b8e80941Smrg for (unsigned i = 0; i < vector_elements; i++) { 675b8e80941Smrg this->value.u[i] = u; 676b8e80941Smrg } 677b8e80941Smrg for (unsigned i = vector_elements; i < 16; i++) { 678b8e80941Smrg this->value.u[i] = 0; 679b8e80941Smrg } 680b8e80941Smrg} 681b8e80941Smrg 682b8e80941Smrgir_constant::ir_constant(int integer, unsigned vector_elements) 683b8e80941Smrg : ir_rvalue(ir_type_constant) 684b8e80941Smrg{ 685b8e80941Smrg assert(vector_elements <= 4); 686b8e80941Smrg this->type = glsl_type::get_instance(GLSL_TYPE_INT, vector_elements, 1); 687b8e80941Smrg for (unsigned i = 0; i < vector_elements; i++) { 688b8e80941Smrg this->value.i[i] = integer; 689b8e80941Smrg } 690b8e80941Smrg for (unsigned i = vector_elements; i < 16; i++) { 691b8e80941Smrg this->value.i[i] = 0; 692b8e80941Smrg } 693b8e80941Smrg} 694b8e80941Smrg 695b8e80941Smrgir_constant::ir_constant(uint64_t u64, unsigned vector_elements) 696b8e80941Smrg : ir_rvalue(ir_type_constant) 697b8e80941Smrg{ 698b8e80941Smrg assert(vector_elements <= 4); 699b8e80941Smrg this->type = glsl_type::get_instance(GLSL_TYPE_UINT64, vector_elements, 1); 700b8e80941Smrg for (unsigned i = 0; i < vector_elements; i++) { 701b8e80941Smrg this->value.u64[i] = u64; 702b8e80941Smrg } 703b8e80941Smrg for (unsigned i = vector_elements; i < 16; i++) { 704b8e80941Smrg this->value.u64[i] = 0; 705b8e80941Smrg } 706b8e80941Smrg} 707b8e80941Smrg 708b8e80941Smrgir_constant::ir_constant(int64_t int64, unsigned vector_elements) 709b8e80941Smrg : ir_rvalue(ir_type_constant) 710b8e80941Smrg{ 711b8e80941Smrg assert(vector_elements <= 4); 712b8e80941Smrg this->type = glsl_type::get_instance(GLSL_TYPE_INT64, vector_elements, 1); 713b8e80941Smrg for (unsigned i = 0; i < vector_elements; i++) { 714b8e80941Smrg this->value.i64[i] = int64; 715b8e80941Smrg } 716b8e80941Smrg for (unsigned i = vector_elements; i < 16; i++) { 717b8e80941Smrg this->value.i64[i] = 0; 718b8e80941Smrg } 719b8e80941Smrg} 720b8e80941Smrg 721b8e80941Smrgir_constant::ir_constant(bool b, unsigned vector_elements) 722b8e80941Smrg : ir_rvalue(ir_type_constant) 723b8e80941Smrg{ 724b8e80941Smrg assert(vector_elements <= 4); 725b8e80941Smrg this->type = glsl_type::get_instance(GLSL_TYPE_BOOL, vector_elements, 1); 726b8e80941Smrg for (unsigned i = 0; i < vector_elements; i++) { 727b8e80941Smrg this->value.b[i] = b; 728b8e80941Smrg } 729b8e80941Smrg for (unsigned i = vector_elements; i < 16; i++) { 730b8e80941Smrg this->value.b[i] = false; 731b8e80941Smrg } 732b8e80941Smrg} 733b8e80941Smrg 734b8e80941Smrgir_constant::ir_constant(const ir_constant *c, unsigned i) 735b8e80941Smrg : ir_rvalue(ir_type_constant) 736b8e80941Smrg{ 737b8e80941Smrg this->const_elements = NULL; 738b8e80941Smrg this->type = c->type->get_base_type(); 739b8e80941Smrg 740b8e80941Smrg switch (this->type->base_type) { 741b8e80941Smrg case GLSL_TYPE_UINT: this->value.u[0] = c->value.u[i]; break; 742b8e80941Smrg case GLSL_TYPE_INT: this->value.i[0] = c->value.i[i]; break; 743b8e80941Smrg case GLSL_TYPE_FLOAT: this->value.f[0] = c->value.f[i]; break; 744b8e80941Smrg case GLSL_TYPE_BOOL: this->value.b[0] = c->value.b[i]; break; 745b8e80941Smrg case GLSL_TYPE_DOUBLE: this->value.d[0] = c->value.d[i]; break; 746b8e80941Smrg default: assert(!"Should not get here."); break; 747b8e80941Smrg } 748b8e80941Smrg} 749b8e80941Smrg 750b8e80941Smrgir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list) 751b8e80941Smrg : ir_rvalue(ir_type_constant) 752b8e80941Smrg{ 753b8e80941Smrg this->const_elements = NULL; 754b8e80941Smrg this->type = type; 755b8e80941Smrg 756b8e80941Smrg assert(type->is_scalar() || type->is_vector() || type->is_matrix() 757b8e80941Smrg || type->is_struct() || type->is_array()); 758b8e80941Smrg 759b8e80941Smrg /* If the constant is a record, the types of each of the entries in 760b8e80941Smrg * value_list must be a 1-for-1 match with the structure components. Each 761b8e80941Smrg * entry must also be a constant. Just move the nodes from the value_list 762b8e80941Smrg * to the list in the ir_constant. 763b8e80941Smrg */ 764b8e80941Smrg if (type->is_array() || type->is_struct()) { 765b8e80941Smrg this->const_elements = ralloc_array(this, ir_constant *, type->length); 766b8e80941Smrg unsigned i = 0; 767b8e80941Smrg foreach_in_list(ir_constant, value, value_list) { 768b8e80941Smrg assert(value->as_constant() != NULL); 769b8e80941Smrg 770b8e80941Smrg this->const_elements[i++] = value; 771b8e80941Smrg } 772b8e80941Smrg return; 773b8e80941Smrg } 774b8e80941Smrg 775b8e80941Smrg for (unsigned i = 0; i < 16; i++) { 776b8e80941Smrg this->value.u[i] = 0; 777b8e80941Smrg } 778b8e80941Smrg 779b8e80941Smrg ir_constant *value = (ir_constant *) (value_list->get_head_raw()); 780b8e80941Smrg 781b8e80941Smrg /* Constructors with exactly one scalar argument are special for vectors 782b8e80941Smrg * and matrices. For vectors, the scalar value is replicated to fill all 783b8e80941Smrg * the components. For matrices, the scalar fills the components of the 784b8e80941Smrg * diagonal while the rest is filled with 0. 785b8e80941Smrg */ 786b8e80941Smrg if (value->type->is_scalar() && value->next->is_tail_sentinel()) { 787b8e80941Smrg if (type->is_matrix()) { 788b8e80941Smrg /* Matrix - fill diagonal (rest is already set to 0) */ 789b8e80941Smrg assert(type->is_float() || type->is_double()); 790b8e80941Smrg for (unsigned i = 0; i < type->matrix_columns; i++) { 791b8e80941Smrg if (type->is_float()) 792b8e80941Smrg this->value.f[i * type->vector_elements + i] = 793b8e80941Smrg value->value.f[0]; 794b8e80941Smrg else 795b8e80941Smrg this->value.d[i * type->vector_elements + i] = 796b8e80941Smrg value->value.d[0]; 797b8e80941Smrg } 798b8e80941Smrg } else { 799b8e80941Smrg /* Vector or scalar - fill all components */ 800b8e80941Smrg switch (type->base_type) { 801b8e80941Smrg case GLSL_TYPE_UINT: 802b8e80941Smrg case GLSL_TYPE_INT: 803b8e80941Smrg for (unsigned i = 0; i < type->components(); i++) 804b8e80941Smrg this->value.u[i] = value->value.u[0]; 805b8e80941Smrg break; 806b8e80941Smrg case GLSL_TYPE_FLOAT: 807b8e80941Smrg for (unsigned i = 0; i < type->components(); i++) 808b8e80941Smrg this->value.f[i] = value->value.f[0]; 809b8e80941Smrg break; 810b8e80941Smrg case GLSL_TYPE_DOUBLE: 811b8e80941Smrg for (unsigned i = 0; i < type->components(); i++) 812b8e80941Smrg this->value.d[i] = value->value.d[0]; 813b8e80941Smrg break; 814b8e80941Smrg case GLSL_TYPE_UINT64: 815b8e80941Smrg case GLSL_TYPE_INT64: 816b8e80941Smrg for (unsigned i = 0; i < type->components(); i++) 817b8e80941Smrg this->value.u64[i] = value->value.u64[0]; 818b8e80941Smrg break; 819b8e80941Smrg case GLSL_TYPE_BOOL: 820b8e80941Smrg for (unsigned i = 0; i < type->components(); i++) 821b8e80941Smrg this->value.b[i] = value->value.b[0]; 822b8e80941Smrg break; 823b8e80941Smrg case GLSL_TYPE_SAMPLER: 824b8e80941Smrg case GLSL_TYPE_IMAGE: 825b8e80941Smrg this->value.u64[0] = value->value.u64[0]; 826b8e80941Smrg break; 827b8e80941Smrg default: 828b8e80941Smrg assert(!"Should not get here."); 829b8e80941Smrg break; 830b8e80941Smrg } 831b8e80941Smrg } 832b8e80941Smrg return; 833b8e80941Smrg } 834b8e80941Smrg 835b8e80941Smrg if (type->is_matrix() && value->type->is_matrix()) { 836b8e80941Smrg assert(value->next->is_tail_sentinel()); 837b8e80941Smrg 838b8e80941Smrg /* From section 5.4.2 of the GLSL 1.20 spec: 839b8e80941Smrg * "If a matrix is constructed from a matrix, then each component 840b8e80941Smrg * (column i, row j) in the result that has a corresponding component 841b8e80941Smrg * (column i, row j) in the argument will be initialized from there." 842b8e80941Smrg */ 843b8e80941Smrg unsigned cols = MIN2(type->matrix_columns, value->type->matrix_columns); 844b8e80941Smrg unsigned rows = MIN2(type->vector_elements, value->type->vector_elements); 845b8e80941Smrg for (unsigned i = 0; i < cols; i++) { 846b8e80941Smrg for (unsigned j = 0; j < rows; j++) { 847b8e80941Smrg const unsigned src = i * value->type->vector_elements + j; 848b8e80941Smrg const unsigned dst = i * type->vector_elements + j; 849b8e80941Smrg this->value.f[dst] = value->value.f[src]; 850b8e80941Smrg } 851b8e80941Smrg } 852b8e80941Smrg 853b8e80941Smrg /* "All other components will be initialized to the identity matrix." */ 854b8e80941Smrg for (unsigned i = cols; i < type->matrix_columns; i++) 855b8e80941Smrg this->value.f[i * type->vector_elements + i] = 1.0; 856b8e80941Smrg 857b8e80941Smrg return; 858b8e80941Smrg } 859b8e80941Smrg 860b8e80941Smrg /* Use each component from each entry in the value_list to initialize one 861b8e80941Smrg * component of the constant being constructed. 862b8e80941Smrg */ 863b8e80941Smrg unsigned i = 0; 864b8e80941Smrg for (;;) { 865b8e80941Smrg assert(value->as_constant() != NULL); 866b8e80941Smrg assert(!value->is_tail_sentinel()); 867b8e80941Smrg 868b8e80941Smrg for (unsigned j = 0; j < value->type->components(); j++) { 869b8e80941Smrg switch (type->base_type) { 870b8e80941Smrg case GLSL_TYPE_UINT: 871b8e80941Smrg this->value.u[i] = value->get_uint_component(j); 872b8e80941Smrg break; 873b8e80941Smrg case GLSL_TYPE_INT: 874b8e80941Smrg this->value.i[i] = value->get_int_component(j); 875b8e80941Smrg break; 876b8e80941Smrg case GLSL_TYPE_FLOAT: 877b8e80941Smrg this->value.f[i] = value->get_float_component(j); 878b8e80941Smrg break; 879b8e80941Smrg case GLSL_TYPE_BOOL: 880b8e80941Smrg this->value.b[i] = value->get_bool_component(j); 881b8e80941Smrg break; 882b8e80941Smrg case GLSL_TYPE_DOUBLE: 883b8e80941Smrg this->value.d[i] = value->get_double_component(j); 884b8e80941Smrg break; 885b8e80941Smrg case GLSL_TYPE_UINT64: 886b8e80941Smrg this->value.u64[i] = value->get_uint64_component(j); 887b8e80941Smrg break; 888b8e80941Smrg case GLSL_TYPE_INT64: 889b8e80941Smrg this->value.i64[i] = value->get_int64_component(j); 890b8e80941Smrg break; 891b8e80941Smrg default: 892b8e80941Smrg /* FINISHME: What to do? Exceptions are not the answer. 893b8e80941Smrg */ 894b8e80941Smrg break; 895b8e80941Smrg } 896b8e80941Smrg 897b8e80941Smrg i++; 898b8e80941Smrg if (i >= type->components()) 899b8e80941Smrg break; 900b8e80941Smrg } 901b8e80941Smrg 902b8e80941Smrg if (i >= type->components()) 903b8e80941Smrg break; /* avoid downcasting a list sentinel */ 904b8e80941Smrg value = (ir_constant *) value->next; 905b8e80941Smrg } 906b8e80941Smrg} 907b8e80941Smrg 908b8e80941Smrgir_constant * 909b8e80941Smrgir_constant::zero(void *mem_ctx, const glsl_type *type) 910b8e80941Smrg{ 911b8e80941Smrg assert(type->is_scalar() || type->is_vector() || type->is_matrix() 912b8e80941Smrg || type->is_struct() || type->is_array()); 913b8e80941Smrg 914b8e80941Smrg ir_constant *c = new(mem_ctx) ir_constant; 915b8e80941Smrg c->type = type; 916b8e80941Smrg memset(&c->value, 0, sizeof(c->value)); 917b8e80941Smrg 918b8e80941Smrg if (type->is_array()) { 919b8e80941Smrg c->const_elements = ralloc_array(c, ir_constant *, type->length); 920b8e80941Smrg 921b8e80941Smrg for (unsigned i = 0; i < type->length; i++) 922b8e80941Smrg c->const_elements[i] = ir_constant::zero(c, type->fields.array); 923b8e80941Smrg } 924b8e80941Smrg 925b8e80941Smrg if (type->is_struct()) { 926b8e80941Smrg c->const_elements = ralloc_array(c, ir_constant *, type->length); 927b8e80941Smrg 928b8e80941Smrg for (unsigned i = 0; i < type->length; i++) { 929b8e80941Smrg c->const_elements[i] = 930b8e80941Smrg ir_constant::zero(mem_ctx, type->fields.structure[i].type); 931b8e80941Smrg } 932b8e80941Smrg } 933b8e80941Smrg 934b8e80941Smrg return c; 935b8e80941Smrg} 936b8e80941Smrg 937b8e80941Smrgbool 938b8e80941Smrgir_constant::get_bool_component(unsigned i) const 939b8e80941Smrg{ 940b8e80941Smrg switch (this->type->base_type) { 941b8e80941Smrg case GLSL_TYPE_UINT: return this->value.u[i] != 0; 942b8e80941Smrg case GLSL_TYPE_INT: return this->value.i[i] != 0; 943b8e80941Smrg case GLSL_TYPE_FLOAT: return ((int)this->value.f[i]) != 0; 944b8e80941Smrg case GLSL_TYPE_BOOL: return this->value.b[i]; 945b8e80941Smrg case GLSL_TYPE_DOUBLE: return this->value.d[i] != 0.0; 946b8e80941Smrg case GLSL_TYPE_SAMPLER: 947b8e80941Smrg case GLSL_TYPE_IMAGE: 948b8e80941Smrg case GLSL_TYPE_UINT64: return this->value.u64[i] != 0; 949b8e80941Smrg case GLSL_TYPE_INT64: return this->value.i64[i] != 0; 950b8e80941Smrg default: assert(!"Should not get here."); break; 951b8e80941Smrg } 952b8e80941Smrg 953b8e80941Smrg /* Must return something to make the compiler happy. This is clearly an 954b8e80941Smrg * error case. 955b8e80941Smrg */ 956b8e80941Smrg return false; 957b8e80941Smrg} 958b8e80941Smrg 959b8e80941Smrgfloat 960b8e80941Smrgir_constant::get_float_component(unsigned i) const 961b8e80941Smrg{ 962b8e80941Smrg switch (this->type->base_type) { 963b8e80941Smrg case GLSL_TYPE_UINT: return (float) this->value.u[i]; 964b8e80941Smrg case GLSL_TYPE_INT: return (float) this->value.i[i]; 965b8e80941Smrg case GLSL_TYPE_FLOAT: return this->value.f[i]; 966b8e80941Smrg case GLSL_TYPE_BOOL: return this->value.b[i] ? 1.0f : 0.0f; 967b8e80941Smrg case GLSL_TYPE_DOUBLE: return (float) this->value.d[i]; 968b8e80941Smrg case GLSL_TYPE_SAMPLER: 969b8e80941Smrg case GLSL_TYPE_IMAGE: 970b8e80941Smrg case GLSL_TYPE_UINT64: return (float) this->value.u64[i]; 971b8e80941Smrg case GLSL_TYPE_INT64: return (float) this->value.i64[i]; 972b8e80941Smrg default: assert(!"Should not get here."); break; 973b8e80941Smrg } 974b8e80941Smrg 975b8e80941Smrg /* Must return something to make the compiler happy. This is clearly an 976b8e80941Smrg * error case. 977b8e80941Smrg */ 978b8e80941Smrg return 0.0; 979b8e80941Smrg} 980b8e80941Smrg 981b8e80941Smrgdouble 982b8e80941Smrgir_constant::get_double_component(unsigned i) const 983b8e80941Smrg{ 984b8e80941Smrg switch (this->type->base_type) { 985b8e80941Smrg case GLSL_TYPE_UINT: return (double) this->value.u[i]; 986b8e80941Smrg case GLSL_TYPE_INT: return (double) this->value.i[i]; 987b8e80941Smrg case GLSL_TYPE_FLOAT: return (double) this->value.f[i]; 988b8e80941Smrg case GLSL_TYPE_BOOL: return this->value.b[i] ? 1.0 : 0.0; 989b8e80941Smrg case GLSL_TYPE_DOUBLE: return this->value.d[i]; 990b8e80941Smrg case GLSL_TYPE_SAMPLER: 991b8e80941Smrg case GLSL_TYPE_IMAGE: 992b8e80941Smrg case GLSL_TYPE_UINT64: return (double) this->value.u64[i]; 993b8e80941Smrg case GLSL_TYPE_INT64: return (double) this->value.i64[i]; 994b8e80941Smrg default: assert(!"Should not get here."); break; 995b8e80941Smrg } 996b8e80941Smrg 997b8e80941Smrg /* Must return something to make the compiler happy. This is clearly an 998b8e80941Smrg * error case. 999b8e80941Smrg */ 1000b8e80941Smrg return 0.0; 1001b8e80941Smrg} 1002b8e80941Smrg 1003b8e80941Smrgint 1004b8e80941Smrgir_constant::get_int_component(unsigned i) const 1005b8e80941Smrg{ 1006b8e80941Smrg switch (this->type->base_type) { 1007b8e80941Smrg case GLSL_TYPE_UINT: return this->value.u[i]; 1008b8e80941Smrg case GLSL_TYPE_INT: return this->value.i[i]; 1009b8e80941Smrg case GLSL_TYPE_FLOAT: return (int) this->value.f[i]; 1010b8e80941Smrg case GLSL_TYPE_BOOL: return this->value.b[i] ? 1 : 0; 1011b8e80941Smrg case GLSL_TYPE_DOUBLE: return (int) this->value.d[i]; 1012b8e80941Smrg case GLSL_TYPE_SAMPLER: 1013b8e80941Smrg case GLSL_TYPE_IMAGE: 1014b8e80941Smrg case GLSL_TYPE_UINT64: return (int) this->value.u64[i]; 1015b8e80941Smrg case GLSL_TYPE_INT64: return (int) this->value.i64[i]; 1016b8e80941Smrg default: assert(!"Should not get here."); break; 1017b8e80941Smrg } 1018b8e80941Smrg 1019b8e80941Smrg /* Must return something to make the compiler happy. This is clearly an 1020b8e80941Smrg * error case. 1021b8e80941Smrg */ 1022b8e80941Smrg return 0; 1023b8e80941Smrg} 1024b8e80941Smrg 1025b8e80941Smrgunsigned 1026b8e80941Smrgir_constant::get_uint_component(unsigned i) const 1027b8e80941Smrg{ 1028b8e80941Smrg switch (this->type->base_type) { 1029b8e80941Smrg case GLSL_TYPE_UINT: return this->value.u[i]; 1030b8e80941Smrg case GLSL_TYPE_INT: return this->value.i[i]; 1031b8e80941Smrg case GLSL_TYPE_FLOAT: return (unsigned) this->value.f[i]; 1032b8e80941Smrg case GLSL_TYPE_BOOL: return this->value.b[i] ? 1 : 0; 1033b8e80941Smrg case GLSL_TYPE_DOUBLE: return (unsigned) this->value.d[i]; 1034b8e80941Smrg case GLSL_TYPE_SAMPLER: 1035b8e80941Smrg case GLSL_TYPE_IMAGE: 1036b8e80941Smrg case GLSL_TYPE_UINT64: return (unsigned) this->value.u64[i]; 1037b8e80941Smrg case GLSL_TYPE_INT64: return (unsigned) this->value.i64[i]; 1038b8e80941Smrg default: assert(!"Should not get here."); break; 1039b8e80941Smrg } 1040b8e80941Smrg 1041b8e80941Smrg /* Must return something to make the compiler happy. This is clearly an 1042b8e80941Smrg * error case. 1043b8e80941Smrg */ 1044b8e80941Smrg return 0; 1045b8e80941Smrg} 1046b8e80941Smrg 1047b8e80941Smrgint64_t 1048b8e80941Smrgir_constant::get_int64_component(unsigned i) const 1049b8e80941Smrg{ 1050b8e80941Smrg switch (this->type->base_type) { 1051b8e80941Smrg case GLSL_TYPE_UINT: return this->value.u[i]; 1052b8e80941Smrg case GLSL_TYPE_INT: return this->value.i[i]; 1053b8e80941Smrg case GLSL_TYPE_FLOAT: return (int64_t) this->value.f[i]; 1054b8e80941Smrg case GLSL_TYPE_BOOL: return this->value.b[i] ? 1 : 0; 1055b8e80941Smrg case GLSL_TYPE_DOUBLE: return (int64_t) this->value.d[i]; 1056b8e80941Smrg case GLSL_TYPE_SAMPLER: 1057b8e80941Smrg case GLSL_TYPE_IMAGE: 1058b8e80941Smrg case GLSL_TYPE_UINT64: return (int64_t) this->value.u64[i]; 1059b8e80941Smrg case GLSL_TYPE_INT64: return this->value.i64[i]; 1060b8e80941Smrg default: assert(!"Should not get here."); break; 1061b8e80941Smrg } 1062b8e80941Smrg 1063b8e80941Smrg /* Must return something to make the compiler happy. This is clearly an 1064b8e80941Smrg * error case. 1065b8e80941Smrg */ 1066b8e80941Smrg return 0; 1067b8e80941Smrg} 1068b8e80941Smrg 1069b8e80941Smrguint64_t 1070b8e80941Smrgir_constant::get_uint64_component(unsigned i) const 1071b8e80941Smrg{ 1072b8e80941Smrg switch (this->type->base_type) { 1073b8e80941Smrg case GLSL_TYPE_UINT: return this->value.u[i]; 1074b8e80941Smrg case GLSL_TYPE_INT: return this->value.i[i]; 1075b8e80941Smrg case GLSL_TYPE_FLOAT: return (uint64_t) this->value.f[i]; 1076b8e80941Smrg case GLSL_TYPE_BOOL: return this->value.b[i] ? 1 : 0; 1077b8e80941Smrg case GLSL_TYPE_DOUBLE: return (uint64_t) this->value.d[i]; 1078b8e80941Smrg case GLSL_TYPE_SAMPLER: 1079b8e80941Smrg case GLSL_TYPE_IMAGE: 1080b8e80941Smrg case GLSL_TYPE_UINT64: return this->value.u64[i]; 1081b8e80941Smrg case GLSL_TYPE_INT64: return (uint64_t) this->value.i64[i]; 1082b8e80941Smrg default: assert(!"Should not get here."); break; 1083b8e80941Smrg } 1084b8e80941Smrg 1085b8e80941Smrg /* Must return something to make the compiler happy. This is clearly an 1086b8e80941Smrg * error case. 1087b8e80941Smrg */ 1088b8e80941Smrg return 0; 1089b8e80941Smrg} 1090b8e80941Smrg 1091b8e80941Smrgir_constant * 1092b8e80941Smrgir_constant::get_array_element(unsigned i) const 1093b8e80941Smrg{ 1094b8e80941Smrg assert(this->type->is_array()); 1095b8e80941Smrg 1096b8e80941Smrg /* From page 35 (page 41 of the PDF) of the GLSL 1.20 spec: 1097b8e80941Smrg * 1098b8e80941Smrg * "Behavior is undefined if a shader subscripts an array with an index 1099b8e80941Smrg * less than 0 or greater than or equal to the size the array was 1100b8e80941Smrg * declared with." 1101b8e80941Smrg * 1102b8e80941Smrg * Most out-of-bounds accesses are removed before things could get this far. 1103b8e80941Smrg * There are cases where non-constant array index values can get constant 1104b8e80941Smrg * folded. 1105b8e80941Smrg */ 1106b8e80941Smrg if (int(i) < 0) 1107b8e80941Smrg i = 0; 1108b8e80941Smrg else if (i >= this->type->length) 1109b8e80941Smrg i = this->type->length - 1; 1110b8e80941Smrg 1111b8e80941Smrg return const_elements[i]; 1112b8e80941Smrg} 1113b8e80941Smrg 1114b8e80941Smrgir_constant * 1115b8e80941Smrgir_constant::get_record_field(int idx) 1116b8e80941Smrg{ 1117b8e80941Smrg assert(this->type->is_struct()); 1118b8e80941Smrg assert(idx >= 0 && (unsigned) idx < this->type->length); 1119b8e80941Smrg 1120b8e80941Smrg return const_elements[idx]; 1121b8e80941Smrg} 1122b8e80941Smrg 1123b8e80941Smrgvoid 1124b8e80941Smrgir_constant::copy_offset(ir_constant *src, int offset) 1125b8e80941Smrg{ 1126b8e80941Smrg switch (this->type->base_type) { 1127b8e80941Smrg case GLSL_TYPE_UINT: 1128b8e80941Smrg case GLSL_TYPE_INT: 1129b8e80941Smrg case GLSL_TYPE_FLOAT: 1130b8e80941Smrg case GLSL_TYPE_DOUBLE: 1131b8e80941Smrg case GLSL_TYPE_SAMPLER: 1132b8e80941Smrg case GLSL_TYPE_IMAGE: 1133b8e80941Smrg case GLSL_TYPE_UINT64: 1134b8e80941Smrg case GLSL_TYPE_INT64: 1135b8e80941Smrg case GLSL_TYPE_BOOL: { 1136b8e80941Smrg unsigned int size = src->type->components(); 1137b8e80941Smrg assert (size <= this->type->components() - offset); 1138b8e80941Smrg for (unsigned int i=0; i<size; i++) { 1139b8e80941Smrg switch (this->type->base_type) { 1140b8e80941Smrg case GLSL_TYPE_UINT: 1141b8e80941Smrg value.u[i+offset] = src->get_uint_component(i); 1142b8e80941Smrg break; 1143b8e80941Smrg case GLSL_TYPE_INT: 1144b8e80941Smrg value.i[i+offset] = src->get_int_component(i); 1145b8e80941Smrg break; 1146b8e80941Smrg case GLSL_TYPE_FLOAT: 1147b8e80941Smrg value.f[i+offset] = src->get_float_component(i); 1148b8e80941Smrg break; 1149b8e80941Smrg case GLSL_TYPE_BOOL: 1150b8e80941Smrg value.b[i+offset] = src->get_bool_component(i); 1151b8e80941Smrg break; 1152b8e80941Smrg case GLSL_TYPE_DOUBLE: 1153b8e80941Smrg value.d[i+offset] = src->get_double_component(i); 1154b8e80941Smrg break; 1155b8e80941Smrg case GLSL_TYPE_SAMPLER: 1156b8e80941Smrg case GLSL_TYPE_IMAGE: 1157b8e80941Smrg case GLSL_TYPE_UINT64: 1158b8e80941Smrg value.u64[i+offset] = src->get_uint64_component(i); 1159b8e80941Smrg break; 1160b8e80941Smrg case GLSL_TYPE_INT64: 1161b8e80941Smrg value.i64[i+offset] = src->get_int64_component(i); 1162b8e80941Smrg break; 1163b8e80941Smrg default: // Shut up the compiler 1164b8e80941Smrg break; 1165b8e80941Smrg } 1166b8e80941Smrg } 1167b8e80941Smrg break; 1168b8e80941Smrg } 1169b8e80941Smrg 1170b8e80941Smrg case GLSL_TYPE_STRUCT: 1171b8e80941Smrg case GLSL_TYPE_ARRAY: { 1172b8e80941Smrg assert (src->type == this->type); 1173b8e80941Smrg for (unsigned i = 0; i < this->type->length; i++) { 1174b8e80941Smrg this->const_elements[i] = src->const_elements[i]->clone(this, NULL); 1175b8e80941Smrg } 1176b8e80941Smrg break; 1177b8e80941Smrg } 1178b8e80941Smrg 1179b8e80941Smrg default: 1180b8e80941Smrg assert(!"Should not get here."); 1181b8e80941Smrg break; 1182b8e80941Smrg } 1183b8e80941Smrg} 1184b8e80941Smrg 1185b8e80941Smrgvoid 1186b8e80941Smrgir_constant::copy_masked_offset(ir_constant *src, int offset, unsigned int mask) 1187b8e80941Smrg{ 1188b8e80941Smrg assert (!type->is_array() && !type->is_struct()); 1189b8e80941Smrg 1190b8e80941Smrg if (!type->is_vector() && !type->is_matrix()) { 1191b8e80941Smrg offset = 0; 1192b8e80941Smrg mask = 1; 1193b8e80941Smrg } 1194b8e80941Smrg 1195b8e80941Smrg int id = 0; 1196b8e80941Smrg for (int i=0; i<4; i++) { 1197b8e80941Smrg if (mask & (1 << i)) { 1198b8e80941Smrg switch (this->type->base_type) { 1199b8e80941Smrg case GLSL_TYPE_UINT: 1200b8e80941Smrg value.u[i+offset] = src->get_uint_component(id++); 1201b8e80941Smrg break; 1202b8e80941Smrg case GLSL_TYPE_INT: 1203b8e80941Smrg value.i[i+offset] = src->get_int_component(id++); 1204b8e80941Smrg break; 1205b8e80941Smrg case GLSL_TYPE_FLOAT: 1206b8e80941Smrg value.f[i+offset] = src->get_float_component(id++); 1207b8e80941Smrg break; 1208b8e80941Smrg case GLSL_TYPE_BOOL: 1209b8e80941Smrg value.b[i+offset] = src->get_bool_component(id++); 1210b8e80941Smrg break; 1211b8e80941Smrg case GLSL_TYPE_DOUBLE: 1212b8e80941Smrg value.d[i+offset] = src->get_double_component(id++); 1213b8e80941Smrg break; 1214b8e80941Smrg case GLSL_TYPE_SAMPLER: 1215b8e80941Smrg case GLSL_TYPE_IMAGE: 1216b8e80941Smrg case GLSL_TYPE_UINT64: 1217b8e80941Smrg value.u64[i+offset] = src->get_uint64_component(id++); 1218b8e80941Smrg break; 1219b8e80941Smrg case GLSL_TYPE_INT64: 1220b8e80941Smrg value.i64[i+offset] = src->get_int64_component(id++); 1221b8e80941Smrg break; 1222b8e80941Smrg default: 1223b8e80941Smrg assert(!"Should not get here."); 1224b8e80941Smrg return; 1225b8e80941Smrg } 1226b8e80941Smrg } 1227b8e80941Smrg } 1228b8e80941Smrg} 1229b8e80941Smrg 1230b8e80941Smrgbool 1231b8e80941Smrgir_constant::has_value(const ir_constant *c) const 1232b8e80941Smrg{ 1233b8e80941Smrg if (this->type != c->type) 1234b8e80941Smrg return false; 1235b8e80941Smrg 1236b8e80941Smrg if (this->type->is_array() || this->type->is_struct()) { 1237b8e80941Smrg for (unsigned i = 0; i < this->type->length; i++) { 1238b8e80941Smrg if (!this->const_elements[i]->has_value(c->const_elements[i])) 1239b8e80941Smrg return false; 1240b8e80941Smrg } 1241b8e80941Smrg return true; 1242b8e80941Smrg } 1243b8e80941Smrg 1244b8e80941Smrg for (unsigned i = 0; i < this->type->components(); i++) { 1245b8e80941Smrg switch (this->type->base_type) { 1246b8e80941Smrg case GLSL_TYPE_UINT: 1247b8e80941Smrg if (this->value.u[i] != c->value.u[i]) 1248b8e80941Smrg return false; 1249b8e80941Smrg break; 1250b8e80941Smrg case GLSL_TYPE_INT: 1251b8e80941Smrg if (this->value.i[i] != c->value.i[i]) 1252b8e80941Smrg return false; 1253b8e80941Smrg break; 1254b8e80941Smrg case GLSL_TYPE_FLOAT: 1255b8e80941Smrg if (this->value.f[i] != c->value.f[i]) 1256b8e80941Smrg return false; 1257b8e80941Smrg break; 1258b8e80941Smrg case GLSL_TYPE_BOOL: 1259b8e80941Smrg if (this->value.b[i] != c->value.b[i]) 1260b8e80941Smrg return false; 1261b8e80941Smrg break; 1262b8e80941Smrg case GLSL_TYPE_DOUBLE: 1263b8e80941Smrg if (this->value.d[i] != c->value.d[i]) 1264b8e80941Smrg return false; 1265b8e80941Smrg break; 1266b8e80941Smrg case GLSL_TYPE_SAMPLER: 1267b8e80941Smrg case GLSL_TYPE_IMAGE: 1268b8e80941Smrg case GLSL_TYPE_UINT64: 1269b8e80941Smrg if (this->value.u64[i] != c->value.u64[i]) 1270b8e80941Smrg return false; 1271b8e80941Smrg break; 1272b8e80941Smrg case GLSL_TYPE_INT64: 1273b8e80941Smrg if (this->value.i64[i] != c->value.i64[i]) 1274b8e80941Smrg return false; 1275b8e80941Smrg break; 1276b8e80941Smrg default: 1277b8e80941Smrg assert(!"Should not get here."); 1278b8e80941Smrg return false; 1279b8e80941Smrg } 1280b8e80941Smrg } 1281b8e80941Smrg 1282b8e80941Smrg return true; 1283b8e80941Smrg} 1284b8e80941Smrg 1285b8e80941Smrgbool 1286b8e80941Smrgir_constant::is_value(float f, int i) const 1287b8e80941Smrg{ 1288b8e80941Smrg if (!this->type->is_scalar() && !this->type->is_vector()) 1289b8e80941Smrg return false; 1290b8e80941Smrg 1291b8e80941Smrg /* Only accept boolean values for 0/1. */ 1292b8e80941Smrg if (int(bool(i)) != i && this->type->is_boolean()) 1293b8e80941Smrg return false; 1294b8e80941Smrg 1295b8e80941Smrg for (unsigned c = 0; c < this->type->vector_elements; c++) { 1296b8e80941Smrg switch (this->type->base_type) { 1297b8e80941Smrg case GLSL_TYPE_FLOAT: 1298b8e80941Smrg if (this->value.f[c] != f) 1299b8e80941Smrg return false; 1300b8e80941Smrg break; 1301b8e80941Smrg case GLSL_TYPE_INT: 1302b8e80941Smrg if (this->value.i[c] != i) 1303b8e80941Smrg return false; 1304b8e80941Smrg break; 1305b8e80941Smrg case GLSL_TYPE_UINT: 1306b8e80941Smrg if (this->value.u[c] != unsigned(i)) 1307b8e80941Smrg return false; 1308b8e80941Smrg break; 1309b8e80941Smrg case GLSL_TYPE_BOOL: 1310b8e80941Smrg if (this->value.b[c] != bool(i)) 1311b8e80941Smrg return false; 1312b8e80941Smrg break; 1313b8e80941Smrg case GLSL_TYPE_DOUBLE: 1314b8e80941Smrg if (this->value.d[c] != double(f)) 1315b8e80941Smrg return false; 1316b8e80941Smrg break; 1317b8e80941Smrg case GLSL_TYPE_SAMPLER: 1318b8e80941Smrg case GLSL_TYPE_IMAGE: 1319b8e80941Smrg case GLSL_TYPE_UINT64: 1320b8e80941Smrg if (this->value.u64[c] != uint64_t(i)) 1321b8e80941Smrg return false; 1322b8e80941Smrg break; 1323b8e80941Smrg case GLSL_TYPE_INT64: 1324b8e80941Smrg if (this->value.i64[c] != i) 1325b8e80941Smrg return false; 1326b8e80941Smrg break; 1327b8e80941Smrg default: 1328b8e80941Smrg /* The only other base types are structures, arrays, and samplers. 1329b8e80941Smrg * Samplers cannot be constants, and the others should have been 1330b8e80941Smrg * filtered out above. 1331b8e80941Smrg */ 1332b8e80941Smrg assert(!"Should not get here."); 1333b8e80941Smrg return false; 1334b8e80941Smrg } 1335b8e80941Smrg } 1336b8e80941Smrg 1337b8e80941Smrg return true; 1338b8e80941Smrg} 1339b8e80941Smrg 1340b8e80941Smrgbool 1341b8e80941Smrgir_constant::is_zero() const 1342b8e80941Smrg{ 1343b8e80941Smrg return is_value(0.0, 0); 1344b8e80941Smrg} 1345b8e80941Smrg 1346b8e80941Smrgbool 1347b8e80941Smrgir_constant::is_one() const 1348b8e80941Smrg{ 1349b8e80941Smrg return is_value(1.0, 1); 1350b8e80941Smrg} 1351b8e80941Smrg 1352b8e80941Smrgbool 1353b8e80941Smrgir_constant::is_negative_one() const 1354b8e80941Smrg{ 1355b8e80941Smrg return is_value(-1.0, -1); 1356b8e80941Smrg} 1357b8e80941Smrg 1358b8e80941Smrgbool 1359b8e80941Smrgir_constant::is_uint16_constant() const 1360b8e80941Smrg{ 1361b8e80941Smrg if (!type->is_integer()) 1362b8e80941Smrg return false; 1363b8e80941Smrg 1364b8e80941Smrg return value.u[0] < (1 << 16); 1365b8e80941Smrg} 1366b8e80941Smrg 1367b8e80941Smrgir_loop::ir_loop() 1368b8e80941Smrg : ir_instruction(ir_type_loop) 1369b8e80941Smrg{ 1370b8e80941Smrg} 1371b8e80941Smrg 1372b8e80941Smrg 1373b8e80941Smrgir_dereference_variable::ir_dereference_variable(ir_variable *var) 1374b8e80941Smrg : ir_dereference(ir_type_dereference_variable) 1375b8e80941Smrg{ 1376b8e80941Smrg assert(var != NULL); 1377b8e80941Smrg 1378b8e80941Smrg this->var = var; 1379b8e80941Smrg this->type = var->type; 1380b8e80941Smrg} 1381b8e80941Smrg 1382b8e80941Smrg 1383b8e80941Smrgir_dereference_array::ir_dereference_array(ir_rvalue *value, 1384b8e80941Smrg ir_rvalue *array_index) 1385b8e80941Smrg : ir_dereference(ir_type_dereference_array) 1386b8e80941Smrg{ 1387b8e80941Smrg this->array_index = array_index; 1388b8e80941Smrg this->set_array(value); 1389b8e80941Smrg} 1390b8e80941Smrg 1391b8e80941Smrg 1392b8e80941Smrgir_dereference_array::ir_dereference_array(ir_variable *var, 1393b8e80941Smrg ir_rvalue *array_index) 1394b8e80941Smrg : ir_dereference(ir_type_dereference_array) 1395b8e80941Smrg{ 1396b8e80941Smrg void *ctx = ralloc_parent(var); 1397b8e80941Smrg 1398b8e80941Smrg this->array_index = array_index; 1399b8e80941Smrg this->set_array(new(ctx) ir_dereference_variable(var)); 1400b8e80941Smrg} 1401b8e80941Smrg 1402b8e80941Smrg 1403b8e80941Smrgvoid 1404b8e80941Smrgir_dereference_array::set_array(ir_rvalue *value) 1405b8e80941Smrg{ 1406b8e80941Smrg assert(value != NULL); 1407b8e80941Smrg 1408b8e80941Smrg this->array = value; 1409b8e80941Smrg 1410b8e80941Smrg const glsl_type *const vt = this->array->type; 1411b8e80941Smrg 1412b8e80941Smrg if (vt->is_array()) { 1413b8e80941Smrg type = vt->fields.array; 1414b8e80941Smrg } else if (vt->is_matrix()) { 1415b8e80941Smrg type = vt->column_type(); 1416b8e80941Smrg } else if (vt->is_vector()) { 1417b8e80941Smrg type = vt->get_base_type(); 1418b8e80941Smrg } 1419b8e80941Smrg} 1420b8e80941Smrg 1421b8e80941Smrg 1422b8e80941Smrgir_dereference_record::ir_dereference_record(ir_rvalue *value, 1423b8e80941Smrg const char *field) 1424b8e80941Smrg : ir_dereference(ir_type_dereference_record) 1425b8e80941Smrg{ 1426b8e80941Smrg assert(value != NULL); 1427b8e80941Smrg 1428b8e80941Smrg this->record = value; 1429b8e80941Smrg this->type = this->record->type->field_type(field); 1430b8e80941Smrg this->field_idx = this->record->type->field_index(field); 1431b8e80941Smrg} 1432b8e80941Smrg 1433b8e80941Smrg 1434b8e80941Smrgir_dereference_record::ir_dereference_record(ir_variable *var, 1435b8e80941Smrg const char *field) 1436b8e80941Smrg : ir_dereference(ir_type_dereference_record) 1437b8e80941Smrg{ 1438b8e80941Smrg void *ctx = ralloc_parent(var); 1439b8e80941Smrg 1440b8e80941Smrg this->record = new(ctx) ir_dereference_variable(var); 1441b8e80941Smrg this->type = this->record->type->field_type(field); 1442b8e80941Smrg this->field_idx = this->record->type->field_index(field); 1443b8e80941Smrg} 1444b8e80941Smrg 1445b8e80941Smrgbool 1446b8e80941Smrgir_dereference::is_lvalue(const struct _mesa_glsl_parse_state *state) const 1447b8e80941Smrg{ 1448b8e80941Smrg ir_variable *var = this->variable_referenced(); 1449b8e80941Smrg 1450b8e80941Smrg /* Every l-value derference chain eventually ends in a variable. 1451b8e80941Smrg */ 1452b8e80941Smrg if ((var == NULL) || var->data.read_only) 1453b8e80941Smrg return false; 1454b8e80941Smrg 1455b8e80941Smrg /* From section 4.1.7 of the ARB_bindless_texture spec: 1456b8e80941Smrg * 1457b8e80941Smrg * "Samplers can be used as l-values, so can be assigned into and used as 1458b8e80941Smrg * "out" and "inout" function parameters." 1459b8e80941Smrg * 1460b8e80941Smrg * From section 4.1.X of the ARB_bindless_texture spec: 1461b8e80941Smrg * 1462b8e80941Smrg * "Images can be used as l-values, so can be assigned into and used as 1463b8e80941Smrg * "out" and "inout" function parameters." 1464b8e80941Smrg */ 1465b8e80941Smrg if ((!state || state->has_bindless()) && 1466b8e80941Smrg (this->type->contains_sampler() || this->type->contains_image())) 1467b8e80941Smrg return true; 1468b8e80941Smrg 1469b8e80941Smrg /* From section 4.1.7 of the GLSL 4.40 spec: 1470b8e80941Smrg * 1471b8e80941Smrg * "Opaque variables cannot be treated as l-values; hence cannot 1472b8e80941Smrg * be used as out or inout function parameters, nor can they be 1473b8e80941Smrg * assigned into." 1474b8e80941Smrg */ 1475b8e80941Smrg if (this->type->contains_opaque()) 1476b8e80941Smrg return false; 1477b8e80941Smrg 1478b8e80941Smrg return true; 1479b8e80941Smrg} 1480b8e80941Smrg 1481b8e80941Smrg 1482b8e80941Smrgstatic const char * const tex_opcode_strs[] = { "tex", "txb", "txl", "txd", "txf", "txf_ms", "txs", "lod", "tg4", "query_levels", "texture_samples", "samples_identical" }; 1483b8e80941Smrg 1484b8e80941Smrgconst char *ir_texture::opcode_string() 1485b8e80941Smrg{ 1486b8e80941Smrg assert((unsigned int) op < ARRAY_SIZE(tex_opcode_strs)); 1487b8e80941Smrg return tex_opcode_strs[op]; 1488b8e80941Smrg} 1489b8e80941Smrg 1490b8e80941Smrgir_texture_opcode 1491b8e80941Smrgir_texture::get_opcode(const char *str) 1492b8e80941Smrg{ 1493b8e80941Smrg const int count = sizeof(tex_opcode_strs) / sizeof(tex_opcode_strs[0]); 1494b8e80941Smrg for (int op = 0; op < count; op++) { 1495b8e80941Smrg if (strcmp(str, tex_opcode_strs[op]) == 0) 1496b8e80941Smrg return (ir_texture_opcode) op; 1497b8e80941Smrg } 1498b8e80941Smrg return (ir_texture_opcode) -1; 1499b8e80941Smrg} 1500b8e80941Smrg 1501b8e80941Smrg 1502b8e80941Smrgvoid 1503b8e80941Smrgir_texture::set_sampler(ir_dereference *sampler, const glsl_type *type) 1504b8e80941Smrg{ 1505b8e80941Smrg assert(sampler != NULL); 1506b8e80941Smrg assert(type != NULL); 1507b8e80941Smrg this->sampler = sampler; 1508b8e80941Smrg this->type = type; 1509b8e80941Smrg 1510b8e80941Smrg if (this->op == ir_txs || this->op == ir_query_levels || 1511b8e80941Smrg this->op == ir_texture_samples) { 1512b8e80941Smrg assert(type->base_type == GLSL_TYPE_INT); 1513b8e80941Smrg } else if (this->op == ir_lod) { 1514b8e80941Smrg assert(type->vector_elements == 2); 1515b8e80941Smrg assert(type->is_float()); 1516b8e80941Smrg } else if (this->op == ir_samples_identical) { 1517b8e80941Smrg assert(type == glsl_type::bool_type); 1518b8e80941Smrg assert(sampler->type->is_sampler()); 1519b8e80941Smrg assert(sampler->type->sampler_dimensionality == GLSL_SAMPLER_DIM_MS); 1520b8e80941Smrg } else { 1521b8e80941Smrg assert(sampler->type->sampled_type == (int) type->base_type); 1522b8e80941Smrg if (sampler->type->sampler_shadow) 1523b8e80941Smrg assert(type->vector_elements == 4 || type->vector_elements == 1); 1524b8e80941Smrg else 1525b8e80941Smrg assert(type->vector_elements == 4); 1526b8e80941Smrg } 1527b8e80941Smrg} 1528b8e80941Smrg 1529b8e80941Smrg 1530b8e80941Smrgvoid 1531b8e80941Smrgir_swizzle::init_mask(const unsigned *comp, unsigned count) 1532b8e80941Smrg{ 1533b8e80941Smrg assert((count >= 1) && (count <= 4)); 1534b8e80941Smrg 1535b8e80941Smrg memset(&this->mask, 0, sizeof(this->mask)); 1536b8e80941Smrg this->mask.num_components = count; 1537b8e80941Smrg 1538b8e80941Smrg unsigned dup_mask = 0; 1539b8e80941Smrg switch (count) { 1540b8e80941Smrg case 4: 1541b8e80941Smrg assert(comp[3] <= 3); 1542b8e80941Smrg dup_mask |= (1U << comp[3]) 1543b8e80941Smrg & ((1U << comp[0]) | (1U << comp[1]) | (1U << comp[2])); 1544b8e80941Smrg this->mask.w = comp[3]; 1545b8e80941Smrg 1546b8e80941Smrg case 3: 1547b8e80941Smrg assert(comp[2] <= 3); 1548b8e80941Smrg dup_mask |= (1U << comp[2]) 1549b8e80941Smrg & ((1U << comp[0]) | (1U << comp[1])); 1550b8e80941Smrg this->mask.z = comp[2]; 1551b8e80941Smrg 1552b8e80941Smrg case 2: 1553b8e80941Smrg assert(comp[1] <= 3); 1554b8e80941Smrg dup_mask |= (1U << comp[1]) 1555b8e80941Smrg & ((1U << comp[0])); 1556b8e80941Smrg this->mask.y = comp[1]; 1557b8e80941Smrg 1558b8e80941Smrg case 1: 1559b8e80941Smrg assert(comp[0] <= 3); 1560b8e80941Smrg this->mask.x = comp[0]; 1561b8e80941Smrg } 1562b8e80941Smrg 1563b8e80941Smrg this->mask.has_duplicates = dup_mask != 0; 1564b8e80941Smrg 1565b8e80941Smrg /* Based on the number of elements in the swizzle and the base type 1566b8e80941Smrg * (i.e., float, int, unsigned, or bool) of the vector being swizzled, 1567b8e80941Smrg * generate the type of the resulting value. 1568b8e80941Smrg */ 1569b8e80941Smrg type = glsl_type::get_instance(val->type->base_type, mask.num_components, 1); 1570b8e80941Smrg} 1571b8e80941Smrg 1572b8e80941Smrgir_swizzle::ir_swizzle(ir_rvalue *val, unsigned x, unsigned y, unsigned z, 1573b8e80941Smrg unsigned w, unsigned count) 1574b8e80941Smrg : ir_rvalue(ir_type_swizzle), val(val) 1575b8e80941Smrg{ 1576b8e80941Smrg const unsigned components[4] = { x, y, z, w }; 1577b8e80941Smrg this->init_mask(components, count); 1578b8e80941Smrg} 1579b8e80941Smrg 1580b8e80941Smrgir_swizzle::ir_swizzle(ir_rvalue *val, const unsigned *comp, 1581b8e80941Smrg unsigned count) 1582b8e80941Smrg : ir_rvalue(ir_type_swizzle), val(val) 1583b8e80941Smrg{ 1584b8e80941Smrg this->init_mask(comp, count); 1585b8e80941Smrg} 1586b8e80941Smrg 1587b8e80941Smrgir_swizzle::ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask) 1588b8e80941Smrg : ir_rvalue(ir_type_swizzle), val(val), mask(mask) 1589b8e80941Smrg{ 1590b8e80941Smrg this->type = glsl_type::get_instance(val->type->base_type, 1591b8e80941Smrg mask.num_components, 1); 1592b8e80941Smrg} 1593b8e80941Smrg 1594b8e80941Smrg#define X 1 1595b8e80941Smrg#define R 5 1596b8e80941Smrg#define S 9 1597b8e80941Smrg#define I 13 1598b8e80941Smrg 1599b8e80941Smrgir_swizzle * 1600b8e80941Smrgir_swizzle::create(ir_rvalue *val, const char *str, unsigned vector_length) 1601b8e80941Smrg{ 1602b8e80941Smrg void *ctx = ralloc_parent(val); 1603b8e80941Smrg 1604b8e80941Smrg /* For each possible swizzle character, this table encodes the value in 1605b8e80941Smrg * \c idx_map that represents the 0th element of the vector. For invalid 1606b8e80941Smrg * swizzle characters (e.g., 'k'), a special value is used that will allow 1607b8e80941Smrg * detection of errors. 1608b8e80941Smrg */ 1609b8e80941Smrg static const unsigned char base_idx[26] = { 1610b8e80941Smrg /* a b c d e f g h i j k l m */ 1611b8e80941Smrg R, R, I, I, I, I, R, I, I, I, I, I, I, 1612b8e80941Smrg /* n o p q r s t u v w x y z */ 1613b8e80941Smrg I, I, S, S, R, S, S, I, I, X, X, X, X 1614b8e80941Smrg }; 1615b8e80941Smrg 1616b8e80941Smrg /* Each valid swizzle character has an entry in the previous table. This 1617b8e80941Smrg * table encodes the base index encoded in the previous table plus the actual 1618b8e80941Smrg * index of the swizzle character. When processing swizzles, the first 1619b8e80941Smrg * character in the string is indexed in the previous table. Each character 1620b8e80941Smrg * in the string is indexed in this table, and the value found there has the 1621b8e80941Smrg * value form the first table subtracted. The result must be on the range 1622b8e80941Smrg * [0,3]. 1623b8e80941Smrg * 1624b8e80941Smrg * For example, the string "wzyx" will get X from the first table. Each of 1625b8e80941Smrg * the charcaters will get X+3, X+2, X+1, and X+0 from this table. After 1626b8e80941Smrg * subtraction, the swizzle values are { 3, 2, 1, 0 }. 1627b8e80941Smrg * 1628b8e80941Smrg * The string "wzrg" will get X from the first table. Each of the characters 1629b8e80941Smrg * will get X+3, X+2, R+0, and R+1 from this table. After subtraction, the 1630b8e80941Smrg * swizzle values are { 3, 2, 4, 5 }. Since 4 and 5 are outside the range 1631b8e80941Smrg * [0,3], the error is detected. 1632b8e80941Smrg */ 1633b8e80941Smrg static const unsigned char idx_map[26] = { 1634b8e80941Smrg /* a b c d e f g h i j k l m */ 1635b8e80941Smrg R+3, R+2, 0, 0, 0, 0, R+1, 0, 0, 0, 0, 0, 0, 1636b8e80941Smrg /* n o p q r s t u v w x y z */ 1637b8e80941Smrg 0, 0, S+2, S+3, R+0, S+0, S+1, 0, 0, X+3, X+0, X+1, X+2 1638b8e80941Smrg }; 1639b8e80941Smrg 1640b8e80941Smrg int swiz_idx[4] = { 0, 0, 0, 0 }; 1641b8e80941Smrg unsigned i; 1642b8e80941Smrg 1643b8e80941Smrg 1644b8e80941Smrg /* Validate the first character in the swizzle string and look up the base 1645b8e80941Smrg * index value as described above. 1646b8e80941Smrg */ 1647b8e80941Smrg if ((str[0] < 'a') || (str[0] > 'z')) 1648b8e80941Smrg return NULL; 1649b8e80941Smrg 1650b8e80941Smrg const unsigned base = base_idx[str[0] - 'a']; 1651b8e80941Smrg 1652b8e80941Smrg 1653b8e80941Smrg for (i = 0; (i < 4) && (str[i] != '\0'); i++) { 1654b8e80941Smrg /* Validate the next character, and, as described above, convert it to a 1655b8e80941Smrg * swizzle index. 1656b8e80941Smrg */ 1657b8e80941Smrg if ((str[i] < 'a') || (str[i] > 'z')) 1658b8e80941Smrg return NULL; 1659b8e80941Smrg 1660b8e80941Smrg swiz_idx[i] = idx_map[str[i] - 'a'] - base; 1661b8e80941Smrg if ((swiz_idx[i] < 0) || (swiz_idx[i] >= (int) vector_length)) 1662b8e80941Smrg return NULL; 1663b8e80941Smrg } 1664b8e80941Smrg 1665b8e80941Smrg if (str[i] != '\0') 1666b8e80941Smrg return NULL; 1667b8e80941Smrg 1668b8e80941Smrg return new(ctx) ir_swizzle(val, swiz_idx[0], swiz_idx[1], swiz_idx[2], 1669b8e80941Smrg swiz_idx[3], i); 1670b8e80941Smrg} 1671b8e80941Smrg 1672b8e80941Smrg#undef X 1673b8e80941Smrg#undef R 1674b8e80941Smrg#undef S 1675b8e80941Smrg#undef I 1676b8e80941Smrg 1677b8e80941Smrgir_variable * 1678b8e80941Smrgir_swizzle::variable_referenced() const 1679b8e80941Smrg{ 1680b8e80941Smrg return this->val->variable_referenced(); 1681b8e80941Smrg} 1682b8e80941Smrg 1683b8e80941Smrg 1684b8e80941Smrgbool ir_variable::temporaries_allocate_names = false; 1685b8e80941Smrg 1686b8e80941Smrgconst char ir_variable::tmp_name[] = "compiler_temp"; 1687b8e80941Smrg 1688b8e80941Smrgir_variable::ir_variable(const struct glsl_type *type, const char *name, 1689b8e80941Smrg ir_variable_mode mode) 1690b8e80941Smrg : ir_instruction(ir_type_variable) 1691b8e80941Smrg{ 1692b8e80941Smrg this->type = type; 1693b8e80941Smrg 1694b8e80941Smrg if (mode == ir_var_temporary && !ir_variable::temporaries_allocate_names) 1695b8e80941Smrg name = NULL; 1696b8e80941Smrg 1697b8e80941Smrg /* The ir_variable clone method may call this constructor with name set to 1698b8e80941Smrg * tmp_name. 1699b8e80941Smrg */ 1700b8e80941Smrg assert(name != NULL 1701b8e80941Smrg || mode == ir_var_temporary 1702b8e80941Smrg || mode == ir_var_function_in 1703b8e80941Smrg || mode == ir_var_function_out 1704b8e80941Smrg || mode == ir_var_function_inout); 1705b8e80941Smrg assert(name != ir_variable::tmp_name 1706b8e80941Smrg || mode == ir_var_temporary); 1707b8e80941Smrg if (mode == ir_var_temporary 1708b8e80941Smrg && (name == NULL || name == ir_variable::tmp_name)) { 1709b8e80941Smrg this->name = ir_variable::tmp_name; 1710b8e80941Smrg } else if (name == NULL || 1711b8e80941Smrg strlen(name) < ARRAY_SIZE(this->name_storage)) { 1712b8e80941Smrg strcpy(this->name_storage, name ? name : ""); 1713b8e80941Smrg this->name = this->name_storage; 1714b8e80941Smrg } else { 1715b8e80941Smrg this->name = ralloc_strdup(this, name); 1716b8e80941Smrg } 1717b8e80941Smrg 1718b8e80941Smrg this->u.max_ifc_array_access = NULL; 1719b8e80941Smrg 1720b8e80941Smrg this->data.explicit_location = false; 1721b8e80941Smrg this->data.has_initializer = false; 1722b8e80941Smrg this->data.location = -1; 1723b8e80941Smrg this->data.location_frac = 0; 1724b8e80941Smrg this->data.binding = 0; 1725b8e80941Smrg this->data.warn_extension_index = 0; 1726b8e80941Smrg this->constant_value = NULL; 1727b8e80941Smrg this->constant_initializer = NULL; 1728b8e80941Smrg this->data.depth_layout = ir_depth_layout_none; 1729b8e80941Smrg this->data.used = false; 1730b8e80941Smrg this->data.always_active_io = false; 1731b8e80941Smrg this->data.read_only = false; 1732b8e80941Smrg this->data.centroid = false; 1733b8e80941Smrg this->data.sample = false; 1734b8e80941Smrg this->data.patch = false; 1735b8e80941Smrg this->data.explicit_invariant = false; 1736b8e80941Smrg this->data.invariant = false; 1737b8e80941Smrg this->data.how_declared = ir_var_declared_normally; 1738b8e80941Smrg this->data.mode = mode; 1739b8e80941Smrg this->data.interpolation = INTERP_MODE_NONE; 1740b8e80941Smrg this->data.max_array_access = -1; 1741b8e80941Smrg this->data.offset = 0; 1742b8e80941Smrg this->data.precision = GLSL_PRECISION_NONE; 1743b8e80941Smrg this->data.memory_read_only = false; 1744b8e80941Smrg this->data.memory_write_only = false; 1745b8e80941Smrg this->data.memory_coherent = false; 1746b8e80941Smrg this->data.memory_volatile = false; 1747b8e80941Smrg this->data.memory_restrict = false; 1748b8e80941Smrg this->data.from_ssbo_unsized_array = false; 1749b8e80941Smrg this->data.fb_fetch_output = false; 1750b8e80941Smrg this->data.bindless = false; 1751b8e80941Smrg this->data.bound = false; 1752b8e80941Smrg 1753b8e80941Smrg if (type != NULL) { 1754b8e80941Smrg if (type->is_interface()) 1755b8e80941Smrg this->init_interface_type(type); 1756b8e80941Smrg else if (type->without_array()->is_interface()) 1757b8e80941Smrg this->init_interface_type(type->without_array()); 1758b8e80941Smrg } 1759b8e80941Smrg} 1760b8e80941Smrg 1761b8e80941Smrg 1762b8e80941Smrgconst char * 1763b8e80941Smrginterpolation_string(unsigned interpolation) 1764b8e80941Smrg{ 1765b8e80941Smrg switch (interpolation) { 1766b8e80941Smrg case INTERP_MODE_NONE: return "no"; 1767b8e80941Smrg case INTERP_MODE_SMOOTH: return "smooth"; 1768b8e80941Smrg case INTERP_MODE_FLAT: return "flat"; 1769b8e80941Smrg case INTERP_MODE_NOPERSPECTIVE: return "noperspective"; 1770b8e80941Smrg } 1771b8e80941Smrg 1772b8e80941Smrg assert(!"Should not get here."); 1773b8e80941Smrg return ""; 1774b8e80941Smrg} 1775b8e80941Smrg 1776b8e80941Smrgconst char *const ir_variable::warn_extension_table[] = { 1777b8e80941Smrg "", 1778b8e80941Smrg "GL_ARB_shader_stencil_export", 1779b8e80941Smrg "GL_AMD_shader_stencil_export", 1780b8e80941Smrg}; 1781b8e80941Smrg 1782b8e80941Smrgvoid 1783b8e80941Smrgir_variable::enable_extension_warning(const char *extension) 1784b8e80941Smrg{ 1785b8e80941Smrg for (unsigned i = 0; i < ARRAY_SIZE(warn_extension_table); i++) { 1786b8e80941Smrg if (strcmp(warn_extension_table[i], extension) == 0) { 1787b8e80941Smrg this->data.warn_extension_index = i; 1788b8e80941Smrg return; 1789b8e80941Smrg } 1790b8e80941Smrg } 1791b8e80941Smrg 1792b8e80941Smrg assert(!"Should not get here."); 1793b8e80941Smrg this->data.warn_extension_index = 0; 1794b8e80941Smrg} 1795b8e80941Smrg 1796b8e80941Smrgconst char * 1797b8e80941Smrgir_variable::get_extension_warning() const 1798b8e80941Smrg{ 1799b8e80941Smrg return this->data.warn_extension_index == 0 1800b8e80941Smrg ? NULL : warn_extension_table[this->data.warn_extension_index]; 1801b8e80941Smrg} 1802b8e80941Smrg 1803b8e80941Smrgir_function_signature::ir_function_signature(const glsl_type *return_type, 1804b8e80941Smrg builtin_available_predicate b) 1805b8e80941Smrg : ir_instruction(ir_type_function_signature), 1806b8e80941Smrg return_type(return_type), is_defined(false), 1807b8e80941Smrg intrinsic_id(ir_intrinsic_invalid), builtin_avail(b), _function(NULL) 1808b8e80941Smrg{ 1809b8e80941Smrg this->origin = NULL; 1810b8e80941Smrg} 1811b8e80941Smrg 1812b8e80941Smrg 1813b8e80941Smrgbool 1814b8e80941Smrgir_function_signature::is_builtin() const 1815b8e80941Smrg{ 1816b8e80941Smrg return builtin_avail != NULL; 1817b8e80941Smrg} 1818b8e80941Smrg 1819b8e80941Smrg 1820b8e80941Smrgbool 1821b8e80941Smrgir_function_signature::is_builtin_available(const _mesa_glsl_parse_state *state) const 1822b8e80941Smrg{ 1823b8e80941Smrg /* We can't call the predicate without a state pointer, so just say that 1824b8e80941Smrg * the signature is available. At compile time, we need the filtering, 1825b8e80941Smrg * but also receive a valid state pointer. At link time, we're resolving 1826b8e80941Smrg * imported built-in prototypes to their definitions, which will always 1827b8e80941Smrg * be an exact match. So we can skip the filtering. 1828b8e80941Smrg */ 1829b8e80941Smrg if (state == NULL) 1830b8e80941Smrg return true; 1831b8e80941Smrg 1832b8e80941Smrg assert(builtin_avail != NULL); 1833b8e80941Smrg return builtin_avail(state); 1834b8e80941Smrg} 1835b8e80941Smrg 1836b8e80941Smrg 1837b8e80941Smrgstatic bool 1838b8e80941Smrgmodes_match(unsigned a, unsigned b) 1839b8e80941Smrg{ 1840b8e80941Smrg if (a == b) 1841b8e80941Smrg return true; 1842b8e80941Smrg 1843b8e80941Smrg /* Accept "in" vs. "const in" */ 1844b8e80941Smrg if ((a == ir_var_const_in && b == ir_var_function_in) || 1845b8e80941Smrg (b == ir_var_const_in && a == ir_var_function_in)) 1846b8e80941Smrg return true; 1847b8e80941Smrg 1848b8e80941Smrg return false; 1849b8e80941Smrg} 1850b8e80941Smrg 1851b8e80941Smrg 1852b8e80941Smrgconst char * 1853b8e80941Smrgir_function_signature::qualifiers_match(exec_list *params) 1854b8e80941Smrg{ 1855b8e80941Smrg /* check that the qualifiers match. */ 1856b8e80941Smrg foreach_two_lists(a_node, &this->parameters, b_node, params) { 1857b8e80941Smrg ir_variable *a = (ir_variable *) a_node; 1858b8e80941Smrg ir_variable *b = (ir_variable *) b_node; 1859b8e80941Smrg 1860b8e80941Smrg if (a->data.read_only != b->data.read_only || 1861b8e80941Smrg !modes_match(a->data.mode, b->data.mode) || 1862b8e80941Smrg a->data.interpolation != b->data.interpolation || 1863b8e80941Smrg a->data.centroid != b->data.centroid || 1864b8e80941Smrg a->data.sample != b->data.sample || 1865b8e80941Smrg a->data.patch != b->data.patch || 1866b8e80941Smrg a->data.memory_read_only != b->data.memory_read_only || 1867b8e80941Smrg a->data.memory_write_only != b->data.memory_write_only || 1868b8e80941Smrg a->data.memory_coherent != b->data.memory_coherent || 1869b8e80941Smrg a->data.memory_volatile != b->data.memory_volatile || 1870b8e80941Smrg a->data.memory_restrict != b->data.memory_restrict) { 1871b8e80941Smrg 1872b8e80941Smrg /* parameter a's qualifiers don't match */ 1873b8e80941Smrg return a->name; 1874b8e80941Smrg } 1875b8e80941Smrg } 1876b8e80941Smrg return NULL; 1877b8e80941Smrg} 1878b8e80941Smrg 1879b8e80941Smrg 1880b8e80941Smrgvoid 1881b8e80941Smrgir_function_signature::replace_parameters(exec_list *new_params) 1882b8e80941Smrg{ 1883b8e80941Smrg /* Destroy all of the previous parameter information. If the previous 1884b8e80941Smrg * parameter information comes from the function prototype, it may either 1885b8e80941Smrg * specify incorrect parameter names or not have names at all. 1886b8e80941Smrg */ 1887b8e80941Smrg new_params->move_nodes_to(¶meters); 1888b8e80941Smrg} 1889b8e80941Smrg 1890b8e80941Smrg 1891b8e80941Smrgir_function::ir_function(const char *name) 1892b8e80941Smrg : ir_instruction(ir_type_function) 1893b8e80941Smrg{ 1894b8e80941Smrg this->subroutine_index = -1; 1895b8e80941Smrg this->name = ralloc_strdup(this, name); 1896b8e80941Smrg} 1897b8e80941Smrg 1898b8e80941Smrg 1899b8e80941Smrgbool 1900b8e80941Smrgir_function::has_user_signature() 1901b8e80941Smrg{ 1902b8e80941Smrg foreach_in_list(ir_function_signature, sig, &this->signatures) { 1903b8e80941Smrg if (!sig->is_builtin()) 1904b8e80941Smrg return true; 1905b8e80941Smrg } 1906b8e80941Smrg return false; 1907b8e80941Smrg} 1908b8e80941Smrg 1909b8e80941Smrg 1910b8e80941Smrgir_rvalue * 1911b8e80941Smrgir_rvalue::error_value(void *mem_ctx) 1912b8e80941Smrg{ 1913b8e80941Smrg ir_rvalue *v = new(mem_ctx) ir_rvalue(ir_type_unset); 1914b8e80941Smrg 1915b8e80941Smrg v->type = glsl_type::error_type; 1916b8e80941Smrg return v; 1917b8e80941Smrg} 1918b8e80941Smrg 1919b8e80941Smrg 1920b8e80941Smrgvoid 1921b8e80941Smrgvisit_exec_list(exec_list *list, ir_visitor *visitor) 1922b8e80941Smrg{ 1923b8e80941Smrg foreach_in_list_safe(ir_instruction, node, list) { 1924b8e80941Smrg node->accept(visitor); 1925b8e80941Smrg } 1926b8e80941Smrg} 1927b8e80941Smrg 1928b8e80941Smrg 1929b8e80941Smrgstatic void 1930b8e80941Smrgsteal_memory(ir_instruction *ir, void *new_ctx) 1931b8e80941Smrg{ 1932b8e80941Smrg ir_variable *var = ir->as_variable(); 1933b8e80941Smrg ir_function *fn = ir->as_function(); 1934b8e80941Smrg ir_constant *constant = ir->as_constant(); 1935b8e80941Smrg if (var != NULL && var->constant_value != NULL) 1936b8e80941Smrg steal_memory(var->constant_value, ir); 1937b8e80941Smrg 1938b8e80941Smrg if (var != NULL && var->constant_initializer != NULL) 1939b8e80941Smrg steal_memory(var->constant_initializer, ir); 1940b8e80941Smrg 1941b8e80941Smrg if (fn != NULL && fn->subroutine_types) 1942b8e80941Smrg ralloc_steal(new_ctx, fn->subroutine_types); 1943b8e80941Smrg 1944b8e80941Smrg /* The components of aggregate constants are not visited by the normal 1945b8e80941Smrg * visitor, so steal their values by hand. 1946b8e80941Smrg */ 1947b8e80941Smrg if (constant != NULL && 1948b8e80941Smrg (constant->type->is_array() || constant->type->is_struct())) { 1949b8e80941Smrg for (unsigned int i = 0; i < constant->type->length; i++) { 1950b8e80941Smrg steal_memory(constant->const_elements[i], ir); 1951b8e80941Smrg } 1952b8e80941Smrg } 1953b8e80941Smrg 1954b8e80941Smrg ralloc_steal(new_ctx, ir); 1955b8e80941Smrg} 1956b8e80941Smrg 1957b8e80941Smrg 1958b8e80941Smrgvoid 1959b8e80941Smrgreparent_ir(exec_list *list, void *mem_ctx) 1960b8e80941Smrg{ 1961b8e80941Smrg foreach_in_list(ir_instruction, node, list) { 1962b8e80941Smrg visit_tree(node, steal_memory, mem_ctx); 1963b8e80941Smrg } 1964b8e80941Smrg} 1965b8e80941Smrg 1966b8e80941Smrg 1967b8e80941Smrgstatic ir_rvalue * 1968b8e80941Smrgtry_min_one(ir_rvalue *ir) 1969b8e80941Smrg{ 1970b8e80941Smrg ir_expression *expr = ir->as_expression(); 1971b8e80941Smrg 1972b8e80941Smrg if (!expr || expr->operation != ir_binop_min) 1973b8e80941Smrg return NULL; 1974b8e80941Smrg 1975b8e80941Smrg if (expr->operands[0]->is_one()) 1976b8e80941Smrg return expr->operands[1]; 1977b8e80941Smrg 1978b8e80941Smrg if (expr->operands[1]->is_one()) 1979b8e80941Smrg return expr->operands[0]; 1980b8e80941Smrg 1981b8e80941Smrg return NULL; 1982b8e80941Smrg} 1983b8e80941Smrg 1984b8e80941Smrgstatic ir_rvalue * 1985b8e80941Smrgtry_max_zero(ir_rvalue *ir) 1986b8e80941Smrg{ 1987b8e80941Smrg ir_expression *expr = ir->as_expression(); 1988b8e80941Smrg 1989b8e80941Smrg if (!expr || expr->operation != ir_binop_max) 1990b8e80941Smrg return NULL; 1991b8e80941Smrg 1992b8e80941Smrg if (expr->operands[0]->is_zero()) 1993b8e80941Smrg return expr->operands[1]; 1994b8e80941Smrg 1995b8e80941Smrg if (expr->operands[1]->is_zero()) 1996b8e80941Smrg return expr->operands[0]; 1997b8e80941Smrg 1998b8e80941Smrg return NULL; 1999b8e80941Smrg} 2000b8e80941Smrg 2001b8e80941Smrgir_rvalue * 2002b8e80941Smrgir_rvalue::as_rvalue_to_saturate() 2003b8e80941Smrg{ 2004b8e80941Smrg ir_expression *expr = this->as_expression(); 2005b8e80941Smrg 2006b8e80941Smrg if (!expr) 2007b8e80941Smrg return NULL; 2008b8e80941Smrg 2009b8e80941Smrg ir_rvalue *max_zero = try_max_zero(expr); 2010b8e80941Smrg if (max_zero) { 2011b8e80941Smrg return try_min_one(max_zero); 2012b8e80941Smrg } else { 2013b8e80941Smrg ir_rvalue *min_one = try_min_one(expr); 2014b8e80941Smrg if (min_one) { 2015b8e80941Smrg return try_max_zero(min_one); 2016b8e80941Smrg } 2017b8e80941Smrg } 2018b8e80941Smrg 2019b8e80941Smrg return NULL; 2020b8e80941Smrg} 2021b8e80941Smrg 2022b8e80941Smrg 2023b8e80941Smrgunsigned 2024b8e80941Smrgvertices_per_prim(GLenum prim) 2025b8e80941Smrg{ 2026b8e80941Smrg switch (prim) { 2027b8e80941Smrg case GL_POINTS: 2028b8e80941Smrg return 1; 2029b8e80941Smrg case GL_LINES: 2030b8e80941Smrg return 2; 2031b8e80941Smrg case GL_TRIANGLES: 2032b8e80941Smrg return 3; 2033b8e80941Smrg case GL_LINES_ADJACENCY: 2034b8e80941Smrg return 4; 2035b8e80941Smrg case GL_TRIANGLES_ADJACENCY: 2036b8e80941Smrg return 6; 2037b8e80941Smrg default: 2038b8e80941Smrg assert(!"Bad primitive"); 2039b8e80941Smrg return 3; 2040b8e80941Smrg } 2041b8e80941Smrg} 2042b8e80941Smrg 2043b8e80941Smrg/** 2044b8e80941Smrg * Generate a string describing the mode of a variable 2045b8e80941Smrg */ 2046b8e80941Smrgconst char * 2047b8e80941Smrgmode_string(const ir_variable *var) 2048b8e80941Smrg{ 2049b8e80941Smrg switch (var->data.mode) { 2050b8e80941Smrg case ir_var_auto: 2051b8e80941Smrg return (var->data.read_only) ? "global constant" : "global variable"; 2052b8e80941Smrg 2053b8e80941Smrg case ir_var_uniform: 2054b8e80941Smrg return "uniform"; 2055b8e80941Smrg 2056b8e80941Smrg case ir_var_shader_storage: 2057b8e80941Smrg return "buffer"; 2058b8e80941Smrg 2059b8e80941Smrg case ir_var_shader_in: 2060b8e80941Smrg return "shader input"; 2061b8e80941Smrg 2062b8e80941Smrg case ir_var_shader_out: 2063b8e80941Smrg return "shader output"; 2064b8e80941Smrg 2065b8e80941Smrg case ir_var_function_in: 2066b8e80941Smrg case ir_var_const_in: 2067b8e80941Smrg return "function input"; 2068b8e80941Smrg 2069b8e80941Smrg case ir_var_function_out: 2070b8e80941Smrg return "function output"; 2071b8e80941Smrg 2072b8e80941Smrg case ir_var_function_inout: 2073b8e80941Smrg return "function inout"; 2074b8e80941Smrg 2075b8e80941Smrg case ir_var_system_value: 2076b8e80941Smrg return "shader input"; 2077b8e80941Smrg 2078b8e80941Smrg case ir_var_temporary: 2079b8e80941Smrg return "compiler temporary"; 2080b8e80941Smrg 2081b8e80941Smrg case ir_var_mode_count: 2082b8e80941Smrg break; 2083b8e80941Smrg } 2084b8e80941Smrg 2085b8e80941Smrg assert(!"Should not get here."); 2086b8e80941Smrg return "invalid variable"; 2087b8e80941Smrg} 2088