Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
arch-ppc.h255 linesDownload Raw Back to atomics
1/*-------------------------------------------------------------------------2 *3 * arch-ppc.h4 *	  Atomic operations considerations specific to PowerPC5 *6 * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group7 * Portions Copyright (c) 1994, Regents of the University of California8 *9 * NOTES:10 *11 * src/include/port/atomics/arch-ppc.h12 *13 *-------------------------------------------------------------------------14 */15 16#if defined(__GNUC__)17 18/*19 * lwsync orders loads with respect to each other, and similarly with stores.20 * But a load can be performed before a subsequent store, so sync must be used21 * for a full memory barrier.22 */23#define pg_memory_barrier_impl()	__asm__ __volatile__ ("sync" : : : "memory")24#define pg_read_barrier_impl()		__asm__ __volatile__ ("lwsync" : : : "memory")25#define pg_write_barrier_impl()		__asm__ __volatile__ ("lwsync" : : : "memory")26#endif27 28#define PG_HAVE_ATOMIC_U32_SUPPORT29typedef struct pg_atomic_uint3230{31	volatile uint32 value;32} pg_atomic_uint32;33 34/* 64bit atomics are only supported in 64bit mode */35#if SIZEOF_VOID_P >= 836#define PG_HAVE_ATOMIC_U64_SUPPORT37typedef struct pg_atomic_uint6438{39	volatile uint64 value pg_attribute_aligned(8);40} pg_atomic_uint64;41 42#endif43 44/*45 * This mimics gcc __atomic_compare_exchange_n(..., __ATOMIC_SEQ_CST), but46 * code generation differs at the end.  __atomic_compare_exchange_n():47 *  100:	isync48 *  104:	mfcr    r349 *  108:	rlwinm  r3,r3,3,31,3150 *  10c:	bne     120 <.eb+0x10>51 *  110:	clrldi  r3,r3,6352 *  114:	addi    r1,r1,11253 *  118:	blr54 *  11c:	nop55 *  120:	clrldi  r3,r3,6356 *  124:	stw     r9,0(r4)57 *  128:	addi    r1,r1,11258 *  12c:	blr59 *60 * This:61 *   f0:	isync62 *   f4:	mfcr    r963 *   f8:	rldicl. r3,r9,35,6364 *   fc:	bne     104 <.eb>65 *  100:	stw     r10,0(r4)66 *  104:	addi    r1,r1,11267 *  108:	blr68 *69 * This implementation may or may not have materially different performance.70 * It's not exploiting the fact that cr0 still holds the relevant comparison71 * bits, set during the __asm__.  One could fix that by moving more code into72 * the __asm__.  (That would remove the freedom to eliminate dead stores when73 * the caller ignores "expected", but few callers do.)74 *75 * Recognizing constant "newval" would be superfluous, because there's no76 * immediate-operand version of stwcx.77 */78#define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U3279static inline bool80pg_atomic_compare_exchange_u32_impl(volatile pg_atomic_uint32 *ptr,81									uint32 *expected, uint32 newval)82{83	uint32 found;84	uint32 condition_register;85	bool ret;86 87#ifdef HAVE_I_CONSTRAINT__BUILTIN_CONSTANT_P88	if (__builtin_constant_p(*expected) &&89		(int32) *expected <= PG_INT16_MAX &&90		(int32) *expected >= PG_INT16_MIN)91		__asm__ __volatile__(92			"	sync				\n"93			"	lwarx   %0,0,%5,1	\n"94			"	cmpwi   %0,%3		\n"95			"	bne     $+12		\n"		/* branch to lwsync */96			"	stwcx.  %4,0,%5		\n"97			"	bne     $-16		\n"		/* branch to lwarx */98			"	lwsync				\n"99			"	mfcr    %1          \n"100:			"=&r"(found), "=r"(condition_register), "+m"(ptr->value)101:			"i"(*expected), "r"(newval), "r"(&ptr->value)102:			"memory", "cc");103	else104#endif105		__asm__ __volatile__(106			"	sync				\n"107			"	lwarx   %0,0,%5,1	\n"108			"	cmpw    %0,%3		\n"109			"	bne     $+12		\n"		/* branch to lwsync */110			"	stwcx.  %4,0,%5		\n"111			"	bne     $-16		\n"		/* branch to lwarx */112			"	lwsync				\n"113			"	mfcr    %1          \n"114:			"=&r"(found), "=r"(condition_register), "+m"(ptr->value)115:			"r"(*expected), "r"(newval), "r"(&ptr->value)116:			"memory", "cc");117 118	ret = (condition_register >> 29) & 1;	/* test eq bit of cr0 */119	if (!ret)120		*expected = found;121	return ret;122}123 124/*125 * This mirrors gcc __sync_fetch_and_add().126 *127 * Like tas(), use constraint "=&b" to avoid allocating r0.128 */129#define PG_HAVE_ATOMIC_FETCH_ADD_U32130static inline uint32131pg_atomic_fetch_add_u32_impl(volatile pg_atomic_uint32 *ptr, int32 add_)132{133	uint32 _t;134	uint32 res;135 136#ifdef HAVE_I_CONSTRAINT__BUILTIN_CONSTANT_P137	if (__builtin_constant_p(add_) &&138		add_ <= PG_INT16_MAX && add_ >= PG_INT16_MIN)139		__asm__ __volatile__(140			"	sync				\n"141			"	lwarx   %1,0,%4,1	\n"142			"	addi    %0,%1,%3	\n"143			"	stwcx.  %0,0,%4		\n"144			"	bne     $-12		\n"		/* branch to lwarx */145			"	lwsync				\n"146:			"=&r"(_t), "=&b"(res), "+m"(ptr->value)147:			"i"(add_), "r"(&ptr->value)148:			"memory", "cc");149	else150#endif151		__asm__ __volatile__(152			"	sync				\n"153			"	lwarx   %1,0,%4,1	\n"154			"	add     %0,%1,%3	\n"155			"	stwcx.  %0,0,%4		\n"156			"	bne     $-12		\n"		/* branch to lwarx */157			"	lwsync				\n"158:			"=&r"(_t), "=&r"(res), "+m"(ptr->value)159:			"r"(add_), "r"(&ptr->value)160:			"memory", "cc");161 162	return res;163}164 165#ifdef PG_HAVE_ATOMIC_U64_SUPPORT166 167#define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U64168static inline bool169pg_atomic_compare_exchange_u64_impl(volatile pg_atomic_uint64 *ptr,170									uint64 *expected, uint64 newval)171{172	uint64 found;173	uint32 condition_register;174	bool ret;175 176	/* Like u32, but s/lwarx/ldarx/; s/stwcx/stdcx/; s/cmpw/cmpd/ */177#ifdef HAVE_I_CONSTRAINT__BUILTIN_CONSTANT_P178	if (__builtin_constant_p(*expected) &&179		(int64) *expected <= PG_INT16_MAX &&180		(int64) *expected >= PG_INT16_MIN)181		__asm__ __volatile__(182			"	sync				\n"183			"	ldarx   %0,0,%5,1	\n"184			"	cmpdi   %0,%3		\n"185			"	bne     $+12		\n"		/* branch to lwsync */186			"	stdcx.  %4,0,%5		\n"187			"	bne     $-16		\n"		/* branch to ldarx */188			"	lwsync				\n"189			"	mfcr    %1          \n"190:			"=&r"(found), "=r"(condition_register), "+m"(ptr->value)191:			"i"(*expected), "r"(newval), "r"(&ptr->value)192:			"memory", "cc");193	else194#endif195		__asm__ __volatile__(196			"	sync				\n"197			"	ldarx   %0,0,%5,1	\n"198			"	cmpd    %0,%3		\n"199			"	bne     $+12		\n"		/* branch to lwsync */200			"	stdcx.  %4,0,%5		\n"201			"	bne     $-16		\n"		/* branch to ldarx */202			"	lwsync				\n"203			"	mfcr    %1          \n"204:			"=&r"(found), "=r"(condition_register), "+m"(ptr->value)205:			"r"(*expected), "r"(newval), "r"(&ptr->value)206:			"memory", "cc");207 208	ret = (condition_register >> 29) & 1;	/* test eq bit of cr0 */209	if (!ret)210		*expected = found;211	return ret;212}213 214#define PG_HAVE_ATOMIC_FETCH_ADD_U64215static inline uint64216pg_atomic_fetch_add_u64_impl(volatile pg_atomic_uint64 *ptr, int64 add_)217{218	uint64 _t;219	uint64 res;220 221	/* Like u32, but s/lwarx/ldarx/; s/stwcx/stdcx/ */222#ifdef HAVE_I_CONSTRAINT__BUILTIN_CONSTANT_P223	if (__builtin_constant_p(add_) &&224		add_ <= PG_INT16_MAX && add_ >= PG_INT16_MIN)225		__asm__ __volatile__(226			"	sync				\n"227			"	ldarx   %1,0,%4,1	\n"228			"	addi    %0,%1,%3	\n"229			"	stdcx.  %0,0,%4		\n"230			"	bne     $-12		\n"		/* branch to ldarx */231			"	lwsync				\n"232:			"=&r"(_t), "=&b"(res), "+m"(ptr->value)233:			"i"(add_), "r"(&ptr->value)234:			"memory", "cc");235	else236#endif237		__asm__ __volatile__(238			"	sync				\n"239			"	ldarx   %1,0,%4,1	\n"240			"	add     %0,%1,%3	\n"241			"	stdcx.  %0,0,%4		\n"242			"	bne     $-12		\n"		/* branch to ldarx */243			"	lwsync				\n"244:			"=&r"(_t), "=&r"(res), "+m"(ptr->value)245:			"r"(add_), "r"(&ptr->value)246:			"memory", "cc");247 248	return res;249}250 251#endif /* PG_HAVE_ATOMIC_U64_SUPPORT */252 253/* per architecture manual doubleword accesses have single copy atomicity */254#define PG_HAVE_8BYTE_SINGLE_COPY_ATOMICITY255 
codekingpro/portable-devtools · Team Ai