brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.3 KiB · 93088dc Raw
110 lines · plain
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include <clc/clc_convert.h>10#include <clc/integer/clc_add_sat.h>11#include <clc/integer/clc_mad24.h>12#include <clc/integer/clc_mul_hi.h>13#include <clc/integer/clc_upsample.h>14#include <clc/integer/definitions.h>15#include <clc/internal/clc.h>16#include <clc/relational/clc_select.h>17#include <clc/shared/clc_clamp.h>18 19#define __CLC_DEFINE_SIMPLE_MAD_SAT(TYPE, UP_TYPE, LIT_PREFIX)                 \20  _CLC_OVERLOAD _CLC_DEF TYPE __clc_mad_sat(TYPE x, TYPE y, TYPE z) {          \21    UP_TYPE upscaled_mad =                                                     \22        __clc_mad24(__clc_convert_##UP_TYPE(x), __clc_convert_##UP_TYPE(y),    \23                    __clc_convert_##UP_TYPE(z));                               \24    UP_TYPE clamped_mad = __clc_clamp(upscaled_mad, (UP_TYPE)LIT_PREFIX##_MIN, \25                                      (UP_TYPE)LIT_PREFIX##_MAX);              \26    return __clc_convert_##TYPE(clamped_mad);                                  \27  }28 29#define __CLC_DEFINE_SIMPLE_MAD_SAT_ALL_TYS(TYPE, UP_TYPE, LIT_PREFIX)         \30  __CLC_DEFINE_SIMPLE_MAD_SAT(TYPE, UP_TYPE, LIT_PREFIX)                       \31  __CLC_DEFINE_SIMPLE_MAD_SAT(TYPE##2, UP_TYPE##2, LIT_PREFIX)                 \32  __CLC_DEFINE_SIMPLE_MAD_SAT(TYPE##3, UP_TYPE##3, LIT_PREFIX)                 \33  __CLC_DEFINE_SIMPLE_MAD_SAT(TYPE##4, UP_TYPE##4, LIT_PREFIX)                 \34  __CLC_DEFINE_SIMPLE_MAD_SAT(TYPE##8, UP_TYPE##8, LIT_PREFIX)                 \35  __CLC_DEFINE_SIMPLE_MAD_SAT(TYPE##16, UP_TYPE##16, LIT_PREFIX)36 37__CLC_DEFINE_SIMPLE_MAD_SAT_ALL_TYS(char, int, CHAR)38__CLC_DEFINE_SIMPLE_MAD_SAT_ALL_TYS(uchar, uint, UCHAR)39__CLC_DEFINE_SIMPLE_MAD_SAT_ALL_TYS(short, int, SHRT)40__CLC_DEFINE_SIMPLE_MAD_SAT_ALL_TYS(ushort, uint, USHRT)41 42// Macro for defining mad_sat variants for uint/ulong43#define __CLC_DEFINE_UINTLONG_MAD_SAT(UTYPE, STYPE, ULIT_PREFIX)               \44  _CLC_OVERLOAD _CLC_DEF UTYPE __clc_mad_sat(UTYPE x, UTYPE y, UTYPE z) {      \45    STYPE has_mul_hi = __clc_mul_hi(x, y) != (UTYPE)0;                         \46    return __clc_select(__clc_add_sat(x * y, z), (UTYPE)ULIT_PREFIX##_MAX,     \47                        has_mul_hi);                                           \48  }49 50#define __CLC_DEFINE_UINTLONG_MAD_SAT_ALL_TYS(UTY, STY, ULIT_PREFIX)           \51  __CLC_DEFINE_UINTLONG_MAD_SAT(UTY, STY, ULIT_PREFIX)                         \52  __CLC_DEFINE_UINTLONG_MAD_SAT(UTY##2, STY##2, ULIT_PREFIX)                   \53  __CLC_DEFINE_UINTLONG_MAD_SAT(UTY##3, STY##3, ULIT_PREFIX)                   \54  __CLC_DEFINE_UINTLONG_MAD_SAT(UTY##4, STY##4, ULIT_PREFIX)                   \55  __CLC_DEFINE_UINTLONG_MAD_SAT(UTY##8, STY##8, ULIT_PREFIX)                   \56  __CLC_DEFINE_UINTLONG_MAD_SAT(UTY##16, STY##16, ULIT_PREFIX)57 58__CLC_DEFINE_UINTLONG_MAD_SAT_ALL_TYS(uint, int, UINT)59__CLC_DEFINE_UINTLONG_MAD_SAT_ALL_TYS(ulong, long, ULONG)60 61// Macro for defining mad_sat variants for int62#define __CLC_DEFINE_SINT_MAD_SAT(INTTY, UINTTY, SLONGTY)                      \63  _CLC_OVERLOAD _CLC_DEF INTTY __clc_mad_sat(INTTY x, INTTY y, INTTY z) {      \64    INTTY mhi = __clc_mul_hi(x, y);                                            \65    UINTTY mlo = __clc_as_##UINTTY(x * y);                                     \66    SLONGTY m = __clc_upsample(mhi, mlo);                                      \67    m += __clc_convert_##SLONGTY(z);                                           \68    m = __clc_clamp(m, (SLONGTY)INT_MIN, (SLONGTY)INT_MAX);                    \69    return __clc_convert_##INTTY(m);                                           \70  }71 72#define __CLC_DEFINE_SINT_MAD_SAT_ALL_TYS(INTTY, UINTTY, SLONGTY)              \73  __CLC_DEFINE_SINT_MAD_SAT(INTTY, UINTTY, SLONGTY)                            \74  __CLC_DEFINE_SINT_MAD_SAT(INTTY##2, UINTTY##2, SLONGTY##2)                   \75  __CLC_DEFINE_SINT_MAD_SAT(INTTY##3, UINTTY##3, SLONGTY##3)                   \76  __CLC_DEFINE_SINT_MAD_SAT(INTTY##4, UINTTY##4, SLONGTY##4)                   \77  __CLC_DEFINE_SINT_MAD_SAT(INTTY##8, UINTTY##8, SLONGTY##8)                   \78  __CLC_DEFINE_SINT_MAD_SAT(INTTY##16, UINTTY##16, SLONGTY##16)79 80__CLC_DEFINE_SINT_MAD_SAT_ALL_TYS(int, uint, long)81 82// Macro for defining mad_sat variants for long83#define __CLC_DEFINE_SLONG_MAD_SAT(SLONGTY, ULONGTY)                           \84  _CLC_OVERLOAD _CLC_DEF SLONGTY __clc_mad_sat(SLONGTY x, SLONGTY y,           \85                                               SLONGTY z) {                    \86    SLONGTY hi = __clc_mul_hi(x, y);                                           \87    ULONGTY ulo = __clc_as_##ULONGTY(x * y);                                   \88    SLONGTY max1 = (x < 0) == (y < 0) && hi != 0;                              \89    SLONGTY max2 = hi == 0 && ulo >= LONG_MAX &&                               \90                   (z > 0 || (ulo + __clc_as_##ULONGTY(z)) > LONG_MAX);        \91    SLONGTY min1 = (((x < 0) != (y < 0)) && hi != -1);                         \92    SLONGTY min2 =                                                             \93        hi == -1 && ulo <= ((ULONGTY)LONG_MAX + 1UL) &&                        \94        (z < 0 || __clc_as_##ULONGTY(z) < ((ULONGTY)LONG_MAX - ulo));          \95    SLONGTY ret = __clc_as_##SLONGTY(ulo + __clc_as_##ULONGTY(z));             \96    ret = __clc_select(ret, (SLONGTY)LONG_MAX, (SLONGTY)(max1 || max2));       \97    ret = __clc_select(ret, (SLONGTY)LONG_MIN, (SLONGTY)(min1 || min2));       \98    return ret;                                                                \99  }100 101#define __CLC_DEFINE_SLONG_MAD_SAT_ALL_TYS(SLONGTY, ULONGTY)                   \102  __CLC_DEFINE_SLONG_MAD_SAT(SLONGTY, ULONGTY)                                 \103  __CLC_DEFINE_SLONG_MAD_SAT(SLONGTY##2, ULONGTY##2)                           \104  __CLC_DEFINE_SLONG_MAD_SAT(SLONGTY##3, ULONGTY##3)                           \105  __CLC_DEFINE_SLONG_MAD_SAT(SLONGTY##4, ULONGTY##4)                           \106  __CLC_DEFINE_SLONG_MAD_SAT(SLONGTY##8, ULONGTY##8)                           \107  __CLC_DEFINE_SLONG_MAD_SAT(SLONGTY##16, ULONGTY##16)108 109__CLC_DEFINE_SLONG_MAD_SAT_ALL_TYS(long, ulong)110