Path: blob/main/sys/contrib/ck/include/gcc/sparcv9/ck_pr.h
48524 views
/*1* Copyright 2009, 2010 Samy Al Bahra.2* All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12*13* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND14* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE15* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE16* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE17* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL18* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS19* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)20* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT21* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY22* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF23* SUCH DAMAGE.24*/2526#ifndef CK_PR_SPARCV9_H27#define CK_PR_SPARCV9_H2829#ifndef CK_PR_H30#error Do not include this file directly, use ck_pr.h31#endif3233#include <ck_cc.h>34#include <ck_md.h>3536/*37* The following represent supported atomic operations.38* These operations may be emulated.39*/40#include "ck_f_pr.h"4142/*43* Minimum interface requirement met.44*/45#define CK_F_PR4647/*48* Order loads at the least.49*/50CK_CC_INLINE static void51ck_pr_stall(void)52{5354__asm__ __volatile__("membar #LoadLoad" ::: "memory");55return;56}5758#define CK_PR_FENCE(T, I) \59CK_CC_INLINE static void \60ck_pr_fence_strict_##T(void) \61{ \62__asm__ __volatile__(I ::: "memory"); \63}6465/*66* Atomic operations are treated as both load and store67* operations on SPARCv9.68*/69CK_PR_FENCE(atomic, "membar #StoreStore")70CK_PR_FENCE(atomic_store, "membar #StoreStore")71CK_PR_FENCE(atomic_load, "membar #StoreLoad")72CK_PR_FENCE(store_atomic, "membar #StoreStore")73CK_PR_FENCE(load_atomic, "membar #LoadStore")74CK_PR_FENCE(store, "membar #StoreStore")75CK_PR_FENCE(store_load, "membar #StoreLoad")76CK_PR_FENCE(load, "membar #LoadLoad")77CK_PR_FENCE(load_store, "membar #LoadStore")78CK_PR_FENCE(memory, "membar #MemIssue")79CK_PR_FENCE(acquire, "membar #LoadLoad | #LoadStore")80CK_PR_FENCE(release, "membar #LoadStore | #StoreStore")81CK_PR_FENCE(acqrel, "membar #LoadLoad | #LoadStore | #StoreStore")82CK_PR_FENCE(lock, "membar #LoadLoad | #LoadStore | #StoreStore | #StoreLoad")83CK_PR_FENCE(unlock, "membar #LoadStore | #StoreStore")8485#undef CK_PR_FENCE8687#define CK_PR_LOAD(S, M, T, C, I) \88CK_CC_INLINE static T \89ck_pr_md_load_##S(const M *target) \90{ \91T r; \92__asm__ __volatile__(I " [%1], %0" \93: "=&r" (r) \94: "r" (target) \95: "memory"); \96return (r); \97}9899CK_PR_LOAD(ptr, void, void *, uint64_t, "ldx")100101#define CK_PR_LOAD_S(S, T, I) CK_PR_LOAD(S, T, T, T, I)102103CK_PR_LOAD_S(64, uint64_t, "ldx")104CK_PR_LOAD_S(32, uint32_t, "lduw")105CK_PR_LOAD_S(uint, unsigned int, "lduw")106CK_PR_LOAD_S(double, double, "ldx")107CK_PR_LOAD_S(int, int, "ldsw")108109#undef CK_PR_LOAD_S110#undef CK_PR_LOAD111112#define CK_PR_STORE(S, M, T, C, I) \113CK_CC_INLINE static void \114ck_pr_md_store_##S(M *target, T v) \115{ \116__asm__ __volatile__(I " %0, [%1]" \117: \118: "r" (v), \119"r" (target) \120: "memory"); \121return; \122}123124CK_PR_STORE(ptr, void, const void *, uint64_t, "stx")125126#define CK_PR_STORE_S(S, T, I) CK_PR_STORE(S, T, T, T, I)127128CK_PR_STORE_S(8, uint8_t, "stub")129CK_PR_STORE_S(64, uint64_t, "stx")130CK_PR_STORE_S(32, uint32_t, "stuw")131CK_PR_STORE_S(uint, unsigned int, "stuw")132CK_PR_STORE_S(double, double, "stx")133CK_PR_STORE_S(int, int, "stsw")134135#undef CK_PR_STORE_S136#undef CK_PR_STORE137138/* Use the appropriate address space for atomics within the FreeBSD kernel. */139#if defined(__FreeBSD__) && defined(_KERNEL)140#include <sys/cdefs.h>141#include <machine/atomic.h>142#define CK_PR_INS_CAS "casa"143#define CK_PR_INS_CASX "casxa"144#define CK_PR_INS_SWAP "swapa"145#define CK_PR_ASI_ATOMIC __XSTRING(__ASI_ATOMIC)146#else147#define CK_PR_INS_CAS "cas"148#define CK_PR_INS_CASX "casx"149#define CK_PR_INS_SWAP "swap"150#define CK_PR_ASI_ATOMIC ""151#endif152153CK_CC_INLINE static bool154ck_pr_cas_64_value(uint64_t *target, uint64_t compare, uint64_t set, uint64_t *value)155{156157__asm__ __volatile__(CK_PR_INS_CASX " [%1] " CK_PR_ASI_ATOMIC ", %2, %0"158: "+&r" (set)159: "r" (target),160"r" (compare)161: "memory");162163*value = set;164return (compare == set);165}166167CK_CC_INLINE static bool168ck_pr_cas_64(uint64_t *target, uint64_t compare, uint64_t set)169{170171__asm__ __volatile__(CK_PR_INS_CASX " [%1] " CK_PR_ASI_ATOMIC ", %2, %0"172: "+&r" (set)173: "r" (target),174"r" (compare)175: "memory");176177return (compare == set);178}179180CK_CC_INLINE static bool181ck_pr_cas_ptr(void *target, void *compare, void *set)182{183184return ck_pr_cas_64(target, (uint64_t)compare, (uint64_t)set);185}186187CK_CC_INLINE static bool188ck_pr_cas_ptr_value(void *target, void *compare, void *set, void *previous)189{190191return ck_pr_cas_64_value(target, (uint64_t)compare, (uint64_t)set, previous);192}193194#define CK_PR_CAS(N, T) \195CK_CC_INLINE static bool \196ck_pr_cas_##N##_value(T *target, T compare, T set, T *value) \197{ \198__asm__ __volatile__(CK_PR_INS_CAS " [%1] " CK_PR_ASI_ATOMIC ", %2, %0" \199: "+&r" (set) \200: "r" (target), \201"r" (compare) \202: "memory"); \203*value = set; \204return (compare == set); \205} \206CK_CC_INLINE static bool \207ck_pr_cas_##N(T *target, T compare, T set) \208{ \209__asm__ __volatile__(CK_PR_INS_CAS " [%1] " CK_PR_ASI_ATOMIC ", %2, %0" \210: "+&r" (set) \211: "r" (target), \212"r" (compare) \213: "memory"); \214return (compare == set); \215}216217CK_PR_CAS(32, uint32_t)218CK_PR_CAS(uint, unsigned int)219CK_PR_CAS(int, int)220221#undef CK_PR_CAS222223#define CK_PR_FAS(N, T) \224CK_CC_INLINE static T \225ck_pr_fas_##N(T *target, T update) \226{ \227\228__asm__ __volatile__(CK_PR_INS_SWAP " [%1] " CK_PR_ASI_ATOMIC ", %0" \229: "+&r" (update) \230: "r" (target) \231: "memory"); \232return (update); \233}234235CK_PR_FAS(int, int)236CK_PR_FAS(uint, unsigned int)237CK_PR_FAS(32, uint32_t)238239#undef CK_PR_FAS240241#undef CK_PR_INS_CAS242#undef CK_PR_INS_CASX243#undef CK_PR_INS_SWAP244#undef CK_PR_ASI_ATOMIC245246#endif /* CK_PR_SPARCV9_H */247248249250