1627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca/************************************************************************** 2627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca * 3627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca * Copyright 2009 VMware, Inc. 4627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca * All Rights Reserved. 5627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca * 6627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca * Permission is hereby granted, free of charge, to any person obtaining a 7627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca * copy of this software and associated documentation files (the 8627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca * "Software"), to deal in the Software without restriction, including 9627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca * without limitation the rights to use, copy, modify, merge, publish, 10627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca * distribute, sub license, and/or sell copies of the Software, and to 11627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca * permit persons to whom the Software is furnished to do so, subject to 12627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca * the following conditions: 13627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca * 14627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca * The above copyright notice and this permission notice (including the 15627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca * next paragraph) shall be included in all copies or substantial portions 16627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca * of the Software. 17627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca * 18627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca * 26627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca **************************************************************************/ 27627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca 28627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca 29627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca/** 30627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca * @file 315811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * Helpers for emiting intrinsic calls. 325811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * 335811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * LLVM vanilla IR doesn't represent all basic arithmetic operations we care 345811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * about, and it is often necessary to resort target-specific intrinsics for 355811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * performance, convenience. 365811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * 375811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * Ideally we would like to stay away from target specific intrinsics and 385811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * move all the instruction selection logic into upstream LLVM where it belongs. 395811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * 405811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * These functions are also used for calling C functions provided by us from 415811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * generated LLVM code. 42627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca * 43627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca * @author Jose Fonseca <jfonseca@vmware.com> 44627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca */ 45627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca 46627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca 47627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca#include "util/u_debug.h" 48627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca 49efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul#include "lp_bld_const.h" 50627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca#include "lp_bld_intr.h" 513469715a8a171512cf9b528702e70393f01c6041José Fonseca#include "lp_bld_type.h" 523469715a8a171512cf9b528702e70393f01c6041José Fonseca#include "lp_bld_pack.h" 53627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca 54627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca 55627d6a6b044b3916996cb9f50ce7f911f2196565José FonsecaLLVMValueRef 5603180dca7a3b5d57100158eb06d00419e55d9dc8José Fonsecalp_declare_intrinsic(LLVMModuleRef module, 5703180dca7a3b5d57100158eb06d00419e55d9dc8José Fonseca const char *name, 5803180dca7a3b5d57100158eb06d00419e55d9dc8José Fonseca LLVMTypeRef ret_type, 5903180dca7a3b5d57100158eb06d00419e55d9dc8José Fonseca LLVMTypeRef *arg_types, 6003180dca7a3b5d57100158eb06d00419e55d9dc8José Fonseca unsigned num_args) 6103180dca7a3b5d57100158eb06d00419e55d9dc8José Fonseca{ 6203180dca7a3b5d57100158eb06d00419e55d9dc8José Fonseca LLVMTypeRef function_type; 6303180dca7a3b5d57100158eb06d00419e55d9dc8José Fonseca LLVMValueRef function; 6403180dca7a3b5d57100158eb06d00419e55d9dc8José Fonseca 6503180dca7a3b5d57100158eb06d00419e55d9dc8José Fonseca assert(!LLVMGetNamedFunction(module, name)); 6603180dca7a3b5d57100158eb06d00419e55d9dc8José Fonseca 6703180dca7a3b5d57100158eb06d00419e55d9dc8José Fonseca function_type = LLVMFunctionType(ret_type, arg_types, num_args, 0); 6803180dca7a3b5d57100158eb06d00419e55d9dc8José Fonseca function = LLVMAddFunction(module, name, function_type); 6903180dca7a3b5d57100158eb06d00419e55d9dc8José Fonseca 7003180dca7a3b5d57100158eb06d00419e55d9dc8José Fonseca LLVMSetFunctionCallConv(function, LLVMCCallConv); 7103180dca7a3b5d57100158eb06d00419e55d9dc8José Fonseca LLVMSetLinkage(function, LLVMExternalLinkage); 7203180dca7a3b5d57100158eb06d00419e55d9dc8José Fonseca 7303180dca7a3b5d57100158eb06d00419e55d9dc8José Fonseca assert(LLVMIsDeclaration(function)); 7403180dca7a3b5d57100158eb06d00419e55d9dc8José Fonseca 7503180dca7a3b5d57100158eb06d00419e55d9dc8José Fonseca return function; 7603180dca7a3b5d57100158eb06d00419e55d9dc8José Fonseca} 7703180dca7a3b5d57100158eb06d00419e55d9dc8José Fonseca 7803180dca7a3b5d57100158eb06d00419e55d9dc8José Fonseca 7903180dca7a3b5d57100158eb06d00419e55d9dc8José FonsecaLLVMValueRef 8036249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonsecalp_build_intrinsic(LLVMBuilderRef builder, 8136249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca const char *name, 8236249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca LLVMTypeRef ret_type, 8336249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca LLVMValueRef *args, 8436249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca unsigned num_args) 85627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca{ 86627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca LLVMModuleRef module = LLVMGetGlobalParent(LLVMGetBasicBlockParent(LLVMGetInsertBlock(builder))); 87627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca LLVMValueRef function; 8836249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca 89627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca function = LLVMGetNamedFunction(module, name); 90627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca if(!function) { 9136249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca LLVMTypeRef arg_types[LP_MAX_FUNC_ARGS]; 9236249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca unsigned i; 9303180dca7a3b5d57100158eb06d00419e55d9dc8José Fonseca 9403180dca7a3b5d57100158eb06d00419e55d9dc8José Fonseca assert(num_args <= LP_MAX_FUNC_ARGS); 9503180dca7a3b5d57100158eb06d00419e55d9dc8José Fonseca 9636249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca for(i = 0; i < num_args; ++i) { 9736249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca assert(args[i]); 9836249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca arg_types[i] = LLVMTypeOf(args[i]); 9936249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca } 100627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca 10103180dca7a3b5d57100158eb06d00419e55d9dc8José Fonseca function = lp_declare_intrinsic(module, name, ret_type, arg_types, num_args); 10203180dca7a3b5d57100158eb06d00419e55d9dc8José Fonseca } 10358f20b2b65ec0237202dad2be5db6b29d3cf6e93José Fonseca 10436249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca return LLVMBuildCall(builder, function, args, num_args, ""); 10536249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca} 10636249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca 10736249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca 10836249348ed6dfae63ef2b81e6db88c975a801f2aJosé FonsecaLLVMValueRef 10936249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonsecalp_build_intrinsic_unary(LLVMBuilderRef builder, 11036249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca const char *name, 11136249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca LLVMTypeRef ret_type, 11236249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca LLVMValueRef a) 11336249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca{ 11436249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca return lp_build_intrinsic(builder, name, ret_type, &a, 1); 11536249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca} 11636249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca 11736249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca 11836249348ed6dfae63ef2b81e6db88c975a801f2aJosé FonsecaLLVMValueRef 11936249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonsecalp_build_intrinsic_binary(LLVMBuilderRef builder, 12036249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca const char *name, 12136249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca LLVMTypeRef ret_type, 12236249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca LLVMValueRef a, 12336249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca LLVMValueRef b) 12436249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca{ 12536249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca LLVMValueRef args[2]; 126627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca 127627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca args[0] = a; 128627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca args[1] = b; 129627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca 13036249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca return lp_build_intrinsic(builder, name, ret_type, args, 2); 131627d6a6b044b3916996cb9f50ce7f911f2196565José Fonseca} 13236249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca 13336249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca 1343469715a8a171512cf9b528702e70393f01c6041José Fonseca/** 1353469715a8a171512cf9b528702e70393f01c6041José Fonseca * Call intrinsic with arguments adapted to intrinsic vector length. 1363469715a8a171512cf9b528702e70393f01c6041José Fonseca * 1373469715a8a171512cf9b528702e70393f01c6041José Fonseca * Split vectors which are too large for the hw, or expand them if they 1383469715a8a171512cf9b528702e70393f01c6041José Fonseca * are too small, so a caller calling a function which might use intrinsics 1393469715a8a171512cf9b528702e70393f01c6041José Fonseca * doesn't need to do splitting/expansion on its own. 1403469715a8a171512cf9b528702e70393f01c6041José Fonseca * This only supports intrinsics where src and dst types match. 1413469715a8a171512cf9b528702e70393f01c6041José Fonseca */ 1423469715a8a171512cf9b528702e70393f01c6041José FonsecaLLVMValueRef 1433469715a8a171512cf9b528702e70393f01c6041José Fonsecalp_build_intrinsic_binary_anylength(struct gallivm_state *gallivm, 1443469715a8a171512cf9b528702e70393f01c6041José Fonseca const char *name, 1453469715a8a171512cf9b528702e70393f01c6041José Fonseca struct lp_type src_type, 1463469715a8a171512cf9b528702e70393f01c6041José Fonseca unsigned intr_size, 1473469715a8a171512cf9b528702e70393f01c6041José Fonseca LLVMValueRef a, 1483469715a8a171512cf9b528702e70393f01c6041José Fonseca LLVMValueRef b) 1493469715a8a171512cf9b528702e70393f01c6041José Fonseca{ 1503469715a8a171512cf9b528702e70393f01c6041José Fonseca unsigned i; 1513469715a8a171512cf9b528702e70393f01c6041José Fonseca struct lp_type intrin_type = src_type; 1523469715a8a171512cf9b528702e70393f01c6041José Fonseca LLVMBuilderRef builder = gallivm->builder; 1533469715a8a171512cf9b528702e70393f01c6041José Fonseca LLVMValueRef i32undef = LLVMGetUndef(LLVMInt32TypeInContext(gallivm->context)); 1543469715a8a171512cf9b528702e70393f01c6041José Fonseca LLVMValueRef anative, bnative; 1553469715a8a171512cf9b528702e70393f01c6041José Fonseca unsigned intrin_length = intr_size / src_type.width; 1563469715a8a171512cf9b528702e70393f01c6041José Fonseca 1573469715a8a171512cf9b528702e70393f01c6041José Fonseca intrin_type.length = intrin_length; 1583469715a8a171512cf9b528702e70393f01c6041José Fonseca 1593469715a8a171512cf9b528702e70393f01c6041José Fonseca if (intrin_length > src_type.length) { 1603469715a8a171512cf9b528702e70393f01c6041José Fonseca LLVMValueRef elems[LP_MAX_VECTOR_LENGTH]; 1613469715a8a171512cf9b528702e70393f01c6041José Fonseca LLVMValueRef constvec, tmp; 1623469715a8a171512cf9b528702e70393f01c6041José Fonseca 1633469715a8a171512cf9b528702e70393f01c6041José Fonseca for (i = 0; i < src_type.length; i++) { 1643469715a8a171512cf9b528702e70393f01c6041José Fonseca elems[i] = lp_build_const_int32(gallivm, i); 1653469715a8a171512cf9b528702e70393f01c6041José Fonseca } 1663469715a8a171512cf9b528702e70393f01c6041José Fonseca for (; i < intrin_length; i++) { 1673469715a8a171512cf9b528702e70393f01c6041José Fonseca elems[i] = i32undef; 1683469715a8a171512cf9b528702e70393f01c6041José Fonseca } 1693469715a8a171512cf9b528702e70393f01c6041José Fonseca if (src_type.length == 1) { 1703469715a8a171512cf9b528702e70393f01c6041José Fonseca LLVMTypeRef elem_type = lp_build_elem_type(gallivm, intrin_type); 1713469715a8a171512cf9b528702e70393f01c6041José Fonseca a = LLVMBuildBitCast(builder, a, LLVMVectorType(elem_type, 1), ""); 1723469715a8a171512cf9b528702e70393f01c6041José Fonseca b = LLVMBuildBitCast(builder, b, LLVMVectorType(elem_type, 1), ""); 1733469715a8a171512cf9b528702e70393f01c6041José Fonseca } 1743469715a8a171512cf9b528702e70393f01c6041José Fonseca constvec = LLVMConstVector(elems, intrin_length); 1753469715a8a171512cf9b528702e70393f01c6041José Fonseca anative = LLVMBuildShuffleVector(builder, a, a, constvec, ""); 1763469715a8a171512cf9b528702e70393f01c6041José Fonseca bnative = LLVMBuildShuffleVector(builder, b, b, constvec, ""); 1773469715a8a171512cf9b528702e70393f01c6041José Fonseca tmp = lp_build_intrinsic_binary(builder, name, 1783469715a8a171512cf9b528702e70393f01c6041José Fonseca lp_build_vec_type(gallivm, intrin_type), 1793469715a8a171512cf9b528702e70393f01c6041José Fonseca anative, bnative); 1803469715a8a171512cf9b528702e70393f01c6041José Fonseca if (src_type.length > 1) { 1813469715a8a171512cf9b528702e70393f01c6041José Fonseca constvec = LLVMConstVector(elems, src_type.length); 1823469715a8a171512cf9b528702e70393f01c6041José Fonseca return LLVMBuildShuffleVector(builder, tmp, tmp, constvec, ""); 1833469715a8a171512cf9b528702e70393f01c6041José Fonseca } 1843469715a8a171512cf9b528702e70393f01c6041José Fonseca else { 1853469715a8a171512cf9b528702e70393f01c6041José Fonseca return LLVMBuildExtractElement(builder, tmp, elems[0], ""); 1863469715a8a171512cf9b528702e70393f01c6041José Fonseca } 1873469715a8a171512cf9b528702e70393f01c6041José Fonseca } 1883469715a8a171512cf9b528702e70393f01c6041José Fonseca else if (intrin_length < src_type.length) { 1893469715a8a171512cf9b528702e70393f01c6041José Fonseca unsigned num_vec = src_type.length / intrin_length; 1903469715a8a171512cf9b528702e70393f01c6041José Fonseca LLVMValueRef tmp[LP_MAX_VECTOR_LENGTH]; 1913469715a8a171512cf9b528702e70393f01c6041José Fonseca 1923469715a8a171512cf9b528702e70393f01c6041José Fonseca /* don't support arbitrary size here as this is so yuck */ 1933469715a8a171512cf9b528702e70393f01c6041José Fonseca if (src_type.length % intrin_length) { 1943469715a8a171512cf9b528702e70393f01c6041José Fonseca /* FIXME: This is something which should be supported 1953469715a8a171512cf9b528702e70393f01c6041José Fonseca * but there doesn't seem to be any need for it currently 1963469715a8a171512cf9b528702e70393f01c6041José Fonseca * so crash and burn. 1973469715a8a171512cf9b528702e70393f01c6041José Fonseca */ 1983469715a8a171512cf9b528702e70393f01c6041José Fonseca debug_printf("%s: should handle arbitrary vector size\n", 1993469715a8a171512cf9b528702e70393f01c6041José Fonseca __FUNCTION__); 2003469715a8a171512cf9b528702e70393f01c6041José Fonseca assert(0); 2013469715a8a171512cf9b528702e70393f01c6041José Fonseca return NULL; 2023469715a8a171512cf9b528702e70393f01c6041José Fonseca } 2033469715a8a171512cf9b528702e70393f01c6041José Fonseca 2043469715a8a171512cf9b528702e70393f01c6041José Fonseca for (i = 0; i < num_vec; i++) { 2053469715a8a171512cf9b528702e70393f01c6041José Fonseca anative = lp_build_extract_range(gallivm, a, i*intrin_length, 2063469715a8a171512cf9b528702e70393f01c6041José Fonseca intrin_length); 2073469715a8a171512cf9b528702e70393f01c6041José Fonseca bnative = lp_build_extract_range(gallivm, b, i*intrin_length, 2083469715a8a171512cf9b528702e70393f01c6041José Fonseca intrin_length); 2093469715a8a171512cf9b528702e70393f01c6041José Fonseca tmp[i] = lp_build_intrinsic_binary(builder, name, 2103469715a8a171512cf9b528702e70393f01c6041José Fonseca lp_build_vec_type(gallivm, intrin_type), 2113469715a8a171512cf9b528702e70393f01c6041José Fonseca anative, bnative); 2123469715a8a171512cf9b528702e70393f01c6041José Fonseca } 2133469715a8a171512cf9b528702e70393f01c6041José Fonseca return lp_build_concat(gallivm, tmp, intrin_type, num_vec); 2143469715a8a171512cf9b528702e70393f01c6041José Fonseca } 2153469715a8a171512cf9b528702e70393f01c6041José Fonseca else { 2163469715a8a171512cf9b528702e70393f01c6041José Fonseca return lp_build_intrinsic_binary(builder, name, 2173469715a8a171512cf9b528702e70393f01c6041José Fonseca lp_build_vec_type(gallivm, src_type), 2183469715a8a171512cf9b528702e70393f01c6041José Fonseca a, b); 2193469715a8a171512cf9b528702e70393f01c6041José Fonseca } 2203469715a8a171512cf9b528702e70393f01c6041José Fonseca} 2213469715a8a171512cf9b528702e70393f01c6041José Fonseca 2223469715a8a171512cf9b528702e70393f01c6041José Fonseca 22336249348ed6dfae63ef2b81e6db88c975a801f2aJosé FonsecaLLVMValueRef 224efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paullp_build_intrinsic_map(struct gallivm_state *gallivm, 22536249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca const char *name, 22636249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca LLVMTypeRef ret_type, 22736249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca LLVMValueRef *args, 22836249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca unsigned num_args) 22936249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca{ 230efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul LLVMBuilderRef builder = gallivm->builder; 23136249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca LLVMTypeRef ret_elem_type = LLVMGetElementType(ret_type); 23236249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca unsigned n = LLVMGetVectorSize(ret_type); 23336249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca unsigned i, j; 23436249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca LLVMValueRef res; 23536249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca 23636249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca assert(num_args <= LP_MAX_FUNC_ARGS); 23736249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca 23836249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca res = LLVMGetUndef(ret_type); 23936249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca for(i = 0; i < n; ++i) { 240efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul LLVMValueRef index = lp_build_const_int32(gallivm, i); 24136249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca LLVMValueRef arg_elems[LP_MAX_FUNC_ARGS]; 24236249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca LLVMValueRef res_elem; 24336249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca for(j = 0; j < num_args; ++j) 24436249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca arg_elems[j] = LLVMBuildExtractElement(builder, args[j], index, ""); 24536249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca res_elem = lp_build_intrinsic(builder, name, ret_elem_type, arg_elems, num_args); 24636249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca res = LLVMBuildInsertElement(builder, res, res_elem, index, ""); 24736249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca } 24836249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca 24936249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca return res; 25036249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca} 25136249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca 25236249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca 25336249348ed6dfae63ef2b81e6db88c975a801f2aJosé FonsecaLLVMValueRef 254efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paullp_build_intrinsic_map_unary(struct gallivm_state *gallivm, 25536249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca const char *name, 25636249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca LLVMTypeRef ret_type, 25736249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca LLVMValueRef a) 25836249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca{ 259efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul return lp_build_intrinsic_map(gallivm, name, ret_type, &a, 1); 26036249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca} 26136249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca 26236249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca 26336249348ed6dfae63ef2b81e6db88c975a801f2aJosé FonsecaLLVMValueRef 264efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paullp_build_intrinsic_map_binary(struct gallivm_state *gallivm, 26536249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca const char *name, 26636249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca LLVMTypeRef ret_type, 26736249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca LLVMValueRef a, 26836249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca LLVMValueRef b) 26936249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca{ 27036249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca LLVMValueRef args[2]; 27136249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca 27236249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca args[0] = a; 27336249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca args[1] = b; 27436249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca 275efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul return lp_build_intrinsic_map(gallivm, name, ret_type, args, 2); 27636249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca} 27736249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca 27836249348ed6dfae63ef2b81e6db88c975a801f2aJosé Fonseca 279