Neither clang nor GCC like this very much with -m32:

        long long ret;
        asm ("movb $5, %0" : "=q" (ret));

However, GCC can tolerate this variant:

        long long ret;
        switch (sizeof(ret)) {
        case 1:
                asm ("movb $5, %0" : "=q" (ret));
        case 8:
                ;
        }

Clang, on the other hand, won't accept that because it validates the 
inline asm for the '1' case *before* the optimisation phase where it 
realises that it wouldn't have to emit it anyway.

This patch puts some casts in to make clang less unhappy. I don't like
it very much.

Note that we don't have the same problem for the "=r" case, where a 
64-bit value *also* doesn't fit. This is because even if it *does* have 
to emit it, clang will happily and silently do so even though it's 
clearly bogus:

        long long ret;
        asm ("movl $5, %0" : "=r" (ret));

 $ clang -c -o q.o q.c -m32
 $ gcc -c -o q.o q.c -m32
q.c: In function ‘foo’:
q.c:6:1: warning: unsupported size for integer register


---

 arch/x86/include/asm/percpu.h | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h
index ba3c523aaf16..3b0e413670e4 100644
--- a/arch/x86/include/asm/percpu.h
+++ b/arch/x86/include/asm/percpu.h
@@ -99,7 +99,7 @@ do {                                                  \
        case 1:                                         \
                asm(op "b %1,"__percpu_arg(0)           \
                    : "+m" (var)                        \
-                   : "qi" ((pto_T__)(val)));           \
+                   : "qi" ((unsigned char)(unsigned long)(val))); \
                break;                                  \
        case 2:                                         \
                asm(op "w %1,"__percpu_arg(0)           \
@@ -144,7 +144,7 @@ do {                                                        
                \
                else                                                    \
                        asm("addb %1, "__percpu_arg(0)                  \
                            : "+m" (var)                                \
-                           : "qi" ((pao_T__)(val)));                   \
+                           : "qi" ((unsigned char)(unsigned long)(val))); \
                break;                                                  \
        case 2:                                                         \
                if (pao_ID__ == 1)                                      \
@@ -182,12 +182,14 @@ do {                                                      
                \
 
 #define percpu_from_op(op, var)                                \
 ({                                                     \
+       unsigned char pfo_u8__;                         \
        typeof(var) pfo_ret__;                          \
        switch (sizeof(var)) {                          \
        case 1:                                         \
                asm(op "b "__percpu_arg(1)",%0"         \
-                   : "=q" (pfo_ret__)                  \
+                   : "=q" (pfo_u8__)                   \
                    : "m" (var));                       \
+               pfo_ret__ = (typeof(var))(unsigned long)pfo_u8__;       \
                break;                                  \
        case 2:                                         \
                asm(op "w "__percpu_arg(1)",%0"         \
@@ -211,12 +213,14 @@ do {                                                      
                \
 
 #define percpu_stable_op(op, var)                      \
 ({                                                     \
+       unsigned char pfo_u8__;                         \
        typeof(var) pfo_ret__;                          \
        switch (sizeof(var)) {                          \
        case 1:                                         \
                asm(op "b "__percpu_arg(P1)",%0"        \
-                   : "=q" (pfo_ret__)                  \
+                   : "=q" (pfo_u8__)                   \
                    : "p" (&(var)));                    \
+               pfo_ret__ = (typeof(var))(unsigned long)pfo_u8__;       \
                break;                                  \
        case 2:                                         \
                asm(op "w "__percpu_arg(P1)",%0"        \
-- 
2.14.3

Reply via email to