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