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)