diff options
author | anatasluo <luolongjuna@gmail.com> | 2020-12-03 13:53:43 +0300 |
---|---|---|
committer | Andrei Vagin <avagin@gmail.com> | 2021-09-03 20:31:00 +0300 |
commit | 898329b302bd91ecfcbd015576feebea4ef27c85 (patch) | |
tree | bccfd748ec65fa9a46675b2e1f15ed137291db42 /include | |
parent | 371d9c83d7f9294f5a235069e3e472c72b58a017 (diff) |
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 <luolongjuna@gmail.com>
Diffstat (limited to 'include')
-rw-r--r-- | include/common/arch/x86/asm/asm.h | 28 | ||||
-rw-r--r-- | include/common/arch/x86/asm/bitops.h | 27 |
2 files changed, 38 insertions, 17 deletions
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 <stdbool.h> #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"); |