1bf215546Sopenharmony_ci/************************************************************************** 2bf215546Sopenharmony_ci * 3bf215546Sopenharmony_ci * Copyright 2009 VMware, Inc. 4bf215546Sopenharmony_ci * All Rights Reserved. 5bf215546Sopenharmony_ci * 6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the 8bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 9bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 10bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to 11bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 12bf215546Sopenharmony_ci * the following conditions: 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the 15bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions 16bf215546Sopenharmony_ci * of the Software. 17bf215546Sopenharmony_ci * 18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21bf215546Sopenharmony_ci * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25bf215546Sopenharmony_ci * 26bf215546Sopenharmony_ci **************************************************************************/ 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_ci/** 30bf215546Sopenharmony_ci * @file 31bf215546Sopenharmony_ci * Helper functions for constant building. 32bf215546Sopenharmony_ci * 33bf215546Sopenharmony_ci * @author Jose Fonseca <jfonseca@vmware.com> 34bf215546Sopenharmony_ci */ 35bf215546Sopenharmony_ci 36bf215546Sopenharmony_ci#include <float.h> 37bf215546Sopenharmony_ci 38bf215546Sopenharmony_ci#include "util/u_debug.h" 39bf215546Sopenharmony_ci#include "util/u_math.h" 40bf215546Sopenharmony_ci#include "util/half_float.h" 41bf215546Sopenharmony_ci 42bf215546Sopenharmony_ci#include "lp_bld_type.h" 43bf215546Sopenharmony_ci#include "lp_bld_const.h" 44bf215546Sopenharmony_ci#include "lp_bld_init.h" 45bf215546Sopenharmony_ci#include "lp_bld_limits.h" 46bf215546Sopenharmony_ci 47bf215546Sopenharmony_ci 48bf215546Sopenharmony_ciunsigned 49bf215546Sopenharmony_cilp_mantissa(struct lp_type type) 50bf215546Sopenharmony_ci{ 51bf215546Sopenharmony_ci assert(type.floating); 52bf215546Sopenharmony_ci 53bf215546Sopenharmony_ci if (type.floating) { 54bf215546Sopenharmony_ci switch (type.width) { 55bf215546Sopenharmony_ci case 16: 56bf215546Sopenharmony_ci return 10; 57bf215546Sopenharmony_ci case 32: 58bf215546Sopenharmony_ci return 23; 59bf215546Sopenharmony_ci case 64: 60bf215546Sopenharmony_ci return 52; 61bf215546Sopenharmony_ci default: 62bf215546Sopenharmony_ci assert(0); 63bf215546Sopenharmony_ci return 0; 64bf215546Sopenharmony_ci } 65bf215546Sopenharmony_ci } else { 66bf215546Sopenharmony_ci if (type.sign) 67bf215546Sopenharmony_ci return type.width - 1; 68bf215546Sopenharmony_ci else 69bf215546Sopenharmony_ci return type.width; 70bf215546Sopenharmony_ci } 71bf215546Sopenharmony_ci} 72bf215546Sopenharmony_ci 73bf215546Sopenharmony_ci 74bf215546Sopenharmony_ci/** 75bf215546Sopenharmony_ci * Shift of the unity. 76bf215546Sopenharmony_ci * 77bf215546Sopenharmony_ci * Same as lp_const_scale(), but in terms of shifts. 78bf215546Sopenharmony_ci */ 79bf215546Sopenharmony_ciunsigned 80bf215546Sopenharmony_cilp_const_shift(struct lp_type type) 81bf215546Sopenharmony_ci{ 82bf215546Sopenharmony_ci if (type.floating) 83bf215546Sopenharmony_ci return 0; 84bf215546Sopenharmony_ci else if (type.fixed) 85bf215546Sopenharmony_ci return type.width/2; 86bf215546Sopenharmony_ci else if (type.norm) 87bf215546Sopenharmony_ci return type.sign ? type.width - 1 : type.width; 88bf215546Sopenharmony_ci else 89bf215546Sopenharmony_ci return 0; 90bf215546Sopenharmony_ci} 91bf215546Sopenharmony_ci 92bf215546Sopenharmony_ci 93bf215546Sopenharmony_ciunsigned 94bf215546Sopenharmony_cilp_const_offset(struct lp_type type) 95bf215546Sopenharmony_ci{ 96bf215546Sopenharmony_ci if (type.floating || type.fixed) 97bf215546Sopenharmony_ci return 0; 98bf215546Sopenharmony_ci else if (type.norm) 99bf215546Sopenharmony_ci return 1; 100bf215546Sopenharmony_ci else 101bf215546Sopenharmony_ci return 0; 102bf215546Sopenharmony_ci} 103bf215546Sopenharmony_ci 104bf215546Sopenharmony_ci 105bf215546Sopenharmony_ci/** 106bf215546Sopenharmony_ci * Scaling factor between the LLVM native value and its interpretation. 107bf215546Sopenharmony_ci * 108bf215546Sopenharmony_ci * This is 1.0 for all floating types and unnormalized integers, and something 109bf215546Sopenharmony_ci * else for the fixed points types and normalized integers. 110bf215546Sopenharmony_ci */ 111bf215546Sopenharmony_cidouble 112bf215546Sopenharmony_cilp_const_scale(struct lp_type type) 113bf215546Sopenharmony_ci{ 114bf215546Sopenharmony_ci unsigned long long llscale; 115bf215546Sopenharmony_ci double dscale; 116bf215546Sopenharmony_ci 117bf215546Sopenharmony_ci llscale = (unsigned long long)1 << lp_const_shift(type); 118bf215546Sopenharmony_ci llscale -= lp_const_offset(type); 119bf215546Sopenharmony_ci dscale = (double)llscale; 120bf215546Sopenharmony_ci assert((unsigned long long)dscale == llscale); 121bf215546Sopenharmony_ci 122bf215546Sopenharmony_ci return dscale; 123bf215546Sopenharmony_ci} 124bf215546Sopenharmony_ci 125bf215546Sopenharmony_ci 126bf215546Sopenharmony_ci/** 127bf215546Sopenharmony_ci * Minimum value representable by the type. 128bf215546Sopenharmony_ci */ 129bf215546Sopenharmony_cidouble 130bf215546Sopenharmony_cilp_const_min(struct lp_type type) 131bf215546Sopenharmony_ci{ 132bf215546Sopenharmony_ci if (!type.sign) 133bf215546Sopenharmony_ci return 0.0; 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_ci if (type.norm) 136bf215546Sopenharmony_ci return -1.0; 137bf215546Sopenharmony_ci 138bf215546Sopenharmony_ci if (type.floating) { 139bf215546Sopenharmony_ci switch (type.width) { 140bf215546Sopenharmony_ci case 16: 141bf215546Sopenharmony_ci return -65504; 142bf215546Sopenharmony_ci case 32: 143bf215546Sopenharmony_ci return -FLT_MAX; 144bf215546Sopenharmony_ci case 64: 145bf215546Sopenharmony_ci return -DBL_MAX; 146bf215546Sopenharmony_ci default: 147bf215546Sopenharmony_ci assert(0); 148bf215546Sopenharmony_ci return 0.0; 149bf215546Sopenharmony_ci } 150bf215546Sopenharmony_ci } 151bf215546Sopenharmony_ci 152bf215546Sopenharmony_ci unsigned bits; 153bf215546Sopenharmony_ci if (type.fixed) 154bf215546Sopenharmony_ci /* FIXME: consider the fractional bits? */ 155bf215546Sopenharmony_ci bits = type.width / 2 - 1; 156bf215546Sopenharmony_ci else 157bf215546Sopenharmony_ci bits = type.width - 1; 158bf215546Sopenharmony_ci 159bf215546Sopenharmony_ci return (double)-((long long)1 << bits); 160bf215546Sopenharmony_ci} 161bf215546Sopenharmony_ci 162bf215546Sopenharmony_ci 163bf215546Sopenharmony_ci/** 164bf215546Sopenharmony_ci * Maximum value representable by the type. 165bf215546Sopenharmony_ci */ 166bf215546Sopenharmony_cidouble 167bf215546Sopenharmony_cilp_const_max(struct lp_type type) 168bf215546Sopenharmony_ci{ 169bf215546Sopenharmony_ci if (type.norm) 170bf215546Sopenharmony_ci return 1.0; 171bf215546Sopenharmony_ci 172bf215546Sopenharmony_ci if (type.floating) { 173bf215546Sopenharmony_ci switch (type.width) { 174bf215546Sopenharmony_ci case 16: 175bf215546Sopenharmony_ci return 65504; 176bf215546Sopenharmony_ci case 32: 177bf215546Sopenharmony_ci return FLT_MAX; 178bf215546Sopenharmony_ci case 64: 179bf215546Sopenharmony_ci return DBL_MAX; 180bf215546Sopenharmony_ci default: 181bf215546Sopenharmony_ci assert(0); 182bf215546Sopenharmony_ci return 0.0; 183bf215546Sopenharmony_ci } 184bf215546Sopenharmony_ci } 185bf215546Sopenharmony_ci 186bf215546Sopenharmony_ci unsigned bits; 187bf215546Sopenharmony_ci if (type.fixed) 188bf215546Sopenharmony_ci bits = type.width / 2; 189bf215546Sopenharmony_ci else 190bf215546Sopenharmony_ci bits = type.width; 191bf215546Sopenharmony_ci 192bf215546Sopenharmony_ci if (type.sign) 193bf215546Sopenharmony_ci bits -= 1; 194bf215546Sopenharmony_ci 195bf215546Sopenharmony_ci return (double)(((unsigned long long)1 << bits) - 1); 196bf215546Sopenharmony_ci} 197bf215546Sopenharmony_ci 198bf215546Sopenharmony_ci 199bf215546Sopenharmony_cidouble 200bf215546Sopenharmony_cilp_const_eps(struct lp_type type) 201bf215546Sopenharmony_ci{ 202bf215546Sopenharmony_ci if (type.floating) { 203bf215546Sopenharmony_ci switch (type.width) { 204bf215546Sopenharmony_ci case 16: 205bf215546Sopenharmony_ci return 2E-10; 206bf215546Sopenharmony_ci case 32: 207bf215546Sopenharmony_ci return FLT_EPSILON; 208bf215546Sopenharmony_ci case 64: 209bf215546Sopenharmony_ci return DBL_EPSILON; 210bf215546Sopenharmony_ci default: 211bf215546Sopenharmony_ci assert(0); 212bf215546Sopenharmony_ci return 0.0; 213bf215546Sopenharmony_ci } 214bf215546Sopenharmony_ci } else { 215bf215546Sopenharmony_ci double scale = lp_const_scale(type); 216bf215546Sopenharmony_ci return 1.0/scale; 217bf215546Sopenharmony_ci } 218bf215546Sopenharmony_ci} 219bf215546Sopenharmony_ci 220bf215546Sopenharmony_ci 221bf215546Sopenharmony_ciLLVMValueRef 222bf215546Sopenharmony_cilp_build_undef(struct gallivm_state *gallivm, struct lp_type type) 223bf215546Sopenharmony_ci{ 224bf215546Sopenharmony_ci LLVMTypeRef vec_type = lp_build_vec_type(gallivm, type); 225bf215546Sopenharmony_ci return LLVMGetUndef(vec_type); 226bf215546Sopenharmony_ci} 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_ci 229bf215546Sopenharmony_ciLLVMValueRef 230bf215546Sopenharmony_cilp_build_zero(struct gallivm_state *gallivm, struct lp_type type) 231bf215546Sopenharmony_ci{ 232bf215546Sopenharmony_ci if (type.length == 1) { 233bf215546Sopenharmony_ci if (type.floating) 234bf215546Sopenharmony_ci return lp_build_const_float(gallivm, 0.0); 235bf215546Sopenharmony_ci else 236bf215546Sopenharmony_ci return LLVMConstInt(LLVMIntTypeInContext(gallivm->context, type.width), 0, 0); 237bf215546Sopenharmony_ci } else { 238bf215546Sopenharmony_ci LLVMTypeRef vec_type = lp_build_vec_type(gallivm, type); 239bf215546Sopenharmony_ci return LLVMConstNull(vec_type); 240bf215546Sopenharmony_ci } 241bf215546Sopenharmony_ci} 242bf215546Sopenharmony_ci 243bf215546Sopenharmony_ci 244bf215546Sopenharmony_ciLLVMValueRef 245bf215546Sopenharmony_cilp_build_one(struct gallivm_state *gallivm, struct lp_type type) 246bf215546Sopenharmony_ci{ 247bf215546Sopenharmony_ci LLVMTypeRef elem_type; 248bf215546Sopenharmony_ci LLVMValueRef elems[LP_MAX_VECTOR_LENGTH]; 249bf215546Sopenharmony_ci 250bf215546Sopenharmony_ci assert(type.length <= LP_MAX_VECTOR_LENGTH); 251bf215546Sopenharmony_ci 252bf215546Sopenharmony_ci elem_type = lp_build_elem_type(gallivm, type); 253bf215546Sopenharmony_ci 254bf215546Sopenharmony_ci if (!lp_has_fp16() && type.floating && type.width == 16) 255bf215546Sopenharmony_ci elems[0] = LLVMConstInt(elem_type, _mesa_float_to_half(1.0f), 0); 256bf215546Sopenharmony_ci else if (type.floating) 257bf215546Sopenharmony_ci elems[0] = LLVMConstReal(elem_type, 1.0); 258bf215546Sopenharmony_ci else if (type.fixed) 259bf215546Sopenharmony_ci elems[0] = LLVMConstInt(elem_type, 1LL << (type.width/2), 0); 260bf215546Sopenharmony_ci else if (!type.norm) 261bf215546Sopenharmony_ci elems[0] = LLVMConstInt(elem_type, 1, 0); 262bf215546Sopenharmony_ci else if (type.sign) 263bf215546Sopenharmony_ci elems[0] = LLVMConstInt(elem_type, (1LL << (type.width - 1)) - 1, 0); 264bf215546Sopenharmony_ci else { 265bf215546Sopenharmony_ci /* special case' -- 1.0 for normalized types is more easily attained if 266bf215546Sopenharmony_ci * we start with a vector consisting of all bits set */ 267bf215546Sopenharmony_ci LLVMTypeRef vec_type = lp_build_vec_type(gallivm, type); 268bf215546Sopenharmony_ci LLVMValueRef vec = LLVMConstAllOnes(vec_type); 269bf215546Sopenharmony_ci 270bf215546Sopenharmony_ci#if 0 271bf215546Sopenharmony_ci if (type.sign) 272bf215546Sopenharmony_ci /* TODO: Unfortunately this caused "Tried to create a shift operation 273bf215546Sopenharmony_ci * on a non-integer type!" */ 274bf215546Sopenharmony_ci vec = LLVMConstLShr(vec, lp_build_const_int_vec(type, 1)); 275bf215546Sopenharmony_ci#endif 276bf215546Sopenharmony_ci 277bf215546Sopenharmony_ci return vec; 278bf215546Sopenharmony_ci } 279bf215546Sopenharmony_ci 280bf215546Sopenharmony_ci for (unsigned i = 1; i < type.length; ++i) 281bf215546Sopenharmony_ci elems[i] = elems[0]; 282bf215546Sopenharmony_ci 283bf215546Sopenharmony_ci if (type.length == 1) 284bf215546Sopenharmony_ci return elems[0]; 285bf215546Sopenharmony_ci else 286bf215546Sopenharmony_ci return LLVMConstVector(elems, type.length); 287bf215546Sopenharmony_ci} 288bf215546Sopenharmony_ci 289bf215546Sopenharmony_ci 290bf215546Sopenharmony_ci/** 291bf215546Sopenharmony_ci * Build constant-valued element from a scalar value. 292bf215546Sopenharmony_ci */ 293bf215546Sopenharmony_ciLLVMValueRef 294bf215546Sopenharmony_cilp_build_const_elem(struct gallivm_state *gallivm, 295bf215546Sopenharmony_ci struct lp_type type, 296bf215546Sopenharmony_ci double val) 297bf215546Sopenharmony_ci{ 298bf215546Sopenharmony_ci LLVMTypeRef elem_type = lp_build_elem_type(gallivm, type); 299bf215546Sopenharmony_ci LLVMValueRef elem; 300bf215546Sopenharmony_ci 301bf215546Sopenharmony_ci if (!lp_has_fp16() && type.floating && type.width == 16) { 302bf215546Sopenharmony_ci elem = LLVMConstInt(elem_type, _mesa_float_to_half((float)val), 0); 303bf215546Sopenharmony_ci } else if (type.floating) { 304bf215546Sopenharmony_ci elem = LLVMConstReal(elem_type, val); 305bf215546Sopenharmony_ci } else { 306bf215546Sopenharmony_ci double dscale = lp_const_scale(type); 307bf215546Sopenharmony_ci 308bf215546Sopenharmony_ci elem = LLVMConstInt(elem_type, (long long) round(val*dscale), 0); 309bf215546Sopenharmony_ci } 310bf215546Sopenharmony_ci 311bf215546Sopenharmony_ci return elem; 312bf215546Sopenharmony_ci} 313bf215546Sopenharmony_ci 314bf215546Sopenharmony_ci 315bf215546Sopenharmony_ci/** 316bf215546Sopenharmony_ci * Build constant-valued vector from a scalar value. 317bf215546Sopenharmony_ci */ 318bf215546Sopenharmony_ciLLVMValueRef 319bf215546Sopenharmony_cilp_build_const_vec(struct gallivm_state *gallivm, struct lp_type type, 320bf215546Sopenharmony_ci double val) 321bf215546Sopenharmony_ci{ 322bf215546Sopenharmony_ci if (type.length == 1) { 323bf215546Sopenharmony_ci return lp_build_const_elem(gallivm, type, val); 324bf215546Sopenharmony_ci } else { 325bf215546Sopenharmony_ci LLVMValueRef elems[LP_MAX_VECTOR_LENGTH]; 326bf215546Sopenharmony_ci elems[0] = lp_build_const_elem(gallivm, type, val); 327bf215546Sopenharmony_ci for (unsigned i = 1; i < type.length; ++i) 328bf215546Sopenharmony_ci elems[i] = elems[0]; 329bf215546Sopenharmony_ci return LLVMConstVector(elems, type.length); 330bf215546Sopenharmony_ci } 331bf215546Sopenharmony_ci} 332bf215546Sopenharmony_ci 333bf215546Sopenharmony_ci 334bf215546Sopenharmony_ciLLVMValueRef 335bf215546Sopenharmony_cilp_build_const_int_vec(struct gallivm_state *gallivm, struct lp_type type, 336bf215546Sopenharmony_ci long long val) 337bf215546Sopenharmony_ci{ 338bf215546Sopenharmony_ci LLVMTypeRef elem_type = lp_build_int_elem_type(gallivm, type); 339bf215546Sopenharmony_ci LLVMValueRef elems[LP_MAX_VECTOR_LENGTH]; 340bf215546Sopenharmony_ci 341bf215546Sopenharmony_ci assert(type.length <= LP_MAX_VECTOR_LENGTH); 342bf215546Sopenharmony_ci 343bf215546Sopenharmony_ci for (unsigned i = 0; i < type.length; ++i) 344bf215546Sopenharmony_ci elems[i] = LLVMConstInt(elem_type, val, type.sign ? 1 : 0); 345bf215546Sopenharmony_ci 346bf215546Sopenharmony_ci if (type.length == 1) 347bf215546Sopenharmony_ci return elems[0]; 348bf215546Sopenharmony_ci 349bf215546Sopenharmony_ci return LLVMConstVector(elems, type.length); 350bf215546Sopenharmony_ci} 351bf215546Sopenharmony_ci 352bf215546Sopenharmony_ci 353bf215546Sopenharmony_ciLLVMValueRef 354bf215546Sopenharmony_cilp_build_const_aos(struct gallivm_state *gallivm, 355bf215546Sopenharmony_ci struct lp_type type, 356bf215546Sopenharmony_ci double r, double g, double b, double a, 357bf215546Sopenharmony_ci const unsigned char *swizzle) 358bf215546Sopenharmony_ci{ 359bf215546Sopenharmony_ci const unsigned char default_swizzle[4] = {0, 1, 2, 3}; 360bf215546Sopenharmony_ci LLVMValueRef elems[LP_MAX_VECTOR_LENGTH]; 361bf215546Sopenharmony_ci 362bf215546Sopenharmony_ci assert(type.length % 4 == 0); 363bf215546Sopenharmony_ci assert(type.length <= LP_MAX_VECTOR_LENGTH); 364bf215546Sopenharmony_ci 365bf215546Sopenharmony_ci lp_build_elem_type(gallivm, type); 366bf215546Sopenharmony_ci 367bf215546Sopenharmony_ci if (!swizzle) 368bf215546Sopenharmony_ci swizzle = default_swizzle; 369bf215546Sopenharmony_ci 370bf215546Sopenharmony_ci elems[swizzle[0]] = lp_build_const_elem(gallivm, type, r); 371bf215546Sopenharmony_ci elems[swizzle[1]] = lp_build_const_elem(gallivm, type, g); 372bf215546Sopenharmony_ci elems[swizzle[2]] = lp_build_const_elem(gallivm, type, b); 373bf215546Sopenharmony_ci elems[swizzle[3]] = lp_build_const_elem(gallivm, type, a); 374bf215546Sopenharmony_ci 375bf215546Sopenharmony_ci for (unsigned i = 4; i < type.length; ++i) 376bf215546Sopenharmony_ci elems[i] = elems[i % 4]; 377bf215546Sopenharmony_ci 378bf215546Sopenharmony_ci return LLVMConstVector(elems, type.length); 379bf215546Sopenharmony_ci} 380bf215546Sopenharmony_ci 381bf215546Sopenharmony_ci 382bf215546Sopenharmony_ci/** 383bf215546Sopenharmony_ci * @param mask TGSI_WRITEMASK_xxx 384bf215546Sopenharmony_ci */ 385bf215546Sopenharmony_ciLLVMValueRef 386bf215546Sopenharmony_cilp_build_const_mask_aos(struct gallivm_state *gallivm, 387bf215546Sopenharmony_ci struct lp_type type, 388bf215546Sopenharmony_ci unsigned mask, 389bf215546Sopenharmony_ci unsigned channels) 390bf215546Sopenharmony_ci{ 391bf215546Sopenharmony_ci LLVMTypeRef elem_type = LLVMIntTypeInContext(gallivm->context, type.width); 392bf215546Sopenharmony_ci LLVMValueRef masks[LP_MAX_VECTOR_LENGTH]; 393bf215546Sopenharmony_ci 394bf215546Sopenharmony_ci assert(type.length <= LP_MAX_VECTOR_LENGTH); 395bf215546Sopenharmony_ci 396bf215546Sopenharmony_ci for (unsigned j = 0; j < type.length; j += channels) { 397bf215546Sopenharmony_ci for (unsigned i = 0; i < channels; ++i) { 398bf215546Sopenharmony_ci masks[j + i] = LLVMConstInt(elem_type, 399bf215546Sopenharmony_ci mask & (1 << i) ? ~0ULL : 0, 400bf215546Sopenharmony_ci 1); 401bf215546Sopenharmony_ci } 402bf215546Sopenharmony_ci } 403bf215546Sopenharmony_ci 404bf215546Sopenharmony_ci return LLVMConstVector(masks, type.length); 405bf215546Sopenharmony_ci} 406bf215546Sopenharmony_ci 407bf215546Sopenharmony_ci 408bf215546Sopenharmony_ci/** 409bf215546Sopenharmony_ci * Performs lp_build_const_mask_aos, but first swizzles the mask 410bf215546Sopenharmony_ci */ 411bf215546Sopenharmony_ciLLVMValueRef 412bf215546Sopenharmony_cilp_build_const_mask_aos_swizzled(struct gallivm_state *gallivm, 413bf215546Sopenharmony_ci struct lp_type type, 414bf215546Sopenharmony_ci unsigned mask, 415bf215546Sopenharmony_ci unsigned channels, 416bf215546Sopenharmony_ci const unsigned char *swizzle) 417bf215546Sopenharmony_ci{ 418bf215546Sopenharmony_ci unsigned mask_swizzled = 0; 419bf215546Sopenharmony_ci 420bf215546Sopenharmony_ci for (unsigned i = 0; i < channels; ++i) { 421bf215546Sopenharmony_ci if (swizzle[i] < 4) { 422bf215546Sopenharmony_ci mask_swizzled |= ((mask & (1 << swizzle[i])) >> swizzle[i]) << i; 423bf215546Sopenharmony_ci } 424bf215546Sopenharmony_ci } 425bf215546Sopenharmony_ci 426bf215546Sopenharmony_ci return lp_build_const_mask_aos(gallivm, type, mask_swizzled, channels); 427bf215546Sopenharmony_ci} 428bf215546Sopenharmony_ci 429bf215546Sopenharmony_ci 430bf215546Sopenharmony_ci/** 431bf215546Sopenharmony_ci * Build a zero-terminated constant string. 432bf215546Sopenharmony_ci */ 433bf215546Sopenharmony_ciLLVMValueRef 434bf215546Sopenharmony_cilp_build_const_string(struct gallivm_state *gallivm, 435bf215546Sopenharmony_ci const char *str) 436bf215546Sopenharmony_ci{ 437bf215546Sopenharmony_ci unsigned len = strlen(str) + 1; 438bf215546Sopenharmony_ci LLVMTypeRef i8 = LLVMInt8TypeInContext(gallivm->context); 439bf215546Sopenharmony_ci LLVMValueRef string = LLVMAddGlobal(gallivm->module, LLVMArrayType(i8, len), ""); 440bf215546Sopenharmony_ci LLVMSetGlobalConstant(string, TRUE); 441bf215546Sopenharmony_ci LLVMSetLinkage(string, LLVMInternalLinkage); 442bf215546Sopenharmony_ci LLVMSetInitializer(string, LLVMConstStringInContext(gallivm->context, str, len, TRUE)); 443bf215546Sopenharmony_ci string = LLVMConstBitCast(string, LLVMPointerType(i8, 0)); 444bf215546Sopenharmony_ci return string; 445bf215546Sopenharmony_ci} 446bf215546Sopenharmony_ci 447bf215546Sopenharmony_ci 448bf215546Sopenharmony_ciLLVMValueRef 449bf215546Sopenharmony_cilp_build_const_func_pointer_from_type(struct gallivm_state *gallivm, 450bf215546Sopenharmony_ci const void *ptr, 451bf215546Sopenharmony_ci LLVMTypeRef function_type, 452bf215546Sopenharmony_ci const char *name) 453bf215546Sopenharmony_ci{ 454bf215546Sopenharmony_ci return LLVMBuildBitCast(gallivm->builder, 455bf215546Sopenharmony_ci lp_build_const_int_pointer(gallivm, ptr), 456bf215546Sopenharmony_ci LLVMPointerType(function_type, 0), 457bf215546Sopenharmony_ci name); 458bf215546Sopenharmony_ci} 459bf215546Sopenharmony_ci 460bf215546Sopenharmony_ci 461bf215546Sopenharmony_ci/** 462bf215546Sopenharmony_ci * Build a callable function pointer. 463bf215546Sopenharmony_ci * 464bf215546Sopenharmony_ci * We use function pointer constants instead of LLVMAddGlobalMapping() 465bf215546Sopenharmony_ci * to work around a bug in LLVM 2.6, and for efficiency/simplicity. 466bf215546Sopenharmony_ci */ 467bf215546Sopenharmony_ciLLVMValueRef 468bf215546Sopenharmony_cilp_build_const_func_pointer(struct gallivm_state *gallivm, 469bf215546Sopenharmony_ci const void *ptr, 470bf215546Sopenharmony_ci LLVMTypeRef ret_type, 471bf215546Sopenharmony_ci LLVMTypeRef *arg_types, 472bf215546Sopenharmony_ci unsigned num_args, 473bf215546Sopenharmony_ci const char *name) 474bf215546Sopenharmony_ci{ 475bf215546Sopenharmony_ci LLVMTypeRef function_type = LLVMFunctionType(ret_type, arg_types, num_args, 0); 476bf215546Sopenharmony_ci return lp_build_const_func_pointer_from_type(gallivm, ptr, function_type, name); 477bf215546Sopenharmony_ci} 478