Mercurial > vec
diff utils/gengcc.c @ 41:c6e0df09b86f default tip
*: performance improvements with old GCC, reimplement altivec
author | Paper <paper@tflc.us> |
---|---|
date | Mon, 28 Apr 2025 16:31:59 -0400 |
parents | 55cadb1fac4b |
children |
line wrap: on
line diff
--- a/utils/gengcc.c Sun Apr 27 02:49:53 2025 -0400 +++ b/utils/gengcc.c Mon Apr 28 16:31:59 2025 -0400 @@ -119,7 +119,27 @@ static void print_gcc_op(enum op op, int is_signed, int bits, int size) { int i; + int gccprereq = 0; + switch (op) { + case OP_CMPEQ: + case OP_CMPLE: + case OP_CMPLT: + case OP_CMPGT: + case OP_CMPGE: + case OP_MIN: + case OP_MAX: + case OP_LSHIFT: + case OP_RSHIFT: + case OP_LRSHIFT: + case OP_AVG: + puts("#if VEC_GNUC_ATLEAST(4, 3, 0)"); + gccprereq = 1; + break; + default: + break; + } + printf("#ifndef V%sINT%dx%d_%s_DEFINED\n", UPSIGN(is_signed), bits, size, op_names[op].u); printf("VEC_FUNC_IMPL "); @@ -271,16 +291,17 @@ break; } case OP_AVG: + printf("\tvint%dx%d ones = vint%dx%d_splat(1);\n", bits, size, bits, size); + if (is_signed) { - printf("\tvint%dx%d ones = vint%dx%d_splat(1);\n", bits, size, bits, size); - printf("\t__typeof__(vec1.gcc) x_d_rem = (vec1.gcc % 2);\n"); - printf("\t__typeof__(vec1.gcc) y_d_rem = (vec2.gcc % 2);\n"); - printf("\t__typeof__(vec1.gcc) rem_d_quot = ((x_d_rem + y_d_rem) / 2);\n"); - printf("\t__typeof__(vec1.gcc) rem_d_rem = ((x_d_rem + y_d_rem) % 2);\n"); + puts("\t__typeof__(vec1.gcc) x_d_rem = (vec1.gcc % 2);"); + puts("\t__typeof__(vec1.gcc) y_d_rem = (vec2.gcc % 2);"); + puts("\t__typeof__(vec1.gcc) rem_d_quot = ((x_d_rem + y_d_rem) / 2);"); + puts("\t__typeof__(vec1.gcc) rem_d_rem = ((x_d_rem + y_d_rem) % 2);"); puts(""); printf("\tvec1.gcc = ((vec1.gcc / 2) + (vec2.gcc / 2)) + (rem_d_quot) + ((rem_d_rem == 1) & ones.gcc);\n"); } else { - printf("\tvec1.gcc = (vec1.gcc >> 1) + (vec2.gcc >> 1) + ((vec1.gcc | vec2.gcc) & 1);\n"); + printf("\tvec1.gcc = (vec1.gcc >> 1) + (vec2.gcc >> 1) + ((vec1.gcc | vec2.gcc) & ones.gcc);\n"); } printf("\treturn vec1;\n"); @@ -299,6 +320,9 @@ printf("# define V%sINT%dx%d_%s_DEFINED\n", UPSIGN(is_signed), bits, size, op_names[op].u); puts("#endif"); + + if (gccprereq) + puts("#endif"); } static inline void print_ops(int is_signed, int bits, int size)