Mercurial > vec
comparison 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 |
comparison
equal
deleted
inserted
replaced
40:55cadb1fac4b | 41:c6e0df09b86f |
---|---|
117 #define LOSIGN(x) ((x) ? "" : "u") | 117 #define LOSIGN(x) ((x) ? "" : "u") |
118 | 118 |
119 static void print_gcc_op(enum op op, int is_signed, int bits, int size) | 119 static void print_gcc_op(enum op op, int is_signed, int bits, int size) |
120 { | 120 { |
121 int i; | 121 int i; |
122 | 122 int gccprereq = 0; |
123 | |
124 switch (op) { | |
125 case OP_CMPEQ: | |
126 case OP_CMPLE: | |
127 case OP_CMPLT: | |
128 case OP_CMPGT: | |
129 case OP_CMPGE: | |
130 case OP_MIN: | |
131 case OP_MAX: | |
132 case OP_LSHIFT: | |
133 case OP_RSHIFT: | |
134 case OP_LRSHIFT: | |
135 case OP_AVG: | |
136 puts("#if VEC_GNUC_ATLEAST(4, 3, 0)"); | |
137 gccprereq = 1; | |
138 break; | |
139 default: | |
140 break; | |
141 } | |
142 | |
123 printf("#ifndef V%sINT%dx%d_%s_DEFINED\n", UPSIGN(is_signed), bits, size, op_names[op].u); | 143 printf("#ifndef V%sINT%dx%d_%s_DEFINED\n", UPSIGN(is_signed), bits, size, op_names[op].u); |
124 | 144 |
125 printf("VEC_FUNC_IMPL "); | 145 printf("VEC_FUNC_IMPL "); |
126 | 146 |
127 /* first; the return value */ | 147 /* first; the return value */ |
269 printf("\tvec1.gcc = (vec1.gcc & mask.gcc) | (vec2.gcc & ~mask.gcc);\n"); | 289 printf("\tvec1.gcc = (vec1.gcc & mask.gcc) | (vec2.gcc & ~mask.gcc);\n"); |
270 printf("\treturn vec1;\n"); | 290 printf("\treturn vec1;\n"); |
271 break; | 291 break; |
272 } | 292 } |
273 case OP_AVG: | 293 case OP_AVG: |
294 printf("\tvint%dx%d ones = vint%dx%d_splat(1);\n", bits, size, bits, size); | |
295 | |
274 if (is_signed) { | 296 if (is_signed) { |
275 printf("\tvint%dx%d ones = vint%dx%d_splat(1);\n", bits, size, bits, size); | 297 puts("\t__typeof__(vec1.gcc) x_d_rem = (vec1.gcc % 2);"); |
276 printf("\t__typeof__(vec1.gcc) x_d_rem = (vec1.gcc % 2);\n"); | 298 puts("\t__typeof__(vec1.gcc) y_d_rem = (vec2.gcc % 2);"); |
277 printf("\t__typeof__(vec1.gcc) y_d_rem = (vec2.gcc % 2);\n"); | 299 puts("\t__typeof__(vec1.gcc) rem_d_quot = ((x_d_rem + y_d_rem) / 2);"); |
278 printf("\t__typeof__(vec1.gcc) rem_d_quot = ((x_d_rem + y_d_rem) / 2);\n"); | 300 puts("\t__typeof__(vec1.gcc) rem_d_rem = ((x_d_rem + y_d_rem) % 2);"); |
279 printf("\t__typeof__(vec1.gcc) rem_d_rem = ((x_d_rem + y_d_rem) % 2);\n"); | |
280 puts(""); | 301 puts(""); |
281 printf("\tvec1.gcc = ((vec1.gcc / 2) + (vec2.gcc / 2)) + (rem_d_quot) + ((rem_d_rem == 1) & ones.gcc);\n"); | 302 printf("\tvec1.gcc = ((vec1.gcc / 2) + (vec2.gcc / 2)) + (rem_d_quot) + ((rem_d_rem == 1) & ones.gcc);\n"); |
282 } else { | 303 } else { |
283 printf("\tvec1.gcc = (vec1.gcc >> 1) + (vec2.gcc >> 1) + ((vec1.gcc | vec2.gcc) & 1);\n"); | 304 printf("\tvec1.gcc = (vec1.gcc >> 1) + (vec2.gcc >> 1) + ((vec1.gcc | vec2.gcc) & ones.gcc);\n"); |
284 } | 305 } |
285 | 306 |
286 printf("\treturn vec1;\n"); | 307 printf("\treturn vec1;\n"); |
287 break; | 308 break; |
288 case OP_NOT: | 309 case OP_NOT: |
297 /* end function definition */ | 318 /* end function definition */ |
298 puts("}"); | 319 puts("}"); |
299 | 320 |
300 printf("# define V%sINT%dx%d_%s_DEFINED\n", UPSIGN(is_signed), bits, size, op_names[op].u); | 321 printf("# define V%sINT%dx%d_%s_DEFINED\n", UPSIGN(is_signed), bits, size, op_names[op].u); |
301 puts("#endif"); | 322 puts("#endif"); |
323 | |
324 if (gccprereq) | |
325 puts("#endif"); | |
302 } | 326 } |
303 | 327 |
304 static inline void print_ops(int is_signed, int bits, int size) | 328 static inline void print_ops(int is_signed, int bits, int size) |
305 { | 329 { |
306 int i; | 330 int i; |