gallivm: add a version of log2 which handles edge cases
[mesa.git] / src / gallium / auxiliary / gallivm / lp_bld_arit.h
1 /**************************************************************************
2 *
3 * Copyright 2009 VMware, Inc.
4 * All Rights Reserved.
5 *
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:
13 *
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.
17 *
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.
25 *
26 **************************************************************************/
27
28 /**
29 * @file
30 * Helper arithmetic functions.
31 *
32 * @author Jose Fonseca <jfonseca@vmware.com>
33 */
34
35
36 #ifndef LP_BLD_ARIT_H
37 #define LP_BLD_ARIT_H
38
39
40 #include "gallivm/lp_bld.h"
41
42
43 struct lp_type;
44 struct lp_build_context;
45
46
47 /**
48 * Complement, i.e., 1 - a.
49 */
50 LLVMValueRef
51 lp_build_comp(struct lp_build_context *bld,
52 LLVMValueRef a);
53
54 LLVMValueRef
55 lp_build_add(struct lp_build_context *bld,
56 LLVMValueRef a,
57 LLVMValueRef b);
58
59 LLVMValueRef
60 lp_build_horizontal_add(struct lp_build_context *bld,
61 LLVMValueRef a);
62
63 LLVMValueRef
64 lp_build_hadd_partial4(struct lp_build_context *bld,
65 LLVMValueRef vectors[],
66 unsigned num_vecs);
67
68 LLVMValueRef
69 lp_build_sub(struct lp_build_context *bld,
70 LLVMValueRef a,
71 LLVMValueRef b);
72
73 LLVMValueRef
74 lp_build_mul(struct lp_build_context *bld,
75 LLVMValueRef a,
76 LLVMValueRef b);
77
78 LLVMValueRef
79 lp_build_mul_imm(struct lp_build_context *bld,
80 LLVMValueRef a,
81 int b);
82
83 LLVMValueRef
84 lp_build_div(struct lp_build_context *bld,
85 LLVMValueRef a,
86 LLVMValueRef b);
87
88
89 /**
90 * Set when the weights for normalized are prescaled, that is, in range
91 * 0..2**n, as opposed to range 0..2**(n-1).
92 */
93 #define LP_BLD_LERP_PRESCALED_WEIGHTS (1 << 0)
94
95 /**
96 * Used internally when using wide intermediates for normalized lerps.
97 *
98 * Do not use.
99 */
100 #define LP_BLD_LERP_WIDE_NORMALIZED (1 << 1)
101
102 LLVMValueRef
103 lp_build_lerp(struct lp_build_context *bld,
104 LLVMValueRef x,
105 LLVMValueRef v0,
106 LLVMValueRef v1,
107 unsigned flags);
108
109 LLVMValueRef
110 lp_build_lerp_2d(struct lp_build_context *bld,
111 LLVMValueRef x,
112 LLVMValueRef y,
113 LLVMValueRef v00,
114 LLVMValueRef v01,
115 LLVMValueRef v10,
116 LLVMValueRef v11,
117 unsigned flags);
118
119 LLVMValueRef
120 lp_build_lerp_3d(struct lp_build_context *bld,
121 LLVMValueRef x,
122 LLVMValueRef y,
123 LLVMValueRef z,
124 LLVMValueRef v000,
125 LLVMValueRef v001,
126 LLVMValueRef v010,
127 LLVMValueRef v011,
128 LLVMValueRef v100,
129 LLVMValueRef v101,
130 LLVMValueRef v110,
131 LLVMValueRef v111,
132 unsigned flags);
133
134 /**
135 * Specifies floating point NaN behavior.
136 */
137 enum gallivm_nan_behavior {
138 /* Results are undefined with NaN. Results in fastest code */
139 GALLIVM_NAN_BEHAVIOR_UNDEFINED,
140 /* If input is NaN, NaN is returned */
141 GALLIVM_NAN_RETURN_NAN,
142 /* If one of the inputs is NaN, the other operand is returned */
143 GALLIVM_NAN_RETURN_OTHER,
144 /* If one of the inputs is NaN, the second operand is returned.
145 * In min/max it will be as fast as undefined with sse opcodes */
146 GALLIVM_NAN_RETURN_SECOND
147 };
148
149 LLVMValueRef
150 lp_build_min(struct lp_build_context *bld,
151 LLVMValueRef a,
152 LLVMValueRef b);
153
154 LLVMValueRef
155 lp_build_min_ext(struct lp_build_context *bld,
156 LLVMValueRef a,
157 LLVMValueRef b,
158 enum gallivm_nan_behavior nan_behavior);
159
160 LLVMValueRef
161 lp_build_max(struct lp_build_context *bld,
162 LLVMValueRef a,
163 LLVMValueRef b);
164
165 LLVMValueRef
166 lp_build_max_ext(struct lp_build_context *bld,
167 LLVMValueRef a,
168 LLVMValueRef b,
169 enum gallivm_nan_behavior nan_behavior);
170
171 LLVMValueRef
172 lp_build_clamp(struct lp_build_context *bld,
173 LLVMValueRef a,
174 LLVMValueRef min,
175 LLVMValueRef max);
176
177 LLVMValueRef
178 lp_build_abs(struct lp_build_context *bld,
179 LLVMValueRef a);
180
181 LLVMValueRef
182 lp_build_negate(struct lp_build_context *bld,
183 LLVMValueRef a);
184
185 LLVMValueRef
186 lp_build_sgn(struct lp_build_context *bld,
187 LLVMValueRef a);
188
189 LLVMValueRef
190 lp_build_set_sign(struct lp_build_context *bld,
191 LLVMValueRef a, LLVMValueRef sign);
192
193 LLVMValueRef
194 lp_build_int_to_float(struct lp_build_context *bld,
195 LLVMValueRef a);
196
197 LLVMValueRef
198 lp_build_round(struct lp_build_context *bld,
199 LLVMValueRef a);
200
201 LLVMValueRef
202 lp_build_floor(struct lp_build_context *bld,
203 LLVMValueRef a);
204
205 LLVMValueRef
206 lp_build_ceil(struct lp_build_context *bld,
207 LLVMValueRef a);
208
209 LLVMValueRef
210 lp_build_trunc(struct lp_build_context *bld,
211 LLVMValueRef a);
212
213 LLVMValueRef
214 lp_build_fract(struct lp_build_context *bld,
215 LLVMValueRef a);
216
217 LLVMValueRef
218 lp_build_fract_safe(struct lp_build_context *bld,
219 LLVMValueRef a);
220
221 LLVMValueRef
222 lp_build_ifloor(struct lp_build_context *bld,
223 LLVMValueRef a);
224 LLVMValueRef
225 lp_build_iceil(struct lp_build_context *bld,
226 LLVMValueRef a);
227
228 LLVMValueRef
229 lp_build_iround(struct lp_build_context *bld,
230 LLVMValueRef a);
231
232 LLVMValueRef
233 lp_build_itrunc(struct lp_build_context *bld,
234 LLVMValueRef a);
235
236 void
237 lp_build_ifloor_fract(struct lp_build_context *bld,
238 LLVMValueRef a,
239 LLVMValueRef *out_ipart,
240 LLVMValueRef *out_fpart);
241
242 void
243 lp_build_ifloor_fract_safe(struct lp_build_context *bld,
244 LLVMValueRef a,
245 LLVMValueRef *out_ipart,
246 LLVMValueRef *out_fpart);
247
248 LLVMValueRef
249 lp_build_sqrt(struct lp_build_context *bld,
250 LLVMValueRef a);
251
252 LLVMValueRef
253 lp_build_rcp(struct lp_build_context *bld,
254 LLVMValueRef a);
255
256 LLVMValueRef
257 lp_build_rsqrt(struct lp_build_context *bld,
258 LLVMValueRef a);
259
260 boolean
261 lp_build_fast_rsqrt_available(struct lp_type type);
262
263 LLVMValueRef
264 lp_build_fast_rsqrt(struct lp_build_context *bld,
265 LLVMValueRef a);
266
267 LLVMValueRef
268 lp_build_polynomial(struct lp_build_context *bld,
269 LLVMValueRef x,
270 const double *coeffs,
271 unsigned num_coeffs);
272
273 LLVMValueRef
274 lp_build_cos(struct lp_build_context *bld,
275 LLVMValueRef a);
276
277 LLVMValueRef
278 lp_build_sin(struct lp_build_context *bld,
279 LLVMValueRef a);
280
281 LLVMValueRef
282 lp_build_pow(struct lp_build_context *bld,
283 LLVMValueRef a,
284 LLVMValueRef b);
285
286 LLVMValueRef
287 lp_build_exp(struct lp_build_context *bld,
288 LLVMValueRef a);
289
290 LLVMValueRef
291 lp_build_log(struct lp_build_context *bld,
292 LLVMValueRef a);
293
294 LLVMValueRef
295 lp_build_exp2(struct lp_build_context *bld,
296 LLVMValueRef a);
297
298 LLVMValueRef
299 lp_build_extract_exponent(struct lp_build_context *bld,
300 LLVMValueRef x,
301 int bias);
302
303 LLVMValueRef
304 lp_build_extract_mantissa(struct lp_build_context *bld,
305 LLVMValueRef x);
306
307 LLVMValueRef
308 lp_build_log2(struct lp_build_context *bld,
309 LLVMValueRef a);
310
311 LLVMValueRef
312 lp_build_log2_safe(struct lp_build_context *bld,
313 LLVMValueRef a);
314
315 LLVMValueRef
316 lp_build_fast_log2(struct lp_build_context *bld,
317 LLVMValueRef a);
318
319 LLVMValueRef
320 lp_build_ilog2(struct lp_build_context *bld,
321 LLVMValueRef x);
322
323 void
324 lp_build_exp2_approx(struct lp_build_context *bld,
325 LLVMValueRef x,
326 LLVMValueRef *p_exp2_int_part,
327 LLVMValueRef *p_frac_part,
328 LLVMValueRef *p_exp2);
329
330 void
331 lp_build_log2_approx(struct lp_build_context *bld,
332 LLVMValueRef x,
333 LLVMValueRef *p_exp,
334 LLVMValueRef *p_floor_log2,
335 LLVMValueRef *p_log2,
336 boolean handle_nans);
337
338 LLVMValueRef
339 lp_build_mod(struct lp_build_context *bld,
340 LLVMValueRef x,
341 LLVMValueRef y);
342
343 LLVMValueRef
344 lp_build_isnan(struct lp_build_context *bld,
345 LLVMValueRef x);
346
347 #endif /* !LP_BLD_ARIT_H */