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