1 /**************************************************************************
3 * Copyright 2009-2010 VMware, Inc.
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
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 **************************************************************************/
33 * LLVM IR doesn't support all basic arithmetic operations we care about (most
34 * notably min/max and saturated operations), and it is often necessary to
35 * resort machine-specific intrinsics directly. The functions here hide all
36 * these implementation details from the other modules.
38 * We also do simple expressions simplification here. Reasons are:
39 * - it is very easy given we have all necessary information readily available
40 * - LLVM optimization passes fail to simplify several vector expressions
41 * - We often know value constraints which the optimization passes have no way
42 * of knowing, such as when source arguments are known to be in [0, 1] range.
44 * @author Jose Fonseca <jfonseca@vmware.com>
48 #include "util/u_memory.h"
49 #include "util/u_debug.h"
50 #include "util/u_math.h"
51 #include "util/u_string.h"
52 #include "util/u_cpu_detect.h"
54 #include "lp_bld_type.h"
55 #include "lp_bld_const.h"
56 #include "lp_bld_init.h"
57 #include "lp_bld_intr.h"
58 #include "lp_bld_logic.h"
59 #include "lp_bld_pack.h"
60 #include "lp_bld_debug.h"
61 #include "lp_bld_arit.h"
64 #define EXP_POLY_DEGREE 3
66 #define LOG_POLY_DEGREE 5
71 * No checks for special case values of a or b = 1 or 0 are done.
74 lp_build_min_simple(struct lp_build_context
*bld
,
78 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
79 const struct lp_type type
= bld
->type
;
80 const char *intrinsic
= NULL
;
83 assert(lp_check_value(type
, a
));
84 assert(lp_check_value(type
, b
));
86 /* TODO: optimize the constant case */
88 if(type
.width
* type
.length
== 128) {
90 if(type
.width
== 32 && util_cpu_caps
.has_sse
)
91 intrinsic
= "llvm.x86.sse.min.ps";
92 if(type
.width
== 64 && util_cpu_caps
.has_sse2
)
93 intrinsic
= "llvm.x86.sse2.min.pd";
96 if(type
.width
== 8 && !type
.sign
&& util_cpu_caps
.has_sse2
)
97 intrinsic
= "llvm.x86.sse2.pminu.b";
98 if(type
.width
== 8 && type
.sign
&& util_cpu_caps
.has_sse4_1
)
99 intrinsic
= "llvm.x86.sse41.pminsb";
100 if(type
.width
== 16 && !type
.sign
&& util_cpu_caps
.has_sse4_1
)
101 intrinsic
= "llvm.x86.sse41.pminuw";
102 if(type
.width
== 16 && type
.sign
&& util_cpu_caps
.has_sse2
)
103 intrinsic
= "llvm.x86.sse2.pmins.w";
104 if(type
.width
== 32 && !type
.sign
&& util_cpu_caps
.has_sse4_1
)
105 intrinsic
= "llvm.x86.sse41.pminud";
106 if(type
.width
== 32 && type
.sign
&& util_cpu_caps
.has_sse4_1
)
107 intrinsic
= "llvm.x86.sse41.pminsd";
112 return lp_build_intrinsic_binary(builder
, intrinsic
, lp_build_vec_type(bld
->gallivm
, bld
->type
), a
, b
);
114 cond
= lp_build_cmp(bld
, PIPE_FUNC_LESS
, a
, b
);
115 return lp_build_select(bld
, cond
, a
, b
);
121 * No checks for special case values of a or b = 1 or 0 are done.
124 lp_build_max_simple(struct lp_build_context
*bld
,
128 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
129 const struct lp_type type
= bld
->type
;
130 const char *intrinsic
= NULL
;
133 assert(lp_check_value(type
, a
));
134 assert(lp_check_value(type
, b
));
136 /* TODO: optimize the constant case */
138 if(type
.width
* type
.length
== 128) {
140 if(type
.width
== 32 && util_cpu_caps
.has_sse
)
141 intrinsic
= "llvm.x86.sse.max.ps";
142 if(type
.width
== 64 && util_cpu_caps
.has_sse2
)
143 intrinsic
= "llvm.x86.sse2.max.pd";
146 if(type
.width
== 8 && !type
.sign
&& util_cpu_caps
.has_sse2
)
147 intrinsic
= "llvm.x86.sse2.pmaxu.b";
148 if(type
.width
== 8 && type
.sign
&& util_cpu_caps
.has_sse4_1
)
149 intrinsic
= "llvm.x86.sse41.pmaxsb";
150 if(type
.width
== 16 && !type
.sign
&& util_cpu_caps
.has_sse4_1
)
151 intrinsic
= "llvm.x86.sse41.pmaxuw";
152 if(type
.width
== 16 && type
.sign
&& util_cpu_caps
.has_sse2
)
153 intrinsic
= "llvm.x86.sse2.pmaxs.w";
154 if(type
.width
== 32 && !type
.sign
&& util_cpu_caps
.has_sse4_1
)
155 intrinsic
= "llvm.x86.sse41.pmaxud";
156 if(type
.width
== 32 && type
.sign
&& util_cpu_caps
.has_sse4_1
)
157 intrinsic
= "llvm.x86.sse41.pmaxsd";
162 return lp_build_intrinsic_binary(builder
, intrinsic
, lp_build_vec_type(bld
->gallivm
, bld
->type
), a
, b
);
164 cond
= lp_build_cmp(bld
, PIPE_FUNC_GREATER
, a
, b
);
165 return lp_build_select(bld
, cond
, a
, b
);
170 * Generate 1 - a, or ~a depending on bld->type.
173 lp_build_comp(struct lp_build_context
*bld
,
176 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
177 const struct lp_type type
= bld
->type
;
179 assert(lp_check_value(type
, a
));
186 if(type
.norm
&& !type
.floating
&& !type
.fixed
&& !type
.sign
) {
187 if(LLVMIsConstant(a
))
188 return LLVMConstNot(a
);
190 return LLVMBuildNot(builder
, a
, "");
193 if(LLVMIsConstant(a
))
195 return LLVMConstFSub(bld
->one
, a
);
197 return LLVMConstSub(bld
->one
, a
);
200 return LLVMBuildFSub(builder
, bld
->one
, a
, "");
202 return LLVMBuildSub(builder
, bld
->one
, a
, "");
210 lp_build_add(struct lp_build_context
*bld
,
214 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
215 const struct lp_type type
= bld
->type
;
218 assert(lp_check_value(type
, a
));
219 assert(lp_check_value(type
, b
));
225 if(a
== bld
->undef
|| b
== bld
->undef
)
229 const char *intrinsic
= NULL
;
231 if(a
== bld
->one
|| b
== bld
->one
)
234 if(util_cpu_caps
.has_sse2
&&
235 type
.width
* type
.length
== 128 &&
236 !type
.floating
&& !type
.fixed
) {
238 intrinsic
= type
.sign
? "llvm.x86.sse2.padds.b" : "llvm.x86.sse2.paddus.b";
240 intrinsic
= type
.sign
? "llvm.x86.sse2.padds.w" : "llvm.x86.sse2.paddus.w";
244 return lp_build_intrinsic_binary(builder
, intrinsic
, lp_build_vec_type(bld
->gallivm
, bld
->type
), a
, b
);
247 if(LLVMIsConstant(a
) && LLVMIsConstant(b
))
249 res
= LLVMConstFAdd(a
, b
);
251 res
= LLVMConstAdd(a
, b
);
254 res
= LLVMBuildFAdd(builder
, a
, b
, "");
256 res
= LLVMBuildAdd(builder
, a
, b
, "");
258 /* clamp to ceiling of 1.0 */
259 if(bld
->type
.norm
&& (bld
->type
.floating
|| bld
->type
.fixed
))
260 res
= lp_build_min_simple(bld
, res
, bld
->one
);
262 /* XXX clamp to floor of -1 or 0??? */
268 /** Return the scalar sum of the elements of a */
270 lp_build_sum_vector(struct lp_build_context
*bld
,
273 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
274 const struct lp_type type
= bld
->type
;
275 LLVMValueRef index
, res
;
278 assert(lp_check_value(type
, a
));
280 if (type
.length
== 1) {
284 assert(!bld
->type
.norm
);
286 index
= lp_build_const_int32(bld
->gallivm
, 0);
287 res
= LLVMBuildExtractElement(builder
, a
, index
, "");
289 for (i
= 1; i
< type
.length
; i
++) {
290 index
= lp_build_const_int32(bld
->gallivm
, i
);
292 res
= LLVMBuildFAdd(builder
, res
,
293 LLVMBuildExtractElement(builder
,
297 res
= LLVMBuildAdd(builder
, res
,
298 LLVMBuildExtractElement(builder
,
311 lp_build_sub(struct lp_build_context
*bld
,
315 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
316 const struct lp_type type
= bld
->type
;
319 assert(lp_check_value(type
, a
));
320 assert(lp_check_value(type
, b
));
324 if(a
== bld
->undef
|| b
== bld
->undef
)
330 const char *intrinsic
= NULL
;
335 if(util_cpu_caps
.has_sse2
&&
336 type
.width
* type
.length
== 128 &&
337 !type
.floating
&& !type
.fixed
) {
339 intrinsic
= type
.sign
? "llvm.x86.sse2.psubs.b" : "llvm.x86.sse2.psubus.b";
341 intrinsic
= type
.sign
? "llvm.x86.sse2.psubs.w" : "llvm.x86.sse2.psubus.w";
345 return lp_build_intrinsic_binary(builder
, intrinsic
, lp_build_vec_type(bld
->gallivm
, bld
->type
), a
, b
);
348 if(LLVMIsConstant(a
) && LLVMIsConstant(b
))
350 res
= LLVMConstFSub(a
, b
);
352 res
= LLVMConstSub(a
, b
);
355 res
= LLVMBuildFSub(builder
, a
, b
, "");
357 res
= LLVMBuildSub(builder
, a
, b
, "");
359 if(bld
->type
.norm
&& (bld
->type
.floating
|| bld
->type
.fixed
))
360 res
= lp_build_max_simple(bld
, res
, bld
->zero
);
367 * Normalized 8bit multiplication.
371 * makes the following approximation to the division (Sree)
373 * a*b/255 ~= (a*(b + 1)) >> 256
375 * which is the fastest method that satisfies the following OpenGL criteria
377 * 0*0 = 0 and 255*255 = 255
381 * takes the geometric series approximation to the division
383 * t/255 = (t >> 8) + (t >> 16) + (t >> 24) ..
385 * in this case just the first two terms to fit in 16bit arithmetic
387 * t/255 ~= (t + (t >> 8)) >> 8
389 * note that just by itself it doesn't satisfies the OpenGL criteria, as
390 * 255*255 = 254, so the special case b = 255 must be accounted or roundoff
393 * - geometric series plus rounding
395 * when using a geometric series division instead of truncating the result
396 * use roundoff in the approximation (Jim Blinn)
398 * t/255 ~= (t + (t >> 8) + 0x80) >> 8
400 * achieving the exact results
402 * @sa Alvy Ray Smith, Image Compositing Fundamentals, Tech Memo 4, Aug 15, 1995,
403 * ftp://ftp.alvyray.com/Acrobat/4_Comp.pdf
404 * @sa Michael Herf, The "double blend trick", May 2000,
405 * http://www.stereopsis.com/doubleblend.html
408 lp_build_mul_u8n(struct gallivm_state
*gallivm
,
409 struct lp_type i16_type
,
410 LLVMValueRef a
, LLVMValueRef b
)
412 LLVMBuilderRef builder
= gallivm
->builder
;
416 assert(!i16_type
.floating
);
417 assert(lp_check_value(i16_type
, a
));
418 assert(lp_check_value(i16_type
, b
));
420 c8
= lp_build_const_int_vec(gallivm
, i16_type
, 8);
424 /* a*b/255 ~= (a*(b + 1)) >> 256 */
425 b
= LLVMBuildAdd(builder
, b
, lp_build_const_int_vec(gallium
, i16_type
, 1), "");
426 ab
= LLVMBuildMul(builder
, a
, b
, "");
430 /* ab/255 ~= (ab + (ab >> 8) + 0x80) >> 8 */
431 ab
= LLVMBuildMul(builder
, a
, b
, "");
432 ab
= LLVMBuildAdd(builder
, ab
, LLVMBuildLShr(builder
, ab
, c8
, ""), "");
433 ab
= LLVMBuildAdd(builder
, ab
, lp_build_const_int_vec(gallivm
, i16_type
, 0x80), "");
437 ab
= LLVMBuildLShr(builder
, ab
, c8
, "");
447 lp_build_mul(struct lp_build_context
*bld
,
451 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
452 const struct lp_type type
= bld
->type
;
456 assert(lp_check_value(type
, a
));
457 assert(lp_check_value(type
, b
));
467 if(a
== bld
->undef
|| b
== bld
->undef
)
470 if(!type
.floating
&& !type
.fixed
&& type
.norm
) {
471 if(type
.width
== 8) {
472 struct lp_type i16_type
= lp_wider_type(type
);
473 LLVMValueRef al
, ah
, bl
, bh
, abl
, abh
, ab
;
475 lp_build_unpack2(bld
->gallivm
, type
, i16_type
, a
, &al
, &ah
);
476 lp_build_unpack2(bld
->gallivm
, type
, i16_type
, b
, &bl
, &bh
);
478 /* PMULLW, PSRLW, PADDW */
479 abl
= lp_build_mul_u8n(bld
->gallivm
, i16_type
, al
, bl
);
480 abh
= lp_build_mul_u8n(bld
->gallivm
, i16_type
, ah
, bh
);
482 ab
= lp_build_pack2(bld
->gallivm
, i16_type
, type
, abl
, abh
);
492 shift
= lp_build_const_int_vec(bld
->gallivm
, type
, type
.width
/2);
496 if(LLVMIsConstant(a
) && LLVMIsConstant(b
)) {
498 res
= LLVMConstFMul(a
, b
);
500 res
= LLVMConstMul(a
, b
);
503 res
= LLVMConstAShr(res
, shift
);
505 res
= LLVMConstLShr(res
, shift
);
510 res
= LLVMBuildFMul(builder
, a
, b
, "");
512 res
= LLVMBuildMul(builder
, a
, b
, "");
515 res
= LLVMBuildAShr(builder
, res
, shift
, "");
517 res
= LLVMBuildLShr(builder
, res
, shift
, "");
526 * Small vector x scale multiplication optimization.
529 lp_build_mul_imm(struct lp_build_context
*bld
,
533 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
536 assert(lp_check_value(bld
->type
, a
));
545 return lp_build_negate(bld
, a
);
547 if(b
== 2 && bld
->type
.floating
)
548 return lp_build_add(bld
, a
, a
);
550 if(util_is_power_of_two(b
)) {
551 unsigned shift
= ffs(b
) - 1;
553 if(bld
->type
.floating
) {
556 * Power of two multiplication by directly manipulating the mantissa.
558 * XXX: This might not be always faster, it will introduce a small error
559 * for multiplication by zero, and it will produce wrong results
562 unsigned mantissa
= lp_mantissa(bld
->type
);
563 factor
= lp_build_const_int_vec(bld
->gallivm
, bld
->type
, (unsigned long long)shift
<< mantissa
);
564 a
= LLVMBuildBitCast(builder
, a
, lp_build_int_vec_type(bld
->type
), "");
565 a
= LLVMBuildAdd(builder
, a
, factor
, "");
566 a
= LLVMBuildBitCast(builder
, a
, lp_build_vec_type(bld
->gallivm
, bld
->type
), "");
571 factor
= lp_build_const_vec(bld
->gallivm
, bld
->type
, shift
);
572 return LLVMBuildShl(builder
, a
, factor
, "");
576 factor
= lp_build_const_vec(bld
->gallivm
, bld
->type
, (double)b
);
577 return lp_build_mul(bld
, a
, factor
);
585 lp_build_div(struct lp_build_context
*bld
,
589 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
590 const struct lp_type type
= bld
->type
;
592 assert(lp_check_value(type
, a
));
593 assert(lp_check_value(type
, b
));
598 return lp_build_rcp(bld
, b
);
603 if(a
== bld
->undef
|| b
== bld
->undef
)
606 if(LLVMIsConstant(a
) && LLVMIsConstant(b
)) {
608 return LLVMConstFDiv(a
, b
);
610 return LLVMConstSDiv(a
, b
);
612 return LLVMConstUDiv(a
, b
);
615 if(util_cpu_caps
.has_sse
&& type
.width
== 32 && type
.length
== 4)
616 return lp_build_mul(bld
, a
, lp_build_rcp(bld
, b
));
619 return LLVMBuildFDiv(builder
, a
, b
, "");
621 return LLVMBuildSDiv(builder
, a
, b
, "");
623 return LLVMBuildUDiv(builder
, a
, b
, "");
628 * Linear interpolation -- without any checks.
630 * @sa http://www.stereopsis.com/doubleblend.html
632 static INLINE LLVMValueRef
633 lp_build_lerp_simple(struct lp_build_context
*bld
,
638 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
642 assert(lp_check_value(bld
->type
, x
));
643 assert(lp_check_value(bld
->type
, v0
));
644 assert(lp_check_value(bld
->type
, v1
));
646 delta
= lp_build_sub(bld
, v1
, v0
);
648 res
= lp_build_mul(bld
, x
, delta
);
650 res
= lp_build_add(bld
, v0
, res
);
652 if (bld
->type
.fixed
) {
653 /* XXX: This step is necessary for lerping 8bit colors stored on 16bits,
654 * but it will be wrong for other uses. Basically we need a more
655 * powerful lp_type, capable of further distinguishing the values
656 * interpretation from the value storage. */
657 res
= LLVMBuildAnd(builder
, res
, lp_build_const_int_vec(bld
->gallivm
, bld
->type
, (1 << bld
->type
.width
/2) - 1), "");
665 * Linear interpolation.
668 lp_build_lerp(struct lp_build_context
*bld
,
673 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
674 const struct lp_type type
= bld
->type
;
677 assert(lp_check_value(type
, x
));
678 assert(lp_check_value(type
, v0
));
679 assert(lp_check_value(type
, v1
));
682 struct lp_type wide_type
;
683 struct lp_build_context wide_bld
;
684 LLVMValueRef xl
, xh
, v0l
, v0h
, v1l
, v1h
, resl
, resh
;
687 assert(type
.length
>= 2);
691 * Create a wider type, enough to hold the intermediate result of the
694 memset(&wide_type
, 0, sizeof wide_type
);
695 wide_type
.fixed
= TRUE
;
696 wide_type
.width
= type
.width
*2;
697 wide_type
.length
= type
.length
/2;
699 lp_build_context_init(&wide_bld
, bld
->gallivm
, wide_type
);
701 lp_build_unpack2(bld
->gallivm
, type
, wide_type
, x
, &xl
, &xh
);
702 lp_build_unpack2(bld
->gallivm
, type
, wide_type
, v0
, &v0l
, &v0h
);
703 lp_build_unpack2(bld
->gallivm
, type
, wide_type
, v1
, &v1l
, &v1h
);
706 * Scale x from [0, 255] to [0, 256]
709 shift
= lp_build_const_int_vec(bld
->gallivm
, wide_type
, type
.width
- 1);
711 xl
= lp_build_add(&wide_bld
, xl
,
712 LLVMBuildAShr(builder
, xl
, shift
, ""));
713 xh
= lp_build_add(&wide_bld
, xh
,
714 LLVMBuildAShr(builder
, xh
, shift
, ""));
720 resl
= lp_build_lerp_simple(&wide_bld
, xl
, v0l
, v1l
);
721 resh
= lp_build_lerp_simple(&wide_bld
, xh
, v0h
, v1h
);
723 res
= lp_build_pack2(bld
->gallivm
, wide_type
, type
, resl
, resh
);
725 res
= lp_build_lerp_simple(bld
, x
, v0
, v1
);
733 lp_build_lerp_2d(struct lp_build_context
*bld
,
741 LLVMValueRef v0
= lp_build_lerp(bld
, x
, v00
, v01
);
742 LLVMValueRef v1
= lp_build_lerp(bld
, x
, v10
, v11
);
743 return lp_build_lerp(bld
, y
, v0
, v1
);
749 * Do checks for special cases.
752 lp_build_min(struct lp_build_context
*bld
,
756 assert(lp_check_value(bld
->type
, a
));
757 assert(lp_check_value(bld
->type
, b
));
759 if(a
== bld
->undef
|| b
== bld
->undef
)
766 if(a
== bld
->zero
|| b
== bld
->zero
)
774 return lp_build_min_simple(bld
, a
, b
);
780 * Do checks for special cases.
783 lp_build_max(struct lp_build_context
*bld
,
787 assert(lp_check_value(bld
->type
, a
));
788 assert(lp_check_value(bld
->type
, b
));
790 if(a
== bld
->undef
|| b
== bld
->undef
)
797 if(a
== bld
->one
|| b
== bld
->one
)
805 return lp_build_max_simple(bld
, a
, b
);
810 * Generate clamp(a, min, max)
811 * Do checks for special cases.
814 lp_build_clamp(struct lp_build_context
*bld
,
819 assert(lp_check_value(bld
->type
, a
));
820 assert(lp_check_value(bld
->type
, min
));
821 assert(lp_check_value(bld
->type
, max
));
823 a
= lp_build_min(bld
, a
, max
);
824 a
= lp_build_max(bld
, a
, min
);
833 lp_build_abs(struct lp_build_context
*bld
,
836 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
837 const struct lp_type type
= bld
->type
;
838 LLVMTypeRef vec_type
= lp_build_vec_type(bld
->gallivm
, type
);
840 assert(lp_check_value(type
, a
));
846 /* Mask out the sign bit */
847 LLVMTypeRef int_vec_type
= lp_build_int_vec_type(bld
->gallivm
, type
);
848 unsigned long long absMask
= ~(1ULL << (type
.width
- 1));
849 LLVMValueRef mask
= lp_build_const_int_vec(bld
->gallivm
, type
, ((unsigned long long) absMask
));
850 a
= LLVMBuildBitCast(builder
, a
, int_vec_type
, "");
851 a
= LLVMBuildAnd(builder
, a
, mask
, "");
852 a
= LLVMBuildBitCast(builder
, a
, vec_type
, "");
856 if(type
.width
*type
.length
== 128 && util_cpu_caps
.has_ssse3
) {
859 return lp_build_intrinsic_unary(builder
, "llvm.x86.ssse3.pabs.b.128", vec_type
, a
);
861 return lp_build_intrinsic_unary(builder
, "llvm.x86.ssse3.pabs.w.128", vec_type
, a
);
863 return lp_build_intrinsic_unary(builder
, "llvm.x86.ssse3.pabs.d.128", vec_type
, a
);
867 return lp_build_max(bld
, a
, LLVMBuildNeg(builder
, a
, ""));
872 lp_build_negate(struct lp_build_context
*bld
,
875 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
877 assert(lp_check_value(bld
->type
, a
));
879 #if HAVE_LLVM >= 0x0207
880 if (bld
->type
.floating
)
881 a
= LLVMBuildFNeg(builder
, a
, "");
884 a
= LLVMBuildNeg(builder
, a
, "");
890 /** Return -1, 0 or +1 depending on the sign of a */
892 lp_build_sgn(struct lp_build_context
*bld
,
895 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
896 const struct lp_type type
= bld
->type
;
900 assert(lp_check_value(type
, a
));
902 /* Handle non-zero case */
904 /* if not zero then sign must be positive */
907 else if(type
.floating
) {
908 LLVMTypeRef vec_type
;
909 LLVMTypeRef int_type
;
913 unsigned long long maskBit
= (unsigned long long)1 << (type
.width
- 1);
915 int_type
= lp_build_int_vec_type(bld
->gallivm
, type
);
916 vec_type
= lp_build_vec_type(bld
->gallivm
, type
);
917 mask
= lp_build_const_int_vec(bld
->gallivm
, type
, maskBit
);
919 /* Take the sign bit and add it to 1 constant */
920 sign
= LLVMBuildBitCast(builder
, a
, int_type
, "");
921 sign
= LLVMBuildAnd(builder
, sign
, mask
, "");
922 one
= LLVMConstBitCast(bld
->one
, int_type
);
923 res
= LLVMBuildOr(builder
, sign
, one
, "");
924 res
= LLVMBuildBitCast(builder
, res
, vec_type
, "");
928 LLVMValueRef minus_one
= lp_build_const_vec(bld
->gallivm
, type
, -1.0);
929 cond
= lp_build_cmp(bld
, PIPE_FUNC_GREATER
, a
, bld
->zero
);
930 res
= lp_build_select(bld
, cond
, bld
->one
, minus_one
);
934 cond
= lp_build_cmp(bld
, PIPE_FUNC_EQUAL
, a
, bld
->zero
);
935 res
= lp_build_select(bld
, cond
, bld
->zero
, res
);
942 * Set the sign of float vector 'a' according to 'sign'.
943 * If sign==0, return abs(a).
944 * If sign==1, return -abs(a);
945 * Other values for sign produce undefined results.
948 lp_build_set_sign(struct lp_build_context
*bld
,
949 LLVMValueRef a
, LLVMValueRef sign
)
951 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
952 const struct lp_type type
= bld
->type
;
953 LLVMTypeRef int_vec_type
= lp_build_int_vec_type(bld
->gallivm
, type
);
954 LLVMTypeRef vec_type
= lp_build_vec_type(bld
->gallivm
, type
);
955 LLVMValueRef shift
= lp_build_const_int_vec(bld
->gallivm
, type
, type
.width
- 1);
956 LLVMValueRef mask
= lp_build_const_int_vec(bld
->gallivm
, type
,
957 ~((unsigned long long) 1 << (type
.width
- 1)));
958 LLVMValueRef val
, res
;
960 assert(type
.floating
);
961 assert(lp_check_value(type
, a
));
963 /* val = reinterpret_cast<int>(a) */
964 val
= LLVMBuildBitCast(builder
, a
, int_vec_type
, "");
965 /* val = val & mask */
966 val
= LLVMBuildAnd(builder
, val
, mask
, "");
967 /* sign = sign << shift */
968 sign
= LLVMBuildShl(builder
, sign
, shift
, "");
969 /* res = val | sign */
970 res
= LLVMBuildOr(builder
, val
, sign
, "");
971 /* res = reinterpret_cast<float>(res) */
972 res
= LLVMBuildBitCast(builder
, res
, vec_type
, "");
979 * Convert vector of (or scalar) int to vector of (or scalar) float.
982 lp_build_int_to_float(struct lp_build_context
*bld
,
985 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
986 const struct lp_type type
= bld
->type
;
987 LLVMTypeRef vec_type
= lp_build_vec_type(bld
->gallivm
, type
);
989 assert(type
.floating
);
991 return LLVMBuildSIToFP(builder
, a
, vec_type
, "");
996 enum lp_build_round_sse41_mode
998 LP_BUILD_ROUND_SSE41_NEAREST
= 0,
999 LP_BUILD_ROUND_SSE41_FLOOR
= 1,
1000 LP_BUILD_ROUND_SSE41_CEIL
= 2,
1001 LP_BUILD_ROUND_SSE41_TRUNCATE
= 3
1006 * Helper for SSE4.1's ROUNDxx instructions.
1008 * NOTE: In the SSE4.1's nearest mode, if two values are equally close, the
1009 * result is the even value. That is, rounding 2.5 will be 2.0, and not 3.0.
1011 static INLINE LLVMValueRef
1012 lp_build_round_sse41(struct lp_build_context
*bld
,
1014 enum lp_build_round_sse41_mode mode
)
1016 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
1017 const struct lp_type type
= bld
->type
;
1018 LLVMTypeRef i32t
= LLVMInt32TypeInContext(bld
->gallivm
->context
);
1019 const char *intrinsic
;
1022 assert(type
.floating
);
1024 assert(lp_check_value(type
, a
));
1025 assert(util_cpu_caps
.has_sse4_1
);
1027 if (type
.length
== 1) {
1028 LLVMTypeRef vec_type
;
1030 LLVMValueRef args
[3];
1031 LLVMValueRef index0
= LLVMConstInt(i32t
, 0, 0);
1033 switch(type
.width
) {
1035 intrinsic
= "llvm.x86.sse41.round.ss";
1038 intrinsic
= "llvm.x86.sse41.round.sd";
1045 vec_type
= LLVMVectorType(bld
->elem_type
, 4);
1047 undef
= LLVMGetUndef(vec_type
);
1050 args
[1] = LLVMBuildInsertElement(builder
, undef
, a
, index0
, "");
1051 args
[2] = LLVMConstInt(i32t
, mode
, 0);
1053 res
= lp_build_intrinsic(builder
, intrinsic
,
1054 vec_type
, args
, Elements(args
));
1056 res
= LLVMBuildExtractElement(builder
, res
, index0
, "");
1059 assert(type
.width
*type
.length
== 128);
1061 switch(type
.width
) {
1063 intrinsic
= "llvm.x86.sse41.round.ps";
1066 intrinsic
= "llvm.x86.sse41.round.pd";
1073 res
= lp_build_intrinsic_binary(builder
, intrinsic
,
1075 LLVMConstInt(i32t
, mode
, 0));
1082 static INLINE LLVMValueRef
1083 lp_build_iround_nearest_sse2(struct lp_build_context
*bld
,
1086 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
1087 const struct lp_type type
= bld
->type
;
1088 LLVMTypeRef i32t
= LLVMInt32TypeInContext(bld
->gallivm
->context
);
1089 LLVMTypeRef ret_type
= lp_build_int_vec_type(bld
->gallivm
, type
);
1090 const char *intrinsic
;
1093 assert(type
.floating
);
1094 /* using the double precision conversions is a bit more complicated */
1095 assert(type
.width
== 32);
1097 assert(lp_check_value(type
, a
));
1098 assert(util_cpu_caps
.has_sse2
);
1100 /* This is relying on MXCSR rounding mode, which should always be nearest. */
1101 if (type
.length
== 1) {
1102 LLVMTypeRef vec_type
;
1105 LLVMValueRef index0
= LLVMConstInt(i32t
, 0, 0);
1107 vec_type
= LLVMVectorType(bld
->elem_type
, 4);
1109 intrinsic
= "llvm.x86.sse.cvtss2si";
1111 undef
= LLVMGetUndef(vec_type
);
1113 arg
= LLVMBuildInsertElement(builder
, undef
, a
, index0
, "");
1115 res
= lp_build_intrinsic_unary(builder
, intrinsic
,
1119 assert(type
.width
*type
.length
== 128);
1121 intrinsic
= "llvm.x86.sse2.cvtps2dq";
1123 res
= lp_build_intrinsic_unary(builder
, intrinsic
,
1132 * Return the integer part of a float (vector) value (== round toward zero).
1133 * The returned value is a float (vector).
1134 * Ex: trunc(-1.5) = -1.0
1137 lp_build_trunc(struct lp_build_context
*bld
,
1140 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
1141 const struct lp_type type
= bld
->type
;
1143 assert(type
.floating
);
1144 assert(lp_check_value(type
, a
));
1146 if (util_cpu_caps
.has_sse4_1
&&
1147 (type
.length
== 1 || type
.width
*type
.length
== 128)) {
1148 return lp_build_round_sse41(bld
, a
, LP_BUILD_ROUND_SSE41_TRUNCATE
);
1151 LLVMTypeRef vec_type
= lp_build_vec_type(bld
->gallivm
, type
);
1152 LLVMTypeRef int_vec_type
= lp_build_int_vec_type(bld
->gallivm
, type
);
1154 res
= LLVMBuildFPToSI(builder
, a
, int_vec_type
, "");
1155 res
= LLVMBuildSIToFP(builder
, res
, vec_type
, "");
1162 * Return float (vector) rounded to nearest integer (vector). The returned
1163 * value is a float (vector).
1164 * Ex: round(0.9) = 1.0
1165 * Ex: round(-1.5) = -2.0
1168 lp_build_round(struct lp_build_context
*bld
,
1171 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
1172 const struct lp_type type
= bld
->type
;
1174 assert(type
.floating
);
1175 assert(lp_check_value(type
, a
));
1177 if (util_cpu_caps
.has_sse4_1
&&
1178 (type
.length
== 1 || type
.width
*type
.length
== 128)) {
1179 return lp_build_round_sse41(bld
, a
, LP_BUILD_ROUND_SSE41_NEAREST
);
1182 LLVMTypeRef vec_type
= lp_build_vec_type(bld
->gallivm
, type
);
1184 res
= lp_build_iround(bld
, a
);
1185 res
= LLVMBuildSIToFP(builder
, res
, vec_type
, "");
1192 * Return floor of float (vector), result is a float (vector)
1193 * Ex: floor(1.1) = 1.0
1194 * Ex: floor(-1.1) = -2.0
1197 lp_build_floor(struct lp_build_context
*bld
,
1200 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
1201 const struct lp_type type
= bld
->type
;
1203 assert(type
.floating
);
1204 assert(lp_check_value(type
, a
));
1206 if (util_cpu_caps
.has_sse4_1
&&
1207 (type
.length
== 1 || type
.width
*type
.length
== 128)) {
1208 return lp_build_round_sse41(bld
, a
, LP_BUILD_ROUND_SSE41_FLOOR
);
1211 LLVMTypeRef vec_type
= lp_build_vec_type(bld
->gallivm
, type
);
1213 res
= lp_build_ifloor(bld
, a
);
1214 res
= LLVMBuildSIToFP(builder
, res
, vec_type
, "");
1221 * Return ceiling of float (vector), returning float (vector).
1222 * Ex: ceil( 1.1) = 2.0
1223 * Ex: ceil(-1.1) = -1.0
1226 lp_build_ceil(struct lp_build_context
*bld
,
1229 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
1230 const struct lp_type type
= bld
->type
;
1232 assert(type
.floating
);
1233 assert(lp_check_value(type
, a
));
1235 if (util_cpu_caps
.has_sse4_1
&&
1236 (type
.length
== 1 || type
.width
*type
.length
== 128)) {
1237 return lp_build_round_sse41(bld
, a
, LP_BUILD_ROUND_SSE41_CEIL
);
1240 LLVMTypeRef vec_type
= lp_build_vec_type(bld
->gallivm
, type
);
1242 res
= lp_build_iceil(bld
, a
);
1243 res
= LLVMBuildSIToFP(builder
, res
, vec_type
, "");
1250 * Return fractional part of 'a' computed as a - floor(a)
1251 * Typically used in texture coord arithmetic.
1254 lp_build_fract(struct lp_build_context
*bld
,
1257 assert(bld
->type
.floating
);
1258 return lp_build_sub(bld
, a
, lp_build_floor(bld
, a
));
1263 * Return the integer part of a float (vector) value (== round toward zero).
1264 * The returned value is an integer (vector).
1265 * Ex: itrunc(-1.5) = -1
1268 lp_build_itrunc(struct lp_build_context
*bld
,
1271 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
1272 const struct lp_type type
= bld
->type
;
1273 LLVMTypeRef int_vec_type
= lp_build_int_vec_type(bld
->gallivm
, type
);
1275 assert(type
.floating
);
1276 assert(lp_check_value(type
, a
));
1278 return LLVMBuildFPToSI(builder
, a
, int_vec_type
, "");
1283 * Return float (vector) rounded to nearest integer (vector). The returned
1284 * value is an integer (vector).
1285 * Ex: iround(0.9) = 1
1286 * Ex: iround(-1.5) = -2
1289 lp_build_iround(struct lp_build_context
*bld
,
1292 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
1293 const struct lp_type type
= bld
->type
;
1294 LLVMTypeRef int_vec_type
= bld
->int_vec_type
;
1297 assert(type
.floating
);
1299 assert(lp_check_value(type
, a
));
1301 if (util_cpu_caps
.has_sse2
&&
1302 ((type
.width
== 32) && (type
.length
== 1 || type
.length
== 4))) {
1303 return lp_build_iround_nearest_sse2(bld
, a
);
1305 else if (util_cpu_caps
.has_sse4_1
&&
1306 (type
.length
== 1 || type
.width
*type
.length
== 128)) {
1307 res
= lp_build_round_sse41(bld
, a
, LP_BUILD_ROUND_SSE41_NEAREST
);
1312 half
= lp_build_const_vec(bld
->gallivm
, type
, 0.5);
1315 LLVMTypeRef vec_type
= bld
->vec_type
;
1316 LLVMValueRef mask
= lp_build_const_int_vec(bld
->gallivm
, type
,
1317 (unsigned long long)1 << (type
.width
- 1));
1321 sign
= LLVMBuildBitCast(builder
, a
, int_vec_type
, "");
1322 sign
= LLVMBuildAnd(builder
, sign
, mask
, "");
1325 half
= LLVMBuildBitCast(builder
, half
, int_vec_type
, "");
1326 half
= LLVMBuildOr(builder
, sign
, half
, "");
1327 half
= LLVMBuildBitCast(builder
, half
, vec_type
, "");
1330 res
= LLVMBuildFAdd(builder
, a
, half
, "");
1333 res
= LLVMBuildFPToSI(builder
, res
, int_vec_type
, "");
1340 * Return floor of float (vector), result is an int (vector)
1341 * Ex: ifloor(1.1) = 1.0
1342 * Ex: ifloor(-1.1) = -2.0
1345 lp_build_ifloor(struct lp_build_context
*bld
,
1348 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
1349 const struct lp_type type
= bld
->type
;
1350 LLVMTypeRef int_vec_type
= bld
->int_vec_type
;
1353 assert(type
.floating
);
1354 assert(lp_check_value(type
, a
));
1356 if (util_cpu_caps
.has_sse4_1
&&
1357 (type
.length
== 1 || type
.width
*type
.length
== 128)) {
1358 res
= lp_build_round_sse41(bld
, a
, LP_BUILD_ROUND_SSE41_FLOOR
);
1364 /* Take the sign bit and add it to 1 constant */
1365 LLVMTypeRef vec_type
= bld
->vec_type
;
1366 unsigned mantissa
= lp_mantissa(type
);
1367 LLVMValueRef mask
= lp_build_const_int_vec(bld
->gallivm
, type
,
1368 (unsigned long long)1 << (type
.width
- 1));
1370 LLVMValueRef offset
;
1372 /* sign = a < 0 ? ~0 : 0 */
1373 sign
= LLVMBuildBitCast(builder
, a
, int_vec_type
, "");
1374 sign
= LLVMBuildAnd(builder
, sign
, mask
, "");
1375 sign
= LLVMBuildAShr(builder
, sign
,
1376 lp_build_const_int_vec(bld
->gallivm
, type
,
1380 /* offset = -0.99999(9)f */
1381 offset
= lp_build_const_vec(bld
->gallivm
, type
,
1382 -(double)(((unsigned long long)1 << mantissa
) - 10)/((unsigned long long)1 << mantissa
));
1383 offset
= LLVMConstBitCast(offset
, int_vec_type
);
1385 /* offset = a < 0 ? offset : 0.0f */
1386 offset
= LLVMBuildAnd(builder
, offset
, sign
, "");
1387 offset
= LLVMBuildBitCast(builder
, offset
, vec_type
, "ifloor.offset");
1389 res
= LLVMBuildFAdd(builder
, res
, offset
, "ifloor.res");
1393 /* round to nearest (toward zero) */
1394 res
= LLVMBuildFPToSI(builder
, res
, int_vec_type
, "ifloor.res");
1401 * Return ceiling of float (vector), returning int (vector).
1402 * Ex: iceil( 1.1) = 2
1403 * Ex: iceil(-1.1) = -1
1406 lp_build_iceil(struct lp_build_context
*bld
,
1409 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
1410 const struct lp_type type
= bld
->type
;
1411 LLVMTypeRef int_vec_type
= bld
->int_vec_type
;
1414 assert(type
.floating
);
1415 assert(lp_check_value(type
, a
));
1417 if (util_cpu_caps
.has_sse4_1
&&
1418 (type
.length
== 1 || type
.width
*type
.length
== 128)) {
1419 res
= lp_build_round_sse41(bld
, a
, LP_BUILD_ROUND_SSE41_CEIL
);
1422 LLVMTypeRef vec_type
= bld
->vec_type
;
1423 unsigned mantissa
= lp_mantissa(type
);
1424 LLVMValueRef offset
;
1426 /* offset = 0.99999(9)f */
1427 offset
= lp_build_const_vec(bld
->gallivm
, type
,
1428 (double)(((unsigned long long)1 << mantissa
) - 10)/((unsigned long long)1 << mantissa
));
1431 LLVMValueRef mask
= lp_build_const_int_vec(bld
->gallivm
, type
,
1432 (unsigned long long)1 << (type
.width
- 1));
1435 /* sign = a < 0 ? 0 : ~0 */
1436 sign
= LLVMBuildBitCast(builder
, a
, int_vec_type
, "");
1437 sign
= LLVMBuildAnd(builder
, sign
, mask
, "");
1438 sign
= LLVMBuildAShr(builder
, sign
,
1439 lp_build_const_int_vec(bld
->gallivm
, type
,
1442 sign
= LLVMBuildNot(builder
, sign
, "iceil.not");
1444 /* offset = a < 0 ? 0.0 : offset */
1445 offset
= LLVMConstBitCast(offset
, int_vec_type
);
1446 offset
= LLVMBuildAnd(builder
, offset
, sign
, "");
1447 offset
= LLVMBuildBitCast(builder
, offset
, vec_type
, "iceil.offset");
1450 res
= LLVMBuildFAdd(builder
, a
, offset
, "iceil.res");
1453 /* round to nearest (toward zero) */
1454 res
= LLVMBuildFPToSI(builder
, res
, int_vec_type
, "iceil.res");
1461 * Combined ifloor() & fract().
1463 * Preferred to calling the functions separately, as it will ensure that the
1464 * stratergy (floor() vs ifloor()) that results in less redundant work is used.
1467 lp_build_ifloor_fract(struct lp_build_context
*bld
,
1469 LLVMValueRef
*out_ipart
,
1470 LLVMValueRef
*out_fpart
)
1472 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
1473 const struct lp_type type
= bld
->type
;
1476 assert(type
.floating
);
1477 assert(lp_check_value(type
, a
));
1479 if (util_cpu_caps
.has_sse4_1
&&
1480 (type
.length
== 1 || type
.width
*type
.length
== 128)) {
1482 * floor() is easier.
1485 ipart
= lp_build_floor(bld
, a
);
1486 *out_fpart
= LLVMBuildFSub(builder
, a
, ipart
, "fpart");
1487 *out_ipart
= LLVMBuildFPToSI(builder
, ipart
, bld
->int_vec_type
, "ipart");
1491 * ifloor() is easier.
1494 *out_ipart
= lp_build_ifloor(bld
, a
);
1495 ipart
= LLVMBuildSIToFP(builder
, *out_ipart
, bld
->vec_type
, "ipart");
1496 *out_fpart
= LLVMBuildFSub(builder
, a
, ipart
, "fpart");
1502 lp_build_sqrt(struct lp_build_context
*bld
,
1505 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
1506 const struct lp_type type
= bld
->type
;
1507 LLVMTypeRef vec_type
= lp_build_vec_type(bld
->gallivm
, type
);
1510 assert(lp_check_value(type
, a
));
1512 /* TODO: optimize the constant case */
1513 /* TODO: optimize the constant case */
1515 assert(type
.floating
);
1516 util_snprintf(intrinsic
, sizeof intrinsic
, "llvm.sqrt.v%uf%u", type
.length
, type
.width
);
1518 return lp_build_intrinsic_unary(builder
, intrinsic
, vec_type
, a
);
1523 * Do one Newton-Raphson step to improve reciprocate precision:
1525 * x_{i+1} = x_i * (2 - a * x_i)
1527 * XXX: Unfortunately this won't give IEEE-754 conformant results for 0 or
1528 * +/-Inf, giving NaN instead. Certain applications rely on this behavior,
1529 * such as Google Earth, which does RCP(RSQRT(0.0) when drawing the Earth's
1530 * halo. It would be necessary to clamp the argument to prevent this.
1533 * - http://en.wikipedia.org/wiki/Division_(digital)#Newton.E2.80.93Raphson_division
1534 * - http://softwarecommunity.intel.com/articles/eng/1818.htm
1536 static INLINE LLVMValueRef
1537 lp_build_rcp_refine(struct lp_build_context
*bld
,
1541 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
1542 LLVMValueRef two
= lp_build_const_vec(bld
->gallivm
, bld
->type
, 2.0);
1545 res
= LLVMBuildFMul(builder
, a
, rcp_a
, "");
1546 res
= LLVMBuildFSub(builder
, two
, res
, "");
1547 res
= LLVMBuildFMul(builder
, rcp_a
, res
, "");
1554 lp_build_rcp(struct lp_build_context
*bld
,
1557 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
1558 const struct lp_type type
= bld
->type
;
1560 assert(lp_check_value(type
, a
));
1569 assert(type
.floating
);
1571 if(LLVMIsConstant(a
))
1572 return LLVMConstFDiv(bld
->one
, a
);
1575 * We don't use RCPPS because:
1576 * - it only has 10bits of precision
1577 * - it doesn't even get the reciprocate of 1.0 exactly
1578 * - doing Newton-Rapshon steps yields wrong (NaN) values for 0.0 or Inf
1579 * - for recent processors the benefit over DIVPS is marginal, a case
1582 * We could still use it on certain processors if benchmarks show that the
1583 * RCPPS plus necessary workarounds are still preferrable to DIVPS; or for
1584 * particular uses that require less workarounds.
1587 if (FALSE
&& util_cpu_caps
.has_sse
&& type
.width
== 32 && type
.length
== 4) {
1588 const unsigned num_iterations
= 0;
1592 res
= lp_build_intrinsic_unary(builder
, "llvm.x86.sse.rcp.ps", bld
->vec_type
, a
);
1594 for (i
= 0; i
< num_iterations
; ++i
) {
1595 res
= lp_build_rcp_refine(bld
, a
, res
);
1601 return LLVMBuildFDiv(builder
, bld
->one
, a
, "");
1606 * Do one Newton-Raphson step to improve rsqrt precision:
1608 * x_{i+1} = 0.5 * x_i * (3.0 - a * x_i * x_i)
1611 * - http://softwarecommunity.intel.com/articles/eng/1818.htm
1613 static INLINE LLVMValueRef
1614 lp_build_rsqrt_refine(struct lp_build_context
*bld
,
1616 LLVMValueRef rsqrt_a
)
1618 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
1619 LLVMValueRef half
= lp_build_const_vec(bld
->gallivm
, bld
->type
, 0.5);
1620 LLVMValueRef three
= lp_build_const_vec(bld
->gallivm
, bld
->type
, 3.0);
1623 res
= LLVMBuildFMul(builder
, rsqrt_a
, rsqrt_a
, "");
1624 res
= LLVMBuildFMul(builder
, a
, res
, "");
1625 res
= LLVMBuildFSub(builder
, three
, res
, "");
1626 res
= LLVMBuildFMul(builder
, rsqrt_a
, res
, "");
1627 res
= LLVMBuildFMul(builder
, half
, res
, "");
1634 * Generate 1/sqrt(a)
1637 lp_build_rsqrt(struct lp_build_context
*bld
,
1640 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
1641 const struct lp_type type
= bld
->type
;
1643 assert(lp_check_value(type
, a
));
1645 assert(type
.floating
);
1647 if (util_cpu_caps
.has_sse
&& type
.width
== 32 && type
.length
== 4) {
1648 const unsigned num_iterations
= 0;
1652 res
= lp_build_intrinsic_unary(builder
, "llvm.x86.sse.rsqrt.ps", bld
->vec_type
, a
);
1654 for (i
= 0; i
< num_iterations
; ++i
) {
1655 res
= lp_build_rsqrt_refine(bld
, a
, res
);
1661 return lp_build_rcp(bld
, lp_build_sqrt(bld
, a
));
1665 static inline LLVMValueRef
1666 lp_build_const_v4si(struct gallivm_state
*gallivm
, unsigned long value
)
1668 LLVMValueRef element
= lp_build_const_int32(gallivm
, value
);
1669 LLVMValueRef elements
[4] = { element
, element
, element
, element
};
1670 return LLVMConstVector(elements
, 4);
1673 static inline LLVMValueRef
1674 lp_build_const_v4sf(struct gallivm_state
*gallivm
, float value
)
1676 LLVMValueRef element
= lp_build_const_float(gallivm
, value
);
1677 LLVMValueRef elements
[4] = { element
, element
, element
, element
};
1678 return LLVMConstVector(elements
, 4);
1683 * Generate sin(a) using SSE2
1686 lp_build_sin(struct lp_build_context
*bld
,
1689 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
1690 struct gallivm_state
*gallivm
= bld
->gallivm
;
1691 struct lp_type int_type
= lp_int_type(bld
->type
);
1692 LLVMBuilderRef b
= builder
;
1693 LLVMTypeRef v4sf
= LLVMVectorType(LLVMFloatTypeInContext(bld
->gallivm
->context
), 4);
1694 LLVMTypeRef v4si
= LLVMVectorType(LLVMInt32TypeInContext(bld
->gallivm
->context
), 4);
1697 * take the absolute value,
1698 * x = _mm_and_ps(x, *(v4sf*)_ps_inv_sign_mask);
1701 LLVMValueRef inv_sig_mask
= lp_build_const_v4si(bld
->gallivm
, ~0x80000000);
1702 LLVMValueRef a_v4si
= LLVMBuildBitCast(b
, a
, v4si
, "a_v4si");
1704 LLVMValueRef absi
= LLVMBuildAnd(b
, a_v4si
, inv_sig_mask
, "absi");
1705 LLVMValueRef x_abs
= LLVMBuildBitCast(b
, absi
, v4sf
, "x_abs");
1708 * extract the sign bit (upper one)
1709 * sign_bit = _mm_and_ps(sign_bit, *(v4sf*)_ps_sign_mask);
1711 LLVMValueRef sig_mask
= lp_build_const_v4si(bld
->gallivm
, 0x80000000);
1712 LLVMValueRef sign_bit_i
= LLVMBuildAnd(b
, a_v4si
, sig_mask
, "sign_bit_i");
1716 * y = _mm_mul_ps(x, *(v4sf*)_ps_cephes_FOPI);
1719 LLVMValueRef FOPi
= lp_build_const_v4sf(gallivm
, 1.27323954473516);
1720 LLVMValueRef scale_y
= LLVMBuildFMul(b
, x_abs
, FOPi
, "scale_y");
1723 * store the integer part of y in mm0
1724 * emm2 = _mm_cvttps_epi32(y);
1727 LLVMValueRef emm2_i
= LLVMBuildFPToSI(b
, scale_y
, v4si
, "emm2_i");
1730 * j=(j+1) & (~1) (see the cephes sources)
1731 * emm2 = _mm_add_epi32(emm2, *(v4si*)_pi32_1);
1734 LLVMValueRef all_one
= lp_build_const_v4si(bld
->gallivm
, 1);
1735 LLVMValueRef emm2_add
= LLVMBuildAdd(b
, emm2_i
, all_one
, "emm2_add");
1737 * emm2 = _mm_and_si128(emm2, *(v4si*)_pi32_inv1);
1739 LLVMValueRef inv_one
= lp_build_const_v4si(bld
->gallivm
, ~1);
1740 LLVMValueRef emm2_and
= LLVMBuildAnd(b
, emm2_add
, inv_one
, "emm2_and");
1743 * y = _mm_cvtepi32_ps(emm2);
1745 LLVMValueRef y_2
= LLVMBuildSIToFP(b
, emm2_and
, v4sf
, "y_2");
1747 /* get the swap sign flag
1748 * emm0 = _mm_and_si128(emm2, *(v4si*)_pi32_4);
1750 LLVMValueRef pi32_4
= lp_build_const_v4si(bld
->gallivm
, 4);
1751 LLVMValueRef emm0_and
= LLVMBuildAnd(b
, emm2_add
, pi32_4
, "emm0_and");
1754 * emm2 = _mm_slli_epi32(emm0, 29);
1756 LLVMValueRef const_29
= lp_build_const_v4si(bld
->gallivm
, 29);
1757 LLVMValueRef swap_sign_bit
= LLVMBuildShl(b
, emm0_and
, const_29
, "swap_sign_bit");
1760 * get the polynom selection mask
1761 * there is one polynom for 0 <= x <= Pi/4
1762 * and another one for Pi/4<x<=Pi/2
1763 * Both branches will be computed.
1765 * emm2 = _mm_and_si128(emm2, *(v4si*)_pi32_2);
1766 * emm2 = _mm_cmpeq_epi32(emm2, _mm_setzero_si128());
1769 LLVMValueRef pi32_2
= lp_build_const_v4si(bld
->gallivm
, 2);
1770 LLVMValueRef emm2_3
= LLVMBuildAnd(b
, emm2_and
, pi32_2
, "emm2_3");
1771 LLVMValueRef poly_mask
= lp_build_compare(bld
->gallivm
,
1772 int_type
, PIPE_FUNC_EQUAL
,
1773 emm2_3
, lp_build_const_v4si(bld
->gallivm
, 0));
1775 * sign_bit = _mm_xor_ps(sign_bit, swap_sign_bit);
1777 LLVMValueRef sign_bit_1
= LLVMBuildXor(b
, sign_bit_i
, swap_sign_bit
, "sign_bit");
1780 * _PS_CONST(minus_cephes_DP1, -0.78515625);
1781 * _PS_CONST(minus_cephes_DP2, -2.4187564849853515625e-4);
1782 * _PS_CONST(minus_cephes_DP3, -3.77489497744594108e-8);
1784 LLVMValueRef DP1
= lp_build_const_v4sf(gallivm
, -0.78515625);
1785 LLVMValueRef DP2
= lp_build_const_v4sf(gallivm
, -2.4187564849853515625e-4);
1786 LLVMValueRef DP3
= lp_build_const_v4sf(gallivm
, -3.77489497744594108e-8);
1789 * The magic pass: "Extended precision modular arithmetic"
1790 * x = ((x - y * DP1) - y * DP2) - y * DP3;
1791 * xmm1 = _mm_mul_ps(y, xmm1);
1792 * xmm2 = _mm_mul_ps(y, xmm2);
1793 * xmm3 = _mm_mul_ps(y, xmm3);
1795 LLVMValueRef xmm1
= LLVMBuildFMul(b
, y_2
, DP1
, "xmm1");
1796 LLVMValueRef xmm2
= LLVMBuildFMul(b
, y_2
, DP2
, "xmm2");
1797 LLVMValueRef xmm3
= LLVMBuildFMul(b
, y_2
, DP3
, "xmm3");
1800 * x = _mm_add_ps(x, xmm1);
1801 * x = _mm_add_ps(x, xmm2);
1802 * x = _mm_add_ps(x, xmm3);
1805 LLVMValueRef x_1
= LLVMBuildFAdd(b
, x_abs
, xmm1
, "x_1");
1806 LLVMValueRef x_2
= LLVMBuildFAdd(b
, x_1
, xmm2
, "x_2");
1807 LLVMValueRef x_3
= LLVMBuildFAdd(b
, x_2
, xmm3
, "x_3");
1810 * Evaluate the first polynom (0 <= x <= Pi/4)
1812 * z = _mm_mul_ps(x,x);
1814 LLVMValueRef z
= LLVMBuildFMul(b
, x_3
, x_3
, "z");
1817 * _PS_CONST(coscof_p0, 2.443315711809948E-005);
1818 * _PS_CONST(coscof_p1, -1.388731625493765E-003);
1819 * _PS_CONST(coscof_p2, 4.166664568298827E-002);
1821 LLVMValueRef coscof_p0
= lp_build_const_v4sf(gallivm
, 2.443315711809948E-005);
1822 LLVMValueRef coscof_p1
= lp_build_const_v4sf(gallivm
, -1.388731625493765E-003);
1823 LLVMValueRef coscof_p2
= lp_build_const_v4sf(gallivm
, 4.166664568298827E-002);
1826 * y = *(v4sf*)_ps_coscof_p0;
1827 * y = _mm_mul_ps(y, z);
1829 LLVMValueRef y_3
= LLVMBuildFMul(b
, z
, coscof_p0
, "y_3");
1830 LLVMValueRef y_4
= LLVMBuildFAdd(b
, y_3
, coscof_p1
, "y_4");
1831 LLVMValueRef y_5
= LLVMBuildFMul(b
, y_4
, z
, "y_5");
1832 LLVMValueRef y_6
= LLVMBuildFAdd(b
, y_5
, coscof_p2
, "y_6");
1833 LLVMValueRef y_7
= LLVMBuildFMul(b
, y_6
, z
, "y_7");
1834 LLVMValueRef y_8
= LLVMBuildFMul(b
, y_7
, z
, "y_8");
1838 * tmp = _mm_mul_ps(z, *(v4sf*)_ps_0p5);
1839 * y = _mm_sub_ps(y, tmp);
1840 * y = _mm_add_ps(y, *(v4sf*)_ps_1);
1842 LLVMValueRef half
= lp_build_const_v4sf(gallivm
, 0.5);
1843 LLVMValueRef tmp
= LLVMBuildFMul(b
, z
, half
, "tmp");
1844 LLVMValueRef y_9
= LLVMBuildFSub(b
, y_8
, tmp
, "y_8");
1845 LLVMValueRef one
= lp_build_const_v4sf(gallivm
, 1.0);
1846 LLVMValueRef y_10
= LLVMBuildFAdd(b
, y_9
, one
, "y_9");
1849 * _PS_CONST(sincof_p0, -1.9515295891E-4);
1850 * _PS_CONST(sincof_p1, 8.3321608736E-3);
1851 * _PS_CONST(sincof_p2, -1.6666654611E-1);
1853 LLVMValueRef sincof_p0
= lp_build_const_v4sf(gallivm
, -1.9515295891E-4);
1854 LLVMValueRef sincof_p1
= lp_build_const_v4sf(gallivm
, 8.3321608736E-3);
1855 LLVMValueRef sincof_p2
= lp_build_const_v4sf(gallivm
, -1.6666654611E-1);
1858 * Evaluate the second polynom (Pi/4 <= x <= 0)
1860 * y2 = *(v4sf*)_ps_sincof_p0;
1861 * y2 = _mm_mul_ps(y2, z);
1862 * y2 = _mm_add_ps(y2, *(v4sf*)_ps_sincof_p1);
1863 * y2 = _mm_mul_ps(y2, z);
1864 * y2 = _mm_add_ps(y2, *(v4sf*)_ps_sincof_p2);
1865 * y2 = _mm_mul_ps(y2, z);
1866 * y2 = _mm_mul_ps(y2, x);
1867 * y2 = _mm_add_ps(y2, x);
1870 LLVMValueRef y2_3
= LLVMBuildFMul(b
, z
, sincof_p0
, "y2_3");
1871 LLVMValueRef y2_4
= LLVMBuildFAdd(b
, y2_3
, sincof_p1
, "y2_4");
1872 LLVMValueRef y2_5
= LLVMBuildFMul(b
, y2_4
, z
, "y2_5");
1873 LLVMValueRef y2_6
= LLVMBuildFAdd(b
, y2_5
, sincof_p2
, "y2_6");
1874 LLVMValueRef y2_7
= LLVMBuildFMul(b
, y2_6
, z
, "y2_7");
1875 LLVMValueRef y2_8
= LLVMBuildFMul(b
, y2_7
, x_3
, "y2_8");
1876 LLVMValueRef y2_9
= LLVMBuildFAdd(b
, y2_8
, x_3
, "y2_9");
1879 * select the correct result from the two polynoms
1881 * y2 = _mm_and_ps(xmm3, y2); //, xmm3);
1882 * y = _mm_andnot_ps(xmm3, y);
1883 * y = _mm_add_ps(y,y2);
1885 LLVMValueRef y2_i
= LLVMBuildBitCast(b
, y2_9
, v4si
, "y2_i");
1886 LLVMValueRef y_i
= LLVMBuildBitCast(b
, y_10
, v4si
, "y_i");
1887 LLVMValueRef y2_and
= LLVMBuildAnd(b
, y2_i
, poly_mask
, "y2_and");
1888 LLVMValueRef inv
= lp_build_const_v4si(bld
->gallivm
, ~0);
1889 LLVMValueRef poly_mask_inv
= LLVMBuildXor(b
, poly_mask
, inv
, "poly_mask_inv");
1890 LLVMValueRef y_and
= LLVMBuildAnd(b
, y_i
, poly_mask_inv
, "y_and");
1891 LLVMValueRef y_combine
= LLVMBuildAdd(b
, y_and
, y2_and
, "y_combine");
1895 * y = _mm_xor_ps(y, sign_bit);
1897 LLVMValueRef y_sign
= LLVMBuildXor(b
, y_combine
, sign_bit_1
, "y_sin");
1898 LLVMValueRef y_result
= LLVMBuildBitCast(b
, y_sign
, v4sf
, "y_result");
1904 * Generate cos(a) using SSE2
1907 lp_build_cos(struct lp_build_context
*bld
,
1910 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
1911 struct gallivm_state
*gallivm
= bld
->gallivm
;
1912 struct lp_type int_type
= lp_int_type(bld
->type
);
1913 LLVMBuilderRef b
= builder
;
1914 LLVMTypeRef v4sf
= LLVMVectorType(LLVMFloatTypeInContext(bld
->gallivm
->context
), 4);
1915 LLVMTypeRef v4si
= LLVMVectorType(LLVMInt32TypeInContext(bld
->gallivm
->context
), 4);
1918 * take the absolute value,
1919 * x = _mm_and_ps(x, *(v4sf*)_ps_inv_sign_mask);
1922 LLVMValueRef inv_sig_mask
= lp_build_const_v4si(bld
->gallivm
, ~0x80000000);
1923 LLVMValueRef a_v4si
= LLVMBuildBitCast(b
, a
, v4si
, "a_v4si");
1925 LLVMValueRef absi
= LLVMBuildAnd(b
, a_v4si
, inv_sig_mask
, "absi");
1926 LLVMValueRef x_abs
= LLVMBuildBitCast(b
, absi
, v4sf
, "x_abs");
1930 * y = _mm_mul_ps(x, *(v4sf*)_ps_cephes_FOPI);
1933 LLVMValueRef FOPi
= lp_build_const_v4sf(gallivm
, 1.27323954473516);
1934 LLVMValueRef scale_y
= LLVMBuildFMul(b
, x_abs
, FOPi
, "scale_y");
1937 * store the integer part of y in mm0
1938 * emm2 = _mm_cvttps_epi32(y);
1941 LLVMValueRef emm2_i
= LLVMBuildFPToSI(b
, scale_y
, v4si
, "emm2_i");
1944 * j=(j+1) & (~1) (see the cephes sources)
1945 * emm2 = _mm_add_epi32(emm2, *(v4si*)_pi32_1);
1948 LLVMValueRef all_one
= lp_build_const_v4si(bld
->gallivm
, 1);
1949 LLVMValueRef emm2_add
= LLVMBuildAdd(b
, emm2_i
, all_one
, "emm2_add");
1951 * emm2 = _mm_and_si128(emm2, *(v4si*)_pi32_inv1);
1953 LLVMValueRef inv_one
= lp_build_const_v4si(bld
->gallivm
, ~1);
1954 LLVMValueRef emm2_and
= LLVMBuildAnd(b
, emm2_add
, inv_one
, "emm2_and");
1957 * y = _mm_cvtepi32_ps(emm2);
1959 LLVMValueRef y_2
= LLVMBuildSIToFP(b
, emm2_and
, v4sf
, "y_2");
1963 * emm2 = _mm_sub_epi32(emm2, *(v4si*)_pi32_2);
1965 LLVMValueRef const_2
= lp_build_const_v4si(bld
->gallivm
, 2);
1966 LLVMValueRef emm2_2
= LLVMBuildSub(b
, emm2_and
, const_2
, "emm2_2");
1969 /* get the swap sign flag
1970 * emm0 = _mm_andnot_si128(emm2, *(v4si*)_pi32_4);
1972 LLVMValueRef inv
= lp_build_const_v4si(bld
->gallivm
, ~0);
1973 LLVMValueRef emm0_not
= LLVMBuildXor(b
, emm2_2
, inv
, "emm0_not");
1974 LLVMValueRef pi32_4
= lp_build_const_v4si(bld
->gallivm
, 4);
1975 LLVMValueRef emm0_and
= LLVMBuildAnd(b
, emm0_not
, pi32_4
, "emm0_and");
1978 * emm2 = _mm_slli_epi32(emm0, 29);
1980 LLVMValueRef const_29
= lp_build_const_v4si(bld
->gallivm
, 29);
1981 LLVMValueRef sign_bit
= LLVMBuildShl(b
, emm0_and
, const_29
, "sign_bit");
1984 * get the polynom selection mask
1985 * there is one polynom for 0 <= x <= Pi/4
1986 * and another one for Pi/4<x<=Pi/2
1987 * Both branches will be computed.
1989 * emm2 = _mm_and_si128(emm2, *(v4si*)_pi32_2);
1990 * emm2 = _mm_cmpeq_epi32(emm2, _mm_setzero_si128());
1993 LLVMValueRef pi32_2
= lp_build_const_v4si(bld
->gallivm
, 2);
1994 LLVMValueRef emm2_3
= LLVMBuildAnd(b
, emm2_2
, pi32_2
, "emm2_3");
1995 LLVMValueRef poly_mask
= lp_build_compare(bld
->gallivm
,
1996 int_type
, PIPE_FUNC_EQUAL
,
1997 emm2_3
, lp_build_const_v4si(bld
->gallivm
, 0));
2000 * _PS_CONST(minus_cephes_DP1, -0.78515625);
2001 * _PS_CONST(minus_cephes_DP2, -2.4187564849853515625e-4);
2002 * _PS_CONST(minus_cephes_DP3, -3.77489497744594108e-8);
2004 LLVMValueRef DP1
= lp_build_const_v4sf(gallivm
, -0.78515625);
2005 LLVMValueRef DP2
= lp_build_const_v4sf(gallivm
, -2.4187564849853515625e-4);
2006 LLVMValueRef DP3
= lp_build_const_v4sf(gallivm
, -3.77489497744594108e-8);
2009 * The magic pass: "Extended precision modular arithmetic"
2010 * x = ((x - y * DP1) - y * DP2) - y * DP3;
2011 * xmm1 = _mm_mul_ps(y, xmm1);
2012 * xmm2 = _mm_mul_ps(y, xmm2);
2013 * xmm3 = _mm_mul_ps(y, xmm3);
2015 LLVMValueRef xmm1
= LLVMBuildFMul(b
, y_2
, DP1
, "xmm1");
2016 LLVMValueRef xmm2
= LLVMBuildFMul(b
, y_2
, DP2
, "xmm2");
2017 LLVMValueRef xmm3
= LLVMBuildFMul(b
, y_2
, DP3
, "xmm3");
2020 * x = _mm_add_ps(x, xmm1);
2021 * x = _mm_add_ps(x, xmm2);
2022 * x = _mm_add_ps(x, xmm3);
2025 LLVMValueRef x_1
= LLVMBuildFAdd(b
, x_abs
, xmm1
, "x_1");
2026 LLVMValueRef x_2
= LLVMBuildFAdd(b
, x_1
, xmm2
, "x_2");
2027 LLVMValueRef x_3
= LLVMBuildFAdd(b
, x_2
, xmm3
, "x_3");
2030 * Evaluate the first polynom (0 <= x <= Pi/4)
2032 * z = _mm_mul_ps(x,x);
2034 LLVMValueRef z
= LLVMBuildFMul(b
, x_3
, x_3
, "z");
2037 * _PS_CONST(coscof_p0, 2.443315711809948E-005);
2038 * _PS_CONST(coscof_p1, -1.388731625493765E-003);
2039 * _PS_CONST(coscof_p2, 4.166664568298827E-002);
2041 LLVMValueRef coscof_p0
= lp_build_const_v4sf(gallivm
, 2.443315711809948E-005);
2042 LLVMValueRef coscof_p1
= lp_build_const_v4sf(gallivm
, -1.388731625493765E-003);
2043 LLVMValueRef coscof_p2
= lp_build_const_v4sf(gallivm
, 4.166664568298827E-002);
2046 * y = *(v4sf*)_ps_coscof_p0;
2047 * y = _mm_mul_ps(y, z);
2049 LLVMValueRef y_3
= LLVMBuildFMul(b
, z
, coscof_p0
, "y_3");
2050 LLVMValueRef y_4
= LLVMBuildFAdd(b
, y_3
, coscof_p1
, "y_4");
2051 LLVMValueRef y_5
= LLVMBuildFMul(b
, y_4
, z
, "y_5");
2052 LLVMValueRef y_6
= LLVMBuildFAdd(b
, y_5
, coscof_p2
, "y_6");
2053 LLVMValueRef y_7
= LLVMBuildFMul(b
, y_6
, z
, "y_7");
2054 LLVMValueRef y_8
= LLVMBuildFMul(b
, y_7
, z
, "y_8");
2058 * tmp = _mm_mul_ps(z, *(v4sf*)_ps_0p5);
2059 * y = _mm_sub_ps(y, tmp);
2060 * y = _mm_add_ps(y, *(v4sf*)_ps_1);
2062 LLVMValueRef half
= lp_build_const_v4sf(gallivm
, 0.5);
2063 LLVMValueRef tmp
= LLVMBuildFMul(b
, z
, half
, "tmp");
2064 LLVMValueRef y_9
= LLVMBuildFSub(b
, y_8
, tmp
, "y_8");
2065 LLVMValueRef one
= lp_build_const_v4sf(gallivm
, 1.0);
2066 LLVMValueRef y_10
= LLVMBuildFAdd(b
, y_9
, one
, "y_9");
2069 * _PS_CONST(sincof_p0, -1.9515295891E-4);
2070 * _PS_CONST(sincof_p1, 8.3321608736E-3);
2071 * _PS_CONST(sincof_p2, -1.6666654611E-1);
2073 LLVMValueRef sincof_p0
= lp_build_const_v4sf(gallivm
, -1.9515295891E-4);
2074 LLVMValueRef sincof_p1
= lp_build_const_v4sf(gallivm
, 8.3321608736E-3);
2075 LLVMValueRef sincof_p2
= lp_build_const_v4sf(gallivm
, -1.6666654611E-1);
2078 * Evaluate the second polynom (Pi/4 <= x <= 0)
2080 * y2 = *(v4sf*)_ps_sincof_p0;
2081 * y2 = _mm_mul_ps(y2, z);
2082 * y2 = _mm_add_ps(y2, *(v4sf*)_ps_sincof_p1);
2083 * y2 = _mm_mul_ps(y2, z);
2084 * y2 = _mm_add_ps(y2, *(v4sf*)_ps_sincof_p2);
2085 * y2 = _mm_mul_ps(y2, z);
2086 * y2 = _mm_mul_ps(y2, x);
2087 * y2 = _mm_add_ps(y2, x);
2090 LLVMValueRef y2_3
= LLVMBuildFMul(b
, z
, sincof_p0
, "y2_3");
2091 LLVMValueRef y2_4
= LLVMBuildFAdd(b
, y2_3
, sincof_p1
, "y2_4");
2092 LLVMValueRef y2_5
= LLVMBuildFMul(b
, y2_4
, z
, "y2_5");
2093 LLVMValueRef y2_6
= LLVMBuildFAdd(b
, y2_5
, sincof_p2
, "y2_6");
2094 LLVMValueRef y2_7
= LLVMBuildFMul(b
, y2_6
, z
, "y2_7");
2095 LLVMValueRef y2_8
= LLVMBuildFMul(b
, y2_7
, x_3
, "y2_8");
2096 LLVMValueRef y2_9
= LLVMBuildFAdd(b
, y2_8
, x_3
, "y2_9");
2099 * select the correct result from the two polynoms
2101 * y2 = _mm_and_ps(xmm3, y2); //, xmm3);
2102 * y = _mm_andnot_ps(xmm3, y);
2103 * y = _mm_add_ps(y,y2);
2105 LLVMValueRef y2_i
= LLVMBuildBitCast(b
, y2_9
, v4si
, "y2_i");
2106 LLVMValueRef y_i
= LLVMBuildBitCast(b
, y_10
, v4si
, "y_i");
2107 LLVMValueRef y2_and
= LLVMBuildAnd(b
, y2_i
, poly_mask
, "y2_and");
2108 LLVMValueRef poly_mask_inv
= LLVMBuildXor(b
, poly_mask
, inv
, "poly_mask_inv");
2109 LLVMValueRef y_and
= LLVMBuildAnd(b
, y_i
, poly_mask_inv
, "y_and");
2110 LLVMValueRef y_combine
= LLVMBuildAdd(b
, y_and
, y2_and
, "y_combine");
2114 * y = _mm_xor_ps(y, sign_bit);
2116 LLVMValueRef y_sign
= LLVMBuildXor(b
, y_combine
, sign_bit
, "y_sin");
2117 LLVMValueRef y_result
= LLVMBuildBitCast(b
, y_sign
, v4sf
, "y_result");
2123 * Generate pow(x, y)
2126 lp_build_pow(struct lp_build_context
*bld
,
2130 /* TODO: optimize the constant case */
2131 if (gallivm_debug
& GALLIVM_DEBUG_PERF
&&
2132 LLVMIsConstant(x
) && LLVMIsConstant(y
)) {
2133 debug_printf("%s: inefficient/imprecise constant arithmetic\n",
2137 return lp_build_exp2(bld
, lp_build_mul(bld
, lp_build_log2(bld
, x
), y
));
2145 lp_build_exp(struct lp_build_context
*bld
,
2148 /* log2(e) = 1/log(2) */
2149 LLVMValueRef log2e
= lp_build_const_vec(bld
->gallivm
, bld
->type
,
2150 1.4426950408889634);
2152 assert(lp_check_value(bld
->type
, x
));
2154 return lp_build_mul(bld
, log2e
, lp_build_exp2(bld
, x
));
2162 lp_build_log(struct lp_build_context
*bld
,
2166 LLVMValueRef log2
= lp_build_const_vec(bld
->gallivm
, bld
->type
,
2167 0.69314718055994529);
2169 assert(lp_check_value(bld
->type
, x
));
2171 return lp_build_mul(bld
, log2
, lp_build_exp2(bld
, x
));
2176 * Generate polynomial.
2177 * Ex: coeffs[0] + x * coeffs[1] + x^2 * coeffs[2].
2180 lp_build_polynomial(struct lp_build_context
*bld
,
2182 const double *coeffs
,
2183 unsigned num_coeffs
)
2185 const struct lp_type type
= bld
->type
;
2186 LLVMValueRef res
= NULL
;
2189 assert(lp_check_value(bld
->type
, x
));
2191 /* TODO: optimize the constant case */
2192 if (gallivm_debug
& GALLIVM_DEBUG_PERF
&&
2193 LLVMIsConstant(x
)) {
2194 debug_printf("%s: inefficient/imprecise constant arithmetic\n",
2198 for (i
= num_coeffs
; i
--; ) {
2201 coeff
= lp_build_const_vec(bld
->gallivm
, type
, coeffs
[i
]);
2204 res
= lp_build_add(bld
, coeff
, lp_build_mul(bld
, x
, res
));
2217 * Minimax polynomial fit of 2**x, in range [0, 1[
2219 const double lp_build_exp2_polynomial
[] = {
2220 #if EXP_POLY_DEGREE == 5
2221 0.999999999690134838155,
2222 0.583974334321735217258,
2223 0.164553105719676828492,
2224 0.0292811063701710962255,
2225 0.00354944426657875141846,
2226 0.000296253726543423377365
2227 #elif EXP_POLY_DEGREE == 4
2228 1.00000001502262084505,
2229 0.563586057338685991394,
2230 0.150436017652442413623,
2231 0.0243220604213317927308,
2232 0.0025359088446580436489
2233 #elif EXP_POLY_DEGREE == 3
2234 0.999925218562710312959,
2235 0.695833540494823811697,
2236 0.226067155427249155588,
2237 0.0780245226406372992967
2238 #elif EXP_POLY_DEGREE == 2
2239 1.00172476321474503578,
2240 0.657636275736077639316,
2241 0.33718943461968720704
2249 lp_build_exp2_approx(struct lp_build_context
*bld
,
2251 LLVMValueRef
*p_exp2_int_part
,
2252 LLVMValueRef
*p_frac_part
,
2253 LLVMValueRef
*p_exp2
)
2255 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
2256 const struct lp_type type
= bld
->type
;
2257 LLVMTypeRef vec_type
= lp_build_vec_type(bld
->gallivm
, type
);
2258 LLVMTypeRef int_vec_type
= lp_build_int_vec_type(bld
->gallivm
, type
);
2259 LLVMValueRef ipart
= NULL
;
2260 LLVMValueRef fpart
= NULL
;
2261 LLVMValueRef expipart
= NULL
;
2262 LLVMValueRef expfpart
= NULL
;
2263 LLVMValueRef res
= NULL
;
2265 assert(lp_check_value(bld
->type
, x
));
2267 if(p_exp2_int_part
|| p_frac_part
|| p_exp2
) {
2268 /* TODO: optimize the constant case */
2269 if (gallivm_debug
& GALLIVM_DEBUG_PERF
&&
2270 LLVMIsConstant(x
)) {
2271 debug_printf("%s: inefficient/imprecise constant arithmetic\n",
2275 assert(type
.floating
&& type
.width
== 32);
2277 x
= lp_build_min(bld
, x
, lp_build_const_vec(bld
->gallivm
, type
, 129.0));
2278 x
= lp_build_max(bld
, x
, lp_build_const_vec(bld
->gallivm
, type
, -126.99999));
2280 /* ipart = floor(x) */
2281 ipart
= lp_build_floor(bld
, x
);
2283 /* fpart = x - ipart */
2284 fpart
= LLVMBuildFSub(builder
, x
, ipart
, "");
2287 if(p_exp2_int_part
|| p_exp2
) {
2288 /* expipart = (float) (1 << ipart) */
2289 ipart
= LLVMBuildFPToSI(builder
, ipart
, int_vec_type
, "");
2290 expipart
= LLVMBuildAdd(builder
, ipart
,
2291 lp_build_const_int_vec(bld
->gallivm
, type
, 127), "");
2292 expipart
= LLVMBuildShl(builder
, expipart
,
2293 lp_build_const_int_vec(bld
->gallivm
, type
, 23), "");
2294 expipart
= LLVMBuildBitCast(builder
, expipart
, vec_type
, "");
2298 expfpart
= lp_build_polynomial(bld
, fpart
, lp_build_exp2_polynomial
,
2299 Elements(lp_build_exp2_polynomial
));
2301 res
= LLVMBuildFMul(builder
, expipart
, expfpart
, "");
2305 *p_exp2_int_part
= expipart
;
2308 *p_frac_part
= fpart
;
2316 lp_build_exp2(struct lp_build_context
*bld
,
2320 lp_build_exp2_approx(bld
, x
, NULL
, NULL
, &res
);
2326 * Extract the exponent of a IEEE-754 floating point value.
2328 * Optionally apply an integer bias.
2330 * Result is an integer value with
2332 * ifloor(log2(x)) + bias
2335 lp_build_extract_exponent(struct lp_build_context
*bld
,
2339 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
2340 const struct lp_type type
= bld
->type
;
2341 unsigned mantissa
= lp_mantissa(type
);
2344 assert(type
.floating
);
2346 assert(lp_check_value(bld
->type
, x
));
2348 x
= LLVMBuildBitCast(builder
, x
, bld
->int_vec_type
, "");
2350 res
= LLVMBuildLShr(builder
, x
,
2351 lp_build_const_int_vec(bld
->gallivm
, type
, mantissa
), "");
2352 res
= LLVMBuildAnd(builder
, res
,
2353 lp_build_const_int_vec(bld
->gallivm
, type
, 255), "");
2354 res
= LLVMBuildSub(builder
, res
,
2355 lp_build_const_int_vec(bld
->gallivm
, type
, 127 - bias
), "");
2362 * Extract the mantissa of the a floating.
2364 * Result is a floating point value with
2366 * x / floor(log2(x))
2369 lp_build_extract_mantissa(struct lp_build_context
*bld
,
2372 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
2373 const struct lp_type type
= bld
->type
;
2374 unsigned mantissa
= lp_mantissa(type
);
2375 LLVMValueRef mantmask
= lp_build_const_int_vec(bld
->gallivm
, type
,
2376 (1ULL << mantissa
) - 1);
2377 LLVMValueRef one
= LLVMConstBitCast(bld
->one
, bld
->int_vec_type
);
2380 assert(lp_check_value(bld
->type
, x
));
2382 assert(type
.floating
);
2384 x
= LLVMBuildBitCast(builder
, x
, bld
->int_vec_type
, "");
2386 /* res = x / 2**ipart */
2387 res
= LLVMBuildAnd(builder
, x
, mantmask
, "");
2388 res
= LLVMBuildOr(builder
, res
, one
, "");
2389 res
= LLVMBuildBitCast(builder
, res
, bld
->vec_type
, "");
2397 * Minimax polynomial fit of log2(x)/(x - 1), for x in range [1, 2[
2398 * These coefficients can be generate with
2399 * http://www.boost.org/doc/libs/1_36_0/libs/math/doc/sf_and_dist/html/math_toolkit/toolkit/internals2/minimax.html
2401 const double lp_build_log2_polynomial
[] = {
2402 #if LOG_POLY_DEGREE == 6
2403 3.11578814719469302614,
2404 -3.32419399085241980044,
2405 2.59883907202499966007,
2406 -1.23152682416275988241,
2407 0.318212422185251071475,
2408 -0.0344359067839062357313
2409 #elif LOG_POLY_DEGREE == 5
2410 2.8882704548164776201,
2411 -2.52074962577807006663,
2412 1.48116647521213171641,
2413 -0.465725644288844778798,
2414 0.0596515482674574969533
2415 #elif LOG_POLY_DEGREE == 4
2416 2.61761038894603480148,
2417 -1.75647175389045657003,
2418 0.688243882994381274313,
2419 -0.107254423828329604454
2420 #elif LOG_POLY_DEGREE == 3
2421 2.28330284476918490682,
2422 -1.04913055217340124191,
2423 0.204446009836232697516
2431 * See http://www.devmaster.net/forums/showthread.php?p=43580
2434 lp_build_log2_approx(struct lp_build_context
*bld
,
2436 LLVMValueRef
*p_exp
,
2437 LLVMValueRef
*p_floor_log2
,
2438 LLVMValueRef
*p_log2
)
2440 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
2441 const struct lp_type type
= bld
->type
;
2442 LLVMTypeRef vec_type
= lp_build_vec_type(bld
->gallivm
, type
);
2443 LLVMTypeRef int_vec_type
= lp_build_int_vec_type(bld
->gallivm
, type
);
2445 LLVMValueRef expmask
= lp_build_const_int_vec(bld
->gallivm
, type
, 0x7f800000);
2446 LLVMValueRef mantmask
= lp_build_const_int_vec(bld
->gallivm
, type
, 0x007fffff);
2447 LLVMValueRef one
= LLVMConstBitCast(bld
->one
, int_vec_type
);
2449 LLVMValueRef i
= NULL
;
2450 LLVMValueRef exp
= NULL
;
2451 LLVMValueRef mant
= NULL
;
2452 LLVMValueRef logexp
= NULL
;
2453 LLVMValueRef logmant
= NULL
;
2454 LLVMValueRef res
= NULL
;
2456 assert(lp_check_value(bld
->type
, x
));
2458 if(p_exp
|| p_floor_log2
|| p_log2
) {
2459 /* TODO: optimize the constant case */
2460 if (gallivm_debug
& GALLIVM_DEBUG_PERF
&&
2461 LLVMIsConstant(x
)) {
2462 debug_printf("%s: inefficient/imprecise constant arithmetic\n",
2466 assert(type
.floating
&& type
.width
== 32);
2468 i
= LLVMBuildBitCast(builder
, x
, int_vec_type
, "");
2470 /* exp = (float) exponent(x) */
2471 exp
= LLVMBuildAnd(builder
, i
, expmask
, "");
2474 if(p_floor_log2
|| p_log2
) {
2475 logexp
= LLVMBuildLShr(builder
, exp
, lp_build_const_int_vec(bld
->gallivm
, type
, 23), "");
2476 logexp
= LLVMBuildSub(builder
, logexp
, lp_build_const_int_vec(bld
->gallivm
, type
, 127), "");
2477 logexp
= LLVMBuildSIToFP(builder
, logexp
, vec_type
, "");
2481 /* mant = (float) mantissa(x) */
2482 mant
= LLVMBuildAnd(builder
, i
, mantmask
, "");
2483 mant
= LLVMBuildOr(builder
, mant
, one
, "");
2484 mant
= LLVMBuildBitCast(builder
, mant
, vec_type
, "");
2486 logmant
= lp_build_polynomial(bld
, mant
, lp_build_log2_polynomial
,
2487 Elements(lp_build_log2_polynomial
));
2489 /* This effectively increases the polynomial degree by one, but ensures that log2(1) == 0*/
2490 logmant
= LLVMBuildFMul(builder
, logmant
, LLVMBuildFSub(builder
, mant
, bld
->one
, ""), "");
2492 res
= LLVMBuildFAdd(builder
, logmant
, logexp
, "");
2496 exp
= LLVMBuildBitCast(builder
, exp
, vec_type
, "");
2501 *p_floor_log2
= logexp
;
2509 lp_build_log2(struct lp_build_context
*bld
,
2513 lp_build_log2_approx(bld
, x
, NULL
, NULL
, &res
);
2519 * Faster (and less accurate) log2.
2521 * log2(x) = floor(log2(x)) - 1 + x / 2**floor(log2(x))
2523 * Piece-wise linear approximation, with exact results when x is a
2526 * See http://www.flipcode.com/archives/Fast_log_Function.shtml
2529 lp_build_fast_log2(struct lp_build_context
*bld
,
2532 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
2536 assert(lp_check_value(bld
->type
, x
));
2538 assert(bld
->type
.floating
);
2540 /* ipart = floor(log2(x)) - 1 */
2541 ipart
= lp_build_extract_exponent(bld
, x
, -1);
2542 ipart
= LLVMBuildSIToFP(builder
, ipart
, bld
->vec_type
, "");
2544 /* fpart = x / 2**ipart */
2545 fpart
= lp_build_extract_mantissa(bld
, x
);
2548 return LLVMBuildFAdd(builder
, ipart
, fpart
, "");
2553 * Fast implementation of iround(log2(x)).
2555 * Not an approximation -- it should give accurate results all the time.
2558 lp_build_ilog2(struct lp_build_context
*bld
,
2561 LLVMBuilderRef builder
= bld
->gallivm
->builder
;
2562 LLVMValueRef sqrt2
= lp_build_const_vec(bld
->gallivm
, bld
->type
, M_SQRT2
);
2565 assert(bld
->type
.floating
);
2567 assert(lp_check_value(bld
->type
, x
));
2569 /* x * 2^(0.5) i.e., add 0.5 to the log2(x) */
2570 x
= LLVMBuildFMul(builder
, x
, sqrt2
, "");
2572 /* ipart = floor(log2(x) + 0.5) */
2573 ipart
= lp_build_extract_exponent(bld
, x
, 0);