diff options
| -rw-r--r-- | arch/x86/include/asm/rmwcc.h | 37 |
1 files changed, 24 insertions, 13 deletions
diff --git a/arch/x86/include/asm/rmwcc.h b/arch/x86/include/asm/rmwcc.h index 661dd305694a..045f99211a99 100644 --- a/arch/x86/include/asm/rmwcc.h +++ b/arch/x86/include/asm/rmwcc.h | |||
| @@ -1,45 +1,56 @@ | |||
| 1 | #ifndef _ASM_X86_RMWcc | 1 | #ifndef _ASM_X86_RMWcc |
| 2 | #define _ASM_X86_RMWcc | 2 | #define _ASM_X86_RMWcc |
| 3 | 3 | ||
| 4 | #define __CLOBBERS_MEM "memory" | ||
| 5 | #define __CLOBBERS_MEM_CC_CX "memory", "cc", "cx" | ||
| 6 | |||
| 4 | #if !defined(__GCC_ASM_FLAG_OUTPUTS__) && defined(CC_HAVE_ASM_GOTO) | 7 | #if !defined(__GCC_ASM_FLAG_OUTPUTS__) && defined(CC_HAVE_ASM_GOTO) |
| 5 | 8 | ||
| 6 | /* Use asm goto */ | 9 | /* Use asm goto */ |
| 7 | 10 | ||
| 8 | #define __GEN_RMWcc(fullop, var, cc, ...) \ | 11 | #define __GEN_RMWcc(fullop, var, cc, clobbers, ...) \ |
| 9 | do { \ | 12 | do { \ |
| 10 | asm_volatile_goto (fullop "; j" #cc " %l[cc_label]" \ | 13 | asm_volatile_goto (fullop "; j" #cc " %l[cc_label]" \ |
| 11 | : : "m" (var), ## __VA_ARGS__ \ | 14 | : : [counter] "m" (var), ## __VA_ARGS__ \ |
| 12 | : "memory" : cc_label); \ | 15 | : clobbers : cc_label); \ |
| 13 | return 0; \ | 16 | return 0; \ |
| 14 | cc_label: \ | 17 | cc_label: \ |
| 15 | return 1; \ | 18 | return 1; \ |
| 16 | } while (0) | 19 | } while (0) |
| 17 | 20 | ||
| 18 | #define GEN_UNARY_RMWcc(op, var, arg0, cc) \ | 21 | #define __BINARY_RMWcc_ARG " %1, " |
| 19 | __GEN_RMWcc(op " " arg0, var, cc) | ||
| 20 | 22 | ||
| 21 | #define GEN_BINARY_RMWcc(op, var, vcon, val, arg0, cc) \ | ||
| 22 | __GEN_RMWcc(op " %1, " arg0, var, cc, vcon (val)) | ||
| 23 | 23 | ||
| 24 | #else /* defined(__GCC_ASM_FLAG_OUTPUTS__) || !defined(CC_HAVE_ASM_GOTO) */ | 24 | #else /* defined(__GCC_ASM_FLAG_OUTPUTS__) || !defined(CC_HAVE_ASM_GOTO) */ |
| 25 | 25 | ||
| 26 | /* Use flags output or a set instruction */ | 26 | /* Use flags output or a set instruction */ |
| 27 | 27 | ||
| 28 | #define __GEN_RMWcc(fullop, var, cc, ...) \ | 28 | #define __GEN_RMWcc(fullop, var, cc, clobbers, ...) \ |
| 29 | do { \ | 29 | do { \ |
| 30 | bool c; \ | 30 | bool c; \ |
| 31 | asm volatile (fullop ";" CC_SET(cc) \ | 31 | asm volatile (fullop ";" CC_SET(cc) \ |
| 32 | : "+m" (var), CC_OUT(cc) (c) \ | 32 | : [counter] "+m" (var), CC_OUT(cc) (c) \ |
| 33 | : __VA_ARGS__ : "memory"); \ | 33 | : __VA_ARGS__ : clobbers); \ |
| 34 | return c; \ | 34 | return c; \ |
| 35 | } while (0) | 35 | } while (0) |
| 36 | 36 | ||
| 37 | #define __BINARY_RMWcc_ARG " %2, " | ||
| 38 | |||
| 39 | #endif /* defined(__GCC_ASM_FLAG_OUTPUTS__) || !defined(CC_HAVE_ASM_GOTO) */ | ||
| 40 | |||
| 37 | #define GEN_UNARY_RMWcc(op, var, arg0, cc) \ | 41 | #define GEN_UNARY_RMWcc(op, var, arg0, cc) \ |
| 38 | __GEN_RMWcc(op " " arg0, var, cc) | 42 | __GEN_RMWcc(op " " arg0, var, cc, __CLOBBERS_MEM) |
| 43 | |||
| 44 | #define GEN_UNARY_SUFFIXED_RMWcc(op, suffix, var, arg0, cc) \ | ||
| 45 | __GEN_RMWcc(op " " arg0 "\n\t" suffix, var, cc, \ | ||
| 46 | __CLOBBERS_MEM_CC_CX) | ||
| 39 | 47 | ||
| 40 | #define GEN_BINARY_RMWcc(op, var, vcon, val, arg0, cc) \ | 48 | #define GEN_BINARY_RMWcc(op, var, vcon, val, arg0, cc) \ |
| 41 | __GEN_RMWcc(op " %2, " arg0, var, cc, vcon (val)) | 49 | __GEN_RMWcc(op __BINARY_RMWcc_ARG arg0, var, cc, \ |
| 50 | __CLOBBERS_MEM, vcon (val)) | ||
| 42 | 51 | ||
| 43 | #endif /* defined(__GCC_ASM_FLAG_OUTPUTS__) || !defined(CC_HAVE_ASM_GOTO) */ | 52 | #define GEN_BINARY_SUFFIXED_RMWcc(op, suffix, var, vcon, val, arg0, cc) \ |
| 53 | __GEN_RMWcc(op __BINARY_RMWcc_ARG arg0 "\n\t" suffix, var, cc, \ | ||
| 54 | __CLOBBERS_MEM_CC_CX, vcon (val)) | ||
| 44 | 55 | ||
| 45 | #endif /* _ASM_X86_RMWcc */ | 56 | #endif /* _ASM_X86_RMWcc */ |
