164611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca/************************************************************************** 264611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca * 364611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca * Copyright 2009 VMware, Inc. 464611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca * All Rights Reserved. 564611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca * 664611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca * Permission is hereby granted, free of charge, to any person obtaining a 764611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca * copy of this software and associated documentation files (the 864611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca * "Software"), to deal in the Software without restriction, including 964611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca * without limitation the rights to use, copy, modify, merge, publish, 1064611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca * distribute, sub license, and/or sell copies of the Software, and to 1164611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca * permit persons to whom the Software is furnished to do so, subject to 1264611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca * the following conditions: 1364611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca * 1464611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca * The above copyright notice and this permission notice (including the 1564611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca * next paragraph) shall be included in all copies or substantial portions 1664611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca * of the Software. 1764611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca * 1864611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 1964611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 2064611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 2164611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 2264611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 2364611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 2464611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2564611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca * 2664611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca **************************************************************************/ 2764611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca 2864611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca 2964611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca/** 3064611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca * @file 3164611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca * Helper functions for constant building. 3264611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca * 3364611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca * @author Jose Fonseca <jfonseca@vmware.com> 3464611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca */ 3564611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca 3633ce51bc0d52dcfbfa481211dd1fe73a5ecb948fJosé Fonseca#include <float.h> 3764611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca 3864611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca#include "util/u_debug.h" 39c95cea50a9e14255a60c37b156271b7ab50515e9José Fonseca#include "util/u_math.h" 403469715a8a171512cf9b528702e70393f01c6041José Fonseca#include "util/u_half.h" 4164611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca 4264611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca#include "lp_bld_type.h" 4364611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca#include "lp_bld_const.h" 44efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul#include "lp_bld_init.h" 4564611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca 4664611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca 4764cc71167f986f6cd29abb228295cf6441b07832José Fonsecaunsigned 48b4835ea03d64261da5a892f9590c9977b06920e8José Fonsecalp_mantissa(struct lp_type type) 4964cc71167f986f6cd29abb228295cf6441b07832José Fonseca{ 5064cc71167f986f6cd29abb228295cf6441b07832José Fonseca assert(type.floating); 5164cc71167f986f6cd29abb228295cf6441b07832José Fonseca 5264cc71167f986f6cd29abb228295cf6441b07832José Fonseca if(type.floating) { 5364cc71167f986f6cd29abb228295cf6441b07832José Fonseca switch(type.width) { 543469715a8a171512cf9b528702e70393f01c6041José Fonseca case 16: 553469715a8a171512cf9b528702e70393f01c6041José Fonseca return 10; 5664cc71167f986f6cd29abb228295cf6441b07832José Fonseca case 32: 5764cc71167f986f6cd29abb228295cf6441b07832José Fonseca return 23; 5864cc71167f986f6cd29abb228295cf6441b07832José Fonseca case 64: 593469715a8a171512cf9b528702e70393f01c6041José Fonseca return 52; 6064cc71167f986f6cd29abb228295cf6441b07832José Fonseca default: 6164cc71167f986f6cd29abb228295cf6441b07832José Fonseca assert(0); 6264cc71167f986f6cd29abb228295cf6441b07832José Fonseca return 0; 6364cc71167f986f6cd29abb228295cf6441b07832José Fonseca } 6464cc71167f986f6cd29abb228295cf6441b07832José Fonseca } 6564cc71167f986f6cd29abb228295cf6441b07832José Fonseca else { 6664cc71167f986f6cd29abb228295cf6441b07832José Fonseca if(type.sign) 6764cc71167f986f6cd29abb228295cf6441b07832José Fonseca return type.width - 1; 6864cc71167f986f6cd29abb228295cf6441b07832José Fonseca else 6964cc71167f986f6cd29abb228295cf6441b07832José Fonseca return type.width; 7064cc71167f986f6cd29abb228295cf6441b07832José Fonseca } 7164cc71167f986f6cd29abb228295cf6441b07832José Fonseca} 7264cc71167f986f6cd29abb228295cf6441b07832José Fonseca 7364cc71167f986f6cd29abb228295cf6441b07832José Fonseca 74138428badea350a20f5afc652a4fa1850e1ec653José Fonseca/** 75138428badea350a20f5afc652a4fa1850e1ec653José Fonseca * Shift of the unity. 76138428badea350a20f5afc652a4fa1850e1ec653José Fonseca * 77138428badea350a20f5afc652a4fa1850e1ec653José Fonseca * Same as lp_const_scale(), but in terms of shifts. 78138428badea350a20f5afc652a4fa1850e1ec653José Fonseca */ 79138428badea350a20f5afc652a4fa1850e1ec653José Fonsecaunsigned 80b4835ea03d64261da5a892f9590c9977b06920e8José Fonsecalp_const_shift(struct lp_type type) 81138428badea350a20f5afc652a4fa1850e1ec653José Fonseca{ 82d52dce0ffbb165146d7b6812ff5152cbeff29a3aJosé Fonseca if(type.floating) 83d52dce0ffbb165146d7b6812ff5152cbeff29a3aJosé Fonseca return 0; 84d52dce0ffbb165146d7b6812ff5152cbeff29a3aJosé Fonseca else if(type.fixed) 85138428badea350a20f5afc652a4fa1850e1ec653José Fonseca return type.width/2; 86138428badea350a20f5afc652a4fa1850e1ec653José Fonseca else if(type.norm) 87138428badea350a20f5afc652a4fa1850e1ec653José Fonseca return type.sign ? type.width - 1 : type.width; 88138428badea350a20f5afc652a4fa1850e1ec653José Fonseca else 89138428badea350a20f5afc652a4fa1850e1ec653José Fonseca return 0; 90138428badea350a20f5afc652a4fa1850e1ec653José Fonseca} 91138428badea350a20f5afc652a4fa1850e1ec653José Fonseca 92138428badea350a20f5afc652a4fa1850e1ec653José Fonseca 93b441a0b658ac00a38bb41eec8b6f0e22cc3de018José Fonsecaunsigned 94b4835ea03d64261da5a892f9590c9977b06920e8José Fonsecalp_const_offset(struct lp_type type) 95138428badea350a20f5afc652a4fa1850e1ec653José Fonseca{ 96138428badea350a20f5afc652a4fa1850e1ec653José Fonseca if(type.floating || type.fixed) 97138428badea350a20f5afc652a4fa1850e1ec653José Fonseca return 0; 98138428badea350a20f5afc652a4fa1850e1ec653José Fonseca else if(type.norm) 99138428badea350a20f5afc652a4fa1850e1ec653José Fonseca return 1; 100138428badea350a20f5afc652a4fa1850e1ec653José Fonseca else 101138428badea350a20f5afc652a4fa1850e1ec653José Fonseca return 0; 102138428badea350a20f5afc652a4fa1850e1ec653José Fonseca} 103138428badea350a20f5afc652a4fa1850e1ec653José Fonseca 104138428badea350a20f5afc652a4fa1850e1ec653José Fonseca 105138428badea350a20f5afc652a4fa1850e1ec653José Fonseca/** 106138428badea350a20f5afc652a4fa1850e1ec653José Fonseca * Scaling factor between the LLVM native value and its interpretation. 107138428badea350a20f5afc652a4fa1850e1ec653José Fonseca * 108138428badea350a20f5afc652a4fa1850e1ec653José Fonseca * This is 1.0 for all floating types and unnormalized integers, and something 109138428badea350a20f5afc652a4fa1850e1ec653José Fonseca * else for the fixed points types and normalized integers. 110138428badea350a20f5afc652a4fa1850e1ec653José Fonseca */ 111138428badea350a20f5afc652a4fa1850e1ec653José Fonsecadouble 112b4835ea03d64261da5a892f9590c9977b06920e8José Fonsecalp_const_scale(struct lp_type type) 113138428badea350a20f5afc652a4fa1850e1ec653José Fonseca{ 114138428badea350a20f5afc652a4fa1850e1ec653José Fonseca unsigned long long llscale; 115138428badea350a20f5afc652a4fa1850e1ec653José Fonseca double dscale; 116138428badea350a20f5afc652a4fa1850e1ec653José Fonseca 117138428badea350a20f5afc652a4fa1850e1ec653José Fonseca llscale = (unsigned long long)1 << lp_const_shift(type); 118138428badea350a20f5afc652a4fa1850e1ec653José Fonseca llscale -= lp_const_offset(type); 119138428badea350a20f5afc652a4fa1850e1ec653José Fonseca dscale = (double)llscale; 120138428badea350a20f5afc652a4fa1850e1ec653José Fonseca assert((unsigned long long)dscale == llscale); 121138428badea350a20f5afc652a4fa1850e1ec653José Fonseca 122138428badea350a20f5afc652a4fa1850e1ec653José Fonseca return dscale; 123138428badea350a20f5afc652a4fa1850e1ec653José Fonseca} 124138428badea350a20f5afc652a4fa1850e1ec653José Fonseca 125138428badea350a20f5afc652a4fa1850e1ec653José Fonseca 12664cc71167f986f6cd29abb228295cf6441b07832José Fonseca/** 12764cc71167f986f6cd29abb228295cf6441b07832José Fonseca * Minimum value representable by the type. 12864cc71167f986f6cd29abb228295cf6441b07832José Fonseca */ 12964cc71167f986f6cd29abb228295cf6441b07832José Fonsecadouble 130b4835ea03d64261da5a892f9590c9977b06920e8José Fonsecalp_const_min(struct lp_type type) 13164cc71167f986f6cd29abb228295cf6441b07832José Fonseca{ 13264cc71167f986f6cd29abb228295cf6441b07832José Fonseca unsigned bits; 13364cc71167f986f6cd29abb228295cf6441b07832José Fonseca 13464cc71167f986f6cd29abb228295cf6441b07832José Fonseca if(!type.sign) 13564cc71167f986f6cd29abb228295cf6441b07832José Fonseca return 0.0; 13664cc71167f986f6cd29abb228295cf6441b07832José Fonseca 13764cc71167f986f6cd29abb228295cf6441b07832José Fonseca if(type.norm) 13864cc71167f986f6cd29abb228295cf6441b07832José Fonseca return -1.0; 13964cc71167f986f6cd29abb228295cf6441b07832José Fonseca 14064cc71167f986f6cd29abb228295cf6441b07832José Fonseca if (type.floating) { 14164cc71167f986f6cd29abb228295cf6441b07832José Fonseca switch(type.width) { 1423469715a8a171512cf9b528702e70393f01c6041José Fonseca case 16: 1433469715a8a171512cf9b528702e70393f01c6041José Fonseca return -65504; 14464cc71167f986f6cd29abb228295cf6441b07832José Fonseca case 32: 14564cc71167f986f6cd29abb228295cf6441b07832José Fonseca return -FLT_MAX; 14664cc71167f986f6cd29abb228295cf6441b07832José Fonseca case 64: 14764cc71167f986f6cd29abb228295cf6441b07832José Fonseca return -DBL_MAX; 14864cc71167f986f6cd29abb228295cf6441b07832José Fonseca default: 14964cc71167f986f6cd29abb228295cf6441b07832José Fonseca assert(0); 15064cc71167f986f6cd29abb228295cf6441b07832José Fonseca return 0.0; 15164cc71167f986f6cd29abb228295cf6441b07832José Fonseca } 15264cc71167f986f6cd29abb228295cf6441b07832José Fonseca } 15364cc71167f986f6cd29abb228295cf6441b07832José Fonseca 15464cc71167f986f6cd29abb228295cf6441b07832José Fonseca if(type.fixed) 15564cc71167f986f6cd29abb228295cf6441b07832José Fonseca /* FIXME: consider the fractional bits? */ 15664cc71167f986f6cd29abb228295cf6441b07832José Fonseca bits = type.width / 2 - 1; 15764cc71167f986f6cd29abb228295cf6441b07832José Fonseca else 15864cc71167f986f6cd29abb228295cf6441b07832José Fonseca bits = type.width - 1; 15964cc71167f986f6cd29abb228295cf6441b07832José Fonseca 16064cc71167f986f6cd29abb228295cf6441b07832José Fonseca return (double)-((long long)1 << bits); 16164cc71167f986f6cd29abb228295cf6441b07832José Fonseca} 16264cc71167f986f6cd29abb228295cf6441b07832José Fonseca 16364cc71167f986f6cd29abb228295cf6441b07832José Fonseca 16464cc71167f986f6cd29abb228295cf6441b07832José Fonseca/** 16564cc71167f986f6cd29abb228295cf6441b07832José Fonseca * Maximum value representable by the type. 16664cc71167f986f6cd29abb228295cf6441b07832José Fonseca */ 16764cc71167f986f6cd29abb228295cf6441b07832José Fonsecadouble 168b4835ea03d64261da5a892f9590c9977b06920e8José Fonsecalp_const_max(struct lp_type type) 16964cc71167f986f6cd29abb228295cf6441b07832José Fonseca{ 17064cc71167f986f6cd29abb228295cf6441b07832José Fonseca unsigned bits; 17164cc71167f986f6cd29abb228295cf6441b07832José Fonseca 17264cc71167f986f6cd29abb228295cf6441b07832José Fonseca if(type.norm) 17364cc71167f986f6cd29abb228295cf6441b07832José Fonseca return 1.0; 17464cc71167f986f6cd29abb228295cf6441b07832José Fonseca 17564cc71167f986f6cd29abb228295cf6441b07832José Fonseca if (type.floating) { 17664cc71167f986f6cd29abb228295cf6441b07832José Fonseca switch(type.width) { 1773469715a8a171512cf9b528702e70393f01c6041José Fonseca case 16: 1783469715a8a171512cf9b528702e70393f01c6041José Fonseca return 65504; 17964cc71167f986f6cd29abb228295cf6441b07832José Fonseca case 32: 18064cc71167f986f6cd29abb228295cf6441b07832José Fonseca return FLT_MAX; 18164cc71167f986f6cd29abb228295cf6441b07832José Fonseca case 64: 18264cc71167f986f6cd29abb228295cf6441b07832José Fonseca return DBL_MAX; 18364cc71167f986f6cd29abb228295cf6441b07832José Fonseca default: 18464cc71167f986f6cd29abb228295cf6441b07832José Fonseca assert(0); 18564cc71167f986f6cd29abb228295cf6441b07832José Fonseca return 0.0; 18664cc71167f986f6cd29abb228295cf6441b07832José Fonseca } 18764cc71167f986f6cd29abb228295cf6441b07832José Fonseca } 18864cc71167f986f6cd29abb228295cf6441b07832José Fonseca 18964cc71167f986f6cd29abb228295cf6441b07832José Fonseca if(type.fixed) 19064cc71167f986f6cd29abb228295cf6441b07832José Fonseca bits = type.width / 2; 19164cc71167f986f6cd29abb228295cf6441b07832José Fonseca else 19264cc71167f986f6cd29abb228295cf6441b07832José Fonseca bits = type.width; 19364cc71167f986f6cd29abb228295cf6441b07832José Fonseca 19464cc71167f986f6cd29abb228295cf6441b07832José Fonseca if(type.sign) 19564cc71167f986f6cd29abb228295cf6441b07832José Fonseca bits -= 1; 19664cc71167f986f6cd29abb228295cf6441b07832José Fonseca 19764cc71167f986f6cd29abb228295cf6441b07832José Fonseca return (double)(((unsigned long long)1 << bits) - 1); 19864cc71167f986f6cd29abb228295cf6441b07832José Fonseca} 19964cc71167f986f6cd29abb228295cf6441b07832José Fonseca 20064cc71167f986f6cd29abb228295cf6441b07832José Fonseca 20133ce51bc0d52dcfbfa481211dd1fe73a5ecb948fJosé Fonsecadouble 202b4835ea03d64261da5a892f9590c9977b06920e8José Fonsecalp_const_eps(struct lp_type type) 20333ce51bc0d52dcfbfa481211dd1fe73a5ecb948fJosé Fonseca{ 20433ce51bc0d52dcfbfa481211dd1fe73a5ecb948fJosé Fonseca if (type.floating) { 20533ce51bc0d52dcfbfa481211dd1fe73a5ecb948fJosé Fonseca switch(type.width) { 2063469715a8a171512cf9b528702e70393f01c6041José Fonseca case 16: 2073469715a8a171512cf9b528702e70393f01c6041José Fonseca return 2E-10; 20833ce51bc0d52dcfbfa481211dd1fe73a5ecb948fJosé Fonseca case 32: 20933ce51bc0d52dcfbfa481211dd1fe73a5ecb948fJosé Fonseca return FLT_EPSILON; 21033ce51bc0d52dcfbfa481211dd1fe73a5ecb948fJosé Fonseca case 64: 21133ce51bc0d52dcfbfa481211dd1fe73a5ecb948fJosé Fonseca return DBL_EPSILON; 21233ce51bc0d52dcfbfa481211dd1fe73a5ecb948fJosé Fonseca default: 21333ce51bc0d52dcfbfa481211dd1fe73a5ecb948fJosé Fonseca assert(0); 21433ce51bc0d52dcfbfa481211dd1fe73a5ecb948fJosé Fonseca return 0.0; 21533ce51bc0d52dcfbfa481211dd1fe73a5ecb948fJosé Fonseca } 21633ce51bc0d52dcfbfa481211dd1fe73a5ecb948fJosé Fonseca } 21733ce51bc0d52dcfbfa481211dd1fe73a5ecb948fJosé Fonseca else { 21833ce51bc0d52dcfbfa481211dd1fe73a5ecb948fJosé Fonseca double scale = lp_const_scale(type); 21933ce51bc0d52dcfbfa481211dd1fe73a5ecb948fJosé Fonseca return 1.0/scale; 22033ce51bc0d52dcfbfa481211dd1fe73a5ecb948fJosé Fonseca } 22133ce51bc0d52dcfbfa481211dd1fe73a5ecb948fJosé Fonseca} 22233ce51bc0d52dcfbfa481211dd1fe73a5ecb948fJosé Fonseca 22333ce51bc0d52dcfbfa481211dd1fe73a5ecb948fJosé Fonseca 22464611e086dbefa2003773ab541c0381b5713e18dJosé FonsecaLLVMValueRef 225efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paullp_build_undef(struct gallivm_state *gallivm, struct lp_type type) 22664611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca{ 227efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul LLVMTypeRef vec_type = lp_build_vec_type(gallivm, type); 22864611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca return LLVMGetUndef(vec_type); 22964611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca} 23064611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca 23164611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca 23264611e086dbefa2003773ab541c0381b5713e18dJosé FonsecaLLVMValueRef 233efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paullp_build_zero(struct gallivm_state *gallivm, struct lp_type type) 23464611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca{ 23522bb7ffd04ca9296bcafa929f448203880cbcb2bBrian Paul if (type.length == 1) { 23622bb7ffd04ca9296bcafa929f448203880cbcb2bBrian Paul if (type.floating) 237efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul return lp_build_const_float(gallivm, 0.0); 23822bb7ffd04ca9296bcafa929f448203880cbcb2bBrian Paul else 239efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul return LLVMConstInt(LLVMIntTypeInContext(gallivm->context, type.width), 0, 0); 24022bb7ffd04ca9296bcafa929f448203880cbcb2bBrian Paul } 24122bb7ffd04ca9296bcafa929f448203880cbcb2bBrian Paul else { 242efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul LLVMTypeRef vec_type = lp_build_vec_type(gallivm, type); 24322bb7ffd04ca9296bcafa929f448203880cbcb2bBrian Paul return LLVMConstNull(vec_type); 24422bb7ffd04ca9296bcafa929f448203880cbcb2bBrian Paul } 24564611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca} 24664611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca 24764611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca 24864611e086dbefa2003773ab541c0381b5713e18dJosé FonsecaLLVMValueRef 249efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paullp_build_one(struct gallivm_state *gallivm, struct lp_type type) 25064611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca{ 25164611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca LLVMTypeRef elem_type; 25264611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca LLVMValueRef elems[LP_MAX_VECTOR_LENGTH]; 25364611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca unsigned i; 25464611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca 25564611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca assert(type.length <= LP_MAX_VECTOR_LENGTH); 25664611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca 257efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul elem_type = lp_build_elem_type(gallivm, type); 25864611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca 2593469715a8a171512cf9b528702e70393f01c6041José Fonseca if(type.floating && type.width == 16) 2603469715a8a171512cf9b528702e70393f01c6041José Fonseca elems[0] = LLVMConstInt(elem_type, util_float_to_half(1.0f), 0); 2613469715a8a171512cf9b528702e70393f01c6041José Fonseca else if(type.floating) 26264611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca elems[0] = LLVMConstReal(elem_type, 1.0); 26364611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca else if(type.fixed) 26464611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca elems[0] = LLVMConstInt(elem_type, 1LL << (type.width/2), 0); 26564611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca else if(!type.norm) 26664611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca elems[0] = LLVMConstInt(elem_type, 1, 0); 267a9771d2b7580ae1273c4edeb9eebcafab39a72bbJosé Fonseca else if(type.sign) 268a9771d2b7580ae1273c4edeb9eebcafab39a72bbJosé Fonseca elems[0] = LLVMConstInt(elem_type, (1LL << (type.width - 1)) - 1, 0); 26964611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca else { 27064611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca /* special case' -- 1.0 for normalized types is more easily attained if 27164611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca * we start with a vector consisting of all bits set */ 27264611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca LLVMTypeRef vec_type = LLVMVectorType(elem_type, type.length); 27364611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca LLVMValueRef vec = LLVMConstAllOnes(vec_type); 27464611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca 275a9771d2b7580ae1273c4edeb9eebcafab39a72bbJosé Fonseca#if 0 27664611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca if(type.sign) 277a9771d2b7580ae1273c4edeb9eebcafab39a72bbJosé Fonseca /* TODO: Unfortunately this caused "Tried to create a shift operation 278a9771d2b7580ae1273c4edeb9eebcafab39a72bbJosé Fonseca * on a non-integer type!" */ 279185be3a87a5b38e8821a560c073975c11dcbd3e9Brian Paul vec = LLVMConstLShr(vec, lp_build_const_int_vec(type, 1)); 280a9771d2b7580ae1273c4edeb9eebcafab39a72bbJosé Fonseca#endif 28164611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca 28264611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca return vec; 28364611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca } 28464611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca 28564611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca for(i = 1; i < type.length; ++i) 28664611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca elems[i] = elems[0]; 28764611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca 2882ccae040a458ad0f95ee46916e2ea467d5cf9d02Brian Paul if (type.length == 1) 2892ccae040a458ad0f95ee46916e2ea467d5cf9d02Brian Paul return elems[0]; 2902ccae040a458ad0f95ee46916e2ea467d5cf9d02Brian Paul else 2912ccae040a458ad0f95ee46916e2ea467d5cf9d02Brian Paul return LLVMConstVector(elems, type.length); 29264611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca} 29364611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca 29464611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca 2952ccae040a458ad0f95ee46916e2ea467d5cf9d02Brian Paul/** 296952d188c3c8ab90bd2919b88457c81b491fcc3c8José Fonseca * Build constant-valued element from a scalar value. 2972ccae040a458ad0f95ee46916e2ea467d5cf9d02Brian Paul */ 29864611e086dbefa2003773ab541c0381b5713e18dJosé FonsecaLLVMValueRef 299efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paullp_build_const_elem(struct gallivm_state *gallivm, 300efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul struct lp_type type, 301952d188c3c8ab90bd2919b88457c81b491fcc3c8José Fonseca double val) 302138428badea350a20f5afc652a4fa1850e1ec653José Fonseca{ 303efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul LLVMTypeRef elem_type = lp_build_elem_type(gallivm, type); 304952d188c3c8ab90bd2919b88457c81b491fcc3c8José Fonseca LLVMValueRef elem; 305138428badea350a20f5afc652a4fa1850e1ec653José Fonseca 3063469715a8a171512cf9b528702e70393f01c6041José Fonseca if(type.floating && type.width == 16) { 3073469715a8a171512cf9b528702e70393f01c6041José Fonseca elem = LLVMConstInt(elem_type, util_float_to_half((float)val), 0); 3083469715a8a171512cf9b528702e70393f01c6041José Fonseca } else if(type.floating) { 309952d188c3c8ab90bd2919b88457c81b491fcc3c8José Fonseca elem = LLVMConstReal(elem_type, val); 310138428badea350a20f5afc652a4fa1850e1ec653José Fonseca } 311138428badea350a20f5afc652a4fa1850e1ec653José Fonseca else { 312138428badea350a20f5afc652a4fa1850e1ec653José Fonseca double dscale = lp_const_scale(type); 313138428badea350a20f5afc652a4fa1850e1ec653José Fonseca 314c95cea50a9e14255a60c37b156271b7ab50515e9José Fonseca elem = LLVMConstInt(elem_type, round(val*dscale), 0); 315138428badea350a20f5afc652a4fa1850e1ec653José Fonseca } 316138428badea350a20f5afc652a4fa1850e1ec653José Fonseca 317952d188c3c8ab90bd2919b88457c81b491fcc3c8José Fonseca return elem; 318952d188c3c8ab90bd2919b88457c81b491fcc3c8José Fonseca} 319ff7542ab90154769930c80d58597cfec40844bd9José Fonseca 320138428badea350a20f5afc652a4fa1850e1ec653José Fonseca 321952d188c3c8ab90bd2919b88457c81b491fcc3c8José Fonseca/** 322952d188c3c8ab90bd2919b88457c81b491fcc3c8José Fonseca * Build constant-valued vector from a scalar value. 323952d188c3c8ab90bd2919b88457c81b491fcc3c8José Fonseca */ 324952d188c3c8ab90bd2919b88457c81b491fcc3c8José FonsecaLLVMValueRef 325efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paullp_build_const_vec(struct gallivm_state *gallivm, struct lp_type type, 326952d188c3c8ab90bd2919b88457c81b491fcc3c8José Fonseca double val) 327952d188c3c8ab90bd2919b88457c81b491fcc3c8José Fonseca{ 328952d188c3c8ab90bd2919b88457c81b491fcc3c8José Fonseca if (type.length == 1) { 329efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul return lp_build_const_elem(gallivm, type, val); 330952d188c3c8ab90bd2919b88457c81b491fcc3c8José Fonseca } else { 331952d188c3c8ab90bd2919b88457c81b491fcc3c8José Fonseca LLVMValueRef elems[LP_MAX_VECTOR_LENGTH]; 332952d188c3c8ab90bd2919b88457c81b491fcc3c8José Fonseca unsigned i; 333efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul elems[0] = lp_build_const_elem(gallivm, type, val); 334952d188c3c8ab90bd2919b88457c81b491fcc3c8José Fonseca for(i = 1; i < type.length; ++i) 335952d188c3c8ab90bd2919b88457c81b491fcc3c8José Fonseca elems[i] = elems[0]; 336952d188c3c8ab90bd2919b88457c81b491fcc3c8José Fonseca return LLVMConstVector(elems, type.length); 337952d188c3c8ab90bd2919b88457c81b491fcc3c8José Fonseca } 338138428badea350a20f5afc652a4fa1850e1ec653José Fonseca} 339138428badea350a20f5afc652a4fa1850e1ec653José Fonseca 340138428badea350a20f5afc652a4fa1850e1ec653José Fonseca 341138428badea350a20f5afc652a4fa1850e1ec653José FonsecaLLVMValueRef 342efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paullp_build_const_int_vec(struct gallivm_state *gallivm, struct lp_type type, 343efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul long long val) 344138428badea350a20f5afc652a4fa1850e1ec653José Fonseca{ 345efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul LLVMTypeRef elem_type = lp_build_int_elem_type(gallivm, type); 346138428badea350a20f5afc652a4fa1850e1ec653José Fonseca LLVMValueRef elems[LP_MAX_VECTOR_LENGTH]; 347138428badea350a20f5afc652a4fa1850e1ec653José Fonseca unsigned i; 348138428badea350a20f5afc652a4fa1850e1ec653José Fonseca 349138428badea350a20f5afc652a4fa1850e1ec653José Fonseca assert(type.length <= LP_MAX_VECTOR_LENGTH); 350138428badea350a20f5afc652a4fa1850e1ec653José Fonseca 351138428badea350a20f5afc652a4fa1850e1ec653José Fonseca for(i = 0; i < type.length; ++i) 352138428badea350a20f5afc652a4fa1850e1ec653José Fonseca elems[i] = LLVMConstInt(elem_type, val, type.sign ? 1 : 0); 353138428badea350a20f5afc652a4fa1850e1ec653José Fonseca 354ff7542ab90154769930c80d58597cfec40844bd9José Fonseca if (type.length == 1) 355ff7542ab90154769930c80d58597cfec40844bd9José Fonseca return elems[0]; 356ff7542ab90154769930c80d58597cfec40844bd9José Fonseca 357138428badea350a20f5afc652a4fa1850e1ec653José Fonseca return LLVMConstVector(elems, type.length); 358138428badea350a20f5afc652a4fa1850e1ec653José Fonseca} 359138428badea350a20f5afc652a4fa1850e1ec653José Fonseca 360138428badea350a20f5afc652a4fa1850e1ec653José Fonseca 361138428badea350a20f5afc652a4fa1850e1ec653José FonsecaLLVMValueRef 362efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paullp_build_const_aos(struct gallivm_state *gallivm, 363efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul struct lp_type type, 36464611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca double r, double g, double b, double a, 36564611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca const unsigned char *swizzle) 36664611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca{ 36764611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca const unsigned char default_swizzle[4] = {0, 1, 2, 3}; 36864611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca LLVMTypeRef elem_type; 36964611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca LLVMValueRef elems[LP_MAX_VECTOR_LENGTH]; 37064611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca unsigned i; 37164611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca 37264611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca assert(type.length % 4 == 0); 37364611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca assert(type.length <= LP_MAX_VECTOR_LENGTH); 37464611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca 375efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul elem_type = lp_build_elem_type(gallivm, type); 37664611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca 37764611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca if(swizzle == NULL) 37864611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca swizzle = default_swizzle; 37964611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca 3803469715a8a171512cf9b528702e70393f01c6041José Fonseca elems[swizzle[0]] = lp_build_const_elem(gallivm, type, r); 3813469715a8a171512cf9b528702e70393f01c6041José Fonseca elems[swizzle[1]] = lp_build_const_elem(gallivm, type, g); 3823469715a8a171512cf9b528702e70393f01c6041José Fonseca elems[swizzle[2]] = lp_build_const_elem(gallivm, type, b); 3833469715a8a171512cf9b528702e70393f01c6041José Fonseca elems[swizzle[3]] = lp_build_const_elem(gallivm, type, a); 38464611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca 38564611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca for(i = 4; i < type.length; ++i) 38664611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca elems[i] = elems[i % 4]; 38764611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca 38864611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca return LLVMConstVector(elems, type.length); 38964611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca} 3901dd7bb17c7331f9ecd0bc830b61ada235a56fe6dJosé Fonseca 3911dd7bb17c7331f9ecd0bc830b61ada235a56fe6dJosé Fonseca 3926ed726b8fc6210a41fe325591e1428d19f419108José Fonseca/** 3936ed726b8fc6210a41fe325591e1428d19f419108José Fonseca * @param mask TGSI_WRITEMASK_xxx 3946ed726b8fc6210a41fe325591e1428d19f419108José Fonseca */ 3951dd7bb17c7331f9ecd0bc830b61ada235a56fe6dJosé FonsecaLLVMValueRef 396efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paullp_build_const_mask_aos(struct gallivm_state *gallivm, 397efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul struct lp_type type, 3986ed726b8fc6210a41fe325591e1428d19f419108José Fonseca unsigned mask) 3991dd7bb17c7331f9ecd0bc830b61ada235a56fe6dJosé Fonseca{ 400efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul LLVMTypeRef elem_type = LLVMIntTypeInContext(gallivm->context, type.width); 4011dd7bb17c7331f9ecd0bc830b61ada235a56fe6dJosé Fonseca LLVMValueRef masks[LP_MAX_VECTOR_LENGTH]; 4021dd7bb17c7331f9ecd0bc830b61ada235a56fe6dJosé Fonseca unsigned i, j; 4031dd7bb17c7331f9ecd0bc830b61ada235a56fe6dJosé Fonseca 4041dd7bb17c7331f9ecd0bc830b61ada235a56fe6dJosé Fonseca assert(type.length <= LP_MAX_VECTOR_LENGTH); 4051dd7bb17c7331f9ecd0bc830b61ada235a56fe6dJosé Fonseca 4066ed726b8fc6210a41fe325591e1428d19f419108José Fonseca for (j = 0; j < type.length; j += 4) { 4076ed726b8fc6210a41fe325591e1428d19f419108José Fonseca for( i = 0; i < 4; ++i) { 4086ed726b8fc6210a41fe325591e1428d19f419108José Fonseca masks[j + i] = LLVMConstInt(elem_type, 4096ed726b8fc6210a41fe325591e1428d19f419108José Fonseca mask & (1 << i) ? ~0ULL : 0, 4106ed726b8fc6210a41fe325591e1428d19f419108José Fonseca 1); 4116ed726b8fc6210a41fe325591e1428d19f419108José Fonseca } 4126ed726b8fc6210a41fe325591e1428d19f419108José Fonseca } 4131dd7bb17c7331f9ecd0bc830b61ada235a56fe6dJosé Fonseca 4141dd7bb17c7331f9ecd0bc830b61ada235a56fe6dJosé Fonseca return LLVMConstVector(masks, type.length); 4151dd7bb17c7331f9ecd0bc830b61ada235a56fe6dJosé Fonseca} 416c23fd547c060c4137eab0f878a1028c5903384ebJames Benton 417c23fd547c060c4137eab0f878a1028c5903384ebJames Benton 418c23fd547c060c4137eab0f878a1028c5903384ebJames Benton/** 419c23fd547c060c4137eab0f878a1028c5903384ebJames Benton * Performs lp_build_const_mask_aos, but first swizzles the mask 420c23fd547c060c4137eab0f878a1028c5903384ebJames Benton */ 421c23fd547c060c4137eab0f878a1028c5903384ebJames BentonLLVMValueRef 422c23fd547c060c4137eab0f878a1028c5903384ebJames Bentonlp_build_const_mask_aos_swizzled(struct gallivm_state *gallivm, 423c23fd547c060c4137eab0f878a1028c5903384ebJames Benton struct lp_type type, 424c23fd547c060c4137eab0f878a1028c5903384ebJames Benton unsigned mask, 425c23fd547c060c4137eab0f878a1028c5903384ebJames Benton const unsigned char *swizzle) 426c23fd547c060c4137eab0f878a1028c5903384ebJames Benton{ 427c23fd547c060c4137eab0f878a1028c5903384ebJames Benton mask = 428c23fd547c060c4137eab0f878a1028c5903384ebJames Benton ((mask & (1 << swizzle[0])) >> swizzle[0]) 429c23fd547c060c4137eab0f878a1028c5903384ebJames Benton | (((mask & (1 << swizzle[1])) >> swizzle[1]) << 1) 430c23fd547c060c4137eab0f878a1028c5903384ebJames Benton | (((mask & (1 << swizzle[2])) >> swizzle[2]) << 2) 431c23fd547c060c4137eab0f878a1028c5903384ebJames Benton | (((mask & (1 << swizzle[3])) >> swizzle[3]) << 3); 432c23fd547c060c4137eab0f878a1028c5903384ebJames Benton 433c23fd547c060c4137eab0f878a1028c5903384ebJames Benton return lp_build_const_mask_aos(gallivm, type, mask); 434c23fd547c060c4137eab0f878a1028c5903384ebJames Benton} 4350005bd9da2b343accad423708eba36a00035c7eeJosé Fonseca 4360005bd9da2b343accad423708eba36a00035c7eeJosé Fonseca 4370005bd9da2b343accad423708eba36a00035c7eeJosé Fonseca/** 4380005bd9da2b343accad423708eba36a00035c7eeJosé Fonseca * Build a zero-terminated constant string. 4390005bd9da2b343accad423708eba36a00035c7eeJosé Fonseca */ 4400005bd9da2b343accad423708eba36a00035c7eeJosé FonsecaLLVMValueRef 4410005bd9da2b343accad423708eba36a00035c7eeJosé Fonsecalp_build_const_string(struct gallivm_state *gallivm, 4420005bd9da2b343accad423708eba36a00035c7eeJosé Fonseca const char *str) 4430005bd9da2b343accad423708eba36a00035c7eeJosé Fonseca{ 4440005bd9da2b343accad423708eba36a00035c7eeJosé Fonseca unsigned len = strlen(str) + 1; 4450005bd9da2b343accad423708eba36a00035c7eeJosé Fonseca LLVMTypeRef i8 = LLVMInt8TypeInContext(gallivm->context); 4460005bd9da2b343accad423708eba36a00035c7eeJosé Fonseca LLVMValueRef string = LLVMAddGlobal(gallivm->module, LLVMArrayType(i8, len), ""); 4470005bd9da2b343accad423708eba36a00035c7eeJosé Fonseca LLVMSetGlobalConstant(string, TRUE); 4480005bd9da2b343accad423708eba36a00035c7eeJosé Fonseca LLVMSetLinkage(string, LLVMInternalLinkage); 4490005bd9da2b343accad423708eba36a00035c7eeJosé Fonseca LLVMSetInitializer(string, LLVMConstStringInContext(gallivm->context, str, len, TRUE)); 4500005bd9da2b343accad423708eba36a00035c7eeJosé Fonseca string = LLVMConstBitCast(string, LLVMPointerType(i8, 0)); 4510005bd9da2b343accad423708eba36a00035c7eeJosé Fonseca return string; 4520005bd9da2b343accad423708eba36a00035c7eeJosé Fonseca} 4536cd76b800bed70435f499c6c498a487a5056a731José Fonseca 4546cd76b800bed70435f499c6c498a487a5056a731José Fonseca 4556cd76b800bed70435f499c6c498a487a5056a731José Fonseca/** 4566cd76b800bed70435f499c6c498a487a5056a731José Fonseca * Build a callable function pointer. 4576cd76b800bed70435f499c6c498a487a5056a731José Fonseca * 4583469715a8a171512cf9b528702e70393f01c6041José Fonseca * We use function pointer constants instead of LLVMAddGlobalMapping() 4596cd76b800bed70435f499c6c498a487a5056a731José Fonseca * to work around a bug in LLVM 2.6, and for efficiency/simplicity. 4606cd76b800bed70435f499c6c498a487a5056a731José Fonseca */ 4616cd76b800bed70435f499c6c498a487a5056a731José FonsecaLLVMValueRef 4626cd76b800bed70435f499c6c498a487a5056a731José Fonsecalp_build_const_func_pointer(struct gallivm_state *gallivm, 4636cd76b800bed70435f499c6c498a487a5056a731José Fonseca const void *ptr, 4646cd76b800bed70435f499c6c498a487a5056a731José Fonseca LLVMTypeRef ret_type, 4656cd76b800bed70435f499c6c498a487a5056a731José Fonseca LLVMTypeRef *arg_types, 4666cd76b800bed70435f499c6c498a487a5056a731José Fonseca unsigned num_args, 4676cd76b800bed70435f499c6c498a487a5056a731José Fonseca const char *name) 4686cd76b800bed70435f499c6c498a487a5056a731José Fonseca{ 4696cd76b800bed70435f499c6c498a487a5056a731José Fonseca LLVMTypeRef function_type; 4706cd76b800bed70435f499c6c498a487a5056a731José Fonseca LLVMValueRef function; 4716cd76b800bed70435f499c6c498a487a5056a731José Fonseca 4726cd76b800bed70435f499c6c498a487a5056a731José Fonseca function_type = LLVMFunctionType(ret_type, arg_types, num_args, 0); 4736cd76b800bed70435f499c6c498a487a5056a731José Fonseca 4746cd76b800bed70435f499c6c498a487a5056a731José Fonseca function = lp_build_const_int_pointer(gallivm, ptr); 4756cd76b800bed70435f499c6c498a487a5056a731José Fonseca 4766cd76b800bed70435f499c6c498a487a5056a731José Fonseca function = LLVMBuildBitCast(gallivm->builder, function, 4776cd76b800bed70435f499c6c498a487a5056a731José Fonseca LLVMPointerType(function_type, 0), 4786cd76b800bed70435f499c6c498a487a5056a731José Fonseca name); 4796cd76b800bed70435f499c6c498a487a5056a731José Fonseca 4806cd76b800bed70435f499c6c498a487a5056a731José Fonseca return function; 4816cd76b800bed70435f499c6c498a487a5056a731José Fonseca} 482