s390: fine-tune stack switch helper
authorMartin Schwidefsky <schwidefsky@de.ibm.com>
Wed, 10 Apr 2019 13:48:43 +0000 (15:48 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Thu, 11 Apr 2019 11:36:45 +0000 (13:36 +0200)
The CALL_ON_STACK helper currently does not work with clang and for
calls without arguments. It does not initialize r2 although the constraint
is "+&d". Rework the CALL_FMT_x and the CALL_ON_STACK macros to work
with clang and produce optimal code in all cases.

Reported-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
arch/s390/include/asm/processor.h

index 81038ab..0ee0222 100644 (file)
@@ -261,12 +261,12 @@ static __no_kasan_or_inline unsigned short stap(void)
        CALL_ARGS_4(arg1, arg2, arg3, arg4);                            \
        register unsigned long r4 asm("6") = (unsigned long)(arg5)
 
-#define CALL_FMT_0
-#define CALL_FMT_1 CALL_FMT_0, "0" (r2)
-#define CALL_FMT_2 CALL_FMT_1, "d" (r3)
-#define CALL_FMT_3 CALL_FMT_2, "d" (r4)
-#define CALL_FMT_4 CALL_FMT_3, "d" (r5)
-#define CALL_FMT_5 CALL_FMT_4, "d" (r6)
+#define CALL_FMT_0 "=&d" (r2) :
+#define CALL_FMT_1 "+&d" (r2) :
+#define CALL_FMT_2 CALL_FMT_1 "d" (r3),
+#define CALL_FMT_3 CALL_FMT_2 "d" (r4),
+#define CALL_FMT_4 CALL_FMT_3 "d" (r5),
+#define CALL_FMT_5 CALL_FMT_4 "d" (r6),
 
 #define CALL_CLOBBER_5 "0", "1", "14", "cc", "memory"
 #define CALL_CLOBBER_4 CALL_CLOBBER_5
@@ -286,10 +286,10 @@ static __no_kasan_or_inline unsigned short stap(void)
                "       stg     %[_prev],%[_bc](15)\n"                  \
                "       brasl   14,%[_fn]\n"                            \
                "       la      15,0(%[_prev])\n"                       \
-               : "+&d" (r2), [_prev] "=&a" (prev)                      \
-               : [_stack] "a" (stack),                                 \
+               : [_prev] "=&a" (prev), CALL_FMT_##nr                   \
+                 [_stack] "a" (stack),                                 \
                  [_bc] "i" (offsetof(struct stack_frame, back_chain)), \
-                 [_fn] "X" (fn) CALL_FMT_##nr : CALL_CLOBBER_##nr);    \
+                 [_fn] "X" (fn) : CALL_CLOBBER_##nr);                  \
        r2;                                                             \
 })