diff options
Diffstat (limited to 'cbits/arith.c')
-rw-r--r-- | cbits/arith.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/cbits/arith.c b/cbits/arith.c new file mode 100644 index 0000000..02c8ce1 --- /dev/null +++ b/cbits/arith.c @@ -0,0 +1,49 @@ +#include <stdint.h> +#include <stdlib.h> +#include <math.h> + +typedef int32_t i32; +typedef int64_t i64; + +#define COMM_OP(name, op, typ) \ + void oxarop_ ## name ## _ ## typ ## _sv(i64 n, typ *out, typ x, typ *y) { \ + for (i64 i = 0; i < n; i++) out[i] = x op y[i]; \ + } \ + void oxarop_ ## name ## _ ## typ ## _vv(i64 n, typ *out, const typ *x, const typ *y) { \ + for (i64 i = 0; i < n; i++) out[i] = x[i] op y[i]; \ + } + +#define NONCOMM_OP(name, op, typ) \ + COMM_OP(name, op, typ) \ + void oxarop_ ## name ## _ ## typ ## _vs(i64 n, typ *out, typ *x, typ y) { \ + for (i64 i = 0; i < n; i++) out[i] = x[i] op y; \ + } + +#define UNARY_OP(name, op, typ) \ + void oxarop_ ## name ## _ ## typ(i64 n, typ *out, typ *x) { \ + for (i64 i = 0; i < n; i++) out[i] = op(x[i]); \ + } + +#define GEN_ABS(x) \ + _Generic((x), \ + int: abs, \ + long: labs, \ + long long: llabs, \ + float: fabsf, \ + double: fabs)(x) + +// This does not result in multiple loads with GCC 13. +#define GEN_SIGNUM(x) ((x) < 0 ? -1 : (x) > 0 ? 1 : 0) + +#define NUM_TYPES_LOOP_XLIST \ + X(i32) X(i64) X(double) X(float) + +#define X(typ) \ + COMM_OP(add, +, typ) \ + NONCOMM_OP(sub, -, typ) \ + COMM_OP(mul, *, typ) \ + UNARY_OP(neg, -, typ) \ + UNARY_OP(abs, GEN_ABS, typ) \ + UNARY_OP(signum, GEN_SIGNUM, typ) +NUM_TYPES_LOOP_XLIST +#undef X |