Module: xenomai-3 Branch: next Commit: c017e404ecb9ae7cdc46f9fd8ad30b72710e2b05 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=c017e404ecb9ae7cdc46f9fd8ad30b72710e2b05
Author: Philippe Gerum <r...@xenomai.org> Date: Thu Oct 22 14:45:05 2015 +0200 cobalt/arm64: disable callee-saved logic in fptest helpers We don't want GCC to apply any callee-saved logic to fpsimd registers in fp_regs_set() before fp_regs_check() can verify their contents, but we still want GCC to know about the registers we have clobbered. --- .../arch/arm64/include/asm/xenomai/uapi/fptest.h | 160 ++++++++++---------- testsuite/switchtest/switchtest.c | 14 +- 2 files changed, 92 insertions(+), 82 deletions(-) diff --git a/kernel/cobalt/arch/arm64/include/asm/xenomai/uapi/fptest.h b/kernel/cobalt/arch/arm64/include/asm/xenomai/uapi/fptest.h index 84607b7..7a2cb92 100644 --- a/kernel/cobalt/arch/arm64/include/asm/xenomai/uapi/fptest.h +++ b/kernel/cobalt/arch/arm64/include/asm/xenomai/uapi/fptest.h @@ -20,86 +20,86 @@ #define __COBALT_HAVE_FPU 0x1 -static inline void fp_regs_set(int features, unsigned int val) -{ - - unsigned long long e[32]; - unsigned int i; - - if (features & __COBALT_HAVE_FPU) { - - for (i = 0; i < 32; i++) - e[i] = val; - - __asm__ __volatile__("ldp d0, d1, [%0, #8 * 0] \n\ - ldp d2, d3, [%0, #8 * 2] \n\ - ldp d4, d5, [%0, #8 * 4]\n\ - ldp d6, d7, [%0, #8 * 6]\n\ - ldp d8, d9, [%0, #8 * 8]\n\ - ldp d10, d11, [%0, #8 * 10]\n\ - ldp d12, d13, [%0, #8 * 12]\n\ - ldp d14, d15, [%0, #8 * 14]\n\ - ldp d16, d17, [%0, #8 * 16]\n\ - ldp d18, d19, [%0, #8 * 18]\n\ - ldp d20, d21, [%0, #8 * 20]\n\ - ldp d22, d23, [%0, #8 * 22]\n\ - ldp d24, d25, [%0, #8 * 24]\n\ - ldp d26, d27, [%0, #8 * 26]\n\ - ldp d28, d29, [%0, #8 * 28]\n\ - ldp d30, d31, [%0, #8 * 30]" - - : /* No outputs. */ - : "r"(&e[0]) - : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15", - "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31", "memory" - ); - } - -} - -static inline unsigned int fp_regs_check(int features, unsigned int val, - int (*report)(const char *fmt, ...)) -{ - unsigned int result = val; - - unsigned int i; - unsigned long long e[32]; - - if (features & __COBALT_HAVE_FPU) { - - __asm__ __volatile__("stp d0, d1, [%0, #8 * 0] \n\ - stp d2, d3, [%0, #8 * 2] \n\ - stp d4, d5, [%0, #8 * 4]\n\ - stp d6, d7, [%0, #8 * 6]\n\ - stp d8, d9, [%0, #8 * 8]\n\ - stp d10, d11, [%0, #8 * 10]\n\ - stp d12, d13, [%0, #8 * 12]\n\ - stp d14, d15, [%0, #8 * 14]\n\ - stp d16, d17, [%0, #8 * 16]\n\ - stp d18, d19, [%0, #8 * 18]\n\ - stp d20, d21, [%0, #8 * 20]\n\ - stp d22, d23, [%0, #8 * 22]\n\ - stp d24, d25, [%0, #8 * 24]\n\ - stp d26, d27, [%0, #8 * 26]\n\ - stp d28, d29, [%0, #8 * 28]\n\ - stp d30, d31, [%0, #8 * 30]" - - : /* No outputs. */ - : "r"(&e[0]) - : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15", - "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31", "memory" - ); - - - - for (i = 0; i < 32; i++) - if (e[i] != val) { - report("d%d: %llu != %u\n", i, e[i], val); - result = e[i]; - } - } +/* + * CAUTION: keep this code strictly inlined in macros: we don't want + * GCC to apply any callee-saved logic to fpsimd registers in + * fp_regs_set() before fp_regs_check() can verify their contents, but + * we still want GCC to know about the registers we have clobbered. + */ - return result; -} +#define fp_regs_set(__features, __val) \ + do { \ + unsigned long long __e[32]; \ + unsigned int __i; \ + \ + if (__features & __COBALT_HAVE_FPU) { \ + \ + for (__i = 0; __i < 32; __i++) \ + __e[__i] = (__val); \ + \ + __asm__ __volatile__("ldp d0, d1, [%0, #8 * 0] \n" \ + "ldp d2, d3, [%0, #8 * 2] \n" \ + "ldp d4, d5, [%0, #8 * 4]\n" \ + "ldp d6, d7, [%0, #8 * 6]\n" \ + "ldp d8, d9, [%0, #8 * 8]\n" \ + "ldp d10, d11, [%0, #8 * 10]\n" \ + "ldp d12, d13, [%0, #8 * 12]\n" \ + "ldp d14, d15, [%0, #8 * 14]\n" \ + "ldp d16, d17, [%0, #8 * 16]\n" \ + "ldp d18, d19, [%0, #8 * 18]\n" \ + "ldp d20, d21, [%0, #8 * 20]\n" \ + "ldp d22, d23, [%0, #8 * 22]\n" \ + "ldp d24, d25, [%0, #8 * 24]\n" \ + "ldp d26, d27, [%0, #8 * 26]\n" \ + "ldp d28, d29, [%0, #8 * 28]\n" \ + "ldp d30, d31, [%0, #8 * 30]\n" \ + : /* No outputs. */ \ + : "r"(&__e[0]) \ + : "d0", "d1", "d2", "d3", "d4", "d5", "d6", \ + "d7", "d8", "d9", "d10", "d11", "d12", "d13", \ + "d14", "d15", "d16", "d17", "d18", "d19", \ + "d20", "d21", "d22", "d23", "d24", "d25", \ + "d26", "d27", "d28", "d29", "d30", "d31", \ + "memory"); \ + } \ + } while (0) + +#define fp_regs_check(__features, __val, __report) \ + ({ \ + unsigned int __result = (__val), __i; \ + unsigned long long __e[32]; \ + \ + if (__features & __COBALT_HAVE_FPU) { \ + \ + __asm__ __volatile__("stp d0, d1, [%0, #8 * 0] \n" \ + "stp d2, d3, [%0, #8 * 2] \n" \ + "stp d4, d5, [%0, #8 * 4]\n" \ + "stp d6, d7, [%0, #8 * 6]\n" \ + "stp d8, d9, [%0, #8 * 8]\n" \ + "stp d10, d11, [%0, #8 * 10]\n" \ + "stp d12, d13, [%0, #8 * 12]\n" \ + "stp d14, d15, [%0, #8 * 14]\n" \ + "stp d16, d17, [%0, #8 * 16]\n" \ + "stp d18, d19, [%0, #8 * 18]\n" \ + "stp d20, d21, [%0, #8 * 20]\n" \ + "stp d22, d23, [%0, #8 * 22]\n" \ + "stp d24, d25, [%0, #8 * 24]\n" \ + "stp d26, d27, [%0, #8 * 26]\n" \ + "stp d28, d29, [%0, #8 * 28]\n" \ + "stp d30, d31, [%0, #8 * 30]\n" \ + : /* No outputs. */ \ + : "r"(&__e[0]) \ + : "memory"); \ + \ + for (__i = 0; __i < 32; __i++) \ + if (__e[__i] != __val) { \ + __report("d%d: %llu != %u\n", \ + __i, __e[__i], __val); \ + __result = __e[__i]; \ + } \ + } \ + \ + __result; \ + }) #endif /* !_COBALT_ARM64_ASM_UAPI_FPTEST_H */ diff --git a/testsuite/switchtest/switchtest.c b/testsuite/switchtest/switchtest.c index 2f1dae3..5c102a2 100644 --- a/testsuite/switchtest/switchtest.c +++ b/testsuite/switchtest/switchtest.c @@ -25,6 +25,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <stdarg.h> #include <limits.h> #include <sched.h> #include <signal.h> @@ -268,13 +269,22 @@ static void display_switches_count(struct cpu_tasks *cpu, struct timespec *now) cpu->last_switches_count = switches_count; } -static int sink(const char *fmt, ...) +static int printout(const char *fmt, ...) { + va_list ap; + + va_start(ap, fmt); + + if (quiet < 2) + vprintf(fmt, ap); + + va_end(ap); + return 0; } #define check_fp_result(__expected) \ - fp_regs_check(fp_features, __expected, quiet < 2 ? printf : sink) + fp_regs_check(fp_features, __expected, printout) static void *sleeper_switcher(void *cookie) { _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git