From 898329b302bd91ecfcbd015576feebea4ef27c85 Mon Sep 17 00:00:00 2001 From: anatasluo Date: Thu, 3 Dec 2020 10:53:43 +0000 Subject: [PATCH] x86/asm: fix compile error in bitops.h Build on Ubuntu 18.04 amd64 with command "make DEBUG=1" produces the following error: include/common/asm/bitops.h: Assembler messages: include/common/asm/bitops.h:71: Error: incorrect register `%edx' used with `q' suffix Signed-off-by: anatasluo --- include/common/arch/x86/asm/asm.h | 28 ++++++++++++++++++++++++++++ include/common/arch/x86/asm/bitops.h | 27 ++++++++++----------------- 2 files changed, 38 insertions(+), 17 deletions(-) create mode 100644 include/common/arch/x86/asm/asm.h diff --git a/include/common/arch/x86/asm/asm.h b/include/common/arch/x86/asm/asm.h new file mode 100644 index 000000000..af324c6e2 --- /dev/null +++ b/include/common/arch/x86/asm/asm.h @@ -0,0 +1,28 @@ +#ifndef __CR_ASM_H__ +#define __CR_ASM_H__ + +#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 __ASSEMBLY__ +# define __ASM_FORM(x) x +#else +# define __ASM_FORM(x) " " #x " " +#endif + +#ifndef __x86_64__ +/* 32 bit */ +# define __ASM_SEL(a,b) __ASM_FORM(a) +#else +/* 64 bit */ +# define __ASM_SEL(a,b) __ASM_FORM(b) +#endif + +#define __ASM_SIZE(inst, ...) __ASM_SEL(inst##l##__VA_ARGS__, inst##q##__VA_ARGS__) + +#endif /* __CR_ASM_H__ */ diff --git a/include/common/arch/x86/asm/bitops.h b/include/common/arch/x86/asm/bitops.h index c69e0ed02..9c7aeb5d7 100644 --- a/include/common/arch/x86/asm/bitops.h +++ b/include/common/arch/x86/asm/bitops.h @@ -3,16 +3,9 @@ #include #include "common/arch/x86/asm/cmpxchg.h" +#include "common/arch/x86/asm/asm.h" #include "common/asm/bitsperlong.h" -#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 - #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) #define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_LONG) @@ -29,21 +22,21 @@ #define ADDR BITOP_ADDR(addr) -static inline void set_bit(int nr, volatile unsigned long *addr) +static inline void set_bit(long nr, volatile unsigned long *addr) { - asm volatile("btsl %1,%0" : ADDR : "Ir" (nr) : "memory"); + asm volatile(__ASM_SIZE(bts) " %1,%0" : ADDR : "Ir" (nr) : "memory"); } -static inline void change_bit(int nr, volatile unsigned long *addr) +static inline void change_bit(long nr, volatile unsigned long *addr) { - asm volatile("btcl %1,%0" : ADDR : "Ir" (nr)); + asm volatile(__ASM_SIZE(btc) " %1,%0" : ADDR : "Ir" (nr)); } static inline bool test_bit(long nr, volatile const unsigned long *addr) { bool oldbit; - asm volatile("btq %2,%1" + asm volatile(__ASM_SIZE(bt) " %2,%1" CC_SET(c) : CC_OUT(c) (oldbit) : "m" (*(unsigned long *)addr), "Ir" (nr) : "memory"); @@ -51,9 +44,9 @@ static inline bool test_bit(long nr, volatile const unsigned long *addr) return oldbit; } -static inline void clear_bit(int nr, volatile unsigned long *addr) +static inline void clear_bit(long nr, volatile unsigned long *addr) { - asm volatile("btrl %1,%0" : ADDR : "Ir" (nr)); + asm volatile(__ASM_SIZE(btr) " %1,%0" : ADDR : "Ir" (nr)); } /** @@ -64,11 +57,11 @@ static inline void clear_bit(int nr, volatile unsigned long *addr) * This operation is atomic and cannot be reordered. * It also implies a memory barrier. */ -static inline bool test_and_set_bit(int nr, volatile unsigned long *addr) +static inline bool test_and_set_bit(long nr, volatile unsigned long *addr) { bool oldbit; - asm("btsq %2,%1" + asm(__ASM_SIZE(bts) " %2,%1" CC_SET(c) : CC_OUT(c) (oldbit) : "m" (*(unsigned long *)addr), "Ir" (nr) : "memory");