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 2401e04c3fSmrg#include "glsl_symbol_table.h" 2501e04c3fSmrg#include "ast.h" 2601e04c3fSmrg#include "compiler/glsl_types.h" 2701e04c3fSmrg#include "ir.h" 2801e04c3fSmrg#include "main/mtypes.h" 2901e04c3fSmrg#include "main/shaderobj.h" 3001e04c3fSmrg#include "builtin_functions.h" 3101e04c3fSmrg 3201e04c3fSmrgstatic ir_rvalue * 3301e04c3fSmrgconvert_component(ir_rvalue *src, const glsl_type *desired_type); 3401e04c3fSmrg 3501e04c3fSmrgstatic unsigned 3601e04c3fSmrgprocess_parameters(exec_list *instructions, exec_list *actual_parameters, 3701e04c3fSmrg exec_list *parameters, 3801e04c3fSmrg struct _mesa_glsl_parse_state *state) 3901e04c3fSmrg{ 4001e04c3fSmrg void *mem_ctx = state; 4101e04c3fSmrg unsigned count = 0; 4201e04c3fSmrg 4301e04c3fSmrg foreach_list_typed(ast_node, ast, link, parameters) { 4401e04c3fSmrg /* We need to process the parameters first in order to know if we can 4501e04c3fSmrg * raise or not a unitialized warning. Calling set_is_lhs silence the 4601e04c3fSmrg * warning for now. Raising the warning or not will be checked at 4701e04c3fSmrg * verify_parameter_modes. 4801e04c3fSmrg */ 4901e04c3fSmrg ast->set_is_lhs(true); 5001e04c3fSmrg ir_rvalue *result = ast->hir(instructions, state); 5101e04c3fSmrg 527ec681f3Smrg /* Error happened processing function parameter */ 537ec681f3Smrg if (!result) { 547ec681f3Smrg actual_parameters->push_tail(ir_rvalue::error_value(mem_ctx)); 557ec681f3Smrg count++; 567ec681f3Smrg continue; 577ec681f3Smrg } 587ec681f3Smrg 5901e04c3fSmrg ir_constant *const constant = 6001e04c3fSmrg result->constant_expression_value(mem_ctx); 6101e04c3fSmrg 6201e04c3fSmrg if (constant != NULL) 6301e04c3fSmrg result = constant; 6401e04c3fSmrg 6501e04c3fSmrg actual_parameters->push_tail(result); 6601e04c3fSmrg count++; 6701e04c3fSmrg } 6801e04c3fSmrg 6901e04c3fSmrg return count; 7001e04c3fSmrg} 7101e04c3fSmrg 7201e04c3fSmrg 7301e04c3fSmrg/** 7401e04c3fSmrg * Generate a source prototype for a function signature 7501e04c3fSmrg * 7601e04c3fSmrg * \param return_type Return type of the function. May be \c NULL. 7701e04c3fSmrg * \param name Name of the function. 7801e04c3fSmrg * \param parameters List of \c ir_instruction nodes representing the 7901e04c3fSmrg * parameter list for the function. This may be either a 8001e04c3fSmrg * formal (\c ir_variable) or actual (\c ir_rvalue) 8101e04c3fSmrg * parameter list. Only the type is used. 8201e04c3fSmrg * 8301e04c3fSmrg * \return 8401e04c3fSmrg * A ralloced string representing the prototype of the function. 8501e04c3fSmrg */ 8601e04c3fSmrgchar * 8701e04c3fSmrgprototype_string(const glsl_type *return_type, const char *name, 8801e04c3fSmrg exec_list *parameters) 8901e04c3fSmrg{ 9001e04c3fSmrg char *str = NULL; 9101e04c3fSmrg 9201e04c3fSmrg if (return_type != NULL) 9301e04c3fSmrg str = ralloc_asprintf(NULL, "%s ", return_type->name); 9401e04c3fSmrg 9501e04c3fSmrg ralloc_asprintf_append(&str, "%s(", name); 9601e04c3fSmrg 9701e04c3fSmrg const char *comma = ""; 9801e04c3fSmrg foreach_in_list(const ir_variable, param, parameters) { 9901e04c3fSmrg ralloc_asprintf_append(&str, "%s%s", comma, param->type->name); 10001e04c3fSmrg comma = ", "; 10101e04c3fSmrg } 10201e04c3fSmrg 10301e04c3fSmrg ralloc_strcat(&str, ")"); 10401e04c3fSmrg return str; 10501e04c3fSmrg} 10601e04c3fSmrg 10701e04c3fSmrgstatic bool 10801e04c3fSmrgverify_image_parameter(YYLTYPE *loc, _mesa_glsl_parse_state *state, 10901e04c3fSmrg const ir_variable *formal, const ir_variable *actual) 11001e04c3fSmrg{ 11101e04c3fSmrg /** 11201e04c3fSmrg * From the ARB_shader_image_load_store specification: 11301e04c3fSmrg * 11401e04c3fSmrg * "The values of image variables qualified with coherent, 11501e04c3fSmrg * volatile, restrict, readonly, or writeonly may not be passed 11601e04c3fSmrg * to functions whose formal parameters lack such 11701e04c3fSmrg * qualifiers. [...] It is legal to have additional qualifiers 11801e04c3fSmrg * on a formal parameter, but not to have fewer." 11901e04c3fSmrg */ 12001e04c3fSmrg if (actual->data.memory_coherent && !formal->data.memory_coherent) { 12101e04c3fSmrg _mesa_glsl_error(loc, state, 12201e04c3fSmrg "function call parameter `%s' drops " 12301e04c3fSmrg "`coherent' qualifier", formal->name); 12401e04c3fSmrg return false; 12501e04c3fSmrg } 12601e04c3fSmrg 12701e04c3fSmrg if (actual->data.memory_volatile && !formal->data.memory_volatile) { 12801e04c3fSmrg _mesa_glsl_error(loc, state, 12901e04c3fSmrg "function call parameter `%s' drops " 13001e04c3fSmrg "`volatile' qualifier", formal->name); 13101e04c3fSmrg return false; 13201e04c3fSmrg } 13301e04c3fSmrg 13401e04c3fSmrg if (actual->data.memory_restrict && !formal->data.memory_restrict) { 13501e04c3fSmrg _mesa_glsl_error(loc, state, 13601e04c3fSmrg "function call parameter `%s' drops " 13701e04c3fSmrg "`restrict' qualifier", formal->name); 13801e04c3fSmrg return false; 13901e04c3fSmrg } 14001e04c3fSmrg 14101e04c3fSmrg if (actual->data.memory_read_only && !formal->data.memory_read_only) { 14201e04c3fSmrg _mesa_glsl_error(loc, state, 14301e04c3fSmrg "function call parameter `%s' drops " 14401e04c3fSmrg "`readonly' qualifier", formal->name); 14501e04c3fSmrg return false; 14601e04c3fSmrg } 14701e04c3fSmrg 14801e04c3fSmrg if (actual->data.memory_write_only && !formal->data.memory_write_only) { 14901e04c3fSmrg _mesa_glsl_error(loc, state, 15001e04c3fSmrg "function call parameter `%s' drops " 15101e04c3fSmrg "`writeonly' qualifier", formal->name); 15201e04c3fSmrg return false; 15301e04c3fSmrg } 15401e04c3fSmrg 15501e04c3fSmrg return true; 15601e04c3fSmrg} 15701e04c3fSmrg 15801e04c3fSmrgstatic bool 15901e04c3fSmrgverify_first_atomic_parameter(YYLTYPE *loc, _mesa_glsl_parse_state *state, 16001e04c3fSmrg ir_variable *var) 16101e04c3fSmrg{ 16201e04c3fSmrg if (!var || 16301e04c3fSmrg (!var->is_in_shader_storage_block() && 16401e04c3fSmrg var->data.mode != ir_var_shader_shared)) { 16501e04c3fSmrg _mesa_glsl_error(loc, state, "First argument to atomic function " 16601e04c3fSmrg "must be a buffer or shared variable"); 16701e04c3fSmrg return false; 16801e04c3fSmrg } 16901e04c3fSmrg return true; 17001e04c3fSmrg} 17101e04c3fSmrg 17201e04c3fSmrgstatic bool 17301e04c3fSmrgis_atomic_function(const char *func_name) 17401e04c3fSmrg{ 17501e04c3fSmrg return !strcmp(func_name, "atomicAdd") || 17601e04c3fSmrg !strcmp(func_name, "atomicMin") || 17701e04c3fSmrg !strcmp(func_name, "atomicMax") || 17801e04c3fSmrg !strcmp(func_name, "atomicAnd") || 17901e04c3fSmrg !strcmp(func_name, "atomicOr") || 18001e04c3fSmrg !strcmp(func_name, "atomicXor") || 18101e04c3fSmrg !strcmp(func_name, "atomicExchange") || 18201e04c3fSmrg !strcmp(func_name, "atomicCompSwap"); 18301e04c3fSmrg} 18401e04c3fSmrg 1857ec681f3Smrgstatic bool 1867ec681f3Smrgverify_atomic_image_parameter_qualifier(YYLTYPE *loc, _mesa_glsl_parse_state *state, 1877ec681f3Smrg ir_variable *var) 1887ec681f3Smrg{ 1897ec681f3Smrg if (!var || 1907ec681f3Smrg (var->data.image_format != PIPE_FORMAT_R32_UINT && 1917ec681f3Smrg var->data.image_format != PIPE_FORMAT_R32_SINT && 1927ec681f3Smrg var->data.image_format != PIPE_FORMAT_R32_FLOAT)) { 1937ec681f3Smrg _mesa_glsl_error(loc, state, "Image atomic functions should use r32i/r32ui " 1947ec681f3Smrg "format qualifier"); 1957ec681f3Smrg return false; 1967ec681f3Smrg } 1977ec681f3Smrg return true; 1987ec681f3Smrg} 1997ec681f3Smrg 2007ec681f3Smrgstatic bool 2017ec681f3Smrgis_atomic_image_function(const char *func_name) 2027ec681f3Smrg{ 2037ec681f3Smrg return !strcmp(func_name, "imageAtomicAdd") || 2047ec681f3Smrg !strcmp(func_name, "imageAtomicMin") || 2057ec681f3Smrg !strcmp(func_name, "imageAtomicMax") || 2067ec681f3Smrg !strcmp(func_name, "imageAtomicAnd") || 2077ec681f3Smrg !strcmp(func_name, "imageAtomicOr") || 2087ec681f3Smrg !strcmp(func_name, "imageAtomicXor") || 2097ec681f3Smrg !strcmp(func_name, "imageAtomicExchange") || 2107ec681f3Smrg !strcmp(func_name, "imageAtomicCompSwap") || 2117ec681f3Smrg !strcmp(func_name, "imageAtomicIncWrap") || 2127ec681f3Smrg !strcmp(func_name, "imageAtomicDecWrap"); 2137ec681f3Smrg} 2147ec681f3Smrg 2157ec681f3Smrg 21601e04c3fSmrg/** 21701e04c3fSmrg * Verify that 'out' and 'inout' actual parameters are lvalues. Also, verify 21801e04c3fSmrg * that 'const_in' formal parameters (an extension in our IR) correspond to 21901e04c3fSmrg * ir_constant actual parameters. 22001e04c3fSmrg */ 22101e04c3fSmrgstatic bool 22201e04c3fSmrgverify_parameter_modes(_mesa_glsl_parse_state *state, 22301e04c3fSmrg ir_function_signature *sig, 22401e04c3fSmrg exec_list &actual_ir_parameters, 22501e04c3fSmrg exec_list &actual_ast_parameters) 22601e04c3fSmrg{ 22701e04c3fSmrg exec_node *actual_ir_node = actual_ir_parameters.get_head_raw(); 22801e04c3fSmrg exec_node *actual_ast_node = actual_ast_parameters.get_head_raw(); 22901e04c3fSmrg 23001e04c3fSmrg foreach_in_list(const ir_variable, formal, &sig->parameters) { 23101e04c3fSmrg /* The lists must be the same length. */ 23201e04c3fSmrg assert(!actual_ir_node->is_tail_sentinel()); 23301e04c3fSmrg assert(!actual_ast_node->is_tail_sentinel()); 23401e04c3fSmrg 23501e04c3fSmrg const ir_rvalue *const actual = (ir_rvalue *) actual_ir_node; 23601e04c3fSmrg const ast_expression *const actual_ast = 23701e04c3fSmrg exec_node_data(ast_expression, actual_ast_node, link); 23801e04c3fSmrg 23901e04c3fSmrg YYLTYPE loc = actual_ast->get_location(); 24001e04c3fSmrg 24101e04c3fSmrg /* Verify that 'const_in' parameters are ir_constants. */ 24201e04c3fSmrg if (formal->data.mode == ir_var_const_in && 24301e04c3fSmrg actual->ir_type != ir_type_constant) { 24401e04c3fSmrg _mesa_glsl_error(&loc, state, 24501e04c3fSmrg "parameter `in %s' must be a constant expression", 24601e04c3fSmrg formal->name); 24701e04c3fSmrg return false; 24801e04c3fSmrg } 24901e04c3fSmrg 25001e04c3fSmrg /* Verify that shader_in parameters are shader inputs */ 25101e04c3fSmrg if (formal->data.must_be_shader_input) { 25201e04c3fSmrg const ir_rvalue *val = actual; 25301e04c3fSmrg 25401e04c3fSmrg /* GLSL 4.40 allows swizzles, while earlier GLSL versions do not. */ 25501e04c3fSmrg if (val->ir_type == ir_type_swizzle) { 25601e04c3fSmrg if (!state->is_version(440, 0)) { 25701e04c3fSmrg _mesa_glsl_error(&loc, state, 25801e04c3fSmrg "parameter `%s` must not be swizzled", 25901e04c3fSmrg formal->name); 26001e04c3fSmrg return false; 26101e04c3fSmrg } 26201e04c3fSmrg val = ((ir_swizzle *)val)->val; 26301e04c3fSmrg } 26401e04c3fSmrg 26501e04c3fSmrg for (;;) { 26601e04c3fSmrg if (val->ir_type == ir_type_dereference_array) { 26701e04c3fSmrg val = ((ir_dereference_array *)val)->array; 26801e04c3fSmrg } else if (val->ir_type == ir_type_dereference_record && 26901e04c3fSmrg !state->es_shader) { 27001e04c3fSmrg val = ((ir_dereference_record *)val)->record; 27101e04c3fSmrg } else 27201e04c3fSmrg break; 27301e04c3fSmrg } 27401e04c3fSmrg 27501e04c3fSmrg ir_variable *var = NULL; 27601e04c3fSmrg if (const ir_dereference_variable *deref_var = val->as_dereference_variable()) 27701e04c3fSmrg var = deref_var->variable_referenced(); 27801e04c3fSmrg 27901e04c3fSmrg if (!var || var->data.mode != ir_var_shader_in) { 28001e04c3fSmrg _mesa_glsl_error(&loc, state, 28101e04c3fSmrg "parameter `%s` must be a shader input", 28201e04c3fSmrg formal->name); 28301e04c3fSmrg return false; 28401e04c3fSmrg } 28501e04c3fSmrg 28601e04c3fSmrg var->data.must_be_shader_input = 1; 28701e04c3fSmrg } 28801e04c3fSmrg 28901e04c3fSmrg /* Verify that 'out' and 'inout' actual parameters are lvalues. */ 29001e04c3fSmrg if (formal->data.mode == ir_var_function_out 29101e04c3fSmrg || formal->data.mode == ir_var_function_inout) { 29201e04c3fSmrg const char *mode = NULL; 29301e04c3fSmrg switch (formal->data.mode) { 29401e04c3fSmrg case ir_var_function_out: mode = "out"; break; 29501e04c3fSmrg case ir_var_function_inout: mode = "inout"; break; 29601e04c3fSmrg default: assert(false); break; 29701e04c3fSmrg } 29801e04c3fSmrg 29901e04c3fSmrg /* This AST-based check catches errors like f(i++). The IR-based 30001e04c3fSmrg * is_lvalue() is insufficient because the actual parameter at the 30101e04c3fSmrg * IR-level is just a temporary value, which is an l-value. 30201e04c3fSmrg */ 30301e04c3fSmrg if (actual_ast->non_lvalue_description != NULL) { 30401e04c3fSmrg _mesa_glsl_error(&loc, state, 30501e04c3fSmrg "function parameter '%s %s' references a %s", 30601e04c3fSmrg mode, formal->name, 30701e04c3fSmrg actual_ast->non_lvalue_description); 30801e04c3fSmrg return false; 30901e04c3fSmrg } 31001e04c3fSmrg 31101e04c3fSmrg ir_variable *var = actual->variable_referenced(); 31201e04c3fSmrg 31301e04c3fSmrg if (var && formal->data.mode == ir_var_function_inout) { 31401e04c3fSmrg if ((var->data.mode == ir_var_auto || 31501e04c3fSmrg var->data.mode == ir_var_shader_out) && 31601e04c3fSmrg !var->data.assigned && 31701e04c3fSmrg !is_gl_identifier(var->name)) { 31801e04c3fSmrg _mesa_glsl_warning(&loc, state, "`%s' used uninitialized", 31901e04c3fSmrg var->name); 32001e04c3fSmrg } 32101e04c3fSmrg } 32201e04c3fSmrg 32301e04c3fSmrg if (var) 32401e04c3fSmrg var->data.assigned = true; 32501e04c3fSmrg 32601e04c3fSmrg if (var && var->data.read_only) { 32701e04c3fSmrg _mesa_glsl_error(&loc, state, 32801e04c3fSmrg "function parameter '%s %s' references the " 32901e04c3fSmrg "read-only variable '%s'", 33001e04c3fSmrg mode, formal->name, 33101e04c3fSmrg actual->variable_referenced()->name); 33201e04c3fSmrg return false; 33301e04c3fSmrg } else if (!actual->is_lvalue(state)) { 33401e04c3fSmrg _mesa_glsl_error(&loc, state, 33501e04c3fSmrg "function parameter '%s %s' is not an lvalue", 33601e04c3fSmrg mode, formal->name); 33701e04c3fSmrg return false; 33801e04c3fSmrg } 33901e04c3fSmrg } else { 34001e04c3fSmrg assert(formal->data.mode == ir_var_function_in || 34101e04c3fSmrg formal->data.mode == ir_var_const_in); 34201e04c3fSmrg ir_variable *var = actual->variable_referenced(); 34301e04c3fSmrg if (var) { 34401e04c3fSmrg if ((var->data.mode == ir_var_auto || 34501e04c3fSmrg var->data.mode == ir_var_shader_out) && 34601e04c3fSmrg !var->data.assigned && 34701e04c3fSmrg !is_gl_identifier(var->name)) { 34801e04c3fSmrg _mesa_glsl_warning(&loc, state, "`%s' used uninitialized", 34901e04c3fSmrg var->name); 35001e04c3fSmrg } 35101e04c3fSmrg } 35201e04c3fSmrg } 35301e04c3fSmrg 35401e04c3fSmrg if (formal->type->is_image() && 35501e04c3fSmrg actual->variable_referenced()) { 35601e04c3fSmrg if (!verify_image_parameter(&loc, state, formal, 35701e04c3fSmrg actual->variable_referenced())) 35801e04c3fSmrg return false; 35901e04c3fSmrg } 36001e04c3fSmrg 36101e04c3fSmrg actual_ir_node = actual_ir_node->next; 36201e04c3fSmrg actual_ast_node = actual_ast_node->next; 36301e04c3fSmrg } 36401e04c3fSmrg 36501e04c3fSmrg /* The first parameter of atomic functions must be a buffer variable */ 36601e04c3fSmrg const char *func_name = sig->function_name(); 36701e04c3fSmrg bool is_atomic = is_atomic_function(func_name); 36801e04c3fSmrg if (is_atomic) { 36901e04c3fSmrg const ir_rvalue *const actual = 37001e04c3fSmrg (ir_rvalue *) actual_ir_parameters.get_head_raw(); 37101e04c3fSmrg 37201e04c3fSmrg const ast_expression *const actual_ast = 37301e04c3fSmrg exec_node_data(ast_expression, 37401e04c3fSmrg actual_ast_parameters.get_head_raw(), link); 37501e04c3fSmrg YYLTYPE loc = actual_ast->get_location(); 37601e04c3fSmrg 37701e04c3fSmrg if (!verify_first_atomic_parameter(&loc, state, 37801e04c3fSmrg actual->variable_referenced())) { 37901e04c3fSmrg return false; 38001e04c3fSmrg } 3817ec681f3Smrg } else if (is_atomic_image_function(func_name)) { 3827ec681f3Smrg const ir_rvalue *const actual = 3837ec681f3Smrg (ir_rvalue *) actual_ir_parameters.get_head_raw(); 3847ec681f3Smrg 3857ec681f3Smrg const ast_expression *const actual_ast = 3867ec681f3Smrg exec_node_data(ast_expression, 3877ec681f3Smrg actual_ast_parameters.get_head_raw(), link); 3887ec681f3Smrg YYLTYPE loc = actual_ast->get_location(); 3897ec681f3Smrg 3907ec681f3Smrg if (!verify_atomic_image_parameter_qualifier(&loc, state, 3917ec681f3Smrg actual->variable_referenced())) { 3927ec681f3Smrg return false; 3937ec681f3Smrg } 39401e04c3fSmrg } 39501e04c3fSmrg 39601e04c3fSmrg return true; 39701e04c3fSmrg} 39801e04c3fSmrg 39901e04c3fSmrgstruct copy_index_deref_data { 40001e04c3fSmrg void *mem_ctx; 40101e04c3fSmrg exec_list *before_instructions; 40201e04c3fSmrg}; 40301e04c3fSmrg 40401e04c3fSmrgstatic void 40501e04c3fSmrgcopy_index_derefs_to_temps(ir_instruction *ir, void *data) 40601e04c3fSmrg{ 40701e04c3fSmrg struct copy_index_deref_data *d = (struct copy_index_deref_data *)data; 40801e04c3fSmrg 40901e04c3fSmrg if (ir->ir_type == ir_type_dereference_array) { 41001e04c3fSmrg ir_dereference_array *a = (ir_dereference_array *) ir; 41101e04c3fSmrg ir = a->array->as_dereference(); 41201e04c3fSmrg 41301e04c3fSmrg ir_rvalue *idx = a->array_index; 41401e04c3fSmrg ir_variable *var = idx->variable_referenced(); 41501e04c3fSmrg 41601e04c3fSmrg /* If the index is read only it cannot change so there is no need 41701e04c3fSmrg * to copy it. 41801e04c3fSmrg */ 41901e04c3fSmrg if (!var || var->data.read_only || var->data.memory_read_only) 42001e04c3fSmrg return; 42101e04c3fSmrg 42201e04c3fSmrg ir_variable *tmp = new(d->mem_ctx) ir_variable(idx->type, "idx_tmp", 42301e04c3fSmrg ir_var_temporary); 42401e04c3fSmrg d->before_instructions->push_tail(tmp); 42501e04c3fSmrg 42601e04c3fSmrg ir_dereference_variable *const deref_tmp_1 = 42701e04c3fSmrg new(d->mem_ctx) ir_dereference_variable(tmp); 42801e04c3fSmrg ir_assignment *const assignment = 42901e04c3fSmrg new(d->mem_ctx) ir_assignment(deref_tmp_1, 43001e04c3fSmrg idx->clone(d->mem_ctx, NULL)); 43101e04c3fSmrg d->before_instructions->push_tail(assignment); 43201e04c3fSmrg 43301e04c3fSmrg /* Replace the array index with a dereference of the new temporary */ 43401e04c3fSmrg ir_dereference_variable *const deref_tmp_2 = 43501e04c3fSmrg new(d->mem_ctx) ir_dereference_variable(tmp); 43601e04c3fSmrg a->array_index = deref_tmp_2; 43701e04c3fSmrg } 43801e04c3fSmrg} 43901e04c3fSmrg 44001e04c3fSmrgstatic void 44101e04c3fSmrgfix_parameter(void *mem_ctx, ir_rvalue *actual, const glsl_type *formal_type, 44201e04c3fSmrg exec_list *before_instructions, exec_list *after_instructions, 44301e04c3fSmrg bool parameter_is_inout) 44401e04c3fSmrg{ 44501e04c3fSmrg ir_expression *const expr = actual->as_expression(); 44601e04c3fSmrg 44701e04c3fSmrg /* If the types match exactly and the parameter is not a vector-extract, 44801e04c3fSmrg * nothing needs to be done to fix the parameter. 44901e04c3fSmrg */ 45001e04c3fSmrg if (formal_type == actual->type 45101e04c3fSmrg && (expr == NULL || expr->operation != ir_binop_vector_extract) 45201e04c3fSmrg && actual->as_dereference_variable()) 45301e04c3fSmrg return; 45401e04c3fSmrg 45501e04c3fSmrg /* An array index could also be an out variable so we need to make a copy 45601e04c3fSmrg * of them before the function is called. 45701e04c3fSmrg */ 45801e04c3fSmrg if (!actual->as_dereference_variable()) { 45901e04c3fSmrg struct copy_index_deref_data data; 46001e04c3fSmrg data.mem_ctx = mem_ctx; 46101e04c3fSmrg data.before_instructions = before_instructions; 46201e04c3fSmrg 46301e04c3fSmrg visit_tree(actual, copy_index_derefs_to_temps, &data); 46401e04c3fSmrg } 46501e04c3fSmrg 46601e04c3fSmrg /* To convert an out parameter, we need to create a temporary variable to 46701e04c3fSmrg * hold the value before conversion, and then perform the conversion after 46801e04c3fSmrg * the function call returns. 46901e04c3fSmrg * 47001e04c3fSmrg * This has the effect of transforming code like this: 47101e04c3fSmrg * 47201e04c3fSmrg * void f(out int x); 47301e04c3fSmrg * float value; 47401e04c3fSmrg * f(value); 47501e04c3fSmrg * 47601e04c3fSmrg * Into IR that's equivalent to this: 47701e04c3fSmrg * 47801e04c3fSmrg * void f(out int x); 47901e04c3fSmrg * float value; 48001e04c3fSmrg * int out_parameter_conversion; 48101e04c3fSmrg * f(out_parameter_conversion); 48201e04c3fSmrg * value = float(out_parameter_conversion); 48301e04c3fSmrg * 48401e04c3fSmrg * If the parameter is an ir_expression of ir_binop_vector_extract, 48501e04c3fSmrg * additional conversion is needed in the post-call re-write. 48601e04c3fSmrg */ 48701e04c3fSmrg ir_variable *tmp = 48801e04c3fSmrg new(mem_ctx) ir_variable(formal_type, "inout_tmp", ir_var_temporary); 48901e04c3fSmrg 49001e04c3fSmrg before_instructions->push_tail(tmp); 49101e04c3fSmrg 49201e04c3fSmrg /* If the parameter is an inout parameter, copy the value of the actual 49301e04c3fSmrg * parameter to the new temporary. Note that no type conversion is allowed 49401e04c3fSmrg * here because inout parameters must match types exactly. 49501e04c3fSmrg */ 49601e04c3fSmrg if (parameter_is_inout) { 49701e04c3fSmrg /* Inout parameters should never require conversion, since that would 49801e04c3fSmrg * require an implicit conversion to exist both to and from the formal 49901e04c3fSmrg * parameter type, and there are no bidirectional implicit conversions. 50001e04c3fSmrg */ 50101e04c3fSmrg assert (actual->type == formal_type); 50201e04c3fSmrg 50301e04c3fSmrg ir_dereference_variable *const deref_tmp_1 = 50401e04c3fSmrg new(mem_ctx) ir_dereference_variable(tmp); 50501e04c3fSmrg ir_assignment *const assignment = 50601e04c3fSmrg new(mem_ctx) ir_assignment(deref_tmp_1, actual->clone(mem_ctx, NULL)); 50701e04c3fSmrg before_instructions->push_tail(assignment); 50801e04c3fSmrg } 50901e04c3fSmrg 51001e04c3fSmrg /* Replace the parameter in the call with a dereference of the new 51101e04c3fSmrg * temporary. 51201e04c3fSmrg */ 51301e04c3fSmrg ir_dereference_variable *const deref_tmp_2 = 51401e04c3fSmrg new(mem_ctx) ir_dereference_variable(tmp); 51501e04c3fSmrg actual->replace_with(deref_tmp_2); 51601e04c3fSmrg 51701e04c3fSmrg 51801e04c3fSmrg /* Copy the temporary variable to the actual parameter with optional 51901e04c3fSmrg * type conversion applied. 52001e04c3fSmrg */ 52101e04c3fSmrg ir_rvalue *rhs = new(mem_ctx) ir_dereference_variable(tmp); 52201e04c3fSmrg if (actual->type != formal_type) 52301e04c3fSmrg rhs = convert_component(rhs, actual->type); 52401e04c3fSmrg 52501e04c3fSmrg ir_rvalue *lhs = actual; 52601e04c3fSmrg if (expr != NULL && expr->operation == ir_binop_vector_extract) { 52701e04c3fSmrg lhs = new(mem_ctx) ir_dereference_array(expr->operands[0]->clone(mem_ctx, 52801e04c3fSmrg NULL), 52901e04c3fSmrg expr->operands[1]->clone(mem_ctx, 53001e04c3fSmrg NULL)); 53101e04c3fSmrg } 53201e04c3fSmrg 53301e04c3fSmrg ir_assignment *const assignment_2 = new(mem_ctx) ir_assignment(lhs, rhs); 53401e04c3fSmrg after_instructions->push_tail(assignment_2); 53501e04c3fSmrg} 53601e04c3fSmrg 53701e04c3fSmrg/** 53801e04c3fSmrg * Generate a function call. 53901e04c3fSmrg * 54001e04c3fSmrg * For non-void functions, this returns a dereference of the temporary 54101e04c3fSmrg * variable which stores the return value for the call. For void functions, 54201e04c3fSmrg * this returns NULL. 54301e04c3fSmrg */ 54401e04c3fSmrgstatic ir_rvalue * 54501e04c3fSmrggenerate_call(exec_list *instructions, ir_function_signature *sig, 54601e04c3fSmrg exec_list *actual_parameters, 54701e04c3fSmrg ir_variable *sub_var, 54801e04c3fSmrg ir_rvalue *array_idx, 54901e04c3fSmrg struct _mesa_glsl_parse_state *state) 55001e04c3fSmrg{ 55101e04c3fSmrg void *ctx = state; 55201e04c3fSmrg exec_list post_call_conversions; 55301e04c3fSmrg 55401e04c3fSmrg /* Perform implicit conversion of arguments. For out parameters, we need 55501e04c3fSmrg * to place them in a temporary variable and do the conversion after the 55601e04c3fSmrg * call takes place. Since we haven't emitted the call yet, we'll place 55701e04c3fSmrg * the post-call conversions in a temporary exec_list, and emit them later. 55801e04c3fSmrg */ 55901e04c3fSmrg foreach_two_lists(formal_node, &sig->parameters, 56001e04c3fSmrg actual_node, actual_parameters) { 56101e04c3fSmrg ir_rvalue *actual = (ir_rvalue *) actual_node; 56201e04c3fSmrg ir_variable *formal = (ir_variable *) formal_node; 56301e04c3fSmrg 56401e04c3fSmrg if (formal->type->is_numeric() || formal->type->is_boolean()) { 56501e04c3fSmrg switch (formal->data.mode) { 56601e04c3fSmrg case ir_var_const_in: 56701e04c3fSmrg case ir_var_function_in: { 56801e04c3fSmrg ir_rvalue *converted 56901e04c3fSmrg = convert_component(actual, formal->type); 57001e04c3fSmrg actual->replace_with(converted); 57101e04c3fSmrg break; 57201e04c3fSmrg } 57301e04c3fSmrg case ir_var_function_out: 57401e04c3fSmrg case ir_var_function_inout: 57501e04c3fSmrg fix_parameter(ctx, actual, formal->type, 57601e04c3fSmrg instructions, &post_call_conversions, 57701e04c3fSmrg formal->data.mode == ir_var_function_inout); 57801e04c3fSmrg break; 57901e04c3fSmrg default: 58001e04c3fSmrg assert (!"Illegal formal parameter mode"); 58101e04c3fSmrg break; 58201e04c3fSmrg } 58301e04c3fSmrg } 58401e04c3fSmrg } 58501e04c3fSmrg 58601e04c3fSmrg /* Section 4.3.2 (Const) of the GLSL 1.10.59 spec says: 58701e04c3fSmrg * 58801e04c3fSmrg * "Initializers for const declarations must be formed from literal 58901e04c3fSmrg * values, other const variables (not including function call 59001e04c3fSmrg * paramaters), or expressions of these. 59101e04c3fSmrg * 59201e04c3fSmrg * Constructors may be used in such expressions, but function calls may 59301e04c3fSmrg * not." 59401e04c3fSmrg * 59501e04c3fSmrg * Section 4.3.3 (Constant Expressions) of the GLSL 1.20.8 spec says: 59601e04c3fSmrg * 59701e04c3fSmrg * "A constant expression is one of 59801e04c3fSmrg * 59901e04c3fSmrg * ... 60001e04c3fSmrg * 60101e04c3fSmrg * - a built-in function call whose arguments are all constant 60201e04c3fSmrg * expressions, with the exception of the texture lookup 60301e04c3fSmrg * functions, the noise functions, and ftransform. The built-in 60401e04c3fSmrg * functions dFdx, dFdy, and fwidth must return 0 when evaluated 60501e04c3fSmrg * inside an initializer with an argument that is a constant 60601e04c3fSmrg * expression." 60701e04c3fSmrg * 60801e04c3fSmrg * Section 5.10 (Constant Expressions) of the GLSL ES 1.00.17 spec says: 60901e04c3fSmrg * 61001e04c3fSmrg * "A constant expression is one of 61101e04c3fSmrg * 61201e04c3fSmrg * ... 61301e04c3fSmrg * 61401e04c3fSmrg * - a built-in function call whose arguments are all constant 61501e04c3fSmrg * expressions, with the exception of the texture lookup 61601e04c3fSmrg * functions." 61701e04c3fSmrg * 61801e04c3fSmrg * Section 4.3.3 (Constant Expressions) of the GLSL ES 3.00.4 spec says: 61901e04c3fSmrg * 62001e04c3fSmrg * "A constant expression is one of 62101e04c3fSmrg * 62201e04c3fSmrg * ... 62301e04c3fSmrg * 62401e04c3fSmrg * - a built-in function call whose arguments are all constant 62501e04c3fSmrg * expressions, with the exception of the texture lookup 62601e04c3fSmrg * functions. The built-in functions dFdx, dFdy, and fwidth must 62701e04c3fSmrg * return 0 when evaluated inside an initializer with an argument 62801e04c3fSmrg * that is a constant expression." 62901e04c3fSmrg * 63001e04c3fSmrg * If the function call is a constant expression, don't generate any 63101e04c3fSmrg * instructions; just generate an ir_constant. 63201e04c3fSmrg */ 63301e04c3fSmrg if (state->is_version(120, 100) || 63401e04c3fSmrg state->ctx->Const.AllowGLSLBuiltinConstantExpression) { 63501e04c3fSmrg ir_constant *value = sig->constant_expression_value(ctx, 63601e04c3fSmrg actual_parameters, 63701e04c3fSmrg NULL); 63801e04c3fSmrg if (value != NULL) { 63901e04c3fSmrg return value; 64001e04c3fSmrg } 64101e04c3fSmrg } 64201e04c3fSmrg 64301e04c3fSmrg ir_dereference_variable *deref = NULL; 64401e04c3fSmrg if (!sig->return_type->is_void()) { 64501e04c3fSmrg /* Create a new temporary to hold the return value. */ 64601e04c3fSmrg char *const name = ir_variable::temporaries_allocate_names 64701e04c3fSmrg ? ralloc_asprintf(ctx, "%s_retval", sig->function_name()) 64801e04c3fSmrg : NULL; 64901e04c3fSmrg 65001e04c3fSmrg ir_variable *var; 65101e04c3fSmrg 65201e04c3fSmrg var = new(ctx) ir_variable(sig->return_type, name, ir_var_temporary); 65301e04c3fSmrg instructions->push_tail(var); 65401e04c3fSmrg 65501e04c3fSmrg ralloc_free(name); 65601e04c3fSmrg 65701e04c3fSmrg deref = new(ctx) ir_dereference_variable(var); 65801e04c3fSmrg } 65901e04c3fSmrg 66001e04c3fSmrg ir_call *call = new(ctx) ir_call(sig, deref, 66101e04c3fSmrg actual_parameters, sub_var, array_idx); 66201e04c3fSmrg instructions->push_tail(call); 66301e04c3fSmrg 66401e04c3fSmrg /* Also emit any necessary out-parameter conversions. */ 66501e04c3fSmrg instructions->append_list(&post_call_conversions); 66601e04c3fSmrg 66701e04c3fSmrg return deref ? deref->clone(ctx, NULL) : NULL; 66801e04c3fSmrg} 66901e04c3fSmrg 67001e04c3fSmrg/** 67101e04c3fSmrg * Given a function name and parameter list, find the matching signature. 67201e04c3fSmrg */ 67301e04c3fSmrgstatic ir_function_signature * 67401e04c3fSmrgmatch_function_by_name(const char *name, 67501e04c3fSmrg exec_list *actual_parameters, 67601e04c3fSmrg struct _mesa_glsl_parse_state *state) 67701e04c3fSmrg{ 67801e04c3fSmrg ir_function *f = state->symbols->get_function(name); 67901e04c3fSmrg ir_function_signature *local_sig = NULL; 68001e04c3fSmrg ir_function_signature *sig = NULL; 68101e04c3fSmrg 68201e04c3fSmrg /* Is the function hidden by a record type constructor? */ 68301e04c3fSmrg if (state->symbols->get_type(name)) 68401e04c3fSmrg return sig; /* no match */ 68501e04c3fSmrg 68601e04c3fSmrg /* Is the function hidden by a variable (impossible in 1.10)? */ 68701e04c3fSmrg if (!state->symbols->separate_function_namespace 68801e04c3fSmrg && state->symbols->get_variable(name)) 68901e04c3fSmrg return sig; /* no match */ 69001e04c3fSmrg 69101e04c3fSmrg if (f != NULL) { 69201e04c3fSmrg /* In desktop GL, the presence of a user-defined signature hides any 69301e04c3fSmrg * built-in signatures, so we must ignore them. In contrast, in ES2 69401e04c3fSmrg * user-defined signatures add new overloads, so we must consider them. 69501e04c3fSmrg */ 69601e04c3fSmrg bool allow_builtins = state->es_shader || !f->has_user_signature(); 69701e04c3fSmrg 69801e04c3fSmrg /* Look for a match in the local shader. If exact, we're done. */ 69901e04c3fSmrg bool is_exact = false; 70001e04c3fSmrg sig = local_sig = f->matching_signature(state, actual_parameters, 70101e04c3fSmrg allow_builtins, &is_exact); 70201e04c3fSmrg if (is_exact) 70301e04c3fSmrg return sig; 70401e04c3fSmrg 70501e04c3fSmrg if (!allow_builtins) 70601e04c3fSmrg return sig; 70701e04c3fSmrg } 70801e04c3fSmrg 70901e04c3fSmrg /* Local shader has no exact candidates; check the built-ins. */ 71001e04c3fSmrg sig = _mesa_glsl_find_builtin_function(state, name, actual_parameters); 711ed98bd31Smaya 712ed98bd31Smaya /* if _mesa_glsl_find_builtin_function failed, fall back to the result 713ed98bd31Smaya * of choose_best_inexact_overload() instead. This should only affect 714ed98bd31Smaya * GLES. 715ed98bd31Smaya */ 716ed98bd31Smaya return sig ? sig : local_sig; 71701e04c3fSmrg} 71801e04c3fSmrg 71901e04c3fSmrgstatic ir_function_signature * 72001e04c3fSmrgmatch_subroutine_by_name(const char *name, 72101e04c3fSmrg exec_list *actual_parameters, 72201e04c3fSmrg struct _mesa_glsl_parse_state *state, 72301e04c3fSmrg ir_variable **var_r) 72401e04c3fSmrg{ 72501e04c3fSmrg void *ctx = state; 72601e04c3fSmrg ir_function_signature *sig = NULL; 72701e04c3fSmrg ir_function *f, *found = NULL; 72801e04c3fSmrg const char *new_name; 72901e04c3fSmrg ir_variable *var; 73001e04c3fSmrg bool is_exact = false; 73101e04c3fSmrg 73201e04c3fSmrg new_name = 73301e04c3fSmrg ralloc_asprintf(ctx, "%s_%s", 73401e04c3fSmrg _mesa_shader_stage_to_subroutine_prefix(state->stage), 73501e04c3fSmrg name); 73601e04c3fSmrg var = state->symbols->get_variable(new_name); 73701e04c3fSmrg if (!var) 73801e04c3fSmrg return NULL; 73901e04c3fSmrg 74001e04c3fSmrg for (int i = 0; i < state->num_subroutine_types; i++) { 74101e04c3fSmrg f = state->subroutine_types[i]; 74201e04c3fSmrg if (strcmp(f->name, var->type->without_array()->name)) 74301e04c3fSmrg continue; 74401e04c3fSmrg found = f; 74501e04c3fSmrg break; 74601e04c3fSmrg } 74701e04c3fSmrg 74801e04c3fSmrg if (!found) 74901e04c3fSmrg return NULL; 75001e04c3fSmrg *var_r = var; 75101e04c3fSmrg sig = found->matching_signature(state, actual_parameters, 75201e04c3fSmrg false, &is_exact); 75301e04c3fSmrg return sig; 75401e04c3fSmrg} 75501e04c3fSmrg 75601e04c3fSmrgstatic ir_rvalue * 75701e04c3fSmrggenerate_array_index(void *mem_ctx, exec_list *instructions, 75801e04c3fSmrg struct _mesa_glsl_parse_state *state, YYLTYPE loc, 75901e04c3fSmrg const ast_expression *array, ast_expression *idx, 76001e04c3fSmrg const char **function_name, exec_list *actual_parameters) 76101e04c3fSmrg{ 76201e04c3fSmrg if (array->oper == ast_array_index) { 76301e04c3fSmrg /* This handles arrays of arrays */ 76401e04c3fSmrg ir_rvalue *outer_array = generate_array_index(mem_ctx, instructions, 76501e04c3fSmrg state, loc, 76601e04c3fSmrg array->subexpressions[0], 76701e04c3fSmrg array->subexpressions[1], 76801e04c3fSmrg function_name, 76901e04c3fSmrg actual_parameters); 77001e04c3fSmrg ir_rvalue *outer_array_idx = idx->hir(instructions, state); 77101e04c3fSmrg 77201e04c3fSmrg YYLTYPE index_loc = idx->get_location(); 77301e04c3fSmrg return _mesa_ast_array_index_to_hir(mem_ctx, state, outer_array, 77401e04c3fSmrg outer_array_idx, loc, 77501e04c3fSmrg index_loc); 77601e04c3fSmrg } else { 77701e04c3fSmrg ir_variable *sub_var = NULL; 77801e04c3fSmrg *function_name = array->primary_expression.identifier; 77901e04c3fSmrg 78001e04c3fSmrg if (!match_subroutine_by_name(*function_name, actual_parameters, 78101e04c3fSmrg state, &sub_var)) { 78201e04c3fSmrg _mesa_glsl_error(&loc, state, "Unknown subroutine `%s'", 78301e04c3fSmrg *function_name); 78401e04c3fSmrg *function_name = NULL; /* indicate error condition to caller */ 78501e04c3fSmrg return NULL; 78601e04c3fSmrg } 78701e04c3fSmrg 78801e04c3fSmrg ir_rvalue *outer_array_idx = idx->hir(instructions, state); 78901e04c3fSmrg return new(mem_ctx) ir_dereference_array(sub_var, outer_array_idx); 79001e04c3fSmrg } 79101e04c3fSmrg} 79201e04c3fSmrg 7937ec681f3Smrgstatic bool 7947ec681f3Smrgfunction_exists(_mesa_glsl_parse_state *state, 7957ec681f3Smrg struct glsl_symbol_table *symbols, const char *name) 7967ec681f3Smrg{ 7977ec681f3Smrg ir_function *f = symbols->get_function(name); 7987ec681f3Smrg if (f != NULL) { 7997ec681f3Smrg foreach_in_list(ir_function_signature, sig, &f->signatures) { 8007ec681f3Smrg if (sig->is_builtin() && !sig->is_builtin_available(state)) 8017ec681f3Smrg continue; 8027ec681f3Smrg return true; 8037ec681f3Smrg } 8047ec681f3Smrg } 8057ec681f3Smrg return false; 8067ec681f3Smrg} 8077ec681f3Smrg 80801e04c3fSmrgstatic void 80901e04c3fSmrgprint_function_prototypes(_mesa_glsl_parse_state *state, YYLTYPE *loc, 81001e04c3fSmrg ir_function *f) 81101e04c3fSmrg{ 81201e04c3fSmrg if (f == NULL) 81301e04c3fSmrg return; 81401e04c3fSmrg 81501e04c3fSmrg foreach_in_list(ir_function_signature, sig, &f->signatures) { 81601e04c3fSmrg if (sig->is_builtin() && !sig->is_builtin_available(state)) 81701e04c3fSmrg continue; 81801e04c3fSmrg 81901e04c3fSmrg char *str = prototype_string(sig->return_type, f->name, 82001e04c3fSmrg &sig->parameters); 82101e04c3fSmrg _mesa_glsl_error(loc, state, " %s", str); 82201e04c3fSmrg ralloc_free(str); 82301e04c3fSmrg } 82401e04c3fSmrg} 82501e04c3fSmrg 82601e04c3fSmrg/** 82701e04c3fSmrg * Raise a "no matching function" error, listing all possible overloads the 82801e04c3fSmrg * compiler considered so developers can figure out what went wrong. 82901e04c3fSmrg */ 83001e04c3fSmrgstatic void 83101e04c3fSmrgno_matching_function_error(const char *name, 83201e04c3fSmrg YYLTYPE *loc, 83301e04c3fSmrg exec_list *actual_parameters, 83401e04c3fSmrg _mesa_glsl_parse_state *state) 83501e04c3fSmrg{ 83601e04c3fSmrg gl_shader *sh = _mesa_glsl_get_builtin_function_shader(); 83701e04c3fSmrg 8387ec681f3Smrg if (!function_exists(state, state->symbols, name) 83901e04c3fSmrg && (!state->uses_builtin_functions 8407ec681f3Smrg || !function_exists(state, sh->symbols, name))) { 84101e04c3fSmrg _mesa_glsl_error(loc, state, "no function with name '%s'", name); 84201e04c3fSmrg } else { 84301e04c3fSmrg char *str = prototype_string(NULL, name, actual_parameters); 84401e04c3fSmrg _mesa_glsl_error(loc, state, 84501e04c3fSmrg "no matching function for call to `%s';" 84601e04c3fSmrg " candidates are:", 84701e04c3fSmrg str); 84801e04c3fSmrg ralloc_free(str); 84901e04c3fSmrg 85001e04c3fSmrg print_function_prototypes(state, loc, 85101e04c3fSmrg state->symbols->get_function(name)); 85201e04c3fSmrg 85301e04c3fSmrg if (state->uses_builtin_functions) { 85401e04c3fSmrg print_function_prototypes(state, loc, 85501e04c3fSmrg sh->symbols->get_function(name)); 85601e04c3fSmrg } 85701e04c3fSmrg } 85801e04c3fSmrg} 85901e04c3fSmrg 86001e04c3fSmrg/** 86101e04c3fSmrg * Perform automatic type conversion of constructor parameters 86201e04c3fSmrg * 86301e04c3fSmrg * This implements the rules in the "Conversion and Scalar Constructors" 86401e04c3fSmrg * section (GLSL 1.10 section 5.4.1), not the "Implicit Conversions" rules. 86501e04c3fSmrg */ 86601e04c3fSmrgstatic ir_rvalue * 86701e04c3fSmrgconvert_component(ir_rvalue *src, const glsl_type *desired_type) 86801e04c3fSmrg{ 86901e04c3fSmrg void *ctx = ralloc_parent(src); 87001e04c3fSmrg const unsigned a = desired_type->base_type; 87101e04c3fSmrg const unsigned b = src->type->base_type; 87201e04c3fSmrg ir_expression *result = NULL; 87301e04c3fSmrg 87401e04c3fSmrg if (src->type->is_error()) 87501e04c3fSmrg return src; 87601e04c3fSmrg 87701e04c3fSmrg assert(a <= GLSL_TYPE_IMAGE); 87801e04c3fSmrg assert(b <= GLSL_TYPE_IMAGE); 87901e04c3fSmrg 88001e04c3fSmrg if (a == b) 88101e04c3fSmrg return src; 88201e04c3fSmrg 88301e04c3fSmrg switch (a) { 88401e04c3fSmrg case GLSL_TYPE_UINT: 88501e04c3fSmrg switch (b) { 88601e04c3fSmrg case GLSL_TYPE_INT: 88701e04c3fSmrg result = new(ctx) ir_expression(ir_unop_i2u, src); 88801e04c3fSmrg break; 88901e04c3fSmrg case GLSL_TYPE_FLOAT: 89001e04c3fSmrg result = new(ctx) ir_expression(ir_unop_f2u, src); 89101e04c3fSmrg break; 89201e04c3fSmrg case GLSL_TYPE_BOOL: 89301e04c3fSmrg result = new(ctx) ir_expression(ir_unop_i2u, 89401e04c3fSmrg new(ctx) ir_expression(ir_unop_b2i, 89501e04c3fSmrg src)); 89601e04c3fSmrg break; 89701e04c3fSmrg case GLSL_TYPE_DOUBLE: 89801e04c3fSmrg result = new(ctx) ir_expression(ir_unop_d2u, src); 89901e04c3fSmrg break; 90001e04c3fSmrg case GLSL_TYPE_UINT64: 90101e04c3fSmrg result = new(ctx) ir_expression(ir_unop_u642u, src); 90201e04c3fSmrg break; 90301e04c3fSmrg case GLSL_TYPE_INT64: 90401e04c3fSmrg result = new(ctx) ir_expression(ir_unop_i642u, src); 90501e04c3fSmrg break; 90601e04c3fSmrg case GLSL_TYPE_SAMPLER: 90701e04c3fSmrg result = new(ctx) ir_expression(ir_unop_unpack_sampler_2x32, src); 90801e04c3fSmrg break; 90901e04c3fSmrg case GLSL_TYPE_IMAGE: 91001e04c3fSmrg result = new(ctx) ir_expression(ir_unop_unpack_image_2x32, src); 91101e04c3fSmrg break; 91201e04c3fSmrg } 91301e04c3fSmrg break; 91401e04c3fSmrg case GLSL_TYPE_INT: 91501e04c3fSmrg switch (b) { 91601e04c3fSmrg case GLSL_TYPE_UINT: 91701e04c3fSmrg result = new(ctx) ir_expression(ir_unop_u2i, src); 91801e04c3fSmrg break; 91901e04c3fSmrg case GLSL_TYPE_FLOAT: 92001e04c3fSmrg result = new(ctx) ir_expression(ir_unop_f2i, src); 92101e04c3fSmrg break; 92201e04c3fSmrg case GLSL_TYPE_BOOL: 92301e04c3fSmrg result = new(ctx) ir_expression(ir_unop_b2i, src); 92401e04c3fSmrg break; 92501e04c3fSmrg case GLSL_TYPE_DOUBLE: 92601e04c3fSmrg result = new(ctx) ir_expression(ir_unop_d2i, src); 92701e04c3fSmrg break; 92801e04c3fSmrg case GLSL_TYPE_UINT64: 92901e04c3fSmrg result = new(ctx) ir_expression(ir_unop_u642i, src); 93001e04c3fSmrg break; 93101e04c3fSmrg case GLSL_TYPE_INT64: 93201e04c3fSmrg result = new(ctx) ir_expression(ir_unop_i642i, src); 93301e04c3fSmrg break; 93401e04c3fSmrg } 93501e04c3fSmrg break; 93601e04c3fSmrg case GLSL_TYPE_FLOAT: 93701e04c3fSmrg switch (b) { 93801e04c3fSmrg case GLSL_TYPE_UINT: 93901e04c3fSmrg result = new(ctx) ir_expression(ir_unop_u2f, desired_type, src, NULL); 94001e04c3fSmrg break; 94101e04c3fSmrg case GLSL_TYPE_INT: 94201e04c3fSmrg result = new(ctx) ir_expression(ir_unop_i2f, desired_type, src, NULL); 94301e04c3fSmrg break; 94401e04c3fSmrg case GLSL_TYPE_BOOL: 94501e04c3fSmrg result = new(ctx) ir_expression(ir_unop_b2f, desired_type, src, NULL); 94601e04c3fSmrg break; 94701e04c3fSmrg case GLSL_TYPE_DOUBLE: 94801e04c3fSmrg result = new(ctx) ir_expression(ir_unop_d2f, desired_type, src, NULL); 94901e04c3fSmrg break; 95001e04c3fSmrg case GLSL_TYPE_UINT64: 95101e04c3fSmrg result = new(ctx) ir_expression(ir_unop_u642f, desired_type, src, NULL); 95201e04c3fSmrg break; 95301e04c3fSmrg case GLSL_TYPE_INT64: 95401e04c3fSmrg result = new(ctx) ir_expression(ir_unop_i642f, desired_type, src, NULL); 95501e04c3fSmrg break; 95601e04c3fSmrg } 95701e04c3fSmrg break; 95801e04c3fSmrg case GLSL_TYPE_BOOL: 95901e04c3fSmrg switch (b) { 96001e04c3fSmrg case GLSL_TYPE_UINT: 96101e04c3fSmrg result = new(ctx) ir_expression(ir_unop_i2b, 96201e04c3fSmrg new(ctx) ir_expression(ir_unop_u2i, 96301e04c3fSmrg src)); 96401e04c3fSmrg break; 96501e04c3fSmrg case GLSL_TYPE_INT: 96601e04c3fSmrg result = new(ctx) ir_expression(ir_unop_i2b, desired_type, src, NULL); 96701e04c3fSmrg break; 96801e04c3fSmrg case GLSL_TYPE_FLOAT: 96901e04c3fSmrg result = new(ctx) ir_expression(ir_unop_f2b, desired_type, src, NULL); 97001e04c3fSmrg break; 97101e04c3fSmrg case GLSL_TYPE_DOUBLE: 97201e04c3fSmrg result = new(ctx) ir_expression(ir_unop_d2b, desired_type, src, NULL); 97301e04c3fSmrg break; 97401e04c3fSmrg case GLSL_TYPE_UINT64: 97501e04c3fSmrg result = new(ctx) ir_expression(ir_unop_i642b, 97601e04c3fSmrg new(ctx) ir_expression(ir_unop_u642i64, 97701e04c3fSmrg src)); 97801e04c3fSmrg break; 97901e04c3fSmrg case GLSL_TYPE_INT64: 98001e04c3fSmrg result = new(ctx) ir_expression(ir_unop_i642b, desired_type, src, NULL); 98101e04c3fSmrg break; 98201e04c3fSmrg } 98301e04c3fSmrg break; 98401e04c3fSmrg case GLSL_TYPE_DOUBLE: 98501e04c3fSmrg switch (b) { 98601e04c3fSmrg case GLSL_TYPE_INT: 98701e04c3fSmrg result = new(ctx) ir_expression(ir_unop_i2d, src); 98801e04c3fSmrg break; 98901e04c3fSmrg case GLSL_TYPE_UINT: 99001e04c3fSmrg result = new(ctx) ir_expression(ir_unop_u2d, src); 99101e04c3fSmrg break; 99201e04c3fSmrg case GLSL_TYPE_BOOL: 99301e04c3fSmrg result = new(ctx) ir_expression(ir_unop_f2d, 99401e04c3fSmrg new(ctx) ir_expression(ir_unop_b2f, 99501e04c3fSmrg src)); 99601e04c3fSmrg break; 99701e04c3fSmrg case GLSL_TYPE_FLOAT: 99801e04c3fSmrg result = new(ctx) ir_expression(ir_unop_f2d, desired_type, src, NULL); 99901e04c3fSmrg break; 100001e04c3fSmrg case GLSL_TYPE_UINT64: 100101e04c3fSmrg result = new(ctx) ir_expression(ir_unop_u642d, desired_type, src, NULL); 100201e04c3fSmrg break; 100301e04c3fSmrg case GLSL_TYPE_INT64: 100401e04c3fSmrg result = new(ctx) ir_expression(ir_unop_i642d, desired_type, src, NULL); 100501e04c3fSmrg break; 100601e04c3fSmrg } 100701e04c3fSmrg break; 100801e04c3fSmrg case GLSL_TYPE_UINT64: 100901e04c3fSmrg switch (b) { 101001e04c3fSmrg case GLSL_TYPE_INT: 101101e04c3fSmrg result = new(ctx) ir_expression(ir_unop_i2u64, src); 101201e04c3fSmrg break; 101301e04c3fSmrg case GLSL_TYPE_UINT: 101401e04c3fSmrg result = new(ctx) ir_expression(ir_unop_u2u64, src); 101501e04c3fSmrg break; 101601e04c3fSmrg case GLSL_TYPE_BOOL: 101701e04c3fSmrg result = new(ctx) ir_expression(ir_unop_i642u64, 101801e04c3fSmrg new(ctx) ir_expression(ir_unop_b2i64, 101901e04c3fSmrg src)); 102001e04c3fSmrg break; 102101e04c3fSmrg case GLSL_TYPE_FLOAT: 102201e04c3fSmrg result = new(ctx) ir_expression(ir_unop_f2u64, src); 102301e04c3fSmrg break; 102401e04c3fSmrg case GLSL_TYPE_DOUBLE: 102501e04c3fSmrg result = new(ctx) ir_expression(ir_unop_d2u64, src); 102601e04c3fSmrg break; 102701e04c3fSmrg case GLSL_TYPE_INT64: 102801e04c3fSmrg result = new(ctx) ir_expression(ir_unop_i642u64, src); 102901e04c3fSmrg break; 103001e04c3fSmrg } 103101e04c3fSmrg break; 103201e04c3fSmrg case GLSL_TYPE_INT64: 103301e04c3fSmrg switch (b) { 103401e04c3fSmrg case GLSL_TYPE_INT: 103501e04c3fSmrg result = new(ctx) ir_expression(ir_unop_i2i64, src); 103601e04c3fSmrg break; 103701e04c3fSmrg case GLSL_TYPE_UINT: 103801e04c3fSmrg result = new(ctx) ir_expression(ir_unop_u2i64, src); 103901e04c3fSmrg break; 104001e04c3fSmrg case GLSL_TYPE_BOOL: 104101e04c3fSmrg result = new(ctx) ir_expression(ir_unop_b2i64, src); 104201e04c3fSmrg break; 104301e04c3fSmrg case GLSL_TYPE_FLOAT: 104401e04c3fSmrg result = new(ctx) ir_expression(ir_unop_f2i64, src); 104501e04c3fSmrg break; 104601e04c3fSmrg case GLSL_TYPE_DOUBLE: 104701e04c3fSmrg result = new(ctx) ir_expression(ir_unop_d2i64, src); 104801e04c3fSmrg break; 104901e04c3fSmrg case GLSL_TYPE_UINT64: 105001e04c3fSmrg result = new(ctx) ir_expression(ir_unop_u642i64, src); 105101e04c3fSmrg break; 105201e04c3fSmrg } 105301e04c3fSmrg break; 105401e04c3fSmrg case GLSL_TYPE_SAMPLER: 105501e04c3fSmrg switch (b) { 105601e04c3fSmrg case GLSL_TYPE_UINT: 105701e04c3fSmrg result = new(ctx) 105801e04c3fSmrg ir_expression(ir_unop_pack_sampler_2x32, desired_type, src); 105901e04c3fSmrg break; 106001e04c3fSmrg } 106101e04c3fSmrg break; 106201e04c3fSmrg case GLSL_TYPE_IMAGE: 106301e04c3fSmrg switch (b) { 106401e04c3fSmrg case GLSL_TYPE_UINT: 106501e04c3fSmrg result = new(ctx) 106601e04c3fSmrg ir_expression(ir_unop_pack_image_2x32, desired_type, src); 106701e04c3fSmrg break; 106801e04c3fSmrg } 106901e04c3fSmrg break; 107001e04c3fSmrg } 107101e04c3fSmrg 107201e04c3fSmrg assert(result != NULL); 107301e04c3fSmrg assert(result->type == desired_type); 107401e04c3fSmrg 107501e04c3fSmrg /* Try constant folding; it may fold in the conversion we just added. */ 107601e04c3fSmrg ir_constant *const constant = result->constant_expression_value(ctx); 107701e04c3fSmrg return (constant != NULL) ? (ir_rvalue *) constant : (ir_rvalue *) result; 107801e04c3fSmrg} 107901e04c3fSmrg 108001e04c3fSmrg 108101e04c3fSmrg/** 108201e04c3fSmrg * Perform automatic type and constant conversion of constructor parameters 108301e04c3fSmrg * 108401e04c3fSmrg * This implements the rules in the "Implicit Conversions" rules, not the 108501e04c3fSmrg * "Conversion and Scalar Constructors". 108601e04c3fSmrg * 108701e04c3fSmrg * After attempting the implicit conversion, an attempt to convert into a 108801e04c3fSmrg * constant valued expression is also done. 108901e04c3fSmrg * 109001e04c3fSmrg * The \c from \c ir_rvalue is converted "in place". 109101e04c3fSmrg * 109201e04c3fSmrg * \param from Operand that is being converted 109301e04c3fSmrg * \param to Base type the operand will be converted to 109401e04c3fSmrg * \param state GLSL compiler state 109501e04c3fSmrg * 109601e04c3fSmrg * \return 109701e04c3fSmrg * If the attempt to convert into a constant expression succeeds, \c true is 109801e04c3fSmrg * returned. Otherwise \c false is returned. 109901e04c3fSmrg */ 110001e04c3fSmrgstatic bool 110101e04c3fSmrgimplicitly_convert_component(ir_rvalue * &from, const glsl_base_type to, 110201e04c3fSmrg struct _mesa_glsl_parse_state *state) 110301e04c3fSmrg{ 110401e04c3fSmrg void *mem_ctx = state; 110501e04c3fSmrg ir_rvalue *result = from; 110601e04c3fSmrg 110701e04c3fSmrg if (to != from->type->base_type) { 110801e04c3fSmrg const glsl_type *desired_type = 110901e04c3fSmrg glsl_type::get_instance(to, 111001e04c3fSmrg from->type->vector_elements, 111101e04c3fSmrg from->type->matrix_columns); 111201e04c3fSmrg 111301e04c3fSmrg if (from->type->can_implicitly_convert_to(desired_type, state)) { 111401e04c3fSmrg /* Even though convert_component() implements the constructor 111501e04c3fSmrg * conversion rules (not the implicit conversion rules), its safe 111601e04c3fSmrg * to use it here because we already checked that the implicit 111701e04c3fSmrg * conversion is legal. 111801e04c3fSmrg */ 111901e04c3fSmrg result = convert_component(from, desired_type); 112001e04c3fSmrg } 112101e04c3fSmrg } 112201e04c3fSmrg 112301e04c3fSmrg ir_rvalue *const constant = result->constant_expression_value(mem_ctx); 112401e04c3fSmrg 112501e04c3fSmrg if (constant != NULL) 112601e04c3fSmrg result = constant; 112701e04c3fSmrg 112801e04c3fSmrg if (from != result) { 112901e04c3fSmrg from->replace_with(result); 113001e04c3fSmrg from = result; 113101e04c3fSmrg } 113201e04c3fSmrg 113301e04c3fSmrg return constant != NULL; 113401e04c3fSmrg} 113501e04c3fSmrg 113601e04c3fSmrg 113701e04c3fSmrg/** 113801e04c3fSmrg * Dereference a specific component from a scalar, vector, or matrix 113901e04c3fSmrg */ 114001e04c3fSmrgstatic ir_rvalue * 114101e04c3fSmrgdereference_component(ir_rvalue *src, unsigned component) 114201e04c3fSmrg{ 114301e04c3fSmrg void *ctx = ralloc_parent(src); 114401e04c3fSmrg assert(component < src->type->components()); 114501e04c3fSmrg 114601e04c3fSmrg /* If the source is a constant, just create a new constant instead of a 114701e04c3fSmrg * dereference of the existing constant. 114801e04c3fSmrg */ 114901e04c3fSmrg ir_constant *constant = src->as_constant(); 115001e04c3fSmrg if (constant) 115101e04c3fSmrg return new(ctx) ir_constant(constant, component); 115201e04c3fSmrg 115301e04c3fSmrg if (src->type->is_scalar()) { 115401e04c3fSmrg return src; 115501e04c3fSmrg } else if (src->type->is_vector()) { 115601e04c3fSmrg return new(ctx) ir_swizzle(src, component, 0, 0, 0, 1); 115701e04c3fSmrg } else { 115801e04c3fSmrg assert(src->type->is_matrix()); 115901e04c3fSmrg 116001e04c3fSmrg /* Dereference a row of the matrix, then call this function again to get 116101e04c3fSmrg * a specific element from that row. 116201e04c3fSmrg */ 116301e04c3fSmrg const int c = component / src->type->column_type()->vector_elements; 116401e04c3fSmrg const int r = component % src->type->column_type()->vector_elements; 116501e04c3fSmrg ir_constant *const col_index = new(ctx) ir_constant(c); 116601e04c3fSmrg ir_dereference *const col = new(ctx) ir_dereference_array(src, 116701e04c3fSmrg col_index); 116801e04c3fSmrg 116901e04c3fSmrg col->type = src->type->column_type(); 117001e04c3fSmrg 117101e04c3fSmrg return dereference_component(col, r); 117201e04c3fSmrg } 117301e04c3fSmrg 117401e04c3fSmrg assert(!"Should not get here."); 117501e04c3fSmrg return NULL; 117601e04c3fSmrg} 117701e04c3fSmrg 117801e04c3fSmrg 117901e04c3fSmrgstatic ir_rvalue * 118001e04c3fSmrgprocess_vec_mat_constructor(exec_list *instructions, 118101e04c3fSmrg const glsl_type *constructor_type, 118201e04c3fSmrg YYLTYPE *loc, exec_list *parameters, 118301e04c3fSmrg struct _mesa_glsl_parse_state *state) 118401e04c3fSmrg{ 118501e04c3fSmrg void *ctx = state; 118601e04c3fSmrg 118701e04c3fSmrg /* The ARB_shading_language_420pack spec says: 118801e04c3fSmrg * 118901e04c3fSmrg * "If an initializer is a list of initializers enclosed in curly braces, 119001e04c3fSmrg * the variable being declared must be a vector, a matrix, an array, or a 119101e04c3fSmrg * structure. 119201e04c3fSmrg * 119301e04c3fSmrg * int i = { 1 }; // illegal, i is not an aggregate" 119401e04c3fSmrg */ 119501e04c3fSmrg if (constructor_type->vector_elements <= 1) { 119601e04c3fSmrg _mesa_glsl_error(loc, state, "aggregates can only initialize vectors, " 119701e04c3fSmrg "matrices, arrays, and structs"); 119801e04c3fSmrg return ir_rvalue::error_value(ctx); 119901e04c3fSmrg } 120001e04c3fSmrg 120101e04c3fSmrg exec_list actual_parameters; 120201e04c3fSmrg const unsigned parameter_count = 120301e04c3fSmrg process_parameters(instructions, &actual_parameters, parameters, state); 120401e04c3fSmrg 120501e04c3fSmrg if (parameter_count == 0 120601e04c3fSmrg || (constructor_type->is_vector() && 120701e04c3fSmrg constructor_type->vector_elements != parameter_count) 120801e04c3fSmrg || (constructor_type->is_matrix() && 120901e04c3fSmrg constructor_type->matrix_columns != parameter_count)) { 121001e04c3fSmrg _mesa_glsl_error(loc, state, "%s constructor must have %u parameters", 121101e04c3fSmrg constructor_type->is_vector() ? "vector" : "matrix", 121201e04c3fSmrg constructor_type->vector_elements); 121301e04c3fSmrg return ir_rvalue::error_value(ctx); 121401e04c3fSmrg } 121501e04c3fSmrg 121601e04c3fSmrg bool all_parameters_are_constant = true; 121701e04c3fSmrg 121801e04c3fSmrg /* Type cast each parameter and, if possible, fold constants. */ 121901e04c3fSmrg foreach_in_list_safe(ir_rvalue, ir, &actual_parameters) { 122001e04c3fSmrg /* Apply implicit conversions (not the scalar constructor rules, see the 122101e04c3fSmrg * spec quote above!) and attempt to convert the parameter to a constant 122201e04c3fSmrg * valued expression. After doing so, track whether or not all the 122301e04c3fSmrg * parameters to the constructor are trivially constant valued 122401e04c3fSmrg * expressions. 122501e04c3fSmrg */ 122601e04c3fSmrg all_parameters_are_constant &= 122701e04c3fSmrg implicitly_convert_component(ir, constructor_type->base_type, state); 122801e04c3fSmrg 122901e04c3fSmrg if (constructor_type->is_matrix()) { 123001e04c3fSmrg if (ir->type != constructor_type->column_type()) { 123101e04c3fSmrg _mesa_glsl_error(loc, state, "type error in matrix constructor: " 123201e04c3fSmrg "expected: %s, found %s", 123301e04c3fSmrg constructor_type->column_type()->name, 123401e04c3fSmrg ir->type->name); 123501e04c3fSmrg return ir_rvalue::error_value(ctx); 123601e04c3fSmrg } 123701e04c3fSmrg } else if (ir->type != constructor_type->get_scalar_type()) { 123801e04c3fSmrg _mesa_glsl_error(loc, state, "type error in vector constructor: " 123901e04c3fSmrg "expected: %s, found %s", 124001e04c3fSmrg constructor_type->get_scalar_type()->name, 124101e04c3fSmrg ir->type->name); 124201e04c3fSmrg return ir_rvalue::error_value(ctx); 124301e04c3fSmrg } 124401e04c3fSmrg } 124501e04c3fSmrg 124601e04c3fSmrg if (all_parameters_are_constant) 124701e04c3fSmrg return new(ctx) ir_constant(constructor_type, &actual_parameters); 124801e04c3fSmrg 124901e04c3fSmrg ir_variable *var = new(ctx) ir_variable(constructor_type, "vec_mat_ctor", 125001e04c3fSmrg ir_var_temporary); 125101e04c3fSmrg instructions->push_tail(var); 125201e04c3fSmrg 125301e04c3fSmrg int i = 0; 125401e04c3fSmrg 125501e04c3fSmrg foreach_in_list(ir_rvalue, rhs, &actual_parameters) { 125601e04c3fSmrg ir_instruction *assignment = NULL; 125701e04c3fSmrg 125801e04c3fSmrg if (var->type->is_matrix()) { 125901e04c3fSmrg ir_rvalue *lhs = 126001e04c3fSmrg new(ctx) ir_dereference_array(var, new(ctx) ir_constant(i)); 126101e04c3fSmrg assignment = new(ctx) ir_assignment(lhs, rhs); 126201e04c3fSmrg } else { 126301e04c3fSmrg /* use writemask rather than index for vector */ 126401e04c3fSmrg assert(var->type->is_vector()); 126501e04c3fSmrg assert(i < 4); 126601e04c3fSmrg ir_dereference *lhs = new(ctx) ir_dereference_variable(var); 126701e04c3fSmrg assignment = new(ctx) ir_assignment(lhs, rhs, NULL, 126801e04c3fSmrg (unsigned)(1 << i)); 126901e04c3fSmrg } 127001e04c3fSmrg 127101e04c3fSmrg instructions->push_tail(assignment); 127201e04c3fSmrg 127301e04c3fSmrg i++; 127401e04c3fSmrg } 127501e04c3fSmrg 127601e04c3fSmrg return new(ctx) ir_dereference_variable(var); 127701e04c3fSmrg} 127801e04c3fSmrg 127901e04c3fSmrg 128001e04c3fSmrgstatic ir_rvalue * 128101e04c3fSmrgprocess_array_constructor(exec_list *instructions, 128201e04c3fSmrg const glsl_type *constructor_type, 128301e04c3fSmrg YYLTYPE *loc, exec_list *parameters, 128401e04c3fSmrg struct _mesa_glsl_parse_state *state) 128501e04c3fSmrg{ 128601e04c3fSmrg void *ctx = state; 128701e04c3fSmrg /* Array constructors come in two forms: sized and unsized. Sized array 128801e04c3fSmrg * constructors look like 'vec4[2](a, b)', where 'a' and 'b' are vec4 128901e04c3fSmrg * variables. In this case the number of parameters must exactly match the 129001e04c3fSmrg * specified size of the array. 129101e04c3fSmrg * 129201e04c3fSmrg * Unsized array constructors look like 'vec4[](a, b)', where 'a' and 'b' 129301e04c3fSmrg * are vec4 variables. In this case the size of the array being constructed 129401e04c3fSmrg * is determined by the number of parameters. 129501e04c3fSmrg * 129601e04c3fSmrg * From page 52 (page 58 of the PDF) of the GLSL 1.50 spec: 129701e04c3fSmrg * 129801e04c3fSmrg * "There must be exactly the same number of arguments as the size of 129901e04c3fSmrg * the array being constructed. If no size is present in the 130001e04c3fSmrg * constructor, then the array is explicitly sized to the number of 130101e04c3fSmrg * arguments provided. The arguments are assigned in order, starting at 130201e04c3fSmrg * element 0, to the elements of the constructed array. Each argument 130301e04c3fSmrg * must be the same type as the element type of the array, or be a type 130401e04c3fSmrg * that can be converted to the element type of the array according to 130501e04c3fSmrg * Section 4.1.10 "Implicit Conversions."" 130601e04c3fSmrg */ 130701e04c3fSmrg exec_list actual_parameters; 130801e04c3fSmrg const unsigned parameter_count = 130901e04c3fSmrg process_parameters(instructions, &actual_parameters, parameters, state); 131001e04c3fSmrg bool is_unsized_array = constructor_type->is_unsized_array(); 131101e04c3fSmrg 131201e04c3fSmrg if ((parameter_count == 0) || 131301e04c3fSmrg (!is_unsized_array && (constructor_type->length != parameter_count))) { 131401e04c3fSmrg const unsigned min_param = is_unsized_array 131501e04c3fSmrg ? 1 : constructor_type->length; 131601e04c3fSmrg 131701e04c3fSmrg _mesa_glsl_error(loc, state, "array constructor must have %s %u " 131801e04c3fSmrg "parameter%s", 131901e04c3fSmrg is_unsized_array ? "at least" : "exactly", 132001e04c3fSmrg min_param, (min_param <= 1) ? "" : "s"); 132101e04c3fSmrg return ir_rvalue::error_value(ctx); 132201e04c3fSmrg } 132301e04c3fSmrg 132401e04c3fSmrg if (is_unsized_array) { 132501e04c3fSmrg constructor_type = 132601e04c3fSmrg glsl_type::get_array_instance(constructor_type->fields.array, 132701e04c3fSmrg parameter_count); 132801e04c3fSmrg assert(constructor_type != NULL); 132901e04c3fSmrg assert(constructor_type->length == parameter_count); 133001e04c3fSmrg } 133101e04c3fSmrg 133201e04c3fSmrg bool all_parameters_are_constant = true; 133301e04c3fSmrg const glsl_type *element_type = constructor_type->fields.array; 133401e04c3fSmrg 133501e04c3fSmrg /* Type cast each parameter and, if possible, fold constants. */ 133601e04c3fSmrg foreach_in_list_safe(ir_rvalue, ir, &actual_parameters) { 133701e04c3fSmrg /* Apply implicit conversions (not the scalar constructor rules, see the 133801e04c3fSmrg * spec quote above!) and attempt to convert the parameter to a constant 133901e04c3fSmrg * valued expression. After doing so, track whether or not all the 134001e04c3fSmrg * parameters to the constructor are trivially constant valued 134101e04c3fSmrg * expressions. 134201e04c3fSmrg */ 134301e04c3fSmrg all_parameters_are_constant &= 134401e04c3fSmrg implicitly_convert_component(ir, element_type->base_type, state); 134501e04c3fSmrg 134601e04c3fSmrg if (constructor_type->fields.array->is_unsized_array()) { 134701e04c3fSmrg /* As the inner parameters of the constructor are created without 134801e04c3fSmrg * knowledge of each other we need to check to make sure unsized 134901e04c3fSmrg * parameters of unsized constructors all end up with the same size. 135001e04c3fSmrg * 135101e04c3fSmrg * e.g we make sure to fail for a constructor like this: 135201e04c3fSmrg * vec4[][] a = vec4[][](vec4[](vec4(0.0), vec4(1.0)), 135301e04c3fSmrg * vec4[](vec4(0.0), vec4(1.0), vec4(1.0)), 135401e04c3fSmrg * vec4[](vec4(0.0), vec4(1.0))); 135501e04c3fSmrg */ 135601e04c3fSmrg if (element_type->is_unsized_array()) { 135701e04c3fSmrg /* This is the first parameter so just get the type */ 135801e04c3fSmrg element_type = ir->type; 135901e04c3fSmrg } else if (element_type != ir->type) { 136001e04c3fSmrg _mesa_glsl_error(loc, state, "type error in array constructor: " 136101e04c3fSmrg "expected: %s, found %s", 136201e04c3fSmrg element_type->name, 136301e04c3fSmrg ir->type->name); 136401e04c3fSmrg return ir_rvalue::error_value(ctx); 136501e04c3fSmrg } 136601e04c3fSmrg } else if (ir->type != constructor_type->fields.array) { 136701e04c3fSmrg _mesa_glsl_error(loc, state, "type error in array constructor: " 136801e04c3fSmrg "expected: %s, found %s", 136901e04c3fSmrg constructor_type->fields.array->name, 137001e04c3fSmrg ir->type->name); 137101e04c3fSmrg return ir_rvalue::error_value(ctx); 137201e04c3fSmrg } else { 137301e04c3fSmrg element_type = ir->type; 137401e04c3fSmrg } 137501e04c3fSmrg } 137601e04c3fSmrg 137701e04c3fSmrg if (constructor_type->fields.array->is_unsized_array()) { 137801e04c3fSmrg constructor_type = 137901e04c3fSmrg glsl_type::get_array_instance(element_type, 138001e04c3fSmrg parameter_count); 138101e04c3fSmrg assert(constructor_type != NULL); 138201e04c3fSmrg assert(constructor_type->length == parameter_count); 138301e04c3fSmrg } 138401e04c3fSmrg 138501e04c3fSmrg if (all_parameters_are_constant) 138601e04c3fSmrg return new(ctx) ir_constant(constructor_type, &actual_parameters); 138701e04c3fSmrg 138801e04c3fSmrg ir_variable *var = new(ctx) ir_variable(constructor_type, "array_ctor", 138901e04c3fSmrg ir_var_temporary); 139001e04c3fSmrg instructions->push_tail(var); 139101e04c3fSmrg 139201e04c3fSmrg int i = 0; 139301e04c3fSmrg foreach_in_list(ir_rvalue, rhs, &actual_parameters) { 139401e04c3fSmrg ir_rvalue *lhs = new(ctx) ir_dereference_array(var, 139501e04c3fSmrg new(ctx) ir_constant(i)); 139601e04c3fSmrg 139701e04c3fSmrg ir_instruction *assignment = new(ctx) ir_assignment(lhs, rhs); 139801e04c3fSmrg instructions->push_tail(assignment); 139901e04c3fSmrg 140001e04c3fSmrg i++; 140101e04c3fSmrg } 140201e04c3fSmrg 140301e04c3fSmrg return new(ctx) ir_dereference_variable(var); 140401e04c3fSmrg} 140501e04c3fSmrg 140601e04c3fSmrg 140701e04c3fSmrg/** 140801e04c3fSmrg * Determine if a list consists of a single scalar r-value 140901e04c3fSmrg */ 141001e04c3fSmrgstatic bool 141101e04c3fSmrgsingle_scalar_parameter(exec_list *parameters) 141201e04c3fSmrg{ 141301e04c3fSmrg const ir_rvalue *const p = (ir_rvalue *) parameters->get_head_raw(); 141401e04c3fSmrg assert(((ir_rvalue *)p)->as_rvalue() != NULL); 141501e04c3fSmrg 141601e04c3fSmrg return (p->type->is_scalar() && p->next->is_tail_sentinel()); 141701e04c3fSmrg} 141801e04c3fSmrg 141901e04c3fSmrg 142001e04c3fSmrg/** 142101e04c3fSmrg * Generate inline code for a vector constructor 142201e04c3fSmrg * 142301e04c3fSmrg * The generated constructor code will consist of a temporary variable 142401e04c3fSmrg * declaration of the same type as the constructor. A sequence of assignments 142501e04c3fSmrg * from constructor parameters to the temporary will follow. 142601e04c3fSmrg * 142701e04c3fSmrg * \return 142801e04c3fSmrg * An \c ir_dereference_variable of the temprorary generated in the constructor 142901e04c3fSmrg * body. 143001e04c3fSmrg */ 143101e04c3fSmrgstatic ir_rvalue * 143201e04c3fSmrgemit_inline_vector_constructor(const glsl_type *type, 143301e04c3fSmrg exec_list *instructions, 143401e04c3fSmrg exec_list *parameters, 143501e04c3fSmrg void *ctx) 143601e04c3fSmrg{ 143701e04c3fSmrg assert(!parameters->is_empty()); 143801e04c3fSmrg 143901e04c3fSmrg ir_variable *var = new(ctx) ir_variable(type, "vec_ctor", ir_var_temporary); 144001e04c3fSmrg instructions->push_tail(var); 144101e04c3fSmrg 144201e04c3fSmrg /* There are three kinds of vector constructors. 144301e04c3fSmrg * 144401e04c3fSmrg * - Construct a vector from a single scalar by replicating that scalar to 144501e04c3fSmrg * all components of the vector. 144601e04c3fSmrg * 144701e04c3fSmrg * - Construct a vector from at least a matrix. This case should already 144801e04c3fSmrg * have been taken care of in ast_function_expression::hir by breaking 144901e04c3fSmrg * down the matrix into a series of column vectors. 145001e04c3fSmrg * 145101e04c3fSmrg * - Construct a vector from an arbirary combination of vectors and 145201e04c3fSmrg * scalars. The components of the constructor parameters are assigned 145301e04c3fSmrg * to the vector in order until the vector is full. 145401e04c3fSmrg */ 145501e04c3fSmrg const unsigned lhs_components = type->components(); 145601e04c3fSmrg if (single_scalar_parameter(parameters)) { 145701e04c3fSmrg ir_rvalue *first_param = (ir_rvalue *)parameters->get_head_raw(); 145801e04c3fSmrg ir_rvalue *rhs = new(ctx) ir_swizzle(first_param, 0, 0, 0, 0, 145901e04c3fSmrg lhs_components); 146001e04c3fSmrg ir_dereference_variable *lhs = new(ctx) ir_dereference_variable(var); 146101e04c3fSmrg const unsigned mask = (1U << lhs_components) - 1; 146201e04c3fSmrg 146301e04c3fSmrg assert(rhs->type == lhs->type); 146401e04c3fSmrg 146501e04c3fSmrg ir_instruction *inst = new(ctx) ir_assignment(lhs, rhs, NULL, mask); 146601e04c3fSmrg instructions->push_tail(inst); 146701e04c3fSmrg } else { 146801e04c3fSmrg unsigned base_component = 0; 146901e04c3fSmrg unsigned base_lhs_component = 0; 147001e04c3fSmrg ir_constant_data data; 147101e04c3fSmrg unsigned constant_mask = 0, constant_components = 0; 147201e04c3fSmrg 147301e04c3fSmrg memset(&data, 0, sizeof(data)); 147401e04c3fSmrg 147501e04c3fSmrg foreach_in_list(ir_rvalue, param, parameters) { 147601e04c3fSmrg unsigned rhs_components = param->type->components(); 147701e04c3fSmrg 147801e04c3fSmrg /* Do not try to assign more components to the vector than it has! */ 147901e04c3fSmrg if ((rhs_components + base_lhs_component) > lhs_components) { 148001e04c3fSmrg rhs_components = lhs_components - base_lhs_component; 148101e04c3fSmrg } 148201e04c3fSmrg 148301e04c3fSmrg const ir_constant *const c = param->as_constant(); 148401e04c3fSmrg if (c != NULL) { 148501e04c3fSmrg for (unsigned i = 0; i < rhs_components; i++) { 148601e04c3fSmrg switch (c->type->base_type) { 148701e04c3fSmrg case GLSL_TYPE_UINT: 148801e04c3fSmrg data.u[i + base_component] = c->get_uint_component(i); 148901e04c3fSmrg break; 149001e04c3fSmrg case GLSL_TYPE_INT: 149101e04c3fSmrg data.i[i + base_component] = c->get_int_component(i); 149201e04c3fSmrg break; 149301e04c3fSmrg case GLSL_TYPE_FLOAT: 149401e04c3fSmrg data.f[i + base_component] = c->get_float_component(i); 149501e04c3fSmrg break; 149601e04c3fSmrg case GLSL_TYPE_DOUBLE: 149701e04c3fSmrg data.d[i + base_component] = c->get_double_component(i); 149801e04c3fSmrg break; 149901e04c3fSmrg case GLSL_TYPE_BOOL: 150001e04c3fSmrg data.b[i + base_component] = c->get_bool_component(i); 150101e04c3fSmrg break; 150201e04c3fSmrg case GLSL_TYPE_UINT64: 150301e04c3fSmrg data.u64[i + base_component] = c->get_uint64_component(i); 150401e04c3fSmrg break; 150501e04c3fSmrg case GLSL_TYPE_INT64: 150601e04c3fSmrg data.i64[i + base_component] = c->get_int64_component(i); 150701e04c3fSmrg break; 150801e04c3fSmrg default: 150901e04c3fSmrg assert(!"Should not get here."); 151001e04c3fSmrg break; 151101e04c3fSmrg } 151201e04c3fSmrg } 151301e04c3fSmrg 151401e04c3fSmrg /* Mask of fields to be written in the assignment. */ 151501e04c3fSmrg constant_mask |= ((1U << rhs_components) - 1) << base_lhs_component; 151601e04c3fSmrg constant_components += rhs_components; 151701e04c3fSmrg 151801e04c3fSmrg base_component += rhs_components; 151901e04c3fSmrg } 152001e04c3fSmrg /* Advance the component index by the number of components 152101e04c3fSmrg * that were just assigned. 152201e04c3fSmrg */ 152301e04c3fSmrg base_lhs_component += rhs_components; 152401e04c3fSmrg } 152501e04c3fSmrg 152601e04c3fSmrg if (constant_mask != 0) { 152701e04c3fSmrg ir_dereference *lhs = new(ctx) ir_dereference_variable(var); 152801e04c3fSmrg const glsl_type *rhs_type = 152901e04c3fSmrg glsl_type::get_instance(var->type->base_type, 153001e04c3fSmrg constant_components, 153101e04c3fSmrg 1); 153201e04c3fSmrg ir_rvalue *rhs = new(ctx) ir_constant(rhs_type, &data); 153301e04c3fSmrg 153401e04c3fSmrg ir_instruction *inst = 153501e04c3fSmrg new(ctx) ir_assignment(lhs, rhs, NULL, constant_mask); 153601e04c3fSmrg instructions->push_tail(inst); 153701e04c3fSmrg } 153801e04c3fSmrg 153901e04c3fSmrg base_component = 0; 154001e04c3fSmrg foreach_in_list(ir_rvalue, param, parameters) { 154101e04c3fSmrg unsigned rhs_components = param->type->components(); 154201e04c3fSmrg 154301e04c3fSmrg /* Do not try to assign more components to the vector than it has! */ 154401e04c3fSmrg if ((rhs_components + base_component) > lhs_components) { 154501e04c3fSmrg rhs_components = lhs_components - base_component; 154601e04c3fSmrg } 154701e04c3fSmrg 154801e04c3fSmrg /* If we do not have any components left to copy, break out of the 154901e04c3fSmrg * loop. This can happen when initializing a vec4 with a mat3 as the 155001e04c3fSmrg * mat3 would have been broken into a series of column vectors. 155101e04c3fSmrg */ 155201e04c3fSmrg if (rhs_components == 0) { 155301e04c3fSmrg break; 155401e04c3fSmrg } 155501e04c3fSmrg 155601e04c3fSmrg const ir_constant *const c = param->as_constant(); 155701e04c3fSmrg if (c == NULL) { 155801e04c3fSmrg /* Mask of fields to be written in the assignment. */ 155901e04c3fSmrg const unsigned write_mask = ((1U << rhs_components) - 1) 156001e04c3fSmrg << base_component; 156101e04c3fSmrg 156201e04c3fSmrg ir_dereference *lhs = new(ctx) ir_dereference_variable(var); 156301e04c3fSmrg 156401e04c3fSmrg /* Generate a swizzle so that LHS and RHS sizes match. */ 156501e04c3fSmrg ir_rvalue *rhs = 156601e04c3fSmrg new(ctx) ir_swizzle(param, 0, 1, 2, 3, rhs_components); 156701e04c3fSmrg 156801e04c3fSmrg ir_instruction *inst = 156901e04c3fSmrg new(ctx) ir_assignment(lhs, rhs, NULL, write_mask); 157001e04c3fSmrg instructions->push_tail(inst); 157101e04c3fSmrg } 157201e04c3fSmrg 157301e04c3fSmrg /* Advance the component index by the number of components that were 157401e04c3fSmrg * just assigned. 157501e04c3fSmrg */ 157601e04c3fSmrg base_component += rhs_components; 157701e04c3fSmrg } 157801e04c3fSmrg } 157901e04c3fSmrg return new(ctx) ir_dereference_variable(var); 158001e04c3fSmrg} 158101e04c3fSmrg 158201e04c3fSmrg 158301e04c3fSmrg/** 158401e04c3fSmrg * Generate assignment of a portion of a vector to a portion of a matrix column 158501e04c3fSmrg * 158601e04c3fSmrg * \param src_base First component of the source to be used in assignment 158701e04c3fSmrg * \param column Column of destination to be assiged 158801e04c3fSmrg * \param row_base First component of the destination column to be assigned 158901e04c3fSmrg * \param count Number of components to be assigned 159001e04c3fSmrg * 159101e04c3fSmrg * \note 159201e04c3fSmrg * \c src_base + \c count must be less than or equal to the number of 159301e04c3fSmrg * components in the source vector. 159401e04c3fSmrg */ 159501e04c3fSmrgstatic ir_instruction * 159601e04c3fSmrgassign_to_matrix_column(ir_variable *var, unsigned column, unsigned row_base, 159701e04c3fSmrg ir_rvalue *src, unsigned src_base, unsigned count, 159801e04c3fSmrg void *mem_ctx) 159901e04c3fSmrg{ 160001e04c3fSmrg ir_constant *col_idx = new(mem_ctx) ir_constant(column); 160101e04c3fSmrg ir_dereference *column_ref = new(mem_ctx) ir_dereference_array(var, 160201e04c3fSmrg col_idx); 160301e04c3fSmrg 160401e04c3fSmrg assert(column_ref->type->components() >= (row_base + count)); 160501e04c3fSmrg assert(src->type->components() >= (src_base + count)); 160601e04c3fSmrg 160701e04c3fSmrg /* Generate a swizzle that extracts the number of components from the source 160801e04c3fSmrg * that are to be assigned to the column of the matrix. 160901e04c3fSmrg */ 161001e04c3fSmrg if (count < src->type->vector_elements) { 161101e04c3fSmrg src = new(mem_ctx) ir_swizzle(src, 161201e04c3fSmrg src_base + 0, src_base + 1, 161301e04c3fSmrg src_base + 2, src_base + 3, 161401e04c3fSmrg count); 161501e04c3fSmrg } 161601e04c3fSmrg 161701e04c3fSmrg /* Mask of fields to be written in the assignment. */ 161801e04c3fSmrg const unsigned write_mask = ((1U << count) - 1) << row_base; 161901e04c3fSmrg 162001e04c3fSmrg return new(mem_ctx) ir_assignment(column_ref, src, NULL, write_mask); 162101e04c3fSmrg} 162201e04c3fSmrg 162301e04c3fSmrg 162401e04c3fSmrg/** 162501e04c3fSmrg * Generate inline code for a matrix constructor 162601e04c3fSmrg * 162701e04c3fSmrg * The generated constructor code will consist of a temporary variable 162801e04c3fSmrg * declaration of the same type as the constructor. A sequence of assignments 162901e04c3fSmrg * from constructor parameters to the temporary will follow. 163001e04c3fSmrg * 163101e04c3fSmrg * \return 163201e04c3fSmrg * An \c ir_dereference_variable of the temprorary generated in the constructor 163301e04c3fSmrg * body. 163401e04c3fSmrg */ 163501e04c3fSmrgstatic ir_rvalue * 163601e04c3fSmrgemit_inline_matrix_constructor(const glsl_type *type, 163701e04c3fSmrg exec_list *instructions, 163801e04c3fSmrg exec_list *parameters, 163901e04c3fSmrg void *ctx) 164001e04c3fSmrg{ 164101e04c3fSmrg assert(!parameters->is_empty()); 164201e04c3fSmrg 164301e04c3fSmrg ir_variable *var = new(ctx) ir_variable(type, "mat_ctor", ir_var_temporary); 164401e04c3fSmrg instructions->push_tail(var); 164501e04c3fSmrg 164601e04c3fSmrg /* There are three kinds of matrix constructors. 164701e04c3fSmrg * 164801e04c3fSmrg * - Construct a matrix from a single scalar by replicating that scalar to 164901e04c3fSmrg * along the diagonal of the matrix and setting all other components to 165001e04c3fSmrg * zero. 165101e04c3fSmrg * 165201e04c3fSmrg * - Construct a matrix from an arbirary combination of vectors and 165301e04c3fSmrg * scalars. The components of the constructor parameters are assigned 165401e04c3fSmrg * to the matrix in column-major order until the matrix is full. 165501e04c3fSmrg * 165601e04c3fSmrg * - Construct a matrix from a single matrix. The source matrix is copied 165701e04c3fSmrg * to the upper left portion of the constructed matrix, and the remaining 165801e04c3fSmrg * elements take values from the identity matrix. 165901e04c3fSmrg */ 166001e04c3fSmrg ir_rvalue *const first_param = (ir_rvalue *) parameters->get_head_raw(); 166101e04c3fSmrg if (single_scalar_parameter(parameters)) { 166201e04c3fSmrg /* Assign the scalar to the X component of a vec4, and fill the remaining 166301e04c3fSmrg * components with zero. 166401e04c3fSmrg */ 166501e04c3fSmrg glsl_base_type param_base_type = first_param->type->base_type; 166601e04c3fSmrg assert(first_param->type->is_float() || first_param->type->is_double()); 166701e04c3fSmrg ir_variable *rhs_var = 166801e04c3fSmrg new(ctx) ir_variable(glsl_type::get_instance(param_base_type, 4, 1), 166901e04c3fSmrg "mat_ctor_vec", 167001e04c3fSmrg ir_var_temporary); 167101e04c3fSmrg instructions->push_tail(rhs_var); 167201e04c3fSmrg 167301e04c3fSmrg ir_constant_data zero; 167401e04c3fSmrg for (unsigned i = 0; i < 4; i++) 167501e04c3fSmrg if (first_param->type->is_float()) 167601e04c3fSmrg zero.f[i] = 0.0; 167701e04c3fSmrg else 167801e04c3fSmrg zero.d[i] = 0.0; 167901e04c3fSmrg 168001e04c3fSmrg ir_instruction *inst = 168101e04c3fSmrg new(ctx) ir_assignment(new(ctx) ir_dereference_variable(rhs_var), 168201e04c3fSmrg new(ctx) ir_constant(rhs_var->type, &zero)); 168301e04c3fSmrg instructions->push_tail(inst); 168401e04c3fSmrg 168501e04c3fSmrg ir_dereference *const rhs_ref = 168601e04c3fSmrg new(ctx) ir_dereference_variable(rhs_var); 168701e04c3fSmrg 168801e04c3fSmrg inst = new(ctx) ir_assignment(rhs_ref, first_param, NULL, 0x01); 168901e04c3fSmrg instructions->push_tail(inst); 169001e04c3fSmrg 169101e04c3fSmrg /* Assign the temporary vector to each column of the destination matrix 169201e04c3fSmrg * with a swizzle that puts the X component on the diagonal of the 169301e04c3fSmrg * matrix. In some cases this may mean that the X component does not 169401e04c3fSmrg * get assigned into the column at all (i.e., when the matrix has more 169501e04c3fSmrg * columns than rows). 169601e04c3fSmrg */ 169701e04c3fSmrg static const unsigned rhs_swiz[4][4] = { 169801e04c3fSmrg { 0, 1, 1, 1 }, 169901e04c3fSmrg { 1, 0, 1, 1 }, 170001e04c3fSmrg { 1, 1, 0, 1 }, 170101e04c3fSmrg { 1, 1, 1, 0 } 170201e04c3fSmrg }; 170301e04c3fSmrg 170401e04c3fSmrg const unsigned cols_to_init = MIN2(type->matrix_columns, 170501e04c3fSmrg type->vector_elements); 170601e04c3fSmrg for (unsigned i = 0; i < cols_to_init; i++) { 170701e04c3fSmrg ir_constant *const col_idx = new(ctx) ir_constant(i); 170801e04c3fSmrg ir_rvalue *const col_ref = new(ctx) ir_dereference_array(var, 170901e04c3fSmrg col_idx); 171001e04c3fSmrg 171101e04c3fSmrg ir_rvalue *const rhs_ref = new(ctx) ir_dereference_variable(rhs_var); 171201e04c3fSmrg ir_rvalue *const rhs = new(ctx) ir_swizzle(rhs_ref, rhs_swiz[i], 171301e04c3fSmrg type->vector_elements); 171401e04c3fSmrg 171501e04c3fSmrg inst = new(ctx) ir_assignment(col_ref, rhs); 171601e04c3fSmrg instructions->push_tail(inst); 171701e04c3fSmrg } 171801e04c3fSmrg 171901e04c3fSmrg for (unsigned i = cols_to_init; i < type->matrix_columns; i++) { 172001e04c3fSmrg ir_constant *const col_idx = new(ctx) ir_constant(i); 172101e04c3fSmrg ir_rvalue *const col_ref = new(ctx) ir_dereference_array(var, 172201e04c3fSmrg col_idx); 172301e04c3fSmrg 172401e04c3fSmrg ir_rvalue *const rhs_ref = new(ctx) ir_dereference_variable(rhs_var); 172501e04c3fSmrg ir_rvalue *const rhs = new(ctx) ir_swizzle(rhs_ref, 1, 1, 1, 1, 172601e04c3fSmrg type->vector_elements); 172701e04c3fSmrg 172801e04c3fSmrg inst = new(ctx) ir_assignment(col_ref, rhs); 172901e04c3fSmrg instructions->push_tail(inst); 173001e04c3fSmrg } 173101e04c3fSmrg } else if (first_param->type->is_matrix()) { 173201e04c3fSmrg /* From page 50 (56 of the PDF) of the GLSL 1.50 spec: 173301e04c3fSmrg * 173401e04c3fSmrg * "If a matrix is constructed from a matrix, then each component 173501e04c3fSmrg * (column i, row j) in the result that has a corresponding 173601e04c3fSmrg * component (column i, row j) in the argument will be initialized 173701e04c3fSmrg * from there. All other components will be initialized to the 173801e04c3fSmrg * identity matrix. If a matrix argument is given to a matrix 173901e04c3fSmrg * constructor, it is an error to have any other arguments." 174001e04c3fSmrg */ 174101e04c3fSmrg assert(first_param->next->is_tail_sentinel()); 174201e04c3fSmrg ir_rvalue *const src_matrix = first_param; 174301e04c3fSmrg 174401e04c3fSmrg /* If the source matrix is smaller, pre-initialize the relavent parts of 174501e04c3fSmrg * the destination matrix to the identity matrix. 174601e04c3fSmrg */ 174701e04c3fSmrg if ((src_matrix->type->matrix_columns < var->type->matrix_columns) || 174801e04c3fSmrg (src_matrix->type->vector_elements < var->type->vector_elements)) { 174901e04c3fSmrg 175001e04c3fSmrg /* If the source matrix has fewer rows, every column of the 175101e04c3fSmrg * destination must be initialized. Otherwise only the columns in 175201e04c3fSmrg * the destination that do not exist in the source must be 175301e04c3fSmrg * initialized. 175401e04c3fSmrg */ 175501e04c3fSmrg unsigned col = 175601e04c3fSmrg (src_matrix->type->vector_elements < var->type->vector_elements) 175701e04c3fSmrg ? 0 : src_matrix->type->matrix_columns; 175801e04c3fSmrg 175901e04c3fSmrg const glsl_type *const col_type = var->type->column_type(); 176001e04c3fSmrg for (/* empty */; col < var->type->matrix_columns; col++) { 176101e04c3fSmrg ir_constant_data ident; 176201e04c3fSmrg 176301e04c3fSmrg if (!col_type->is_double()) { 176401e04c3fSmrg ident.f[0] = 0.0f; 176501e04c3fSmrg ident.f[1] = 0.0f; 176601e04c3fSmrg ident.f[2] = 0.0f; 176701e04c3fSmrg ident.f[3] = 0.0f; 176801e04c3fSmrg ident.f[col] = 1.0f; 176901e04c3fSmrg } else { 177001e04c3fSmrg ident.d[0] = 0.0; 177101e04c3fSmrg ident.d[1] = 0.0; 177201e04c3fSmrg ident.d[2] = 0.0; 177301e04c3fSmrg ident.d[3] = 0.0; 177401e04c3fSmrg ident.d[col] = 1.0; 177501e04c3fSmrg } 177601e04c3fSmrg 177701e04c3fSmrg ir_rvalue *const rhs = new(ctx) ir_constant(col_type, &ident); 177801e04c3fSmrg 177901e04c3fSmrg ir_rvalue *const lhs = 178001e04c3fSmrg new(ctx) ir_dereference_array(var, new(ctx) ir_constant(col)); 178101e04c3fSmrg 178201e04c3fSmrg ir_instruction *inst = new(ctx) ir_assignment(lhs, rhs); 178301e04c3fSmrg instructions->push_tail(inst); 178401e04c3fSmrg } 178501e04c3fSmrg } 178601e04c3fSmrg 178701e04c3fSmrg /* Assign columns from the source matrix to the destination matrix. 178801e04c3fSmrg * 178901e04c3fSmrg * Since the parameter will be used in the RHS of multiple assignments, 179001e04c3fSmrg * generate a temporary and copy the paramter there. 179101e04c3fSmrg */ 179201e04c3fSmrg ir_variable *const rhs_var = 179301e04c3fSmrg new(ctx) ir_variable(first_param->type, "mat_ctor_mat", 179401e04c3fSmrg ir_var_temporary); 179501e04c3fSmrg instructions->push_tail(rhs_var); 179601e04c3fSmrg 179701e04c3fSmrg ir_dereference *const rhs_var_ref = 179801e04c3fSmrg new(ctx) ir_dereference_variable(rhs_var); 179901e04c3fSmrg ir_instruction *const inst = 180001e04c3fSmrg new(ctx) ir_assignment(rhs_var_ref, first_param); 180101e04c3fSmrg instructions->push_tail(inst); 180201e04c3fSmrg 180301e04c3fSmrg const unsigned last_row = MIN2(src_matrix->type->vector_elements, 180401e04c3fSmrg var->type->vector_elements); 180501e04c3fSmrg const unsigned last_col = MIN2(src_matrix->type->matrix_columns, 180601e04c3fSmrg var->type->matrix_columns); 180701e04c3fSmrg 180801e04c3fSmrg unsigned swiz[4] = { 0, 0, 0, 0 }; 180901e04c3fSmrg for (unsigned i = 1; i < last_row; i++) 181001e04c3fSmrg swiz[i] = i; 181101e04c3fSmrg 181201e04c3fSmrg const unsigned write_mask = (1U << last_row) - 1; 181301e04c3fSmrg 181401e04c3fSmrg for (unsigned i = 0; i < last_col; i++) { 181501e04c3fSmrg ir_dereference *const lhs = 181601e04c3fSmrg new(ctx) ir_dereference_array(var, new(ctx) ir_constant(i)); 181701e04c3fSmrg ir_rvalue *const rhs_col = 181801e04c3fSmrg new(ctx) ir_dereference_array(rhs_var, new(ctx) ir_constant(i)); 181901e04c3fSmrg 182001e04c3fSmrg /* If one matrix has columns that are smaller than the columns of the 182101e04c3fSmrg * other matrix, wrap the column access of the larger with a swizzle 182201e04c3fSmrg * so that the LHS and RHS of the assignment have the same size (and 182301e04c3fSmrg * therefore have the same type). 182401e04c3fSmrg * 182501e04c3fSmrg * It would be perfectly valid to unconditionally generate the 182601e04c3fSmrg * swizzles, this this will typically result in a more compact IR 182701e04c3fSmrg * tree. 182801e04c3fSmrg */ 182901e04c3fSmrg ir_rvalue *rhs; 183001e04c3fSmrg if (lhs->type->vector_elements != rhs_col->type->vector_elements) { 183101e04c3fSmrg rhs = new(ctx) ir_swizzle(rhs_col, swiz, last_row); 183201e04c3fSmrg } else { 183301e04c3fSmrg rhs = rhs_col; 183401e04c3fSmrg } 183501e04c3fSmrg 183601e04c3fSmrg ir_instruction *inst = 183701e04c3fSmrg new(ctx) ir_assignment(lhs, rhs, NULL, write_mask); 183801e04c3fSmrg instructions->push_tail(inst); 183901e04c3fSmrg } 184001e04c3fSmrg } else { 184101e04c3fSmrg const unsigned cols = type->matrix_columns; 184201e04c3fSmrg const unsigned rows = type->vector_elements; 184301e04c3fSmrg unsigned remaining_slots = rows * cols; 184401e04c3fSmrg unsigned col_idx = 0; 184501e04c3fSmrg unsigned row_idx = 0; 184601e04c3fSmrg 184701e04c3fSmrg foreach_in_list(ir_rvalue, rhs, parameters) { 184801e04c3fSmrg unsigned rhs_components = rhs->type->components(); 184901e04c3fSmrg unsigned rhs_base = 0; 185001e04c3fSmrg 185101e04c3fSmrg if (remaining_slots == 0) 185201e04c3fSmrg break; 185301e04c3fSmrg 185401e04c3fSmrg /* Since the parameter might be used in the RHS of two assignments, 185501e04c3fSmrg * generate a temporary and copy the paramter there. 185601e04c3fSmrg */ 185701e04c3fSmrg ir_variable *rhs_var = 185801e04c3fSmrg new(ctx) ir_variable(rhs->type, "mat_ctor_vec", ir_var_temporary); 185901e04c3fSmrg instructions->push_tail(rhs_var); 186001e04c3fSmrg 186101e04c3fSmrg ir_dereference *rhs_var_ref = 186201e04c3fSmrg new(ctx) ir_dereference_variable(rhs_var); 186301e04c3fSmrg ir_instruction *inst = new(ctx) ir_assignment(rhs_var_ref, rhs); 186401e04c3fSmrg instructions->push_tail(inst); 186501e04c3fSmrg 186601e04c3fSmrg do { 186701e04c3fSmrg /* Assign the current parameter to as many components of the matrix 186801e04c3fSmrg * as it will fill. 186901e04c3fSmrg * 187001e04c3fSmrg * NOTE: A single vector parameter can span two matrix columns. A 187101e04c3fSmrg * single vec4, for example, can completely fill a mat2. 187201e04c3fSmrg */ 187301e04c3fSmrg unsigned count = MIN2(rows - row_idx, 187401e04c3fSmrg rhs_components - rhs_base); 187501e04c3fSmrg 187601e04c3fSmrg rhs_var_ref = new(ctx) ir_dereference_variable(rhs_var); 187701e04c3fSmrg ir_instruction *inst = assign_to_matrix_column(var, col_idx, 187801e04c3fSmrg row_idx, 187901e04c3fSmrg rhs_var_ref, 188001e04c3fSmrg rhs_base, 188101e04c3fSmrg count, ctx); 188201e04c3fSmrg instructions->push_tail(inst); 188301e04c3fSmrg rhs_base += count; 188401e04c3fSmrg row_idx += count; 188501e04c3fSmrg remaining_slots -= count; 188601e04c3fSmrg 188701e04c3fSmrg /* Sometimes, there is still data left in the parameters and 188801e04c3fSmrg * components left to be set in the destination but in other 188901e04c3fSmrg * column. 189001e04c3fSmrg */ 189101e04c3fSmrg if (row_idx >= rows) { 189201e04c3fSmrg row_idx = 0; 189301e04c3fSmrg col_idx++; 189401e04c3fSmrg } 189501e04c3fSmrg } while(remaining_slots > 0 && rhs_base < rhs_components); 189601e04c3fSmrg } 189701e04c3fSmrg } 189801e04c3fSmrg 189901e04c3fSmrg return new(ctx) ir_dereference_variable(var); 190001e04c3fSmrg} 190101e04c3fSmrg 190201e04c3fSmrg 190301e04c3fSmrgstatic ir_rvalue * 190401e04c3fSmrgemit_inline_record_constructor(const glsl_type *type, 190501e04c3fSmrg exec_list *instructions, 190601e04c3fSmrg exec_list *parameters, 190701e04c3fSmrg void *mem_ctx) 190801e04c3fSmrg{ 190901e04c3fSmrg ir_variable *const var = 191001e04c3fSmrg new(mem_ctx) ir_variable(type, "record_ctor", ir_var_temporary); 191101e04c3fSmrg ir_dereference_variable *const d = 191201e04c3fSmrg new(mem_ctx) ir_dereference_variable(var); 191301e04c3fSmrg 191401e04c3fSmrg instructions->push_tail(var); 191501e04c3fSmrg 191601e04c3fSmrg exec_node *node = parameters->get_head_raw(); 191701e04c3fSmrg for (unsigned i = 0; i < type->length; i++) { 191801e04c3fSmrg assert(!node->is_tail_sentinel()); 191901e04c3fSmrg 192001e04c3fSmrg ir_dereference *const lhs = 192101e04c3fSmrg new(mem_ctx) ir_dereference_record(d->clone(mem_ctx, NULL), 192201e04c3fSmrg type->fields.structure[i].name); 192301e04c3fSmrg 192401e04c3fSmrg ir_rvalue *const rhs = ((ir_instruction *) node)->as_rvalue(); 192501e04c3fSmrg assert(rhs != NULL); 192601e04c3fSmrg 192701e04c3fSmrg ir_instruction *const assign = new(mem_ctx) ir_assignment(lhs, rhs); 192801e04c3fSmrg 192901e04c3fSmrg instructions->push_tail(assign); 193001e04c3fSmrg node = node->next; 193101e04c3fSmrg } 193201e04c3fSmrg 193301e04c3fSmrg return d; 193401e04c3fSmrg} 193501e04c3fSmrg 193601e04c3fSmrg 193701e04c3fSmrgstatic ir_rvalue * 193801e04c3fSmrgprocess_record_constructor(exec_list *instructions, 193901e04c3fSmrg const glsl_type *constructor_type, 194001e04c3fSmrg YYLTYPE *loc, exec_list *parameters, 194101e04c3fSmrg struct _mesa_glsl_parse_state *state) 194201e04c3fSmrg{ 194301e04c3fSmrg void *ctx = state; 194401e04c3fSmrg /* From page 32 (page 38 of the PDF) of the GLSL 1.20 spec: 194501e04c3fSmrg * 194601e04c3fSmrg * "The arguments to the constructor will be used to set the structure's 194701e04c3fSmrg * fields, in order, using one argument per field. Each argument must 194801e04c3fSmrg * be the same type as the field it sets, or be a type that can be 194901e04c3fSmrg * converted to the field's type according to Section 4.1.10 “Implicit 195001e04c3fSmrg * Conversions.”" 195101e04c3fSmrg * 195201e04c3fSmrg * From page 35 (page 41 of the PDF) of the GLSL 4.20 spec: 195301e04c3fSmrg * 195401e04c3fSmrg * "In all cases, the innermost initializer (i.e., not a list of 195501e04c3fSmrg * initializers enclosed in curly braces) applied to an object must 195601e04c3fSmrg * have the same type as the object being initialized or be a type that 195701e04c3fSmrg * can be converted to the object's type according to section 4.1.10 195801e04c3fSmrg * "Implicit Conversions". In the latter case, an implicit conversion 195901e04c3fSmrg * will be done on the initializer before the assignment is done." 196001e04c3fSmrg */ 196101e04c3fSmrg exec_list actual_parameters; 196201e04c3fSmrg 196301e04c3fSmrg const unsigned parameter_count = 196401e04c3fSmrg process_parameters(instructions, &actual_parameters, parameters, 196501e04c3fSmrg state); 196601e04c3fSmrg 196701e04c3fSmrg if (parameter_count != constructor_type->length) { 196801e04c3fSmrg _mesa_glsl_error(loc, state, 196901e04c3fSmrg "%s parameters in constructor for `%s'", 197001e04c3fSmrg parameter_count > constructor_type->length 197101e04c3fSmrg ? "too many": "insufficient", 197201e04c3fSmrg constructor_type->name); 197301e04c3fSmrg return ir_rvalue::error_value(ctx); 197401e04c3fSmrg } 197501e04c3fSmrg 197601e04c3fSmrg bool all_parameters_are_constant = true; 197701e04c3fSmrg 197801e04c3fSmrg int i = 0; 197901e04c3fSmrg /* Type cast each parameter and, if possible, fold constants. */ 198001e04c3fSmrg foreach_in_list_safe(ir_rvalue, ir, &actual_parameters) { 198101e04c3fSmrg 198201e04c3fSmrg const glsl_struct_field *struct_field = 198301e04c3fSmrg &constructor_type->fields.structure[i]; 198401e04c3fSmrg 198501e04c3fSmrg /* Apply implicit conversions (not the scalar constructor rules, see the 198601e04c3fSmrg * spec quote above!) and attempt to convert the parameter to a constant 198701e04c3fSmrg * valued expression. After doing so, track whether or not all the 198801e04c3fSmrg * parameters to the constructor are trivially constant valued 198901e04c3fSmrg * expressions. 199001e04c3fSmrg */ 199101e04c3fSmrg all_parameters_are_constant &= 199201e04c3fSmrg implicitly_convert_component(ir, struct_field->type->base_type, 199301e04c3fSmrg state); 199401e04c3fSmrg 199501e04c3fSmrg if (ir->type != struct_field->type) { 199601e04c3fSmrg _mesa_glsl_error(loc, state, 199701e04c3fSmrg "parameter type mismatch in constructor for `%s.%s' " 199801e04c3fSmrg "(%s vs %s)", 199901e04c3fSmrg constructor_type->name, 200001e04c3fSmrg struct_field->name, 200101e04c3fSmrg ir->type->name, 200201e04c3fSmrg struct_field->type->name); 200301e04c3fSmrg return ir_rvalue::error_value(ctx); 200401e04c3fSmrg } 200501e04c3fSmrg 200601e04c3fSmrg i++; 200701e04c3fSmrg } 200801e04c3fSmrg 200901e04c3fSmrg if (all_parameters_are_constant) { 201001e04c3fSmrg return new(ctx) ir_constant(constructor_type, &actual_parameters); 201101e04c3fSmrg } else { 201201e04c3fSmrg return emit_inline_record_constructor(constructor_type, instructions, 201301e04c3fSmrg &actual_parameters, state); 201401e04c3fSmrg } 201501e04c3fSmrg} 201601e04c3fSmrg 201701e04c3fSmrgir_rvalue * 201801e04c3fSmrgast_function_expression::handle_method(exec_list *instructions, 201901e04c3fSmrg struct _mesa_glsl_parse_state *state) 202001e04c3fSmrg{ 202101e04c3fSmrg const ast_expression *field = subexpressions[0]; 202201e04c3fSmrg ir_rvalue *op; 202301e04c3fSmrg ir_rvalue *result; 202401e04c3fSmrg void *ctx = state; 202501e04c3fSmrg /* Handle "method calls" in GLSL 1.20 - namely, array.length() */ 202601e04c3fSmrg YYLTYPE loc = get_location(); 202701e04c3fSmrg state->check_version(120, 300, &loc, "methods not supported"); 202801e04c3fSmrg 202901e04c3fSmrg const char *method; 203001e04c3fSmrg method = field->primary_expression.identifier; 203101e04c3fSmrg 203201e04c3fSmrg /* This would prevent to raise "uninitialized variable" warnings when 203301e04c3fSmrg * calling array.length. 203401e04c3fSmrg */ 203501e04c3fSmrg field->subexpressions[0]->set_is_lhs(true); 203601e04c3fSmrg op = field->subexpressions[0]->hir(instructions, state); 203701e04c3fSmrg if (strcmp(method, "length") == 0) { 203801e04c3fSmrg if (!this->expressions.is_empty()) { 203901e04c3fSmrg _mesa_glsl_error(&loc, state, "length method takes no arguments"); 204001e04c3fSmrg goto fail; 204101e04c3fSmrg } 204201e04c3fSmrg 204301e04c3fSmrg if (op->type->is_array()) { 204401e04c3fSmrg if (op->type->is_unsized_array()) { 204501e04c3fSmrg if (!state->has_shader_storage_buffer_objects()) { 204601e04c3fSmrg _mesa_glsl_error(&loc, state, 204701e04c3fSmrg "length called on unsized array" 204801e04c3fSmrg " only available with" 204901e04c3fSmrg " ARB_shader_storage_buffer_object"); 20507ec681f3Smrg goto fail; 20517ec681f3Smrg } else if (op->variable_referenced()->is_in_shader_storage_block()) { 20527ec681f3Smrg /* Calculate length of an unsized array in run-time */ 20537ec681f3Smrg result = new(ctx) 20547ec681f3Smrg ir_expression(ir_unop_ssbo_unsized_array_length, op); 20557ec681f3Smrg } else { 20567ec681f3Smrg /* When actual size is known at link-time, this will be 20577ec681f3Smrg * replaced with a constant expression. 20587ec681f3Smrg */ 20597ec681f3Smrg result = new (ctx) 20607ec681f3Smrg ir_expression(ir_unop_implicitly_sized_array_length, op); 206101e04c3fSmrg } 206201e04c3fSmrg } else { 206301e04c3fSmrg result = new(ctx) ir_constant(op->type->array_size()); 206401e04c3fSmrg } 206501e04c3fSmrg } else if (op->type->is_vector()) { 206601e04c3fSmrg if (state->has_420pack()) { 206701e04c3fSmrg /* .length() returns int. */ 206801e04c3fSmrg result = new(ctx) ir_constant((int) op->type->vector_elements); 206901e04c3fSmrg } else { 207001e04c3fSmrg _mesa_glsl_error(&loc, state, "length method on matrix only" 207101e04c3fSmrg " available with ARB_shading_language_420pack"); 207201e04c3fSmrg goto fail; 207301e04c3fSmrg } 207401e04c3fSmrg } else if (op->type->is_matrix()) { 207501e04c3fSmrg if (state->has_420pack()) { 207601e04c3fSmrg /* .length() returns int. */ 207701e04c3fSmrg result = new(ctx) ir_constant((int) op->type->matrix_columns); 207801e04c3fSmrg } else { 207901e04c3fSmrg _mesa_glsl_error(&loc, state, "length method on matrix only" 208001e04c3fSmrg " available with ARB_shading_language_420pack"); 208101e04c3fSmrg goto fail; 208201e04c3fSmrg } 208301e04c3fSmrg } else { 208401e04c3fSmrg _mesa_glsl_error(&loc, state, "length called on scalar."); 208501e04c3fSmrg goto fail; 208601e04c3fSmrg } 208701e04c3fSmrg } else { 208801e04c3fSmrg _mesa_glsl_error(&loc, state, "unknown method: `%s'", method); 208901e04c3fSmrg goto fail; 209001e04c3fSmrg } 209101e04c3fSmrg return result; 209201e04c3fSmrg fail: 209301e04c3fSmrg return ir_rvalue::error_value(ctx); 209401e04c3fSmrg} 209501e04c3fSmrg 209601e04c3fSmrgstatic inline bool is_valid_constructor(const glsl_type *type, 209701e04c3fSmrg struct _mesa_glsl_parse_state *state) 209801e04c3fSmrg{ 209901e04c3fSmrg return type->is_numeric() || type->is_boolean() || 210001e04c3fSmrg (state->has_bindless() && (type->is_sampler() || type->is_image())); 210101e04c3fSmrg} 210201e04c3fSmrg 210301e04c3fSmrgir_rvalue * 210401e04c3fSmrgast_function_expression::hir(exec_list *instructions, 210501e04c3fSmrg struct _mesa_glsl_parse_state *state) 210601e04c3fSmrg{ 210701e04c3fSmrg void *ctx = state; 210801e04c3fSmrg /* There are three sorts of function calls. 210901e04c3fSmrg * 211001e04c3fSmrg * 1. constructors - The first subexpression is an ast_type_specifier. 211101e04c3fSmrg * 2. methods - Only the .length() method of array types. 211201e04c3fSmrg * 3. functions - Calls to regular old functions. 211301e04c3fSmrg * 211401e04c3fSmrg */ 211501e04c3fSmrg if (is_constructor()) { 211601e04c3fSmrg const ast_type_specifier *type = 211701e04c3fSmrg (ast_type_specifier *) subexpressions[0]; 211801e04c3fSmrg YYLTYPE loc = type->get_location(); 211901e04c3fSmrg const char *name; 212001e04c3fSmrg 212101e04c3fSmrg const glsl_type *const constructor_type = type->glsl_type(& name, state); 212201e04c3fSmrg 212301e04c3fSmrg /* constructor_type can be NULL if a variable with the same name as the 212401e04c3fSmrg * structure has come into scope. 212501e04c3fSmrg */ 212601e04c3fSmrg if (constructor_type == NULL) { 212701e04c3fSmrg _mesa_glsl_error(& loc, state, "unknown type `%s' (structure name " 212801e04c3fSmrg "may be shadowed by a variable with the same name)", 212901e04c3fSmrg type->type_name); 213001e04c3fSmrg return ir_rvalue::error_value(ctx); 213101e04c3fSmrg } 213201e04c3fSmrg 213301e04c3fSmrg 213401e04c3fSmrg /* Constructors for opaque types are illegal. 213501e04c3fSmrg * 213601e04c3fSmrg * From section 4.1.7 of the ARB_bindless_texture spec: 213701e04c3fSmrg * 213801e04c3fSmrg * "Samplers are represented using 64-bit integer handles, and may be " 213901e04c3fSmrg * converted to and from 64-bit integers using constructors." 214001e04c3fSmrg * 214101e04c3fSmrg * From section 4.1.X of the ARB_bindless_texture spec: 214201e04c3fSmrg * 214301e04c3fSmrg * "Images are represented using 64-bit integer handles, and may be 214401e04c3fSmrg * converted to and from 64-bit integers using constructors." 214501e04c3fSmrg */ 214601e04c3fSmrg if (constructor_type->contains_atomic() || 214701e04c3fSmrg (!state->has_bindless() && constructor_type->contains_opaque())) { 214801e04c3fSmrg _mesa_glsl_error(& loc, state, "cannot construct %s type `%s'", 214901e04c3fSmrg state->has_bindless() ? "atomic" : "opaque", 215001e04c3fSmrg constructor_type->name); 215101e04c3fSmrg return ir_rvalue::error_value(ctx); 215201e04c3fSmrg } 215301e04c3fSmrg 215401e04c3fSmrg if (constructor_type->is_subroutine()) { 215501e04c3fSmrg _mesa_glsl_error(& loc, state, 215601e04c3fSmrg "subroutine name cannot be a constructor `%s'", 215701e04c3fSmrg constructor_type->name); 215801e04c3fSmrg return ir_rvalue::error_value(ctx); 215901e04c3fSmrg } 216001e04c3fSmrg 216101e04c3fSmrg if (constructor_type->is_array()) { 21627ec681f3Smrg if (!state->check_version(state->allow_glsl_120_subset_in_110 ? 110 : 120, 21637ec681f3Smrg 300, &loc, "array constructors forbidden")) { 216401e04c3fSmrg return ir_rvalue::error_value(ctx); 216501e04c3fSmrg } 216601e04c3fSmrg 216701e04c3fSmrg return process_array_constructor(instructions, constructor_type, 216801e04c3fSmrg & loc, &this->expressions, state); 216901e04c3fSmrg } 217001e04c3fSmrg 217101e04c3fSmrg 217201e04c3fSmrg /* There are two kinds of constructor calls. Constructors for arrays and 217301e04c3fSmrg * structures must have the exact number of arguments with matching types 217401e04c3fSmrg * in the correct order. These constructors follow essentially the same 217501e04c3fSmrg * type matching rules as functions. 217601e04c3fSmrg * 217701e04c3fSmrg * Constructors for built-in language types, such as mat4 and vec2, are 217801e04c3fSmrg * free form. The only requirements are that the parameters must provide 217901e04c3fSmrg * enough values of the correct scalar type and that no arguments are 218001e04c3fSmrg * given past the last used argument. 218101e04c3fSmrg * 218201e04c3fSmrg * When using the C-style initializer syntax from GLSL 4.20, constructors 218301e04c3fSmrg * must have the exact number of arguments with matching types in the 218401e04c3fSmrg * correct order. 218501e04c3fSmrg */ 2186ed98bd31Smaya if (constructor_type->is_struct()) { 218701e04c3fSmrg return process_record_constructor(instructions, constructor_type, 218801e04c3fSmrg &loc, &this->expressions, 218901e04c3fSmrg state); 219001e04c3fSmrg } 219101e04c3fSmrg 219201e04c3fSmrg if (!is_valid_constructor(constructor_type, state)) 219301e04c3fSmrg return ir_rvalue::error_value(ctx); 219401e04c3fSmrg 219501e04c3fSmrg /* Total number of components of the type being constructed. */ 219601e04c3fSmrg const unsigned type_components = constructor_type->components(); 219701e04c3fSmrg 219801e04c3fSmrg /* Number of components from parameters that have actually been 219901e04c3fSmrg * consumed. This is used to perform several kinds of error checking. 220001e04c3fSmrg */ 220101e04c3fSmrg unsigned components_used = 0; 220201e04c3fSmrg 220301e04c3fSmrg unsigned matrix_parameters = 0; 220401e04c3fSmrg unsigned nonmatrix_parameters = 0; 220501e04c3fSmrg exec_list actual_parameters; 220601e04c3fSmrg 220701e04c3fSmrg foreach_list_typed(ast_node, ast, link, &this->expressions) { 220801e04c3fSmrg ir_rvalue *result = ast->hir(instructions, state); 220901e04c3fSmrg 221001e04c3fSmrg /* From page 50 (page 56 of the PDF) of the GLSL 1.50 spec: 221101e04c3fSmrg * 221201e04c3fSmrg * "It is an error to provide extra arguments beyond this 221301e04c3fSmrg * last used argument." 221401e04c3fSmrg */ 221501e04c3fSmrg if (components_used >= type_components) { 221601e04c3fSmrg _mesa_glsl_error(& loc, state, "too many parameters to `%s' " 221701e04c3fSmrg "constructor", 221801e04c3fSmrg constructor_type->name); 221901e04c3fSmrg return ir_rvalue::error_value(ctx); 222001e04c3fSmrg } 222101e04c3fSmrg 222201e04c3fSmrg if (!is_valid_constructor(result->type, state)) { 222301e04c3fSmrg _mesa_glsl_error(& loc, state, "cannot construct `%s' from a " 222401e04c3fSmrg "non-numeric data type", 222501e04c3fSmrg constructor_type->name); 222601e04c3fSmrg return ir_rvalue::error_value(ctx); 222701e04c3fSmrg } 222801e04c3fSmrg 222901e04c3fSmrg /* Count the number of matrix and nonmatrix parameters. This 223001e04c3fSmrg * is used below to enforce some of the constructor rules. 223101e04c3fSmrg */ 223201e04c3fSmrg if (result->type->is_matrix()) 223301e04c3fSmrg matrix_parameters++; 223401e04c3fSmrg else 223501e04c3fSmrg nonmatrix_parameters++; 223601e04c3fSmrg 223701e04c3fSmrg actual_parameters.push_tail(result); 223801e04c3fSmrg components_used += result->type->components(); 223901e04c3fSmrg } 224001e04c3fSmrg 224101e04c3fSmrg /* From page 28 (page 34 of the PDF) of the GLSL 1.10 spec: 224201e04c3fSmrg * 224301e04c3fSmrg * "It is an error to construct matrices from other matrices. This 224401e04c3fSmrg * is reserved for future use." 224501e04c3fSmrg */ 224601e04c3fSmrg if (matrix_parameters > 0 224701e04c3fSmrg && constructor_type->is_matrix() 224801e04c3fSmrg && !state->check_version(120, 100, &loc, 224901e04c3fSmrg "cannot construct `%s' from a matrix", 225001e04c3fSmrg constructor_type->name)) { 225101e04c3fSmrg return ir_rvalue::error_value(ctx); 225201e04c3fSmrg } 225301e04c3fSmrg 225401e04c3fSmrg /* From page 50 (page 56 of the PDF) of the GLSL 1.50 spec: 225501e04c3fSmrg * 225601e04c3fSmrg * "If a matrix argument is given to a matrix constructor, it is 225701e04c3fSmrg * an error to have any other arguments." 225801e04c3fSmrg */ 225901e04c3fSmrg if ((matrix_parameters > 0) 226001e04c3fSmrg && ((matrix_parameters + nonmatrix_parameters) > 1) 226101e04c3fSmrg && constructor_type->is_matrix()) { 226201e04c3fSmrg _mesa_glsl_error(& loc, state, "for matrix `%s' constructor, " 226301e04c3fSmrg "matrix must be only parameter", 226401e04c3fSmrg constructor_type->name); 226501e04c3fSmrg return ir_rvalue::error_value(ctx); 226601e04c3fSmrg } 226701e04c3fSmrg 226801e04c3fSmrg /* From page 28 (page 34 of the PDF) of the GLSL 1.10 spec: 226901e04c3fSmrg * 227001e04c3fSmrg * "In these cases, there must be enough components provided in the 227101e04c3fSmrg * arguments to provide an initializer for every component in the 227201e04c3fSmrg * constructed value." 227301e04c3fSmrg */ 227401e04c3fSmrg if (components_used < type_components && components_used != 1 227501e04c3fSmrg && matrix_parameters == 0) { 227601e04c3fSmrg _mesa_glsl_error(& loc, state, "too few components to construct " 227701e04c3fSmrg "`%s'", 227801e04c3fSmrg constructor_type->name); 227901e04c3fSmrg return ir_rvalue::error_value(ctx); 228001e04c3fSmrg } 228101e04c3fSmrg 228201e04c3fSmrg /* Matrices can never be consumed as is by any constructor but matrix 228301e04c3fSmrg * constructors. If the constructor type is not matrix, always break the 228401e04c3fSmrg * matrix up into a series of column vectors. 228501e04c3fSmrg */ 228601e04c3fSmrg if (!constructor_type->is_matrix()) { 228701e04c3fSmrg foreach_in_list_safe(ir_rvalue, matrix, &actual_parameters) { 228801e04c3fSmrg if (!matrix->type->is_matrix()) 228901e04c3fSmrg continue; 229001e04c3fSmrg 229101e04c3fSmrg /* Create a temporary containing the matrix. */ 229201e04c3fSmrg ir_variable *var = new(ctx) ir_variable(matrix->type, "matrix_tmp", 229301e04c3fSmrg ir_var_temporary); 229401e04c3fSmrg instructions->push_tail(var); 229501e04c3fSmrg instructions->push_tail( 229601e04c3fSmrg new(ctx) ir_assignment(new(ctx) ir_dereference_variable(var), 229701e04c3fSmrg matrix)); 229801e04c3fSmrg var->constant_value = matrix->constant_expression_value(ctx); 229901e04c3fSmrg 230001e04c3fSmrg /* Replace the matrix with dereferences of its columns. */ 230101e04c3fSmrg for (int i = 0; i < matrix->type->matrix_columns; i++) { 230201e04c3fSmrg matrix->insert_before( 230301e04c3fSmrg new (ctx) ir_dereference_array(var, 230401e04c3fSmrg new(ctx) ir_constant(i))); 230501e04c3fSmrg } 230601e04c3fSmrg matrix->remove(); 230701e04c3fSmrg } 230801e04c3fSmrg } 230901e04c3fSmrg 231001e04c3fSmrg bool all_parameters_are_constant = true; 231101e04c3fSmrg 231201e04c3fSmrg /* Type cast each parameter and, if possible, fold constants.*/ 231301e04c3fSmrg foreach_in_list_safe(ir_rvalue, ir, &actual_parameters) { 231401e04c3fSmrg const glsl_type *desired_type; 231501e04c3fSmrg 231601e04c3fSmrg /* From section 5.4.1 of the ARB_bindless_texture spec: 231701e04c3fSmrg * 231801e04c3fSmrg * "In the following four constructors, the low 32 bits of the sampler 231901e04c3fSmrg * type correspond to the .x component of the uvec2 and the high 32 232001e04c3fSmrg * bits correspond to the .y component." 232101e04c3fSmrg * 232201e04c3fSmrg * uvec2(any sampler type) // Converts a sampler type to a 232301e04c3fSmrg * // pair of 32-bit unsigned integers 232401e04c3fSmrg * any sampler type(uvec2) // Converts a pair of 32-bit unsigned integers to 232501e04c3fSmrg * // a sampler type 232601e04c3fSmrg * uvec2(any image type) // Converts an image type to a 232701e04c3fSmrg * // pair of 32-bit unsigned integers 232801e04c3fSmrg * any image type(uvec2) // Converts a pair of 32-bit unsigned integers to 232901e04c3fSmrg * // an image type 233001e04c3fSmrg */ 233101e04c3fSmrg if (ir->type->is_sampler() || ir->type->is_image()) { 233201e04c3fSmrg /* Convert a sampler/image type to a pair of 32-bit unsigned 233301e04c3fSmrg * integers as defined by ARB_bindless_texture. 233401e04c3fSmrg */ 233501e04c3fSmrg if (constructor_type != glsl_type::uvec2_type) { 233601e04c3fSmrg _mesa_glsl_error(&loc, state, "sampler and image types can only " 233701e04c3fSmrg "be converted to a pair of 32-bit unsigned " 233801e04c3fSmrg "integers"); 233901e04c3fSmrg } 234001e04c3fSmrg desired_type = glsl_type::uvec2_type; 234101e04c3fSmrg } else if (constructor_type->is_sampler() || 234201e04c3fSmrg constructor_type->is_image()) { 234301e04c3fSmrg /* Convert a pair of 32-bit unsigned integers to a sampler or image 234401e04c3fSmrg * type as defined by ARB_bindless_texture. 234501e04c3fSmrg */ 234601e04c3fSmrg if (ir->type != glsl_type::uvec2_type) { 234701e04c3fSmrg _mesa_glsl_error(&loc, state, "sampler and image types can only " 234801e04c3fSmrg "be converted from a pair of 32-bit unsigned " 234901e04c3fSmrg "integers"); 235001e04c3fSmrg } 235101e04c3fSmrg desired_type = constructor_type; 235201e04c3fSmrg } else { 235301e04c3fSmrg desired_type = 235401e04c3fSmrg glsl_type::get_instance(constructor_type->base_type, 235501e04c3fSmrg ir->type->vector_elements, 235601e04c3fSmrg ir->type->matrix_columns); 235701e04c3fSmrg } 235801e04c3fSmrg 235901e04c3fSmrg ir_rvalue *result = convert_component(ir, desired_type); 236001e04c3fSmrg 236101e04c3fSmrg /* Attempt to convert the parameter to a constant valued expression. 236201e04c3fSmrg * After doing so, track whether or not all the parameters to the 236301e04c3fSmrg * constructor are trivially constant valued expressions. 236401e04c3fSmrg */ 236501e04c3fSmrg ir_rvalue *const constant = result->constant_expression_value(ctx); 236601e04c3fSmrg 236701e04c3fSmrg if (constant != NULL) 236801e04c3fSmrg result = constant; 236901e04c3fSmrg else 237001e04c3fSmrg all_parameters_are_constant = false; 237101e04c3fSmrg 237201e04c3fSmrg if (result != ir) { 237301e04c3fSmrg ir->replace_with(result); 237401e04c3fSmrg } 237501e04c3fSmrg } 237601e04c3fSmrg 237701e04c3fSmrg /* If all of the parameters are trivially constant, create a 237801e04c3fSmrg * constant representing the complete collection of parameters. 237901e04c3fSmrg */ 238001e04c3fSmrg if (all_parameters_are_constant) { 238101e04c3fSmrg return new(ctx) ir_constant(constructor_type, &actual_parameters); 238201e04c3fSmrg } else if (constructor_type->is_scalar()) { 238301e04c3fSmrg return dereference_component((ir_rvalue *) 238401e04c3fSmrg actual_parameters.get_head_raw(), 238501e04c3fSmrg 0); 238601e04c3fSmrg } else if (constructor_type->is_vector()) { 238701e04c3fSmrg return emit_inline_vector_constructor(constructor_type, 238801e04c3fSmrg instructions, 238901e04c3fSmrg &actual_parameters, 239001e04c3fSmrg ctx); 239101e04c3fSmrg } else { 239201e04c3fSmrg assert(constructor_type->is_matrix()); 239301e04c3fSmrg return emit_inline_matrix_constructor(constructor_type, 239401e04c3fSmrg instructions, 239501e04c3fSmrg &actual_parameters, 239601e04c3fSmrg ctx); 239701e04c3fSmrg } 239801e04c3fSmrg } else if (subexpressions[0]->oper == ast_field_selection) { 239901e04c3fSmrg return handle_method(instructions, state); 240001e04c3fSmrg } else { 240101e04c3fSmrg const ast_expression *id = subexpressions[0]; 240201e04c3fSmrg const char *func_name = NULL; 240301e04c3fSmrg YYLTYPE loc = get_location(); 240401e04c3fSmrg exec_list actual_parameters; 240501e04c3fSmrg ir_variable *sub_var = NULL; 240601e04c3fSmrg ir_rvalue *array_idx = NULL; 240701e04c3fSmrg 240801e04c3fSmrg process_parameters(instructions, &actual_parameters, &this->expressions, 240901e04c3fSmrg state); 241001e04c3fSmrg 241101e04c3fSmrg if (id->oper == ast_array_index) { 241201e04c3fSmrg array_idx = generate_array_index(ctx, instructions, state, loc, 241301e04c3fSmrg id->subexpressions[0], 241401e04c3fSmrg id->subexpressions[1], &func_name, 241501e04c3fSmrg &actual_parameters); 241601e04c3fSmrg } else if (id->oper == ast_identifier) { 241701e04c3fSmrg func_name = id->primary_expression.identifier; 241801e04c3fSmrg } else { 241901e04c3fSmrg _mesa_glsl_error(&loc, state, "function name is not an identifier"); 242001e04c3fSmrg } 242101e04c3fSmrg 242201e04c3fSmrg /* an error was emitted earlier */ 242301e04c3fSmrg if (!func_name) 242401e04c3fSmrg return ir_rvalue::error_value(ctx); 242501e04c3fSmrg 242601e04c3fSmrg ir_function_signature *sig = 242701e04c3fSmrg match_function_by_name(func_name, &actual_parameters, state); 242801e04c3fSmrg 242901e04c3fSmrg ir_rvalue *value = NULL; 243001e04c3fSmrg if (sig == NULL) { 243101e04c3fSmrg sig = match_subroutine_by_name(func_name, &actual_parameters, 243201e04c3fSmrg state, &sub_var); 243301e04c3fSmrg } 243401e04c3fSmrg 243501e04c3fSmrg if (sig == NULL) { 243601e04c3fSmrg no_matching_function_error(func_name, &loc, 243701e04c3fSmrg &actual_parameters, state); 243801e04c3fSmrg value = ir_rvalue::error_value(ctx); 243901e04c3fSmrg } else if (!verify_parameter_modes(state, sig, 244001e04c3fSmrg actual_parameters, 244101e04c3fSmrg this->expressions)) { 244201e04c3fSmrg /* an error has already been emitted */ 244301e04c3fSmrg value = ir_rvalue::error_value(ctx); 244401e04c3fSmrg } else if (sig->is_builtin() && strcmp(func_name, "ftransform") == 0) { 244501e04c3fSmrg /* ftransform refers to global variables, and we don't have any code 244601e04c3fSmrg * for remapping the variable references in the built-in shader. 244701e04c3fSmrg */ 244801e04c3fSmrg ir_variable *mvp = 244901e04c3fSmrg state->symbols->get_variable("gl_ModelViewProjectionMatrix"); 245001e04c3fSmrg ir_variable *vtx = state->symbols->get_variable("gl_Vertex"); 245101e04c3fSmrg value = new(ctx) ir_expression(ir_binop_mul, glsl_type::vec4_type, 245201e04c3fSmrg new(ctx) ir_dereference_variable(mvp), 245301e04c3fSmrg new(ctx) ir_dereference_variable(vtx)); 245401e04c3fSmrg } else { 24557ec681f3Smrg bool is_begin_interlock = false; 24567ec681f3Smrg bool is_end_interlock = false; 24577ec681f3Smrg if (sig->is_builtin() && 24587ec681f3Smrg state->stage == MESA_SHADER_FRAGMENT && 24597ec681f3Smrg state->ARB_fragment_shader_interlock_enable) { 24607ec681f3Smrg is_begin_interlock = strcmp(func_name, "beginInvocationInterlockARB") == 0; 24617ec681f3Smrg is_end_interlock = strcmp(func_name, "endInvocationInterlockARB") == 0; 24627ec681f3Smrg } 24637ec681f3Smrg 24647ec681f3Smrg if (sig->is_builtin() && 24657ec681f3Smrg ((state->stage == MESA_SHADER_TESS_CTRL && 24667ec681f3Smrg strcmp(func_name, "barrier") == 0) || 24677ec681f3Smrg is_begin_interlock || is_end_interlock)) { 246801e04c3fSmrg if (state->current_function == NULL || 246901e04c3fSmrg strcmp(state->current_function->function_name(), "main") != 0) { 247001e04c3fSmrg _mesa_glsl_error(&loc, state, 24717ec681f3Smrg "%s() may only be used in main()", func_name); 247201e04c3fSmrg } 247301e04c3fSmrg 247401e04c3fSmrg if (state->found_return) { 247501e04c3fSmrg _mesa_glsl_error(&loc, state, 24767ec681f3Smrg "%s() may not be used after return", func_name); 247701e04c3fSmrg } 247801e04c3fSmrg 247901e04c3fSmrg if (instructions != &state->current_function->body) { 248001e04c3fSmrg _mesa_glsl_error(&loc, state, 24817ec681f3Smrg "%s() may not be used in control flow", func_name); 248201e04c3fSmrg } 248301e04c3fSmrg } 248401e04c3fSmrg 24857ec681f3Smrg /* There can be only one begin/end interlock pair in the function. */ 24867ec681f3Smrg if (is_begin_interlock) { 24877ec681f3Smrg if (state->found_begin_interlock) 24887ec681f3Smrg _mesa_glsl_error(&loc, state, 24897ec681f3Smrg "beginInvocationInterlockARB may not be used twice"); 24907ec681f3Smrg state->found_begin_interlock = true; 24917ec681f3Smrg } else if (is_end_interlock) { 24927ec681f3Smrg if (!state->found_begin_interlock) 24937ec681f3Smrg _mesa_glsl_error(&loc, state, 24947ec681f3Smrg "endInvocationInterlockARB may not be used " 24957ec681f3Smrg "before beginInvocationInterlockARB"); 24967ec681f3Smrg if (state->found_end_interlock) 24977ec681f3Smrg _mesa_glsl_error(&loc, state, 24987ec681f3Smrg "endInvocationInterlockARB may not be used twice"); 24997ec681f3Smrg state->found_end_interlock = true; 25007ec681f3Smrg } 25017ec681f3Smrg 250201e04c3fSmrg value = generate_call(instructions, sig, &actual_parameters, sub_var, 250301e04c3fSmrg array_idx, state); 250401e04c3fSmrg if (!value) { 250501e04c3fSmrg ir_variable *const tmp = new(ctx) ir_variable(glsl_type::void_type, 250601e04c3fSmrg "void_var", 250701e04c3fSmrg ir_var_temporary); 250801e04c3fSmrg instructions->push_tail(tmp); 250901e04c3fSmrg value = new(ctx) ir_dereference_variable(tmp); 251001e04c3fSmrg } 251101e04c3fSmrg } 251201e04c3fSmrg 251301e04c3fSmrg return value; 251401e04c3fSmrg } 251501e04c3fSmrg 251601e04c3fSmrg unreachable("not reached"); 251701e04c3fSmrg} 251801e04c3fSmrg 251901e04c3fSmrgbool 252001e04c3fSmrgast_function_expression::has_sequence_subexpression() const 252101e04c3fSmrg{ 252201e04c3fSmrg foreach_list_typed(const ast_node, ast, link, &this->expressions) { 252301e04c3fSmrg if (ast->has_sequence_subexpression()) 252401e04c3fSmrg return true; 252501e04c3fSmrg } 252601e04c3fSmrg 252701e04c3fSmrg return false; 252801e04c3fSmrg} 252901e04c3fSmrg 253001e04c3fSmrgir_rvalue * 253101e04c3fSmrgast_aggregate_initializer::hir(exec_list *instructions, 253201e04c3fSmrg struct _mesa_glsl_parse_state *state) 253301e04c3fSmrg{ 253401e04c3fSmrg void *ctx = state; 253501e04c3fSmrg YYLTYPE loc = this->get_location(); 253601e04c3fSmrg 253701e04c3fSmrg if (!this->constructor_type) { 253801e04c3fSmrg _mesa_glsl_error(&loc, state, "type of C-style initializer unknown"); 253901e04c3fSmrg return ir_rvalue::error_value(ctx); 254001e04c3fSmrg } 254101e04c3fSmrg const glsl_type *const constructor_type = this->constructor_type; 254201e04c3fSmrg 254301e04c3fSmrg if (!state->has_420pack()) { 254401e04c3fSmrg _mesa_glsl_error(&loc, state, "C-style initialization requires the " 254501e04c3fSmrg "GL_ARB_shading_language_420pack extension"); 254601e04c3fSmrg return ir_rvalue::error_value(ctx); 254701e04c3fSmrg } 254801e04c3fSmrg 254901e04c3fSmrg if (constructor_type->is_array()) { 255001e04c3fSmrg return process_array_constructor(instructions, constructor_type, &loc, 255101e04c3fSmrg &this->expressions, state); 255201e04c3fSmrg } 255301e04c3fSmrg 2554ed98bd31Smaya if (constructor_type->is_struct()) { 255501e04c3fSmrg return process_record_constructor(instructions, constructor_type, &loc, 255601e04c3fSmrg &this->expressions, state); 255701e04c3fSmrg } 255801e04c3fSmrg 255901e04c3fSmrg return process_vec_mat_constructor(instructions, constructor_type, &loc, 256001e04c3fSmrg &this->expressions, state); 256101e04c3fSmrg} 2562