• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
posinf()318 static const float posinf() {
319     float f = *((float*)&iposinf);
320     return f;
321 }
322 
neginf()323 static const float neginf() {
324     float f = *((float*)&ineginf);
325     return f;
326 }
327 
isinf(float f)328 static bool isinf(float f) {
329     int i = *((int*)(void*)&f);
330     return (i == iposinf) || (i == ineginf);
331 }
332 
isnan(float f)333 static bool isnan(float f) {
334     int i = *((int*)(void*)&f);
335     return (((i & 0x7f800000) == 0x7f800000) && (i & 0x007fffff));
336 }
337 
isposzero(float f)338 static bool isposzero(float f) {
339     int i = *((int*)(void*)&f);
340     return (i == 0x00000000);
341 }
342 
isnegzero(float f)343 static bool isnegzero(float f) {
344     int i = *((int*)(void*)&f);
345     return (i == 0x80000000);
346 }
347 
iszero(float f)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);
FN_FUNC_FN(acosh)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);
FN_FUNC_FN(asinh)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);
FN_FUNC_FN(atanh)383 FN_FUNC_FN(atanh)
384 
385 extern float __attribute__((overloadable)) atanpi(float v) {
386     return atan(v) / M_PI;
387 }
FN_FUNC_FN(atanpi)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);
FN_FUNC_FN(cosh)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 
exp10(float v)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);
FN_FUNC_FN_FN(fmod)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);
FN_FUNC_FN(log10)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);
FN_FUNC_FN(logb)502 FN_FUNC_FN(logb)
503 
504 extern float __attribute__((overloadable)) mad(float a, float b, float c) {
505     return a * b + c;
506 }
mad(float2 a,float2 b,float2 c)507 extern float2 __attribute__((overloadable)) mad(float2 a, float2 b, float2 c) {
508     return a * b + c;
509 }
mad(float3 a,float3 b,float3 c)510 extern float3 __attribute__((overloadable)) mad(float3 a, float3 b, float3 c) {
511     return a * b + c;
512 }
mad(float4 a,float4 b,float4 c)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 
nan(uint v)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 
FN_FUNC_FN_FN(pow)530 FN_FUNC_FN_FN(pow)
531 
532 extern float __attribute__((overloadable)) pown(float v, int p) {
533     return pow(v, (float)p);
534 }
pown(float2 v,int2 p)535 extern float2 __attribute__((overloadable)) pown(float2 v, int2 p) {
536     return pow(v, (float2)p);
537 }
pown(float3 v,int3 p)538 extern float3 __attribute__((overloadable)) pown(float3 v, int3 p) {
539     return pow(v, (float3)p);
540 }
pown(float4 v,int4 p)541 extern float4 __attribute__((overloadable)) pown(float4 v, int4 p) {
542     return pow(v, (float4)p);
543 }
544 
powr(float v,float p)545 extern float __attribute__((overloadable)) powr(float v, float p) {
546     return pow(v, p);
547 }
powr(float2 v,float2 p)548 extern float2 __attribute__((overloadable)) powr(float2 v, float2 p) {
549     return pow(v, p);
550 }
powr(float3 v,float3 p)551 extern float3 __attribute__((overloadable)) powr(float3 v, float3 p) {
552     return pow(v, p);
553 }
powr(float4 v,float4 p)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);
FN_FUNC_FN(rint)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);
rsqrt(float v)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);
FN_FUNC_FN(sin)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 }
sincos(float2 v,float2 * cosptr)617 extern float2 __attribute__((overloadable)) sincos(float2 v, float2 *cosptr) {
618     *cosptr = cos(v);
619     return sin(v);
620 }
sincos(float3 v,float3 * cosptr)621 extern float3 __attribute__((overloadable)) sincos(float3 v, float3 *cosptr) {
622     *cosptr = cos(v);
623     return sin(v);
624 }
sincos(float4 v,float4 * cosptr)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);
FN_FUNC_FN(sinh)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);
FN_FUNC_FN(tanh)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 
UIN_FUNC_IN(abs)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 }
FN_FUNC_FN(degrees)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 }
mix(float2 start,float2 stop,float2 amount)759 extern float2 __attribute__((overloadable)) mix(float2 start, float2 stop, float2 amount) {
760     return start + (stop - start) * amount;
761 }
mix(float3 start,float3 stop,float3 amount)762 extern float3 __attribute__((overloadable)) mix(float3 start, float3 stop, float3 amount) {
763     return start + (stop - start) * amount;
764 }
mix(float4 start,float4 stop,float4 amount)765 extern float4 __attribute__((overloadable)) mix(float4 start, float4 stop, float4 amount) {
766     return start + (stop - start) * amount;
767 }
mix(float2 start,float2 stop,float amount)768 extern float2 __attribute__((overloadable)) mix(float2 start, float2 stop, float amount) {
769     return start + (stop - start) * amount;
770 }
mix(float3 start,float3 stop,float amount)771 extern float3 __attribute__((overloadable)) mix(float3 start, float3 stop, float amount) {
772     return start + (stop - start) * amount;
773 }
mix(float4 start,float4 stop,float amount)774 extern float4 __attribute__((overloadable)) mix(float4 start, float4 stop, float amount) {
775     return start + (stop - start) * amount;
776 }
777 
radians(float degrees)778 extern float __attribute__((overloadable)) radians(float degrees) {
779     return degrees * (M_PI / 180.f);
780 }
FN_FUNC_FN(radians)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 }
step(float2 edge,float2 v)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 }
step(float3 edge,float3 v)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 }
step(float4 edge,float4 v)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 }
step(float2 edge,float v)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 }
step(float3 edge,float v)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 }
step(float4 edge,float v)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 
sign(float v)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 }
FN_FUNC_FN(sign)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 
cross(float4 lhs,float4 rhs)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 
dot(float lhs,float rhs)863 extern float __attribute__((overloadable)) dot(float lhs, float rhs) {
864     return lhs * rhs;
865 }
dot(float2 lhs,float2 rhs)866 extern float __attribute__((overloadable)) dot(float2 lhs, float2 rhs) {
867     return lhs.x*rhs.x + lhs.y*rhs.y;
868 }
dot(float3 lhs,float3 rhs)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 }
dot(float4 lhs,float4 rhs)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 
length(float v)876 extern float __attribute__((overloadable)) length(float v) {
877     return v;
878 }
length(float2 v)879 extern float __attribute__((overloadable)) length(float2 v) {
880     return sqrt(v.x*v.x + v.y*v.y);
881 }
length(float3 v)882 extern float __attribute__((overloadable)) length(float3 v) {
883     return sqrt(v.x*v.x + v.y*v.y + v.z*v.z);
884 }
length(float4 v)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 
distance(float lhs,float rhs)889 extern float __attribute__((overloadable)) distance(float lhs, float rhs) {
890     return length(lhs - rhs);
891 }
distance(float2 lhs,float2 rhs)892 extern float __attribute__((overloadable)) distance(float2 lhs, float2 rhs) {
893     return length(lhs - rhs);
894 }
distance(float3 lhs,float3 rhs)895 extern float __attribute__((overloadable)) distance(float3 lhs, float3 rhs) {
896     return length(lhs - rhs);
897 }
distance(float4 lhs,float4 rhs)898 extern float __attribute__((overloadable)) distance(float4 lhs, float4 rhs) {
899     return length(lhs - rhs);
900 }
901 
normalize(float v)902 extern float __attribute__((overloadable)) normalize(float v) {
903     return 1.f;
904 }
normalize(float2 v)905 extern float2 __attribute__((overloadable)) normalize(float2 v) {
906     return v / length(v);
907 }
normalize(float3 v)908 extern float3 __attribute__((overloadable)) normalize(float3 v) {
909     return v / length(v);
910 }
normalize(float4 v)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