// Copyright 2016 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. #include #include "runtime.h" uint32_t Load (uint32_t *ptr) __asm__ (GOSYM_PREFIX "runtime_internal_atomic.Load") __attribute__ ((no_split_stack)); uint32_t Load (uint32_t *ptr) { return __atomic_load_n (ptr, __ATOMIC_ACQUIRE); } void *Loadp (void *ptr) __asm__ (GOSYM_PREFIX "runtime_internal_atomic.Loadp") __attribute__ ((no_split_stack)); void * Loadp (void *ptr) { return __atomic_load_n ((void **) ptr, __ATOMIC_ACQUIRE); } uint64_t Load64 (uint64_t *ptr) __asm__ (GOSYM_PREFIX "runtime_internal_atomic.Load64") __attribute__ ((no_split_stack)); uint64_t Load64 (uint64_t *ptr) { if (((uintptr_t) ptr & 7) != 0) ptr = NULL; return __atomic_load_n (ptr, __ATOMIC_ACQUIRE); } uintptr_t Loaduintptr (uintptr_t *ptr) __asm__ (GOSYM_PREFIX "runtime_internal_atomic.Loaduintptr") __attribute__ ((no_split_stack)); uintptr_t Loaduintptr (uintptr_t *ptr) { return __atomic_load_n (ptr, __ATOMIC_ACQUIRE); } uintgo Loaduint (uintgo *ptr) __asm__ (GOSYM_PREFIX "runtime_internal_atomic.Loaduint") __attribute__ ((no_split_stack)); uintgo Loaduint (uintgo *ptr) { return __atomic_load_n (ptr, __ATOMIC_ACQUIRE); } int64_t Loadint64 (int64_t *ptr) __asm__ (GOSYM_PREFIX "runtime_internal_atomic.Loadint64") __attribute__ ((no_split_stack)); int64_t Loadint64 (int64_t *ptr) { if (((uintptr_t) ptr & 7) != 0) ptr = NULL; return __atomic_load_n (ptr, __ATOMIC_ACQUIRE); } uint32_t Xadd (uint32_t *ptr, int32_t delta) __asm__ (GOSYM_PREFIX "runtime_internal_atomic.Xadd") __attribute__ ((no_split_stack)); uint32_t Xadd (uint32_t *ptr, int32_t delta) { return __atomic_add_fetch (ptr, (uint32_t) delta, __ATOMIC_SEQ_CST); } uint64_t Xadd64 (uint64_t *ptr, int64_t delta) __asm__ (GOSYM_PREFIX "runtime_internal_atomic.Xadd64") __attribute__ ((no_split_stack)); uint64_t Xadd64 (uint64_t *ptr, int64_t delta) { if (((uintptr_t) ptr & 7) != 0) ptr = NULL; return __atomic_add_fetch (ptr, (uint64_t) delta, __ATOMIC_SEQ_CST); } uintptr_t Xadduintptr (uintptr_t *ptr, uintptr_t delta) __asm__ (GOSYM_PREFIX "runtime_internal_atomic.Xadduintptr") __attribute__ ((no_split_stack)); uintptr_t Xadduintptr (uintptr_t *ptr, uintptr_t delta) { return __atomic_add_fetch (ptr, delta, __ATOMIC_SEQ_CST); } int64_t Xaddint64 (int64_t *ptr, int64_t delta) __asm__ (GOSYM_PREFIX "runtime_internal_atomic.Xaddint64") __attribute__ ((no_split_stack)); int64_t Xaddint64 (int64_t *ptr, int64_t delta) { if (((uintptr_t) ptr & 7) != 0) ptr = NULL; return __atomic_add_fetch (ptr, delta, __ATOMIC_SEQ_CST); } uint32_t Xchg (uint32_t *ptr, uint32_t new) __asm__ (GOSYM_PREFIX "runtime_internal_atomic.Xchg") __attribute__ ((no_split_stack)); uint32_t Xchg (uint32_t *ptr, uint32_t new) { return __atomic_exchange_n (ptr, new, __ATOMIC_SEQ_CST); } uint64_t Xchg64 (uint64_t *ptr, uint64_t new) __asm__ (GOSYM_PREFIX "runtime_internal_atomic.Xchg64") __attribute__ ((no_split_stack)); uint64_t Xchg64 (uint64_t *ptr, uint64_t new) { if (((uintptr_t) ptr & 7) != 0) ptr = NULL; return __atomic_exchange_n (ptr, new, __ATOMIC_SEQ_CST); } uintptr_t Xchguintptr (uintptr_t *ptr, uintptr_t new) __asm__ (GOSYM_PREFIX "runtime_internal_atomic.Xchguintptr") __attribute__ ((no_split_stack)); uintptr_t Xchguintptr (uintptr_t *ptr, uintptr_t new) { return __atomic_exchange_n (ptr, new, __ATOMIC_SEQ_CST); } void And8 (uint8_t *ptr, uint8_t val) __asm__ (GOSYM_PREFIX "runtime_internal_atomic.And8") __attribute__ ((no_split_stack)); void And8 (uint8_t *ptr, uint8_t val) { __atomic_and_fetch (ptr, val, __ATOMIC_SEQ_CST); } void Or8 (uint8_t *ptr, uint8_t val) __asm__ (GOSYM_PREFIX "runtime_internal_atomic.Or8") __attribute__ ((no_split_stack)); void Or8 (uint8_t *ptr, uint8_t val) { __atomic_or_fetch (ptr, val, __ATOMIC_SEQ_CST); } _Bool Cas (uint32_t *ptr, uint32_t old, uint32_t new) __asm__ (GOSYM_PREFIX "runtime_internal_atomic.Cas") __attribute__ ((no_split_stack)); _Bool Cas (uint32_t *ptr, uint32_t old, uint32_t new) { return __atomic_compare_exchange_n (ptr, &old, new, false, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED); } _Bool Cas64 (uint64_t *ptr, uint64_t old, uint64_t new) __asm__ (GOSYM_PREFIX "runtime_internal_atomic.Cas64") __attribute__ ((no_split_stack)); _Bool Cas64 (uint64_t *ptr, uint64_t old, uint64_t new) { if (((uintptr_t) ptr & 7) != 0) ptr = NULL; return __atomic_compare_exchange_n (ptr, &old, new, false, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED); } _Bool Casp1 (void **ptr, void *old, void *new) __asm__ (GOSYM_PREFIX "runtime_internal_atomic.Casp1") __attribute__ ((no_split_stack)); _Bool Casp1 (void **ptr, void *old, void *new) { return __atomic_compare_exchange_n (ptr, &old, new, false, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED); } _Bool Casuintptr (uintptr_t *ptr, uintptr_t old, uintptr_t new) __asm__ (GOSYM_PREFIX "runtime_internal_atomic.Casuintptr") __attribute__ ((no_split_stack)); _Bool Casuintptr (uintptr_t *ptr, uintptr_t old, uintptr_t new) { return __atomic_compare_exchange_n (ptr, &old, new, false, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED); } void Store (uint32_t *ptr, uint32_t val) __asm__ (GOSYM_PREFIX "runtime_internal_atomic.Store") __attribute__ ((no_split_stack)); void Store (uint32_t *ptr, uint32_t val) { __atomic_store_n (ptr, val, __ATOMIC_SEQ_CST); } void Store64 (uint64_t *ptr, uint64_t val) __asm__ (GOSYM_PREFIX "runtime_internal_atomic.Store64") __attribute__ ((no_split_stack)); void Store64 (uint64_t *ptr, uint64_t val) { if (((uintptr_t) ptr & 7) != 0) ptr = NULL; __atomic_store_n (ptr, val, __ATOMIC_SEQ_CST); } void Storeuintptr (uintptr_t *ptr, uintptr_t val) __asm__ (GOSYM_PREFIX "runtime_internal_atomic.Storeuintptr") __attribute__ ((no_split_stack)); void Storeuintptr (uintptr_t *ptr, uintptr_t val) { __atomic_store_n (ptr, val, __ATOMIC_SEQ_CST); } void StorepNoWB (void *ptr, void *val) __asm__ (GOSYM_PREFIX "runtime_internal_atomic.StorepNoWB") __attribute__ ((no_split_stack)); void StorepNoWB (void *ptr, void *val) { __atomic_store_n ((void**) ptr, val, __ATOMIC_SEQ_CST); }