]> www.infradead.org Git - users/hch/misc.git/commitdiff
x86/asm: Remove code depending on __GCC_ASM_FLAG_OUTPUTS__
authorUros Bizjak <ubizjak@gmail.com>
Sun, 7 Sep 2025 18:33:38 +0000 (20:33 +0200)
committerBorislav Petkov (AMD) <bp@alien8.de>
Mon, 8 Sep 2025 13:38:06 +0000 (15:38 +0200)
The minimum supported GCC version is 8.1, which supports flag output operands
and always defines __GCC_ASM_FLAG_OUTPUTS__ macro.

Remove code depending on __GCC_ASM_FLAG_OUTPUTS__ and use the "=@ccCOND" flag
output operand directly.

Use the equivalent "=@ccz" instead of "=@cce" flag output operand for
CMPXCHG8B and CMPXCHG16B instructions. These instructions set a single flag
bit - the Zero flag - and "=@ccz" is used to distinguish the CC user from
comparison instructions, where set ZERO flag indeed means that the values are
equal.

Signed-off-by: Uros Bizjak <ubizjak@gmail.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Link: https://lore.kernel.org/r/20250905121723.GCaLrU04lP2A50PT-B@fat_crate.local
17 files changed:
arch/x86/boot/bitops.h
arch/x86/boot/boot.h
arch/x86/boot/string.c
arch/x86/include/asm/archrandom.h
arch/x86/include/asm/asm.h
arch/x86/include/asm/bitops.h
arch/x86/include/asm/cmpxchg.h
arch/x86/include/asm/cmpxchg_32.h
arch/x86/include/asm/cmpxchg_64.h
arch/x86/include/asm/percpu.h
arch/x86/include/asm/rmwcc.h
arch/x86/include/asm/sev.h
arch/x86/include/asm/signal.h
arch/x86/include/asm/special_insns.h
arch/x86/include/asm/uaccess.h
tools/arch/x86/include/asm/asm.h
tools/perf/bench/find-bit-bench.c

index 8518ae214c9b335917e00c3d976369d6d71edaff..79e15971529d0e89a0ccd444db2cab41e8652d15 100644 (file)
@@ -27,7 +27,7 @@ static inline bool variable_test_bit(int nr, const void *addr)
        bool v;
        const u32 *p = addr;
 
-       asm("btl %2,%1" CC_SET(c) : CC_OUT(c) (v) : "m" (*p), "Ir" (nr));
+       asm("btl %2,%1" : "=@ccc" (v) : "m" (*p), "Ir" (nr));
        return v;
 }
 
index 60580836daf766f7dc961110672020ad98ae4820..a3c58ebe366251b845d3ae069056e25f1f7b3fe5 100644 (file)
@@ -155,15 +155,15 @@ static inline void wrgs32(u32 v, addr_t addr)
 static inline bool memcmp_fs(const void *s1, addr_t s2, size_t len)
 {
        bool diff;
-       asm volatile("fs repe cmpsb" CC_SET(nz)
-                    : CC_OUT(nz) (diff), "+D" (s1), "+S" (s2), "+c" (len));
+       asm volatile("fs repe cmpsb"
+                    : "=@ccnz" (diff), "+D" (s1), "+S" (s2), "+c" (len));
        return diff;
 }
 static inline bool memcmp_gs(const void *s1, addr_t s2, size_t len)
 {
        bool diff;
-       asm volatile("gs repe cmpsb" CC_SET(nz)
-                    : CC_OUT(nz) (diff), "+D" (s1), "+S" (s2), "+c" (len));
+       asm volatile("gs repe cmpsb"
+                    : "=@ccnz" (diff), "+D" (s1), "+S" (s2), "+c" (len));
        return diff;
 }
 
index f35369bb14c5141ea8079a14f81d838e1797161d..b25c6a9303b7314d5caf5c9306239811705294fe 100644 (file)
@@ -32,8 +32,8 @@
 int memcmp(const void *s1, const void *s2, size_t len)
 {
        bool diff;
-       asm("repe cmpsb" CC_SET(nz)
-           : CC_OUT(nz) (diff), "+D" (s1), "+S" (s2), "+c" (len));
+       asm("repe cmpsb"
+           : "=@ccnz" (diff), "+D" (s1), "+S" (s2), "+c" (len));
        return diff;
 }
 
index 02bae8e0758b2b80156a964bcd44d49d78c32261..4c305305871b3ef0b899ce8d1f8b9a5c3be9099a 100644 (file)
@@ -23,8 +23,7 @@ static inline bool __must_check rdrand_long(unsigned long *v)
        unsigned int retry = RDRAND_RETRY_LOOPS;
        do {
                asm volatile("rdrand %[out]"
-                            CC_SET(c)
-                            : CC_OUT(c) (ok), [out] "=r" (*v));
+                            : "=@ccc" (ok), [out] "=r" (*v));
                if (ok)
                        return true;
        } while (--retry);
@@ -35,8 +34,7 @@ static inline bool __must_check rdseed_long(unsigned long *v)
 {
        bool ok;
        asm volatile("rdseed %[out]"
-                    CC_SET(c)
-                    : CC_OUT(c) (ok), [out] "=r" (*v));
+                    : "=@ccc" (ok), [out] "=r" (*v));
        return ok;
 }
 
index f963848024a527269cbcefe482ed909a3a91b559..d5c8d3afe19648e93954588e5189d227c1a71c46 100644 (file)
@@ -122,18 +122,6 @@ static __always_inline __pure void *rip_rel_ptr(void *p)
 }
 #endif
 
-/*
- * Macros to generate condition code outputs from inline assembly,
- * The output operand must be type "bool".
- */
-#ifdef __GCC_ASM_FLAG_OUTPUTS__
-# define CC_SET(c) "\n\t/* output condition code " #c "*/\n"
-# define CC_OUT(c) "=@cc" #c
-#else
-# define CC_SET(c) "\n\tset" #c " %[_cc_" #c "]\n"
-# define CC_OUT(c) [_cc_ ## c] "=qm"
-#endif
-
 #ifdef __KERNEL__
 
 # include <asm/extable_fixup_types.h>
index eebbc8889e70f5003d08e090dc193657a821bc3f..33153dcd119ca61a408315cba5c63f7ea7863376 100644 (file)
@@ -99,8 +99,7 @@ static __always_inline bool arch_xor_unlock_is_negative_byte(unsigned long mask,
 {
        bool negative;
        asm_inline volatile(LOCK_PREFIX "xorb %2,%1"
-               CC_SET(s)
-               : CC_OUT(s) (negative), WBYTE_ADDR(addr)
+               : "=@ccs" (negative), WBYTE_ADDR(addr)
                : "iq" ((char)mask) : "memory");
        return negative;
 }
@@ -149,8 +148,7 @@ arch___test_and_set_bit(unsigned long nr, volatile unsigned long *addr)
        bool oldbit;
 
        asm(__ASM_SIZE(bts) " %2,%1"
-           CC_SET(c)
-           : CC_OUT(c) (oldbit)
+           : "=@ccc" (oldbit)
            : ADDR, "Ir" (nr) : "memory");
        return oldbit;
 }
@@ -175,8 +173,7 @@ arch___test_and_clear_bit(unsigned long nr, volatile unsigned long *addr)
        bool oldbit;
 
        asm volatile(__ASM_SIZE(btr) " %2,%1"
-                    CC_SET(c)
-                    : CC_OUT(c) (oldbit)
+                    : "=@ccc" (oldbit)
                     : ADDR, "Ir" (nr) : "memory");
        return oldbit;
 }
@@ -187,8 +184,7 @@ arch___test_and_change_bit(unsigned long nr, volatile unsigned long *addr)
        bool oldbit;
 
        asm volatile(__ASM_SIZE(btc) " %2,%1"
-                    CC_SET(c)
-                    : CC_OUT(c) (oldbit)
+                    : "=@ccc" (oldbit)
                     : ADDR, "Ir" (nr) : "memory");
 
        return oldbit;
@@ -211,8 +207,7 @@ static __always_inline bool constant_test_bit_acquire(long nr, const volatile un
        bool oldbit;
 
        asm volatile("testb %2,%1"
-                    CC_SET(nz)
-                    : CC_OUT(nz) (oldbit)
+                    : "=@ccnz" (oldbit)
                     : "m" (((unsigned char *)addr)[nr >> 3]),
                       "i" (1 << (nr & 7))
                     :"memory");
@@ -225,8 +220,7 @@ static __always_inline bool variable_test_bit(long nr, volatile const unsigned l
        bool oldbit;
 
        asm volatile(__ASM_SIZE(bt) " %2,%1"
-                    CC_SET(c)
-                    : CC_OUT(c) (oldbit)
+                    : "=@ccc" (oldbit)
                     : "m" (*(unsigned long *)addr), "Ir" (nr) : "memory");
 
        return oldbit;
index b61f32c3459feef53ab304521bcf1a9ee607f7d5..a88b06f1c35e2c284be71d2a9e8f602d46d14cb9 100644 (file)
@@ -166,8 +166,7 @@ extern void __add_wrong_size(void)
        {                                                               \
                volatile u8 *__ptr = (volatile u8 *)(_ptr);             \
                asm_inline volatile(lock "cmpxchgb %[new], %[ptr]"      \
-                            CC_SET(z)                                  \
-                            : CC_OUT(z) (success),                     \
+                            : "=@ccz" (success),                       \
                               [ptr] "+m" (*__ptr),                     \
                               [old] "+a" (__old)                       \
                             : [new] "q" (__new)                        \
@@ -178,8 +177,7 @@ extern void __add_wrong_size(void)
        {                                                               \
                volatile u16 *__ptr = (volatile u16 *)(_ptr);           \
                asm_inline volatile(lock "cmpxchgw %[new], %[ptr]"      \
-                            CC_SET(z)                                  \
-                            : CC_OUT(z) (success),                     \
+                            : "=@ccz" (success),                       \
                               [ptr] "+m" (*__ptr),                     \
                               [old] "+a" (__old)                       \
                             : [new] "r" (__new)                        \
@@ -190,8 +188,7 @@ extern void __add_wrong_size(void)
        {                                                               \
                volatile u32 *__ptr = (volatile u32 *)(_ptr);           \
                asm_inline volatile(lock "cmpxchgl %[new], %[ptr]"      \
-                            CC_SET(z)                                  \
-                            : CC_OUT(z) (success),                     \
+                            : "=@ccz" (success),                       \
                               [ptr] "+m" (*__ptr),                     \
                               [old] "+a" (__old)                       \
                             : [new] "r" (__new)                        \
@@ -202,8 +199,7 @@ extern void __add_wrong_size(void)
        {                                                               \
                volatile u64 *__ptr = (volatile u64 *)(_ptr);           \
                asm_inline volatile(lock "cmpxchgq %[new], %[ptr]"      \
-                            CC_SET(z)                                  \
-                            : CC_OUT(z) (success),                     \
+                            : "=@ccz" (success),                       \
                               [ptr] "+m" (*__ptr),                     \
                               [old] "+a" (__old)                       \
                             : [new] "r" (__new)                        \
index 371f7906019e7714a3b739853c9fee4f8e60b21d..1f80a62be969041127b1358db1663a9043840bee 100644 (file)
@@ -46,8 +46,7 @@ static __always_inline u64 __cmpxchg64_local(volatile u64 *ptr, u64 old, u64 new
        bool ret;                                                       \
                                                                        \
        asm_inline volatile(_lock "cmpxchg8b %[ptr]"                    \
-                    CC_SET(e)                                          \
-                    : CC_OUT(e) (ret),                                 \
+                    : "=@ccz" (ret),                                   \
                       [ptr] "+m" (*(_ptr)),                            \
                       "+a" (o.low), "+d" (o.high)                      \
                     : "b" (n.low), "c" (n.high)                        \
@@ -125,8 +124,7 @@ static __always_inline u64 arch_cmpxchg64_local(volatile u64 *ptr, u64 old, u64
                ALTERNATIVE(_lock_loc                                   \
                            "call cmpxchg8b_emu",                       \
                            _lock "cmpxchg8b %a[ptr]", X86_FEATURE_CX8) \
-               CC_SET(e)                                               \
-               : ALT_OUTPUT_SP(CC_OUT(e) (ret),                        \
+               : ALT_OUTPUT_SP("=@ccz" (ret),                          \
                                "+a" (o.low), "+d" (o.high))            \
                : "b" (n.low), "c" (n.high),                            \
                  [ptr] "S" (_ptr)                                      \
index 71d1e72ed87983f93f2603f9a451f7d736870305..5afea056fb20b50a36c83796d39ec2aa153d9dec 100644 (file)
@@ -66,8 +66,7 @@ static __always_inline u128 arch_cmpxchg128_local(volatile u128 *ptr, u128 old,
        bool ret;                                                       \
                                                                        \
        asm_inline volatile(_lock "cmpxchg16b %[ptr]"                   \
-                    CC_SET(e)                                          \
-                    : CC_OUT(e) (ret),                                 \
+                    : "=@ccz" (ret),                                   \
                       [ptr] "+m" (*(_ptr)),                            \
                       "+a" (o.low), "+d" (o.high)                      \
                     : "b" (n.low), "c" (n.high)                        \
index b0d03b6c279bee16cb029989ff4f08786696d333..332428caaed27df09944f1ebbcc6df4b3a3cebd3 100644 (file)
@@ -309,8 +309,7 @@ do {                                                                        \
                                                                        \
        asm qual (__pcpu_op_##size("cmpxchg") "%[nval], "               \
                  __percpu_arg([var])                                   \
-                 CC_SET(z)                                             \
-                 : CC_OUT(z) (success),                                \
+                 : "=@ccz" (success),                                  \
                    [oval] "+a" (pco_old__),                            \
                    [var] "+m" (__my_cpu_var(_var))                     \
                  : [nval] __pcpu_reg_##size(, pco_new__)               \
@@ -367,8 +366,7 @@ do {                                                                        \
        asm_inline qual (                                               \
                ALTERNATIVE("call this_cpu_cmpxchg8b_emu",              \
                            "cmpxchg8b " __percpu_arg([var]), X86_FEATURE_CX8) \
-               CC_SET(z)                                               \
-               : ALT_OUTPUT_SP(CC_OUT(z) (success),                    \
+               : ALT_OUTPUT_SP("=@ccz" (success),                      \
                                [var] "+m" (__my_cpu_var(_var)),        \
                                "+a" (old__.low), "+d" (old__.high))    \
                : "b" (new__.low), "c" (new__.high),                    \
@@ -436,8 +434,7 @@ do {                                                                        \
        asm_inline qual (                                               \
                ALTERNATIVE("call this_cpu_cmpxchg16b_emu",             \
                            "cmpxchg16b " __percpu_arg([var]), X86_FEATURE_CX16) \
-               CC_SET(z)                                               \
-               : ALT_OUTPUT_SP(CC_OUT(z) (success),                    \
+               : ALT_OUTPUT_SP("=@ccz" (success),                      \
                                [var] "+m" (__my_cpu_var(_var)),        \
                                "+a" (old__.low), "+d" (old__.high))    \
                : "b" (new__.low), "c" (new__.high),                    \
@@ -585,8 +582,7 @@ do {                                                                        \
        bool oldbit;                                                    \
                                                                        \
        asm volatile("btl %[nr], " __percpu_arg([var])                  \
-                    CC_SET(c)                                          \
-                    : CC_OUT(c) (oldbit)                               \
+                    : "=@ccc" (oldbit)                                 \
                     : [var] "m" (__my_cpu_var(_var)),                  \
                       [nr] "rI" (_nr));                                \
        oldbit;                                                         \
index 3821ee3fae35d0330285ece7c659e34ac85365fa..54c8fc43068406170934d343eeb1cc3a62cfb6c6 100644 (file)
@@ -6,37 +6,15 @@
 
 #define __CLOBBERS_MEM(clb...) "memory", ## clb
 
-#ifndef __GCC_ASM_FLAG_OUTPUTS__
-
-/* Use asm goto */
-
-#define __GEN_RMWcc(fullop, _var, cc, clobbers, ...)                   \
-({                                                                     \
-       bool c = false;                                                 \
-       asm goto (fullop "; j" #cc " %l[cc_label]"              \
-                       : : [var] "m" (_var), ## __VA_ARGS__            \
-                       : clobbers : cc_label);                         \
-       if (0) {                                                        \
-cc_label:      c = true;                                               \
-       }                                                               \
-       c;                                                              \
-})
-
-#else /* defined(__GCC_ASM_FLAG_OUTPUTS__) */
-
-/* Use flags output or a set instruction */
-
 #define __GEN_RMWcc(fullop, _var, cc, clobbers, ...)                   \
 ({                                                                     \
        bool c;                                                         \
-       asm_inline volatile (fullop CC_SET(cc)                          \
-                       : [var] "+m" (_var), CC_OUT(cc) (c)             \
+       asm_inline volatile (fullop                                     \
+                       : [var] "+m" (_var), "=@cc" #cc (c)             \
                        : __VA_ARGS__ : clobbers);                      \
        c;                                                              \
 })
 
-#endif /* defined(__GCC_ASM_FLAG_OUTPUTS__) */
-
 #define GEN_UNARY_RMWcc_4(op, var, cc, arg0)                           \
        __GEN_RMWcc(op " " arg0, var, cc, __CLOBBERS_MEM())
 
index 02236962fdb108009e419e010d3862688e1f694d..7cb8e09e749b57531109494c1eda0283dd873d2e 100644 (file)
@@ -491,8 +491,7 @@ static inline int pvalidate(unsigned long vaddr, bool rmp_psize, bool validate)
 
        /* "pvalidate" mnemonic support in binutils 2.36 and newer */
        asm volatile(".byte 0xF2, 0x0F, 0x01, 0xFF\n\t"
-                    CC_SET(c)
-                    : CC_OUT(c) (no_rmpupdate), "=a"(rc)
+                    : "=@ccc"(no_rmpupdate), "=a"(rc)
                     : "a"(vaddr), "c"(rmp_psize), "d"(validate)
                     : "memory", "cc");
 
index c72d461753742f63839c897f03bff70b807c6bf8..5c03aaa890143c437ee9694817d34f26d27de344 100644 (file)
@@ -83,8 +83,7 @@ static inline int __const_sigismember(sigset_t *set, int _sig)
 static inline int __gen_sigismember(sigset_t *set, int _sig)
 {
        bool ret;
-       asm("btl %2,%1" CC_SET(c)
-           : CC_OUT(c) (ret) : "m"(*set), "Ir"(_sig-1));
+       asm("btl %2,%1" : "=@ccc"(ret) : "m"(*set), "Ir"(_sig-1));
        return ret;
 }
 
index c9991456935264564195b5ad1f890264f9e19c8f..46aa2c9c1bda39a7033703038495f67ec3d40740 100644 (file)
@@ -284,8 +284,7 @@ static inline int enqcmds(void __iomem *dst, const void *src)
         * See movdir64b()'s comment on operand specification.
         */
        asm volatile(".byte 0xf3, 0x0f, 0x38, 0xf8, 0x02, 0x66, 0x90"
-                    CC_SET(z)
-                    : CC_OUT(z) (zf), "+m" (*__dst)
+                    : "=@ccz" (zf), "+m" (*__dst)
                     : "m" (*__src), "a" (__dst), "d" (__src));
 
        /* Submission failure is indicated via EFLAGS.ZF=1 */
index 3a7755c1a44102c9a50f043d7fecf9afc9b5969c..91a3fb8ae7ff4683bdcf13ae8d7f15d5342162c2 100644 (file)
@@ -378,7 +378,7 @@ do {                                                                        \
        asm_goto_output("\n"                                            \
                     "1: " LOCK_PREFIX "cmpxchg"itype" %[new], %[ptr]\n"\
                     _ASM_EXTABLE_UA(1b, %l[label])                     \
-                    : CC_OUT(z) (success),                             \
+                    : "=@ccz" (success),                               \
                       [ptr] "+m" (*_ptr),                              \
                       [old] "+a" (__old)                               \
                     : [new] ltype (__new)                              \
@@ -397,7 +397,7 @@ do {                                                                        \
        asm_goto_output("\n"                                            \
                     "1: " LOCK_PREFIX "cmpxchg8b %[ptr]\n"             \
                     _ASM_EXTABLE_UA(1b, %l[label])                     \
-                    : CC_OUT(z) (success),                             \
+                    : "=@ccz" (success),                               \
                       "+A" (__old),                                    \
                       [ptr] "+m" (*_ptr)                               \
                     : "b" ((u32)__new),                                \
@@ -417,11 +417,10 @@ do {                                                                      \
        __typeof__(*(_ptr)) __new = (_new);                             \
        asm volatile("\n"                                               \
                     "1: " LOCK_PREFIX "cmpxchg"itype" %[new], %[ptr]\n"\
-                    CC_SET(z)                                          \
                     "2:\n"                                             \
                     _ASM_EXTABLE_TYPE_REG(1b, 2b, EX_TYPE_EFAULT_REG,  \
                                           %[errout])                   \
-                    : CC_OUT(z) (success),                             \
+                    : "=@ccz" (success),                               \
                       [errout] "+r" (__err),                           \
                       [ptr] "+m" (*_ptr),                              \
                       [old] "+a" (__old)                               \
index dbe39b44256ba3a5489fb9a0afdbc9a7885e438a..6e1b357c374bcea066b5bc71df302e066672eca3 100644 (file)
 
 #endif
 
-/*
- * Macros to generate condition code outputs from inline assembly,
- * The output operand must be type "bool".
- */
-#ifdef __GCC_ASM_FLAG_OUTPUTS__
-# define CC_SET(c) "\n\t/* output condition code " #c "*/\n"
-# define CC_OUT(c) "=@cc" #c
-#else
-# define CC_SET(c) "\n\tset" #c " %[_cc_" #c "]\n"
-# define CC_OUT(c) [_cc_ ## c] "=qm"
-#endif
-
 #ifdef __KERNEL__
 
 /* Exception table entry */
index 7e25b0e413f6f599e6a7d6d30d64959c0dc17c93..e697c20951bcb5704613961ca0039938b45095ce 100644 (file)
@@ -37,7 +37,7 @@ static noinline void workload(int val)
        accumulator++;
 }
 
-#if (defined(__i386__) || defined(__x86_64__)) && defined(__GCC_ASM_FLAG_OUTPUTS__)
+#if defined(__i386__) || defined(__x86_64__)
 static bool asm_test_bit(long nr, const unsigned long *addr)
 {
        bool oldbit;