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;