• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 struct gallivm_state;
46 
47 
48 /**
49  * Complement, i.e., 1 - a.
50  */
51 LLVMValueRef
52 lp_build_comp(struct lp_build_context *bld,
53               LLVMValueRef a);
54 
55 LLVMValueRef
56 lp_build_add(struct lp_build_context *bld,
57              LLVMValueRef a,
58              LLVMValueRef b);
59 
60 LLVMValueRef
61 lp_build_horizontal_add(struct lp_build_context *bld,
62                         LLVMValueRef a);
63 
64 LLVMValueRef
65 lp_build_hadd_partial4(struct lp_build_context *bld,
66                        LLVMValueRef vectors[],
67                        unsigned num_vecs);
68 
69 LLVMValueRef
70 lp_build_sub(struct lp_build_context *bld,
71              LLVMValueRef a,
72              LLVMValueRef b);
73 
74 
75 LLVMValueRef
76 lp_build_mul_norm(struct gallivm_state *gallivm,
77                   struct lp_type wide_type,
78                   LLVMValueRef a,
79                   LLVMValueRef b);
80 
81 LLVMValueRef
82 lp_build_mul(struct lp_build_context *bld,
83              LLVMValueRef a,
84              LLVMValueRef b);
85 
86 LLVMValueRef
87 lp_build_mul_32_lohi_cpu(struct lp_build_context *bld,
88                          LLVMValueRef a,
89                          LLVMValueRef b,
90                          LLVMValueRef *res_hi);
91 
92 LLVMValueRef
93 lp_build_mul_32_lohi(struct lp_build_context *bld,
94                      LLVMValueRef a,
95                      LLVMValueRef b,
96                      LLVMValueRef *res_hi);
97 
98 LLVMValueRef
99 lp_build_mul_imm(struct lp_build_context *bld,
100                  LLVMValueRef a,
101                  int b);
102 
103 LLVMValueRef
104 lp_build_div(struct lp_build_context *bld,
105              LLVMValueRef a,
106              LLVMValueRef b);
107 
108 
109 /* llvm.fmuladd.* intrinsic */
110 LLVMValueRef
111 lp_build_fmuladd(LLVMBuilderRef builder,
112                  LLVMValueRef a,
113                  LLVMValueRef b,
114                  LLVMValueRef c);
115 
116 /* a * b + c */
117 LLVMValueRef
118 lp_build_mad(struct lp_build_context *bld,
119              LLVMValueRef a,
120              LLVMValueRef b,
121              LLVMValueRef c);
122 
123 
124 /**
125  * Set when the weights for normalized are prescaled, that is, in range
126  * 0..2**n, as opposed to range 0..2**(n-1).
127  */
128 #define LP_BLD_LERP_PRESCALED_WEIGHTS (1 << 0)
129 
130 /**
131  * Used internally when using wide intermediates for normalized lerps.
132  *
133  * Do not use.
134  */
135 #define LP_BLD_LERP_WIDE_NORMALIZED (1 << 1)
136 
137 LLVMValueRef
138 lp_build_lerp(struct lp_build_context *bld,
139               LLVMValueRef x,
140               LLVMValueRef v0,
141               LLVMValueRef v1,
142               unsigned flags);
143 
144 LLVMValueRef
145 lp_build_lerp_2d(struct lp_build_context *bld,
146                  LLVMValueRef x,
147                  LLVMValueRef y,
148                  LLVMValueRef v00,
149                  LLVMValueRef v01,
150                  LLVMValueRef v10,
151                  LLVMValueRef v11,
152                  unsigned flags);
153 
154 LLVMValueRef
155 lp_build_lerp_3d(struct lp_build_context *bld,
156                  LLVMValueRef x,
157                  LLVMValueRef y,
158                  LLVMValueRef z,
159                  LLVMValueRef v000,
160                  LLVMValueRef v001,
161                  LLVMValueRef v010,
162                  LLVMValueRef v011,
163                  LLVMValueRef v100,
164                  LLVMValueRef v101,
165                  LLVMValueRef v110,
166                  LLVMValueRef v111,
167                  unsigned flags);
168 
169 /**
170  * Specifies floating point NaN behavior.
171  */
172 enum gallivm_nan_behavior {
173    /* Results are undefined with NaN. Results in fastest code */
174    GALLIVM_NAN_BEHAVIOR_UNDEFINED,
175    /* If one of the inputs is NaN, NaN is returned */
176    GALLIVM_NAN_RETURN_NAN,
177    /* If one of the inputs is NaN, the other operand is returned */
178    GALLIVM_NAN_RETURN_OTHER,
179    /* If one of the inputs is NaN, the other operand is returned,
180     * but we guarantee the second operand is not a NaN.
181     * In min/max it will be as fast as undefined with sse opcodes,
182     * and archs having native return_other can benefit too. */
183    GALLIVM_NAN_RETURN_OTHER_SECOND_NONNAN,
184    /* If one of the inputs is NaN, NaN is returned,
185     * but we guarantee the first operand is not a NaN.
186     * In min/max it will be as fast as undefined with sse opcodes,
187     * and archs having native return_nan can benefit too. */
188    GALLIVM_NAN_RETURN_NAN_FIRST_NONNAN,
189 
190 };
191 
192 LLVMValueRef
193 lp_build_min(struct lp_build_context *bld,
194              LLVMValueRef a,
195              LLVMValueRef b);
196 
197 LLVMValueRef
198 lp_build_min_ext(struct lp_build_context *bld,
199                  LLVMValueRef a,
200                  LLVMValueRef b,
201                  enum gallivm_nan_behavior nan_behavior);
202 
203 LLVMValueRef
204 lp_build_max(struct lp_build_context *bld,
205              LLVMValueRef a,
206              LLVMValueRef b);
207 
208 LLVMValueRef
209 lp_build_max_ext(struct lp_build_context *bld,
210                  LLVMValueRef a,
211                  LLVMValueRef b,
212                  enum gallivm_nan_behavior nan_behavior);
213 
214 LLVMValueRef
215 lp_build_clamp(struct lp_build_context *bld,
216                LLVMValueRef a,
217                LLVMValueRef min,
218                LLVMValueRef max);
219 
220 LLVMValueRef
221 lp_build_clamp_zero_one_nanzero(struct lp_build_context *bld,
222                                 LLVMValueRef a);
223 
224 LLVMValueRef
225 lp_build_abs(struct lp_build_context *bld,
226              LLVMValueRef a);
227 
228 LLVMValueRef
229 lp_build_negate(struct lp_build_context *bld,
230                 LLVMValueRef a);
231 
232 LLVMValueRef
233 lp_build_sgn(struct lp_build_context *bld,
234              LLVMValueRef a);
235 
236 LLVMValueRef
237 lp_build_set_sign(struct lp_build_context *bld,
238                   LLVMValueRef a, LLVMValueRef sign);
239 
240 LLVMValueRef
241 lp_build_int_to_float(struct lp_build_context *bld,
242                       LLVMValueRef a);
243 
244 LLVMValueRef
245 lp_build_round(struct lp_build_context *bld,
246                LLVMValueRef a);
247 
248 LLVMValueRef
249 lp_build_floor(struct lp_build_context *bld,
250                LLVMValueRef a);
251 
252 LLVMValueRef
253 lp_build_ceil(struct lp_build_context *bld,
254               LLVMValueRef a);
255 
256 LLVMValueRef
257 lp_build_trunc(struct lp_build_context *bld,
258                LLVMValueRef a);
259 
260 LLVMValueRef
261 lp_build_fract(struct lp_build_context *bld,
262                LLVMValueRef a);
263 
264 LLVMValueRef
265 lp_build_fract_safe(struct lp_build_context *bld,
266                     LLVMValueRef a);
267 
268 LLVMValueRef
269 lp_build_ifloor(struct lp_build_context *bld,
270                 LLVMValueRef a);
271 LLVMValueRef
272 lp_build_iceil(struct lp_build_context *bld,
273                LLVMValueRef a);
274 
275 LLVMValueRef
276 lp_build_iround(struct lp_build_context *bld,
277                 LLVMValueRef a);
278 
279 LLVMValueRef
280 lp_build_itrunc(struct lp_build_context *bld,
281                 LLVMValueRef a);
282 
283 void
284 lp_build_ifloor_fract(struct lp_build_context *bld,
285                       LLVMValueRef a,
286                       LLVMValueRef *out_ipart,
287                       LLVMValueRef *out_fpart);
288 
289 void
290 lp_build_ifloor_fract_safe(struct lp_build_context *bld,
291                            LLVMValueRef a,
292                            LLVMValueRef *out_ipart,
293                            LLVMValueRef *out_fpart);
294 
295 LLVMValueRef
296 lp_build_sqrt(struct lp_build_context *bld,
297               LLVMValueRef a);
298 
299 LLVMValueRef
300 lp_build_rcp(struct lp_build_context *bld,
301              LLVMValueRef a);
302 
303 LLVMValueRef
304 lp_build_rsqrt(struct lp_build_context *bld,
305                LLVMValueRef a);
306 
307 boolean
308 lp_build_fast_rsqrt_available(struct lp_type type);
309 
310 LLVMValueRef
311 lp_build_fast_rsqrt(struct lp_build_context *bld,
312                     LLVMValueRef a);
313 
314 LLVMValueRef
315 lp_build_polynomial(struct lp_build_context *bld,
316                     LLVMValueRef x,
317                     const double *coeffs,
318                     unsigned num_coeffs);
319 
320 LLVMValueRef
321 lp_build_cos(struct lp_build_context *bld,
322              LLVMValueRef a);
323 
324 LLVMValueRef
325 lp_build_sin(struct lp_build_context *bld,
326              LLVMValueRef a);
327 
328 LLVMValueRef
329 lp_build_pow(struct lp_build_context *bld,
330              LLVMValueRef a,
331              LLVMValueRef b);
332 
333 LLVMValueRef
334 lp_build_exp(struct lp_build_context *bld,
335              LLVMValueRef a);
336 
337 LLVMValueRef
338 lp_build_log(struct lp_build_context *bld,
339              LLVMValueRef a);
340 
341 LLVMValueRef
342 lp_build_log_safe(struct lp_build_context *bld,
343                   LLVMValueRef a);
344 
345 LLVMValueRef
346 lp_build_exp2(struct lp_build_context *bld,
347               LLVMValueRef a);
348 
349 LLVMValueRef
350 lp_build_extract_exponent(struct lp_build_context *bld,
351                           LLVMValueRef x,
352                           int bias);
353 
354 LLVMValueRef
355 lp_build_extract_mantissa(struct lp_build_context *bld,
356                           LLVMValueRef x);
357 
358 LLVMValueRef
359 lp_build_log2(struct lp_build_context *bld,
360               LLVMValueRef a);
361 
362 LLVMValueRef
363 lp_build_log2_safe(struct lp_build_context *bld,
364                    LLVMValueRef a);
365 
366 LLVMValueRef
367 lp_build_fast_log2(struct lp_build_context *bld,
368                    LLVMValueRef a);
369 
370 LLVMValueRef
371 lp_build_ilog2(struct lp_build_context *bld,
372                LLVMValueRef x);
373 
374 void
375 lp_build_log2_approx(struct lp_build_context *bld,
376                      LLVMValueRef x,
377                      LLVMValueRef *p_exp,
378                      LLVMValueRef *p_floor_log2,
379                      LLVMValueRef *p_log2,
380                      boolean handle_nans);
381 
382 LLVMValueRef
383 lp_build_mod(struct lp_build_context *bld,
384              LLVMValueRef x,
385              LLVMValueRef y);
386 
387 LLVMValueRef
388 lp_build_isnan(struct lp_build_context *bld,
389                LLVMValueRef x);
390 
391 LLVMValueRef
392 lp_build_isfinite(struct lp_build_context *bld,
393                   LLVMValueRef x);
394 
395 
396 LLVMValueRef
397 lp_build_is_inf_or_nan(struct gallivm_state *gallivm,
398                        const struct lp_type type,
399                        LLVMValueRef x);
400 
401 
402 LLVMValueRef
403 lp_build_fpstate_get(struct gallivm_state *gallivm);
404 
405 void
406 lp_build_fpstate_set_denorms_zero(struct gallivm_state *gallivm,
407                                   boolean zero);
408 void
409 lp_build_fpstate_set(struct gallivm_state *gallivm,
410                      LLVMValueRef mxcsr);
411 
412 #endif /* !LP_BLD_ARIT_H */
413