|
1 | 1 | #ifndef _ASM_X86_RMWcc
|
2 | 2 | #define _ASM_X86_RMWcc
|
3 | 3 |
|
| 4 | +#define __CLOBBERS_MEM "memory" |
| 5 | +#define __CLOBBERS_MEM_CC_CX "memory", "cc", "cx" |
| 6 | + |
4 | 7 | #if !defined(__GCC_ASM_FLAG_OUTPUTS__) && defined(CC_HAVE_ASM_GOTO)
|
5 | 8 |
|
6 | 9 | /* Use asm goto */
|
7 | 10 |
|
8 |
| -#define __GEN_RMWcc(fullop, var, cc, ...) \ |
| 11 | +#define __GEN_RMWcc(fullop, var, cc, clobbers, ...) \ |
9 | 12 | do { \
|
10 | 13 | asm_volatile_goto (fullop "; j" #cc " %l[cc_label]" \
|
11 |
| - : : "m" (var), ## __VA_ARGS__ \ |
12 |
| - : "memory" : cc_label); \ |
| 14 | + : : [counter] "m" (var), ## __VA_ARGS__ \ |
| 15 | + : clobbers : cc_label); \ |
13 | 16 | return 0; \
|
14 | 17 | cc_label: \
|
15 | 18 | return 1; \
|
16 | 19 | } while (0)
|
17 | 20 |
|
18 |
| -#define GEN_UNARY_RMWcc(op, var, arg0, cc) \ |
19 |
| - __GEN_RMWcc(op " " arg0, var, cc) |
| 21 | +#define __BINARY_RMWcc_ARG " %1, " |
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 | 24 | #else /* defined(__GCC_ASM_FLAG_OUTPUTS__) || !defined(CC_HAVE_ASM_GOTO) */
|
25 | 25 |
|
26 | 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 | 29 | do { \
|
30 | 30 | bool c; \
|
31 | 31 | asm volatile (fullop ";" CC_SET(cc) \
|
32 |
| - : "+m" (var), CC_OUT(cc) (c) \ |
33 |
| - : __VA_ARGS__ : "memory"); \ |
| 32 | + : [counter] "+m" (var), CC_OUT(cc) (c) \ |
| 33 | + : __VA_ARGS__ : clobbers); \ |
34 | 34 | return c; \
|
35 | 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 | 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 | 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 | 56 | #endif /* _ASM_X86_RMWcc */
|
0 commit comments