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