revert 213 commits (to 56092) from the last month. 10 still need work to resolve...
[AROS.git] / workbench / libs / mesa / src / gallium / auxiliary / gallivm / lp_bld_const.c
blob6d8b7c26fc8344f37e588dc9d3133e4bce26fb9e
1 /**************************************************************************
3 * Copyright 2009 VMware, Inc.
4 * All Rights Reserved.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
29 /**
30 * @file
31 * Helper functions for constant building.
33 * @author Jose Fonseca <jfonseca@vmware.com>
36 #include <float.h>
38 #include "util/u_debug.h"
40 #include "lp_bld_type.h"
41 #include "lp_bld_const.h"
42 #include "lp_bld_init.h"
45 unsigned
46 lp_mantissa(struct lp_type type)
48 assert(type.floating);
50 if(type.floating) {
51 switch(type.width) {
52 case 32:
53 return 23;
54 case 64:
55 return 53;
56 default:
57 assert(0);
58 return 0;
61 else {
62 if(type.sign)
63 return type.width - 1;
64 else
65 return type.width;
70 /**
71 * Shift of the unity.
73 * Same as lp_const_scale(), but in terms of shifts.
75 unsigned
76 lp_const_shift(struct lp_type type)
78 if(type.floating)
79 return 0;
80 else if(type.fixed)
81 return type.width/2;
82 else if(type.norm)
83 return type.sign ? type.width - 1 : type.width;
84 else
85 return 0;
89 unsigned
90 lp_const_offset(struct lp_type type)
92 if(type.floating || type.fixed)
93 return 0;
94 else if(type.norm)
95 return 1;
96 else
97 return 0;
102 * Scaling factor between the LLVM native value and its interpretation.
104 * This is 1.0 for all floating types and unnormalized integers, and something
105 * else for the fixed points types and normalized integers.
107 double
108 lp_const_scale(struct lp_type type)
110 unsigned long long llscale;
111 double dscale;
113 llscale = (unsigned long long)1 << lp_const_shift(type);
114 llscale -= lp_const_offset(type);
115 dscale = (double)llscale;
116 assert((unsigned long long)dscale == llscale);
118 return dscale;
123 * Minimum value representable by the type.
125 double
126 lp_const_min(struct lp_type type)
128 unsigned bits;
130 if(!type.sign)
131 return 0.0;
133 if(type.norm)
134 return -1.0;
136 if (type.floating) {
137 switch(type.width) {
138 case 32:
139 return -FLT_MAX;
140 case 64:
141 return -DBL_MAX;
142 default:
143 assert(0);
144 return 0.0;
148 if(type.fixed)
149 /* FIXME: consider the fractional bits? */
150 bits = type.width / 2 - 1;
151 else
152 bits = type.width - 1;
154 return (double)-((long long)1 << bits);
159 * Maximum value representable by the type.
161 double
162 lp_const_max(struct lp_type type)
164 unsigned bits;
166 if(type.norm)
167 return 1.0;
169 if (type.floating) {
170 switch(type.width) {
171 case 32:
172 return FLT_MAX;
173 case 64:
174 return DBL_MAX;
175 default:
176 assert(0);
177 return 0.0;
181 if(type.fixed)
182 bits = type.width / 2;
183 else
184 bits = type.width;
186 if(type.sign)
187 bits -= 1;
189 return (double)(((unsigned long long)1 << bits) - 1);
193 double
194 lp_const_eps(struct lp_type type)
196 if (type.floating) {
197 switch(type.width) {
198 case 32:
199 return FLT_EPSILON;
200 case 64:
201 return DBL_EPSILON;
202 default:
203 assert(0);
204 return 0.0;
207 else {
208 double scale = lp_const_scale(type);
209 return 1.0/scale;
214 LLVMValueRef
215 lp_build_undef(struct gallivm_state *gallivm, struct lp_type type)
217 LLVMTypeRef vec_type = lp_build_vec_type(gallivm, type);
218 return LLVMGetUndef(vec_type);
222 LLVMValueRef
223 lp_build_zero(struct gallivm_state *gallivm, struct lp_type type)
225 if (type.length == 1) {
226 if (type.floating)
227 return lp_build_const_float(gallivm, 0.0);
228 else
229 return LLVMConstInt(LLVMIntTypeInContext(gallivm->context, type.width), 0, 0);
231 else {
232 LLVMTypeRef vec_type = lp_build_vec_type(gallivm, type);
233 return LLVMConstNull(vec_type);
238 LLVMValueRef
239 lp_build_one(struct gallivm_state *gallivm, struct lp_type type)
241 LLVMTypeRef elem_type;
242 LLVMValueRef elems[LP_MAX_VECTOR_LENGTH];
243 unsigned i;
245 assert(type.length <= LP_MAX_VECTOR_LENGTH);
247 elem_type = lp_build_elem_type(gallivm, type);
249 if(type.floating)
250 elems[0] = LLVMConstReal(elem_type, 1.0);
251 else if(type.fixed)
252 elems[0] = LLVMConstInt(elem_type, 1LL << (type.width/2), 0);
253 else if(!type.norm)
254 elems[0] = LLVMConstInt(elem_type, 1, 0);
255 else if(type.sign)
256 elems[0] = LLVMConstInt(elem_type, (1LL << (type.width - 1)) - 1, 0);
257 else {
258 /* special case' -- 1.0 for normalized types is more easily attained if
259 * we start with a vector consisting of all bits set */
260 LLVMTypeRef vec_type = LLVMVectorType(elem_type, type.length);
261 LLVMValueRef vec = LLVMConstAllOnes(vec_type);
263 #if 0
264 if(type.sign)
265 /* TODO: Unfortunately this caused "Tried to create a shift operation
266 * on a non-integer type!" */
267 vec = LLVMConstLShr(vec, lp_build_const_int_vec(type, 1));
268 #endif
270 return vec;
273 for(i = 1; i < type.length; ++i)
274 elems[i] = elems[0];
276 if (type.length == 1)
277 return elems[0];
278 else
279 return LLVMConstVector(elems, type.length);
284 * Build constant-valued element from a scalar value.
286 LLVMValueRef
287 lp_build_const_elem(struct gallivm_state *gallivm,
288 struct lp_type type,
289 double val)
291 LLVMTypeRef elem_type = lp_build_elem_type(gallivm, type);
292 LLVMValueRef elem;
294 if(type.floating) {
295 elem = LLVMConstReal(elem_type, val);
297 else {
298 double dscale = lp_const_scale(type);
300 elem = LLVMConstInt(elem_type, val*dscale + 0.5, 0);
303 return elem;
308 * Build constant-valued vector from a scalar value.
310 LLVMValueRef
311 lp_build_const_vec(struct gallivm_state *gallivm, struct lp_type type,
312 double val)
314 if (type.length == 1) {
315 return lp_build_const_elem(gallivm, type, val);
316 } else {
317 LLVMValueRef elems[LP_MAX_VECTOR_LENGTH];
318 unsigned i;
319 elems[0] = lp_build_const_elem(gallivm, type, val);
320 for(i = 1; i < type.length; ++i)
321 elems[i] = elems[0];
322 return LLVMConstVector(elems, type.length);
327 LLVMValueRef
328 lp_build_const_int_vec(struct gallivm_state *gallivm, struct lp_type type,
329 long long val)
331 LLVMTypeRef elem_type = lp_build_int_elem_type(gallivm, type);
332 LLVMValueRef elems[LP_MAX_VECTOR_LENGTH];
333 unsigned i;
335 assert(type.length <= LP_MAX_VECTOR_LENGTH);
337 for(i = 0; i < type.length; ++i)
338 elems[i] = LLVMConstInt(elem_type, val, type.sign ? 1 : 0);
340 if (type.length == 1)
341 return elems[0];
343 return LLVMConstVector(elems, type.length);
347 LLVMValueRef
348 lp_build_const_aos(struct gallivm_state *gallivm,
349 struct lp_type type,
350 double r, double g, double b, double a,
351 const unsigned char *swizzle)
353 const unsigned char default_swizzle[4] = {0, 1, 2, 3};
354 LLVMTypeRef elem_type;
355 LLVMValueRef elems[LP_MAX_VECTOR_LENGTH];
356 unsigned i;
358 assert(type.length % 4 == 0);
359 assert(type.length <= LP_MAX_VECTOR_LENGTH);
361 elem_type = lp_build_elem_type(gallivm, type);
363 if(swizzle == NULL)
364 swizzle = default_swizzle;
366 if(type.floating) {
367 elems[swizzle[0]] = LLVMConstReal(elem_type, r);
368 elems[swizzle[1]] = LLVMConstReal(elem_type, g);
369 elems[swizzle[2]] = LLVMConstReal(elem_type, b);
370 elems[swizzle[3]] = LLVMConstReal(elem_type, a);
372 else {
373 double dscale = lp_const_scale(type);
375 elems[swizzle[0]] = LLVMConstInt(elem_type, r*dscale + 0.5, 0);
376 elems[swizzle[1]] = LLVMConstInt(elem_type, g*dscale + 0.5, 0);
377 elems[swizzle[2]] = LLVMConstInt(elem_type, b*dscale + 0.5, 0);
378 elems[swizzle[3]] = LLVMConstInt(elem_type, a*dscale + 0.5, 0);
381 for(i = 4; i < type.length; ++i)
382 elems[i] = elems[i % 4];
384 return LLVMConstVector(elems, type.length);
389 * @param mask TGSI_WRITEMASK_xxx
391 LLVMValueRef
392 lp_build_const_mask_aos(struct gallivm_state *gallivm,
393 struct lp_type type,
394 unsigned mask)
396 LLVMTypeRef elem_type = LLVMIntTypeInContext(gallivm->context, type.width);
397 LLVMValueRef masks[LP_MAX_VECTOR_LENGTH];
398 unsigned i, j;
400 assert(type.length <= LP_MAX_VECTOR_LENGTH);
402 for (j = 0; j < type.length; j += 4) {
403 for( i = 0; i < 4; ++i) {
404 masks[j + i] = LLVMConstInt(elem_type,
405 mask & (1 << i) ? ~0ULL : 0,
410 return LLVMConstVector(masks, type.length);