1 /* 2 * Copyright (c) 2014-2017, Siemens AG. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * 1. Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. 9 * 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 * POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #ifndef EMBB_BASE_C_INTERNAL_ATOMIC_LOAD_H_ 28 #define EMBB_BASE_C_INTERNAL_ATOMIC_LOAD_H_ 29 30 #ifndef DOXYGEN 31 32 /* 33 * See file and_assign.h for a detailed (and operation independent) description 34 * of the following macro. 35 */ 36 #ifdef EMBB_PLATFORM_ARCH_X86 37 38 #ifdef EMBB_PLATFORM_COMPILER_MSVC 39 #define EMBB_DEFINE_LOAD(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX) \ 40 extern EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) __fastcall EMBB_CAT2(embb_internal__atomic_load_, EMBB_PARAMETER_SIZE_BYTE)_asm( \ 41 EMBB_CAT2(EMBB_BASE_BASIC_TYPE_ATOMIC_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value); \ 42 EMBB_PLATFORM_INLINE EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) __fastcall EMBB_CAT2(embb_internal__atomic_load_, EMBB_PARAMETER_SIZE_BYTE)(\ 43 EMBB_CAT2(EMBB_BASE_BASIC_TYPE_ATOMIC_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value) { \ 44 register EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) result; \ 45 _ReadWriteBarrier(); \ 46 result = EMBB_CAT2(embb_internal__atomic_load_, \ 47 EMBB_PARAMETER_SIZE_BYTE)_asm(pointer_to_value); \ 48 _ReadWriteBarrier(); \ 49 return result; \ 50 } 51 #elif defined(EMBB_PLATFORM_COMPILER_GNUC) 52 #define EMBB_DEFINE_LOAD(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX) \ 53 EMBB_PLATFORM_INLINE EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ 54 EMBB_CAT2(embb_internal__atomic_load_, EMBB_PARAMETER_SIZE_BYTE)(EMBB_CAT2(EMBB_BASE_BASIC_TYPE_ATOMIC_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value) { \ 55 /* no fence required for loads */ \ 56 EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) result; \ 57 __asm__ __volatile__("mov" EMBB_ATOMIC_X86_SIZE_SUFFIX " %1, %0" \ 58 : "=q" (result) \ 59 : "m" (*pointer_to_value) \ 60 : "memory"); \ 61 return result; \ 62 } 63 #else 64 #error "No atomic fetch and store implementation found" 65 #endif 66 67 /* 68 * The three or four macro calls below generate the methods for 1, 2, 4, and 69 * bytes, as stated in the macro definition. 70 */ 71 EMBB_DEFINE_LOAD(1, "b") 72 EMBB_DEFINE_LOAD(2, "w") 73 EMBB_DEFINE_LOAD(4, "l") 74 #ifdef EMBB_64_BIT_ATOMIC_AVAILABLE 75 EMBB_DEFINE_LOAD(8, "q") 76 #endif 77 78 #elif defined(EMBB_PLATFORM_ARCH_ARM) 79 80 #if defined(EMBB_PLATFORM_COMPILER_GNUC) 81 #define EMBB_DEFINE_LOAD(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_ARM_SIZE_SUFFIX) \ 82 EMBB_PLATFORM_INLINE \ 83 EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ 84 EMBB_CAT2(embb_internal__atomic_load_, EMBB_PARAMETER_SIZE_BYTE)(\ 85 EMBB_CAT2(EMBB_BASE_BASIC_TYPE_ATOMIC_, EMBB_PARAMETER_SIZE_BYTE) \ 86 volatile* pointer_to_value) { \ 87 EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ 88 result; \ 89 __asm__ __volatile__(\ 90 "dmb\n\t" \ 91 "ldr" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %0, [%1]\n\t" \ 92 "dmb" \ 93 : "=&r" (result) \ 94 : "r" (pointer_to_value) \ 95 : "memory"); \ 96 return result; \ 97 } 98 #else 99 #error "No atomic fetch and store implementation found" 100 #endif 101 102 EMBB_DEFINE_LOAD(1, "b") 103 EMBB_DEFINE_LOAD(2, "h") 104 EMBB_DEFINE_LOAD(4, "") 105 106 #else 107 #error "Unknown architecture" 108 #endif 109 110 #endif //DOXYGEN 111 112 #endif //EMBB_BASE_C_INTERNAL_ATOMIC_LOAD_H_ 113 114