Home | History | Annotate | Download | only in ScriptCRT
      1 #include "rs_types.rsh"
      2 
      3 // Conversions
      4 #define CVT_FUNC_2(typeout, typein)                             \
      5 extern typeout##2 __attribute__((overloadable))             \
      6         convert_##typeout##2(typein##2 v) {                     \
      7     typeout##2 r = {(typeout)v.x, (typeout)v.y};                \
      8     return r;                                                   \
      9 }                                                               \
     10 extern typeout##3 __attribute__((overloadable))             \
     11         convert_##typeout##3(typein##3 v) {                     \
     12     typeout##3 r = {(typeout)v.x, (typeout)v.y, (typeout)v.z};  \
     13     return r;                                                   \
     14 }                                                               \
     15 extern typeout##4 __attribute__((overloadable))             \
     16         convert_##typeout##4(typein##4 v) {                     \
     17     typeout##4 r = {(typeout)v.x, (typeout)v.y, (typeout)v.z,   \
     18                     (typeout)v.w};                              \
     19     return r;                                                   \
     20 }
     21 
     22 #define CVT_FUNC(type)  CVT_FUNC_2(type, uchar)     \
     23                         CVT_FUNC_2(type, char)      \
     24                         CVT_FUNC_2(type, ushort)    \
     25                         CVT_FUNC_2(type, short)     \
     26                         CVT_FUNC_2(type, uint)      \
     27                         CVT_FUNC_2(type, int)       \
     28                         CVT_FUNC_2(type, float)
     29 
     30 CVT_FUNC(char)
     31 //CVT_FUNC(uchar)
     32 CVT_FUNC(short)
     33 CVT_FUNC(ushort)
     34 CVT_FUNC(int)
     35 CVT_FUNC(uint)
     36 //CVT_FUNC(float)
     37 
     38 // Float ops, 6.11.2
     39 
     40 #define FN_FUNC_FN(fnc)                                         \
     41 extern float2 __attribute__((overloadable)) fnc(float2 v) { \
     42     float2 r;                                                   \
     43     r.x = fnc(v.x);                                             \
     44     r.y = fnc(v.y);                                             \
     45     return r;                                                   \
     46 }                                                               \
     47 extern float3 __attribute__((overloadable)) fnc(float3 v) { \
     48     float3 r;                                                   \
     49     r.x = fnc(v.x);                                             \
     50     r.y = fnc(v.y);                                             \
     51     r.z = fnc(v.z);                                             \
     52     return r;                                                   \
     53 }                                                               \
     54 extern float4 __attribute__((overloadable)) fnc(float4 v) { \
     55     float4 r;                                                   \
     56     r.x = fnc(v.x);                                             \
     57     r.y = fnc(v.y);                                             \
     58     r.z = fnc(v.z);                                             \
     59     r.w = fnc(v.w);                                             \
     60     return r;                                                   \
     61 }
     62 
     63 #define IN_FUNC_FN(fnc)                                         \
     64 extern int2 __attribute__((overloadable)) fnc(float2 v) {   \
     65     int2 r;                                                     \
     66     r.x = fnc(v.x);                                             \
     67     r.y = fnc(v.y);                                             \
     68     return r;                                                   \
     69 }                                                               \
     70 extern int3 __attribute__((overloadable)) fnc(float3 v) {   \
     71     int3 r;                                                     \
     72     r.x = fnc(v.x);                                             \
     73     r.y = fnc(v.y);                                             \
     74     r.z = fnc(v.z);                                             \
     75     return r;                                                   \
     76 }                                                               \
     77 extern int4 __attribute__((overloadable)) fnc(float4 v) {   \
     78     int4 r;                                                     \
     79     r.x = fnc(v.x);                                             \
     80     r.y = fnc(v.y);                                             \
     81     r.z = fnc(v.z);                                             \
     82     r.w = fnc(v.w);                                             \
     83     return r;                                                   \
     84 }
     85 
     86 #define FN_FUNC_FN_FN(fnc)                                                  \
     87 extern float2 __attribute__((overloadable)) fnc(float2 v1, float2 v2) { \
     88     float2 r;                                                               \
     89     r.x = fnc(v1.x, v2.x);                                                  \
     90     r.y = fnc(v1.y, v2.y);                                                  \
     91     return r;                                                               \
     92 }                                                                           \
     93 extern float3 __attribute__((overloadable)) fnc(float3 v1, float3 v2) { \
     94     float3 r;                                                               \
     95     r.x = fnc(v1.x, v2.x);                                                  \
     96     r.y = fnc(v1.y, v2.y);                                                  \
     97     r.z = fnc(v1.z, v2.z);                                                  \
     98     return r;                                                               \
     99 }                                                                           \
    100 extern float4 __attribute__((overloadable)) fnc(float4 v1, float4 v2) { \
    101     float4 r;                                                               \
    102     r.x = fnc(v1.x, v2.x);                                                  \
    103     r.y = fnc(v1.y, v2.y);                                                  \
    104     r.z = fnc(v1.z, v2.z);                                                  \
    105     r.w = fnc(v1.w, v2.w);                                                  \
    106     return r;                                                               \
    107 }
    108 
    109 #define FN_FUNC_FN_F(fnc)                                                   \
    110 extern float2 __attribute__((overloadable)) fnc(float2 v1, float v2) {  \
    111     float2 r;                                                               \
    112     r.x = fnc(v1.x, v2);                                                    \
    113     r.y = fnc(v1.y, v2);                                                    \
    114     return r;                                                               \
    115 }                                                                           \
    116 extern float3 __attribute__((overloadable)) fnc(float3 v1, float v2) {  \
    117     float3 r;                                                               \
    118     r.x = fnc(v1.x, v2);                                                    \
    119     r.y = fnc(v1.y, v2);                                                    \
    120     r.z = fnc(v1.z, v2);                                                    \
    121     return r;                                                               \
    122 }                                                                           \
    123 extern float4 __attribute__((overloadable)) fnc(float4 v1, float v2) {  \
    124     float4 r;                                                               \
    125     r.x = fnc(v1.x, v2);                                                    \
    126     r.y = fnc(v1.y, v2);                                                    \
    127     r.z = fnc(v1.z, v2);                                                    \
    128     r.w = fnc(v1.w, v2);                                                    \
    129     return r;                                                               \
    130 }
    131 
    132 #define FN_FUNC_FN_IN(fnc)                                                  \
    133 extern float2 __attribute__((overloadable)) fnc(float2 v1, int2 v2) {   \
    134     float2 r;                                                               \
    135     r.x = fnc(v1.x, v2.x);                                                  \
    136     r.y = fnc(v1.y, v2.y);                                                  \
    137     return r;                                                               \
    138 }                                                                           \
    139 extern float3 __attribute__((overloadable)) fnc(float3 v1, int3 v2) {   \
    140     float3 r;                                                               \
    141     r.x = fnc(v1.x, v2.x);                                                  \
    142     r.y = fnc(v1.y, v2.y);                                                  \
    143     r.z = fnc(v1.z, v2.z);                                                  \
    144     return r;                                                               \
    145 }                                                                           \
    146 extern float4 __attribute__((overloadable)) fnc(float4 v1, int4 v2) {   \
    147     float4 r;                                                               \
    148     r.x = fnc(v1.x, v2.x);                                                  \
    149     r.y = fnc(v1.y, v2.y);                                                  \
    150     r.z = fnc(v1.z, v2.z);                                                  \
    151     r.w = fnc(v1.w, v2.w);                                                  \
    152     return r;                                                               \
    153 }
    154 
    155 #define FN_FUNC_FN_I(fnc)                                                   \
    156 extern float2 __attribute__((overloadable)) fnc(float2 v1, int v2) {    \
    157     float2 r;                                                               \
    158     r.x = fnc(v1.x, v2);                                                    \
    159     r.y = fnc(v1.y, v2);                                                    \
    160     return r;                                                               \
    161 }                                                                           \
    162 extern float3 __attribute__((overloadable)) fnc(float3 v1, int v2) {    \
    163     float3 r;                                                               \
    164     r.x = fnc(v1.x, v2);                                                    \
    165     r.y = fnc(v1.y, v2);                                                    \
    166     r.z = fnc(v1.z, v2);                                                    \
    167     return r;                                                               \
    168 }                                                                           \
    169 extern float4 __attribute__((overloadable)) fnc(float4 v1, int v2) {    \
    170     float4 r;                                                               \
    171     r.x = fnc(v1.x, v2);                                                    \
    172     r.y = fnc(v1.y, v2);                                                    \
    173     r.z = fnc(v1.z, v2);                                                    \
    174     r.w = fnc(v1.w, v2);                                                    \
    175     return r;                                                               \
    176 }
    177 
    178 #define FN_FUNC_FN_PFN(fnc)                     \
    179 extern float2 __attribute__((overloadable)) \
    180         fnc(float2 v1, float2 *v2) {            \
    181     float2 r;                                   \
    182     float t[2];                                 \
    183     r.x = fnc(v1.x, &t[0]);                     \
    184     r.y = fnc(v1.y, &t[1]);                     \
    185     v2->x = t[0];                               \
    186     v2->y = t[1];                               \
    187     return r;                                   \
    188 }                                               \
    189 extern float3 __attribute__((overloadable)) \
    190         fnc(float3 v1, float3 *v2) {            \
    191     float3 r;                                   \
    192     float t[3];                                 \
    193     r.x = fnc(v1.x, &t[0]);                     \
    194     r.y = fnc(v1.y, &t[1]);                     \
    195     r.z = fnc(v1.z, &t[2]);                     \
    196     v2->x = t[0];                               \
    197     v2->y = t[1];                               \
    198     v2->z = t[2];                               \
    199     return r;                                   \
    200 }                                               \
    201 extern float4 __attribute__((overloadable)) \
    202         fnc(float4 v1, float4 *v2) {            \
    203     float4 r;                                   \
    204     float t[4];                                 \
    205     r.x = fnc(v1.x, &t[0]);                     \
    206     r.y = fnc(v1.y, &t[1]);                     \
    207     r.z = fnc(v1.z, &t[2]);                     \
    208     r.w = fnc(v1.w, &t[3]);                     \
    209     v2->x = t[0];                               \
    210     v2->y = t[1];                               \
    211     v2->z = t[2];                               \
    212     v2->w = t[3];                               \
    213     return r;                                   \
    214 }
    215 
    216 #define FN_FUNC_FN_PIN(fnc)                                                 \
    217 extern float2 __attribute__((overloadable)) fnc(float2 v1, int2 *v2) {  \
    218     float2 r;                                                               \
    219     int t[2];                                                               \
    220     r.x = fnc(v1.x, &t[0]);                                                 \
    221     r.y = fnc(v1.y, &t[1]);                                                 \
    222     v2->x = t[0];                                                           \
    223     v2->y = t[1];                                                           \
    224     return r;                                                               \
    225 }                                                                           \
    226 extern float3 __attribute__((overloadable)) fnc(float3 v1, int3 *v2) {  \
    227     float3 r;                                                               \
    228     int t[3];                                                               \
    229     r.x = fnc(v1.x, &t[0]);                                                 \
    230     r.y = fnc(v1.y, &t[1]);                                                 \
    231     r.z = fnc(v1.z, &t[2]);                                                 \
    232     v2->x = t[0];                                                           \
    233     v2->y = t[1];                                                           \
    234     v2->z = t[2];                                                           \
    235     return r;                                                               \
    236 }                                                                           \
    237 extern float4 __attribute__((overloadable)) fnc(float4 v1, int4 *v2) {  \
    238     float4 r;                                                               \
    239     int t[4];                                                               \
    240     r.x = fnc(v1.x, &t[0]);                                                 \
    241     r.y = fnc(v1.y, &t[1]);                                                 \
    242     r.z = fnc(v1.z, &t[2]);                                                 \
    243     r.w = fnc(v1.w, &t[3]);                                                 \
    244     v2->x = t[0];                                                           \
    245     v2->y = t[1];                                                           \
    246     v2->z = t[2];                                                           \
    247     v2->w = t[3];                                                           \
    248     return r;                                                               \
    249 }
    250 
    251 #define FN_FUNC_FN_FN_FN(fnc)                   \
    252 extern float2 __attribute__((overloadable)) \
    253         fnc(float2 v1, float2 v2, float2 v3) {  \
    254     float2 r;                                   \
    255     r.x = fnc(v1.x, v2.x, v3.x);                \
    256     r.y = fnc(v1.y, v2.y, v3.y);                \
    257     return r;                                   \
    258 }                                               \
    259 extern float3 __attribute__((overloadable)) \
    260         fnc(float3 v1, float3 v2, float3 v3) {  \
    261     float3 r;                                   \
    262     r.x = fnc(v1.x, v2.x, v3.x);                \
    263     r.y = fnc(v1.y, v2.y, v3.y);                \
    264     r.z = fnc(v1.z, v2.z, v3.z);                \
    265     return r;                                   \
    266 }                                               \
    267 extern float4 __attribute__((overloadable)) \
    268         fnc(float4 v1, float4 v2, float4 v3) {  \
    269     float4 r;                                   \
    270     r.x = fnc(v1.x, v2.x, v3.x);                \
    271     r.y = fnc(v1.y, v2.y, v3.y);                \
    272     r.z = fnc(v1.z, v2.z, v3.z);                \
    273     r.w = fnc(v1.w, v2.w, v3.w);                \
    274     return r;                                   \
    275 }
    276 
    277 #define FN_FUNC_FN_FN_PIN(fnc)                  \
    278 extern float2 __attribute__((overloadable)) \
    279         fnc(float2 v1, float2 v2, int2 *v3) {   \
    280     float2 r;                                   \
    281     int t[2];                                   \
    282     r.x = fnc(v1.x, v2.x, &t[0]);               \
    283     r.y = fnc(v1.y, v2.y, &t[1]);               \
    284     v3->x = t[0];                               \
    285     v3->y = t[1];                               \
    286     return r;                                   \
    287 }                                               \
    288 extern float3 __attribute__((overloadable)) \
    289         fnc(float3 v1, float3 v2, int3 *v3) {   \
    290     float3 r;                                   \
    291     int t[3];                                   \
    292     r.x = fnc(v1.x, v2.x, &t[0]);               \
    293     r.y = fnc(v1.y, v2.y, &t[1]);               \
    294     r.z = fnc(v1.z, v2.z, &t[2]);               \
    295     v3->x = t[0];                               \
    296     v3->y = t[1];                               \
    297     v3->z = t[2];                               \
    298     return r;                                   \
    299 }                                               \
    300 extern float4 __attribute__((overloadable)) \
    301         fnc(float4 v1, float4 v2, int4 *v3) {   \
    302     float4 r;                                   \
    303     int t[4];                                   \
    304     r.x = fnc(v1.x, v2.x, &t[0]);               \
    305     r.y = fnc(v1.y, v2.y, &t[1]);               \
    306     r.z = fnc(v1.z, v2.z, &t[2]);               \
    307     r.w = fnc(v1.w, v2.w, &t[3]);               \
    308     v3->x = t[0];                               \
    309     v3->y = t[1];                               \
    310     v3->z = t[2];                               \
    311     v3->w = t[3];                               \
    312     return r;                                   \
    313 }
    314 
    315 static const int iposinf = 0x7f800000;
    316 static const int ineginf = 0xff800000;
    317 
    318 static const float posinf() {
    319     float f = *((float*)&iposinf);
    320     return f;
    321 }
    322 
    323 static const float neginf() {
    324     float f = *((float*)&ineginf);
    325     return f;
    326 }
    327 
    328 static bool isinf(float f) {
    329     int i = *((int*)(void*)&f);
    330     return (i == iposinf) || (i == ineginf);
    331 }
    332 
    333 static bool isnan(float f) {
    334     int i = *((int*)(void*)&f);
    335     return (((i & 0x7f800000) == 0x7f800000) && (i & 0x007fffff));
    336 }
    337 
    338 static bool isposzero(float f) {
    339     int i = *((int*)(void*)&f);
    340     return (i == 0x00000000);
    341 }
    342 
    343 static bool isnegzero(float f) {
    344     int i = *((int*)(void*)&f);
    345     return (i == 0x80000000);
    346 }
    347 
    348 static bool iszero(float f) {
    349     return isposzero(f) || isnegzero(f);
    350 }
    351 
    352 
    353 extern float __attribute__((overloadable)) acos(float);
    354 FN_FUNC_FN(acos)
    355 
    356 extern float __attribute__((overloadable)) acosh(float);
    357 FN_FUNC_FN(acosh)
    358 
    359 
    360 extern float __attribute__((overloadable)) acospi(float v) {
    361     return acos(v) / M_PI;
    362 }
    363 FN_FUNC_FN(acospi)
    364 
    365 extern float __attribute__((overloadable)) asin(float);
    366 FN_FUNC_FN(asin)
    367 
    368 extern float __attribute__((overloadable)) asinh(float);
    369 FN_FUNC_FN(asinh)
    370 
    371 extern float __attribute__((overloadable)) asinpi(float v) {
    372     return asin(v) / M_PI;
    373 }
    374 FN_FUNC_FN(asinpi)
    375 
    376 extern float __attribute__((overloadable)) atan(float);
    377 FN_FUNC_FN(atan)
    378 
    379 extern float __attribute__((overloadable)) atan2(float, float);
    380 FN_FUNC_FN_FN(atan2)
    381 
    382 extern float __attribute__((overloadable)) atanh(float);
    383 FN_FUNC_FN(atanh)
    384 
    385 extern float __attribute__((overloadable)) atanpi(float v) {
    386     return atan(v) / M_PI;
    387 }
    388 FN_FUNC_FN(atanpi)
    389 
    390 
    391 extern float __attribute__((overloadable)) atan2pi(float y, float x) {
    392     return atan2(y, x) / M_PI;
    393 }
    394 FN_FUNC_FN_FN(atan2pi)
    395 
    396 extern float __attribute__((overloadable)) cbrt(float);
    397 FN_FUNC_FN(cbrt)
    398 
    399 extern float __attribute__((overloadable)) ceil(float);
    400 FN_FUNC_FN(ceil)
    401 
    402 extern float __attribute__((overloadable)) copysign(float, float);
    403 FN_FUNC_FN_FN(copysign)
    404 
    405 extern float __attribute__((overloadable)) cos(float);
    406 FN_FUNC_FN(cos)
    407 
    408 extern float __attribute__((overloadable)) cosh(float);
    409 FN_FUNC_FN(cosh)
    410 
    411 extern float __attribute__((overloadable)) cospi(float v) {
    412     return cos(v * M_PI);
    413 }
    414 FN_FUNC_FN(cospi)
    415 
    416 extern float __attribute__((overloadable)) erfc(float);
    417 FN_FUNC_FN(erfc)
    418 
    419 extern float __attribute__((overloadable)) erf(float);
    420 FN_FUNC_FN(erf)
    421 
    422 extern float __attribute__((overloadable)) exp(float);
    423 FN_FUNC_FN(exp)
    424 
    425 extern float __attribute__((overloadable)) exp2(float);
    426 FN_FUNC_FN(exp2)
    427 
    428 extern float __attribute__((overloadable)) pow(float, float);
    429 
    430 extern float __attribute__((overloadable)) exp10(float v) {
    431     return pow(10.f, v);
    432 }
    433 FN_FUNC_FN(exp10)
    434 
    435 extern float __attribute__((overloadable)) expm1(float);
    436 FN_FUNC_FN(expm1)
    437 
    438 extern float __attribute__((overloadable)) fabs(float);
    439 FN_FUNC_FN(fabs)
    440 
    441 extern float __attribute__((overloadable)) fdim(float, float);
    442 FN_FUNC_FN_FN(fdim)
    443 
    444 extern float __attribute__((overloadable)) floor(float);
    445 FN_FUNC_FN(floor)
    446 
    447 extern float __attribute__((overloadable)) fma(float, float, float);
    448 FN_FUNC_FN_FN_FN(fma)
    449 
    450 extern float __attribute__((overloadable)) fmax(float, float);
    451 FN_FUNC_FN_FN(fmax);
    452 FN_FUNC_FN_F(fmax);
    453 
    454 extern float __attribute__((overloadable)) fmin(float, float);
    455 FN_FUNC_FN_FN(fmin);
    456 FN_FUNC_FN_F(fmin);
    457 
    458 extern float __attribute__((overloadable)) fmod(float, float);
    459 FN_FUNC_FN_FN(fmod)
    460 
    461 extern float __attribute__((overloadable)) fract(float v, float *iptr) {
    462     int i = (int)floor(v);
    463     iptr[0] = i;
    464     return fmin(v - i, 0x1.fffffep-1f);
    465 }
    466 FN_FUNC_FN_PFN(fract)
    467 
    468 extern float __attribute__((overloadable)) frexp(float, int *);
    469 FN_FUNC_FN_PIN(frexp)
    470 
    471 extern float __attribute__((overloadable)) hypot(float, float);
    472 FN_FUNC_FN_FN(hypot)
    473 
    474 extern int __attribute__((overloadable)) ilogb(float);
    475 IN_FUNC_FN(ilogb)
    476 
    477 extern float __attribute__((overloadable)) ldexp(float, int);
    478 FN_FUNC_FN_IN(ldexp)
    479 FN_FUNC_FN_I(ldexp)
    480 
    481 extern float __attribute__((overloadable)) lgamma(float);
    482 FN_FUNC_FN(lgamma)
    483 extern float __attribute__((overloadable)) lgamma(float, int*);
    484 FN_FUNC_FN_PIN(lgamma)
    485 
    486 extern float __attribute__((overloadable)) log(float);
    487 FN_FUNC_FN(log)
    488 
    489 extern float __attribute__((overloadable)) log10(float);
    490 FN_FUNC_FN(log10)
    491 
    492 
    493 extern float __attribute__((overloadable)) log2(float v) {
    494     return log10(v) / log10(2.f);
    495 }
    496 FN_FUNC_FN(log2)
    497 
    498 extern float __attribute__((overloadable)) log1p(float);
    499 FN_FUNC_FN(log1p)
    500 
    501 extern float __attribute__((overloadable)) logb(float);
    502 FN_FUNC_FN(logb)
    503 
    504 extern float __attribute__((overloadable)) mad(float a, float b, float c) {
    505     return a * b + c;
    506 }
    507 extern float2 __attribute__((overloadable)) mad(float2 a, float2 b, float2 c) {
    508     return a * b + c;
    509 }
    510 extern float3 __attribute__((overloadable)) mad(float3 a, float3 b, float3 c) {
    511     return a * b + c;
    512 }
    513 extern float4 __attribute__((overloadable)) mad(float4 a, float4 b, float4 c) {
    514     return a * b + c;
    515 }
    516 
    517 extern float __attribute__((overloadable)) modf(float, float *);
    518 FN_FUNC_FN_PFN(modf);
    519 
    520 extern float __attribute__((overloadable)) nan(uint v) {
    521     float f[1];
    522     uint32_t *ip = (uint32_t *)f;
    523     *ip = v | 0x7fc00000;
    524     return f[0];
    525 }
    526 
    527 extern float __attribute__((overloadable)) nextafter(float, float);
    528 FN_FUNC_FN_FN(nextafter)
    529 
    530 FN_FUNC_FN_FN(pow)
    531 
    532 extern float __attribute__((overloadable)) pown(float v, int p) {
    533     return pow(v, (float)p);
    534 }
    535 extern float2 __attribute__((overloadable)) pown(float2 v, int2 p) {
    536     return pow(v, (float2)p);
    537 }
    538 extern float3 __attribute__((overloadable)) pown(float3 v, int3 p) {
    539     return pow(v, (float3)p);
    540 }
    541 extern float4 __attribute__((overloadable)) pown(float4 v, int4 p) {
    542     return pow(v, (float4)p);
    543 }
    544 
    545 extern float __attribute__((overloadable)) powr(float v, float p) {
    546     return pow(v, p);
    547 }
    548 extern float2 __attribute__((overloadable)) powr(float2 v, float2 p) {
    549     return pow(v, p);
    550 }
    551 extern float3 __attribute__((overloadable)) powr(float3 v, float3 p) {
    552     return pow(v, p);
    553 }
    554 extern float4 __attribute__((overloadable)) powr(float4 v, float4 p) {
    555     return pow(v, p);
    556 }
    557 
    558 extern float __attribute__((overloadable)) remainder(float, float);
    559 FN_FUNC_FN_FN(remainder)
    560 
    561 extern float __attribute__((overloadable)) remquo(float, float, int *);
    562 FN_FUNC_FN_FN_PIN(remquo)
    563 
    564 extern float __attribute__((overloadable)) rint(float);
    565 FN_FUNC_FN(rint)
    566 
    567 extern float __attribute__((overloadable)) rootn(float v, int r) {
    568     if (r == 0) {
    569         return nan(0);
    570     }
    571 
    572     if (iszero(v)) {
    573         if (r < 0) {
    574             if (r & 1) {
    575                 return copysign(posinf(), v);
    576             } else {
    577                 return posinf();
    578             }
    579         } else {
    580             if (r & 1) {
    581                 return copysign(0.f, v);
    582             } else {
    583                 return 0.f;
    584             }
    585         }
    586     }
    587 
    588     if (!isinf(v) && !isnan(v) && (v < 0.f)) {
    589         if (r & 1) {
    590             return (-1.f * pow(-1.f * v, 1.f / r));
    591         } else {
    592             return nan(0);
    593         }
    594     }
    595 
    596     return pow(v, 1.f / r);
    597 }
    598 FN_FUNC_FN_IN(rootn);
    599 
    600 extern float __attribute__((overloadable)) round(float);
    601 FN_FUNC_FN(round)
    602 
    603 
    604 extern float __attribute__((overloadable)) sqrt(float);
    605 extern float __attribute__((overloadable)) rsqrt(float v) {
    606     return 1.f / sqrt(v);
    607 }
    608 FN_FUNC_FN(rsqrt)
    609 
    610 extern float __attribute__((overloadable)) sin(float);
    611 FN_FUNC_FN(sin)
    612 
    613 extern float __attribute__((overloadable)) sincos(float v, float *cosptr) {
    614     *cosptr = cos(v);
    615     return sin(v);
    616 }
    617 extern float2 __attribute__((overloadable)) sincos(float2 v, float2 *cosptr) {
    618     *cosptr = cos(v);
    619     return sin(v);
    620 }
    621 extern float3 __attribute__((overloadable)) sincos(float3 v, float3 *cosptr) {
    622     *cosptr = cos(v);
    623     return sin(v);
    624 }
    625 extern float4 __attribute__((overloadable)) sincos(float4 v, float4 *cosptr) {
    626     *cosptr = cos(v);
    627     return sin(v);
    628 }
    629 
    630 extern float __attribute__((overloadable)) sinh(float);
    631 FN_FUNC_FN(sinh)
    632 
    633 extern float __attribute__((overloadable)) sinpi(float v) {
    634     return sin(v * M_PI);
    635 }
    636 FN_FUNC_FN(sinpi)
    637 
    638 FN_FUNC_FN(sqrt)
    639 
    640 extern float __attribute__((overloadable)) tan(float);
    641 FN_FUNC_FN(tan)
    642 
    643 extern float __attribute__((overloadable)) tanh(float);
    644 FN_FUNC_FN(tanh)
    645 
    646 extern float __attribute__((overloadable)) tanpi(float v) {
    647     return tan(v * M_PI);
    648 }
    649 FN_FUNC_FN(tanpi)
    650 
    651 
    652 extern float __attribute__((overloadable)) tgamma(float);
    653 FN_FUNC_FN(tgamma)
    654 
    655 extern float __attribute__((overloadable)) trunc(float);
    656 FN_FUNC_FN(trunc)
    657 
    658 // Int ops (partial), 6.11.3
    659 
    660 #define XN_FUNC_YN(typeout, fnc, typein)                                \
    661 extern typeout __attribute__((overloadable)) fnc(typein);               \
    662 extern typeout##2 __attribute__((overloadable)) fnc(typein##2 v) {  \
    663     typeout##2 r;                                                       \
    664     r.x = fnc(v.x);                                                     \
    665     r.y = fnc(v.y);                                                     \
    666     return r;                                                           \
    667 }                                                                       \
    668 extern typeout##3 __attribute__((overloadable)) fnc(typein##3 v) {  \
    669     typeout##3 r;                                                       \
    670     r.x = fnc(v.x);                                                     \
    671     r.y = fnc(v.y);                                                     \
    672     r.z = fnc(v.z);                                                     \
    673     return r;                                                           \
    674 }                                                                       \
    675 extern typeout##4 __attribute__((overloadable)) fnc(typein##4 v) {  \
    676     typeout##4 r;                                                       \
    677     r.x = fnc(v.x);                                                     \
    678     r.y = fnc(v.y);                                                     \
    679     r.z = fnc(v.z);                                                     \
    680     r.w = fnc(v.w);                                                     \
    681     return r;                                                           \
    682 }
    683 
    684 
    685 #define UIN_FUNC_IN(fnc)          \
    686 XN_FUNC_YN(uchar, fnc, char)      \
    687 XN_FUNC_YN(ushort, fnc, short)    \
    688 XN_FUNC_YN(uint, fnc, int)
    689 
    690 #define IN_FUNC_IN(fnc)           \
    691 XN_FUNC_YN(uchar, fnc, uchar)     \
    692 XN_FUNC_YN(char, fnc, char)       \
    693 XN_FUNC_YN(ushort, fnc, ushort)   \
    694 XN_FUNC_YN(short, fnc, short)     \
    695 XN_FUNC_YN(uint, fnc, uint)       \
    696 XN_FUNC_YN(int, fnc, int)
    697 
    698 
    699 #define XN_FUNC_XN_XN_BODY(type, fnc, body)         \
    700 extern type __attribute__((overloadable))       \
    701         fnc(type v1, type v2) {                     \
    702     return body;                                    \
    703 }                                                   \
    704 extern type##2 __attribute__((overloadable))    \
    705         fnc(type##2 v1, type##2 v2) {               \
    706     type##2 r;                                      \
    707     r.x = fnc(v1.x, v2.x);                          \
    708     r.y = fnc(v1.y, v2.y);                          \
    709     return r;                                       \
    710 }                                                   \
    711 extern type##3 __attribute__((overloadable))    \
    712         fnc(type##3 v1, type##3 v2) {               \
    713     type##3 r;                                      \
    714     r.x = fnc(v1.x, v2.x);                          \
    715     r.y = fnc(v1.y, v2.y);                          \
    716     r.z = fnc(v1.z, v2.z);                          \
    717     return r;                                       \
    718 }                                                   \
    719 extern type##4 __attribute__((overloadable))    \
    720         fnc(type##4 v1, type##4 v2) {               \
    721     type##4 r;                                      \
    722     r.x = fnc(v1.x, v2.x);                          \
    723     r.y = fnc(v1.y, v2.y);                          \
    724     r.z = fnc(v1.z, v2.z);                          \
    725     r.w = fnc(v1.w, v2.w);                          \
    726     return r;                                       \
    727 }
    728 
    729 #define IN_FUNC_IN_IN_BODY(fnc, body) \
    730 XN_FUNC_XN_XN_BODY(uchar, fnc, body)  \
    731 XN_FUNC_XN_XN_BODY(char, fnc, body)   \
    732 XN_FUNC_XN_XN_BODY(ushort, fnc, body) \
    733 XN_FUNC_XN_XN_BODY(short, fnc, body)  \
    734 XN_FUNC_XN_XN_BODY(uint, fnc, body)   \
    735 XN_FUNC_XN_XN_BODY(int, fnc, body)    \
    736 XN_FUNC_XN_XN_BODY(float, fnc, body)
    737 
    738 UIN_FUNC_IN(abs)
    739 IN_FUNC_IN(clz)
    740 
    741 IN_FUNC_IN_IN_BODY(min, (v1 < v2 ? v1 : v2))
    742 FN_FUNC_FN_F(min)
    743 
    744 IN_FUNC_IN_IN_BODY(max, (v1 > v2 ? v1 : v2))
    745 FN_FUNC_FN_F(max)
    746 
    747 
    748 // 6.11.4
    749 
    750 
    751 extern float __attribute__((overloadable)) degrees(float radians) {
    752     return radians * (180.f / M_PI);
    753 }
    754 FN_FUNC_FN(degrees)
    755 
    756 extern float __attribute__((overloadable)) mix(float start, float stop, float amount) {
    757     return start + (stop - start) * amount;
    758 }
    759 extern float2 __attribute__((overloadable)) mix(float2 start, float2 stop, float2 amount) {
    760     return start + (stop - start) * amount;
    761 }
    762 extern float3 __attribute__((overloadable)) mix(float3 start, float3 stop, float3 amount) {
    763     return start + (stop - start) * amount;
    764 }
    765 extern float4 __attribute__((overloadable)) mix(float4 start, float4 stop, float4 amount) {
    766     return start + (stop - start) * amount;
    767 }
    768 extern float2 __attribute__((overloadable)) mix(float2 start, float2 stop, float amount) {
    769     return start + (stop - start) * amount;
    770 }
    771 extern float3 __attribute__((overloadable)) mix(float3 start, float3 stop, float amount) {
    772     return start + (stop - start) * amount;
    773 }
    774 extern float4 __attribute__((overloadable)) mix(float4 start, float4 stop, float amount) {
    775     return start + (stop - start) * amount;
    776 }
    777 
    778 extern float __attribute__((overloadable)) radians(float degrees) {
    779     return degrees * (M_PI / 180.f);
    780 }
    781 FN_FUNC_FN(radians)
    782 
    783 extern float __attribute__((overloadable)) step(float edge, float v) {
    784     return (v < edge) ? 0.f : 1.f;
    785 }
    786 extern float2 __attribute__((overloadable)) step(float2 edge, float2 v) {
    787     float2 r;
    788     r.x = (v.x < edge.x) ? 0.f : 1.f;
    789     r.y = (v.y < edge.y) ? 0.f : 1.f;
    790     return r;
    791 }
    792 extern float3 __attribute__((overloadable)) step(float3 edge, float3 v) {
    793     float3 r;
    794     r.x = (v.x < edge.x) ? 0.f : 1.f;
    795     r.y = (v.y < edge.y) ? 0.f : 1.f;
    796     r.z = (v.z < edge.z) ? 0.f : 1.f;
    797     return r;
    798 }
    799 extern float4 __attribute__((overloadable)) step(float4 edge, float4 v) {
    800     float4 r;
    801     r.x = (v.x < edge.x) ? 0.f : 1.f;
    802     r.y = (v.y < edge.y) ? 0.f : 1.f;
    803     r.z = (v.z < edge.z) ? 0.f : 1.f;
    804     r.w = (v.w < edge.w) ? 0.f : 1.f;
    805     return r;
    806 }
    807 extern float2 __attribute__((overloadable)) step(float2 edge, float v) {
    808     float2 r;
    809     r.x = (v < edge.x) ? 0.f : 1.f;
    810     r.y = (v < edge.y) ? 0.f : 1.f;
    811     return r;
    812 }
    813 extern float3 __attribute__((overloadable)) step(float3 edge, float v) {
    814     float3 r;
    815     r.x = (v < edge.x) ? 0.f : 1.f;
    816     r.y = (v < edge.y) ? 0.f : 1.f;
    817     r.z = (v < edge.z) ? 0.f : 1.f;
    818     return r;
    819 }
    820 extern float4 __attribute__((overloadable)) step(float4 edge, float v) {
    821     float4 r;
    822     r.x = (v < edge.x) ? 0.f : 1.f;
    823     r.y = (v < edge.y) ? 0.f : 1.f;
    824     r.z = (v < edge.z) ? 0.f : 1.f;
    825     r.w = (v < edge.w) ? 0.f : 1.f;
    826     return r;
    827 }
    828 
    829 extern float __attribute__((overloadable)) smoothstep(float, float, float);
    830 extern float2 __attribute__((overloadable)) smoothstep(float2, float2, float2);
    831 extern float3 __attribute__((overloadable)) smoothstep(float3, float3, float3);
    832 extern float4 __attribute__((overloadable)) smoothstep(float4, float4, float4);
    833 extern float2 __attribute__((overloadable)) smoothstep(float, float, float2);
    834 extern float3 __attribute__((overloadable)) smoothstep(float, float, float3);
    835 extern float4 __attribute__((overloadable)) smoothstep(float, float, float4);
    836 
    837 extern float __attribute__((overloadable)) sign(float v) {
    838     if (v > 0) return 1.f;
    839     if (v < 0) return -1.f;
    840     return v;
    841 }
    842 FN_FUNC_FN(sign)
    843 
    844 
    845 // 6.11.5
    846 extern float3 __attribute__((overloadable)) cross(float3 lhs, float3 rhs) {
    847     float3 r;
    848     r.x = lhs.y * rhs.z  - lhs.z * rhs.y;
    849     r.y = lhs.z * rhs.x  - lhs.x * rhs.z;
    850     r.z = lhs.x * rhs.y  - lhs.y * rhs.x;
    851     return r;
    852 }
    853 
    854 extern float4 __attribute__((overloadable)) cross(float4 lhs, float4 rhs) {
    855     float4 r;
    856     r.x = lhs.y * rhs.z  - lhs.z * rhs.y;
    857     r.y = lhs.z * rhs.x  - lhs.x * rhs.z;
    858     r.z = lhs.x * rhs.y  - lhs.y * rhs.x;
    859     r.w = 0.f;
    860     return r;
    861 }
    862 
    863 extern float __attribute__((overloadable)) dot(float lhs, float rhs) {
    864     return lhs * rhs;
    865 }
    866 extern float __attribute__((overloadable)) dot(float2 lhs, float2 rhs) {
    867     return lhs.x*rhs.x + lhs.y*rhs.y;
    868 }
    869 extern float __attribute__((overloadable)) dot(float3 lhs, float3 rhs) {
    870     return lhs.x*rhs.x + lhs.y*rhs.y + lhs.z*rhs.z;
    871 }
    872 extern float __attribute__((overloadable)) dot(float4 lhs, float4 rhs) {
    873     return lhs.x*rhs.x + lhs.y*rhs.y + lhs.z*rhs.z + lhs.w*rhs.w;
    874 }
    875 
    876 extern float __attribute__((overloadable)) length(float v) {
    877     return v;
    878 }
    879 extern float __attribute__((overloadable)) length(float2 v) {
    880     return sqrt(v.x*v.x + v.y*v.y);
    881 }
    882 extern float __attribute__((overloadable)) length(float3 v) {
    883     return sqrt(v.x*v.x + v.y*v.y + v.z*v.z);
    884 }
    885 extern float __attribute__((overloadable)) length(float4 v) {
    886     return sqrt(v.x*v.x + v.y*v.y + v.z*v.z + v.w*v.w);
    887 }
    888 
    889 extern float __attribute__((overloadable)) distance(float lhs, float rhs) {
    890     return length(lhs - rhs);
    891 }
    892 extern float __attribute__((overloadable)) distance(float2 lhs, float2 rhs) {
    893     return length(lhs - rhs);
    894 }
    895 extern float __attribute__((overloadable)) distance(float3 lhs, float3 rhs) {
    896     return length(lhs - rhs);
    897 }
    898 extern float __attribute__((overloadable)) distance(float4 lhs, float4 rhs) {
    899     return length(lhs - rhs);
    900 }
    901 
    902 extern float __attribute__((overloadable)) normalize(float v) {
    903     return 1.f;
    904 }
    905 extern float2 __attribute__((overloadable)) normalize(float2 v) {
    906     return v / length(v);
    907 }
    908 extern float3 __attribute__((overloadable)) normalize(float3 v) {
    909     return v / length(v);
    910 }
    911 extern float4 __attribute__((overloadable)) normalize(float4 v) {
    912     return v / length(v);
    913 }
    914 
    915 #undef CVT_FUNC
    916 #undef CVT_FUNC_2
    917 #undef FN_FUNC_FN
    918 #undef IN_FUNC_FN
    919 #undef FN_FUNC_FN_FN
    920 #undef FN_FUNC_FN_F
    921 #undef FN_FUNC_FN_IN
    922 #undef FN_FUNC_FN_I
    923 #undef FN_FUNC_FN_PFN
    924 #undef FN_FUNC_FN_PIN
    925 #undef FN_FUNC_FN_FN_FN
    926 #undef FN_FUNC_FN_FN_PIN
    927 #undef XN_FUNC_YN
    928 #undef UIN_FUNC_IN
    929 #undef IN_FUNC_IN
    930 #undef XN_FUNC_XN_XN_BODY
    931 #undef IN_FUNC_IN_IN_BODY
    932