Path: blob/main/sys/contrib/ck/include/gcc/aarch64/ck_pr.h
48422 views
/*1* Copyright 2009-2016 Samy Al Bahra.2* Copyright 2013-2016 Olivier Houchard.3* All rights reserved.4*5* Redistribution and use in source and binary forms, with or without6* modification, are permitted provided that the following conditions7* are met:8* 1. Redistributions of source code must retain the above copyright9* notice, this list of conditions and the following disclaimer.10* 2. Redistributions in binary form must reproduce the above copyright11* notice, this list of conditions and the following disclaimer in the12* documentation and/or other materials provided with the distribution.13*14* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND15* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE16* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE17* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE18* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL19* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS20* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)21* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT22* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY23* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF24* SUCH DAMAGE.25*/2627#ifndef CK_PR_AARCH64_H28#define CK_PR_AARCH64_H2930#ifndef CK_PR_H31#error Do not include this file directly, use ck_pr.h32#endif3334#include <ck_cc.h>35#include <ck_md.h>3637/*38* The following represent supported atomic operations.39* These operations may be emulated.40*/41#include "ck_f_pr.h"4243/*44* Minimum interface requirement met.45*/46#define CK_F_PR4748CK_CC_INLINE static void49ck_pr_stall(void)50{5152__asm__ __volatile__("" ::: "memory");53return;54}5556#define CK_DMB_SY __asm __volatile("dmb ish" : : "r" (0) : "memory")57#define CK_DMB_LD __asm __volatile("dmb ishld" : : "r" (0) : "memory")58#define CK_DMB_ST __asm __volatile("dmb ishst" : : "r" (0) : "memory")5960#define CK_PR_FENCE(T, I) \61CK_CC_INLINE static void \62ck_pr_fence_strict_##T(void) \63{ \64I; \65}6667CK_PR_FENCE(atomic, CK_DMB_ST)68CK_PR_FENCE(atomic_store, CK_DMB_ST)69CK_PR_FENCE(atomic_load, CK_DMB_SY)70CK_PR_FENCE(store_atomic, CK_DMB_ST)71CK_PR_FENCE(load_atomic, CK_DMB_SY)72CK_PR_FENCE(store, CK_DMB_ST)73CK_PR_FENCE(store_load, CK_DMB_SY)74CK_PR_FENCE(load, CK_DMB_LD)75CK_PR_FENCE(load_store, CK_DMB_SY)76CK_PR_FENCE(memory, CK_DMB_SY)77CK_PR_FENCE(acquire, CK_DMB_SY)78CK_PR_FENCE(release, CK_DMB_SY)79CK_PR_FENCE(acqrel, CK_DMB_SY)80CK_PR_FENCE(lock, CK_DMB_SY)81CK_PR_FENCE(unlock, CK_DMB_SY)8283#undef CK_PR_FENCE8485#undef CK_DMB_SI86#undef CK_DMB_LD87#undef CK_DMB_ST8889#define CK_PR_LOAD(S, M, T, I) \90CK_CC_INLINE static T \91ck_pr_md_load_##S(const M *target) \92{ \93long r = 0; \94__asm__ __volatile__(I " %w0, [%1]\n" \95: "=r" (r) \96: "r" (target) \97: "memory"); \98return ((T)r); \99}100#define CK_PR_LOAD_64(S, M, T, I) \101CK_CC_INLINE static T \102ck_pr_md_load_##S(const M *target) \103{ \104long r = 0; \105__asm__ __volatile__(I " %0, [%1]\n" \106: "=r" (r) \107: "r" (target) \108: "memory"); \109return ((T)r); \110}111112113CK_PR_LOAD_64(ptr, void, void *, "ldr")114115#define CK_PR_LOAD_S(S, T, I) CK_PR_LOAD(S, T, T, I)116#define CK_PR_LOAD_S_64(S, T, I) CK_PR_LOAD_64(S, T, T, I)117118CK_PR_LOAD_S_64(64, uint64_t, "ldr")119CK_PR_LOAD_S(32, uint32_t, "ldr")120CK_PR_LOAD_S(16, uint16_t, "ldrh")121CK_PR_LOAD_S(8, uint8_t, "ldrb")122CK_PR_LOAD_S(uint, unsigned int, "ldr")123CK_PR_LOAD_S(int, int, "ldr")124CK_PR_LOAD_S(short, short, "ldrh")125CK_PR_LOAD_S(char, char, "ldrb")126#ifndef CK_PR_DISABLE_DOUBLE127CK_PR_LOAD_S_64(double, double, "ldr")128#endif129130#undef CK_PR_LOAD_S131#undef CK_PR_LOAD_S_64132#undef CK_PR_LOAD133#undef CK_PR_LAOD_64134135#define CK_PR_STORE(S, M, T, I) \136CK_CC_INLINE static void \137ck_pr_md_store_##S(M *target, T v) \138{ \139__asm__ __volatile__(I " %w2, [%1]" \140: "=m" (*(T *)target) \141: "r" (target), \142"r" (v) \143: "memory"); \144return; \145}146#define CK_PR_STORE_64(S, M, T, I) \147CK_CC_INLINE static void \148ck_pr_md_store_##S(M *target, T v) \149{ \150__asm__ __volatile__(I " %2, [%1]" \151: "=m" (*(T *)target) \152: "r" (target), \153"r" (v) \154: "memory"); \155return; \156}157158CK_PR_STORE_64(ptr, void, const void *, "str")159160#define CK_PR_STORE_S(S, T, I) CK_PR_STORE(S, T, T, I)161#define CK_PR_STORE_S_64(S, T, I) CK_PR_STORE_64(S, T, T, I)162163CK_PR_STORE_S_64(64, uint64_t, "str")164CK_PR_STORE_S(32, uint32_t, "str")165CK_PR_STORE_S(16, uint16_t, "strh")166CK_PR_STORE_S(8, uint8_t, "strb")167CK_PR_STORE_S(uint, unsigned int, "str")168CK_PR_STORE_S(int, int, "str")169CK_PR_STORE_S(short, short, "strh")170CK_PR_STORE_S(char, char, "strb")171#ifndef CK_PR_DISABLE_DOUBLE172CK_PR_STORE_S_64(double, double, "str")173#endif174175#undef CK_PR_STORE_S176#undef CK_PR_STORE_S_64177#undef CK_PR_STORE178#undef CK_PR_STORE_64179180#ifdef CK_MD_LSE_ENABLE181#include "ck_pr_lse.h"182#else183#include "ck_pr_llsc.h"184#endif185186/*187* ck_pr_neg_*() functions can only be implemented via LL/SC, as there are no188* LSE alternatives.189*/190#define CK_PR_NEG(N, M, T, W, R) \191CK_CC_INLINE static void \192ck_pr_neg_##N(M *target) \193{ \194T previous = 0; \195T tmp = 0; \196__asm__ __volatile__("1:" \197"ldxr" W " %" R "0, [%2]\n"\198"neg %" R "0, %" R "0\n" \199"stxr" W " %w1, %" R "0, [%2]\n" \200"cbnz %w1, 1b\n" \201: "=&r" (previous), \202"=&r" (tmp) \203: "r" (target) \204: "memory", "cc"); \205return; \206}207208CK_PR_NEG(ptr, void, void *, "", "")209CK_PR_NEG(64, uint64_t, uint64_t, "", "")210211#define CK_PR_NEG_S(S, T, W) \212CK_PR_NEG(S, T, T, W, "w") \213214CK_PR_NEG_S(32, uint32_t, "")215CK_PR_NEG_S(uint, unsigned int, "")216CK_PR_NEG_S(int, int, "")217CK_PR_NEG_S(16, uint16_t, "h")218CK_PR_NEG_S(8, uint8_t, "b")219CK_PR_NEG_S(short, short, "h")220CK_PR_NEG_S(char, char, "b")221222#undef CK_PR_NEG_S223#undef CK_PR_NEG224225#endif /* CK_PR_AARCH64_H */226227228229