aboutsummaryrefslogtreecommitdiff
path: root/include/gcc/x86/ck_pr.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/gcc/x86/ck_pr.h')
-rw-r--r--include/gcc/x86/ck_pr.h109
1 files changed, 60 insertions, 49 deletions
diff --git a/include/gcc/x86/ck_pr.h b/include/gcc/x86/ck_pr.h
index e678e830e0b4..12291c830dfd 100644
--- a/include/gcc/x86/ck_pr.h
+++ b/include/gcc/x86/ck_pr.h
@@ -120,7 +120,7 @@ CK_PR_FENCE(unlock, CK_MD_X86_MFENCE)
return v; \
}
-CK_PR_FAS(ptr, void, void *, char, "xchgl")
+CK_PR_FAS(ptr, void, void *, uint32_t, "xchgl")
#define CK_PR_FAS_S(S, T, I) CK_PR_FAS(S, T, T, T, I)
@@ -146,7 +146,7 @@ CK_PR_FAS_S(8, uint8_t, "xchgb")
return (r); \
}
-CK_PR_LOAD(ptr, void, void *, char, "movl")
+CK_PR_LOAD(ptr, void, void *, uint32_t, "movl")
#define CK_PR_LOAD_S(S, T, I) CK_PR_LOAD(S, T, T, T, I)
@@ -171,7 +171,7 @@ CK_PR_LOAD_S(8, uint8_t, "movb")
return; \
}
-CK_PR_STORE(ptr, void, const void *, char, "movl")
+CK_PR_STORE(ptr, void, const void *, uint32_t, "movl")
#define CK_PR_STORE_S(S, T, I) CK_PR_STORE(S, T, T, T, I)
@@ -200,7 +200,7 @@ CK_PR_STORE_S(8, uint8_t, "movb")
return (d); \
}
-CK_PR_FAA(ptr, void, uintptr_t, char, "xaddl")
+CK_PR_FAA(ptr, void, uintptr_t, uint32_t, "xaddl")
#define CK_PR_FAA_S(S, T, I) CK_PR_FAA(S, T, T, T, I)
@@ -239,7 +239,7 @@ CK_PR_FAA_S(8, uint8_t, "xaddb")
bool ret; \
__asm__ __volatile__(CK_PR_LOCK_PREFIX I " %0; setz %1" \
: "+m" (*(C *)target), \
- "=rm" (ret) \
+ "=qm" (ret) \
: \
: "memory", "cc"); \
return ret; \
@@ -248,7 +248,7 @@ CK_PR_FAA_S(8, uint8_t, "xaddb")
#define CK_PR_UNARY_S(K, S, T, I) CK_PR_UNARY(K, S, T, T, I)
#define CK_PR_GENERATE(K) \
- CK_PR_UNARY(K, ptr, void, char, #K "l") \
+ CK_PR_UNARY(K, ptr, void, uint32_t, #K "l") \
CK_PR_UNARY_S(K, char, char, #K "b") \
CK_PR_UNARY_S(K, int, int, #K "l") \
CK_PR_UNARY_S(K, uint, unsigned int, #K "l") \
@@ -288,7 +288,7 @@ CK_PR_GENERATE(not)
#define CK_PR_BINARY_S(K, S, T, I) CK_PR_BINARY(K, S, T, T, T, I)
#define CK_PR_GENERATE(K) \
- CK_PR_BINARY(K, ptr, void, uintptr_t, char, #K "l") \
+ CK_PR_BINARY(K, ptr, void, uintptr_t, uint32_t, #K "l") \
CK_PR_BINARY_S(K, char, char, #K "b") \
CK_PR_BINARY_S(K, int, int, #K "l") \
CK_PR_BINARY_S(K, uint, unsigned int, #K "l") \
@@ -307,8 +307,38 @@ CK_PR_GENERATE(xor)
#undef CK_PR_BINARY
/*
- * Atomic compare and swap.
+ * Atomic compare and swap, with a variant that sets *v to the old value of target.
*/
+#ifdef __GCC_ASM_FLAG_OUTPUTS__
+#define CK_PR_CAS(S, M, T, C, I) \
+ CK_CC_INLINE static bool \
+ ck_pr_cas_##S(M *target, T compare, T set) \
+ { \
+ bool z; \
+ __asm__ __volatile__(CK_PR_LOCK_PREFIX I " %3, %0" \
+ : "+m" (*(C *)target), \
+ "=@ccz" (z), \
+ /* RAX is clobbered by cmpxchg. */ \
+ "+a" (compare) \
+ : "q" (set) \
+ : "memory", "cc"); \
+ return z; \
+ } \
+ \
+ CK_CC_INLINE static bool \
+ ck_pr_cas_##S##_value(M *target, T compare, T set, M *v) \
+ { \
+ bool z; \
+ __asm__ __volatile__(CK_PR_LOCK_PREFIX I " %3, %0;" \
+ : "+m" (*(C *)target), \
+ "=@ccz" (z), \
+ "+a" (compare) \
+ : "q" (set) \
+ : "memory", "cc"); \
+ *(T *)v = compare; \
+ return z; \
+ }
+#else
#define CK_PR_CAS(S, M, T, C, I) \
CK_CC_INLINE static bool \
ck_pr_cas_##S(M *target, T compare, T set) \
@@ -321,9 +351,25 @@ CK_PR_GENERATE(xor)
"a" (compare) \
: "memory", "cc"); \
return z; \
+ } \
+ \
+ CK_CC_INLINE static bool \
+ ck_pr_cas_##S##_value(M *target, T compare, T set, M *v) \
+ { \
+ bool z; \
+ __asm__ __volatile__(CK_PR_LOCK_PREFIX I " %3, %0;" \
+ "setz %1;" \
+ : "+m" (*(C *)target), \
+ "=q" (z), \
+ "+a" (compare) \
+ : "q" (set) \
+ : "memory", "cc"); \
+ *(T *)v = compare; \
+ return z; \
}
+#endif
-CK_PR_CAS(ptr, void, void *, char, "cmpxchgl")
+CK_PR_CAS(ptr, void, void *, uint32_t, "cmpxchgl")
#define CK_PR_CAS_S(S, T, I) CK_PR_CAS(S, T, T, T, I)
@@ -338,41 +384,6 @@ CK_PR_CAS_S(8, uint8_t, "cmpxchgb")
#undef CK_PR_CAS
/*
- * Compare and swap, set *v to old value of target.
- */
-#define CK_PR_CAS_O(S, M, T, C, I, R) \
- CK_CC_INLINE static bool \
- ck_pr_cas_##S##_value(M *target, T compare, T set, M *v) \
- { \
- bool z; \
- __asm__ __volatile__(CK_PR_LOCK_PREFIX "cmpxchg" I " %3, %0;" \
- "mov %% " R ", %2;" \
- "setz %1;" \
- : "+m" (*(C *)target), \
- "=a" (z), \
- "=m" (*(C *)v) \
- : "q" (set), \
- "a" (compare) \
- : "memory", "cc"); \
- return (bool)z; \
- }
-
-CK_PR_CAS_O(ptr, void, void *, char, "l", "eax")
-
-#define CK_PR_CAS_O_S(S, T, I, R) \
- CK_PR_CAS_O(S, T, T, T, I, R)
-
-CK_PR_CAS_O_S(char, char, "b", "al")
-CK_PR_CAS_O_S(int, int, "l", "eax")
-CK_PR_CAS_O_S(uint, unsigned int, "l", "eax")
-CK_PR_CAS_O_S(32, uint32_t, "l", "eax")
-CK_PR_CAS_O_S(16, uint16_t, "w", "ax")
-CK_PR_CAS_O_S(8, uint8_t, "b", "al")
-
-#undef CK_PR_CAS_O_S
-#undef CK_PR_CAS_O
-
-/*
* Atomic bit test operations.
*/
#define CK_PR_BT(K, S, T, P, C, I) \
@@ -390,11 +401,11 @@ CK_PR_CAS_O_S(8, uint8_t, "b", "al")
#define CK_PR_BT_S(K, S, T, I) CK_PR_BT(K, S, T, T, T, I)
-#define CK_PR_GENERATE(K) \
- CK_PR_BT(K, ptr, void, uint32_t, char, #K "l %2, %0") \
- CK_PR_BT_S(K, uint, unsigned int, #K "l %2, %0") \
- CK_PR_BT_S(K, int, int, #K "l %2, %0") \
- CK_PR_BT_S(K, 32, uint32_t, #K "l %2, %0") \
+#define CK_PR_GENERATE(K) \
+ CK_PR_BT(K, ptr, void, uint32_t, uint32_t, #K "l %2, %0") \
+ CK_PR_BT_S(K, uint, unsigned int, #K "l %2, %0") \
+ CK_PR_BT_S(K, int, int, #K "l %2, %0") \
+ CK_PR_BT_S(K, 32, uint32_t, #K "l %2, %0") \
CK_PR_BT_S(K, 16, uint16_t, #K "w %w2, %0")
CK_PR_GENERATE(btc)