diff options
Diffstat (limited to 'lib/builtins')
| -rw-r--r-- | lib/builtins/CMakeLists.txt | 7 | ||||
| -rw-r--r-- | lib/builtins/atomic.c | 18 | ||||
| -rw-r--r-- | lib/builtins/clear_cache.c | 66 | ||||
| -rw-r--r-- | lib/builtins/gcc_personality_v0.c | 48 | ||||
| -rw-r--r-- | lib/builtins/int_types.h | 3 | 
5 files changed, 81 insertions, 61 deletions
| diff --git a/lib/builtins/CMakeLists.txt b/lib/builtins/CMakeLists.txt index 999faa86739d..4d102c615003 100644 --- a/lib/builtins/CMakeLists.txt +++ b/lib/builtins/CMakeLists.txt @@ -79,7 +79,6 @@ set(GENERIC_SOURCES    floatuntidf.c    floatuntisf.c    floatuntixf.c -  gcc_personality_v0.c    int_util.c    lshrdi3.c    lshrti3.c @@ -137,6 +136,12 @@ set(GENERIC_SOURCES    umodsi3.c    umodti3.c) +if (HAVE_UNWIND_H) +  set(GENERIC_SOURCES +      ${GENERIC_SOURCES} +      gcc_personality_v0.c) +endif () +  set(x86_64_SOURCES    x86_64/floatdidf.c    x86_64/floatdisf.c diff --git a/lib/builtins/atomic.c b/lib/builtins/atomic.c index 02429a653d2b..35c8837dcecf 100644 --- a/lib/builtins/atomic.c +++ b/lib/builtins/atomic.c @@ -28,20 +28,14 @@  #include <stdint.h>  #include <string.h> +#include "assembly.h" +  // Clang objects if you redefine a builtin.  This little hack allows us to  // define a function with the same name as an intrinsic. -#if __APPLE__ -// mach-o has extra leading underscore -#pragma redefine_extname __atomic_load_c ___atomic_load -#pragma redefine_extname __atomic_store_c ___atomic_store -#pragma redefine_extname __atomic_exchange_c ___atomic_exchange -#pragma redefine_extname __atomic_compare_exchange_c ___atomic_compare_exchange -#else -#pragma redefine_extname __atomic_load_c __atomic_load -#pragma redefine_extname __atomic_store_c __atomic_store -#pragma redefine_extname __atomic_exchange_c __atomic_exchange -#pragma redefine_extname __atomic_compare_exchange_c __atomic_compare_exchange -#endif +#pragma redefine_extname __atomic_load_c SYMBOL_NAME(__atomic_load) +#pragma redefine_extname __atomic_store_c SYMBOL_NAME(__atomic_store) +#pragma redefine_extname __atomic_exchange_c SYMBOL_NAME(__atomic_exchange) +#pragma redefine_extname __atomic_compare_exchange_c SYMBOL_NAME(__atomic_compare_exchange)  /// Number of locks.  This allocates one page on 32-bit platforms, two on  /// 64-bit.  This can be specified externally if a different trade between diff --git a/lib/builtins/clear_cache.c b/lib/builtins/clear_cache.c index 86e68afad3b7..61b1e9bbb5c0 100644 --- a/lib/builtins/clear_cache.c +++ b/lib/builtins/clear_cache.c @@ -13,12 +13,62 @@  #if __APPLE__    #include <libkern/OSCacheControl.h>  #endif +#if defined(__FreeBSD__) && defined(__arm__) +  #include <sys/types.h> +  #include <machine/sysarch.h> +#endif +  #if defined(__NetBSD__) && defined(__arm__)    #include <machine/sysarch.h>  #endif  #if defined(__ANDROID__) && defined(__mips__)    #include <sys/cachectl.h> +  #include <sys/syscall.h> +  #ifdef __LP64__ +    /* +     * clear_mips_cache - Invalidates instruction cache for Mips. +     */ +    static void clear_mips_cache(const void* Addr, size_t Size) { +      asm volatile ( +        ".set push\n" +        ".set noreorder\n" +        ".set noat\n" +        "beq %[Size], $zero, 20f\n"          /* If size == 0, branch around. */ +        "nop\n" +        "daddu %[Size], %[Addr], %[Size]\n"  /* Calculate end address + 1 */ +        "rdhwr $v0, $1\n"                    /* Get step size for SYNCI. +                                                $1 is $HW_SYNCI_Step */ +        "beq $v0, $zero, 20f\n"              /* If no caches require +                                                synchronization, branch +                                                around. */ +        "nop\n" +        "10:\n" +        "synci 0(%[Addr])\n"                 /* Synchronize all caches around +                                                address. */ +        "daddu %[Addr], %[Addr], $v0\n"      /* Add step size. */ +        "sltu $at, %[Addr], %[Size]\n"       /* Compare current with end +                                                address. */ +        "bne $at, $zero, 10b\n"              /* Branch if more to do. */ +        "nop\n" +        "sync\n"                             /* Clear memory hazards. */ +        "20:\n" +        "bal 30f\n" +        "nop\n" +        "30:\n" +        "daddiu $ra, $ra, 12\n"              /* $ra has a value of $pc here. +                                                Add offset of 12 to point to the +                                                instruction after the last nop. +                                              */ +        "jr.hb $ra\n"                        /* Return, clearing instruction +                                                hazards. */ +        "nop\n" +        ".set pop\n" +        : [Addr] "+r"(Addr), [Size] "+r"(Size) +        :: "at", "ra", "v0", "memory" +      ); +    } +  #endif  #endif  #if defined(__ANDROID__) && defined(__arm__) @@ -39,7 +89,7 @@ void __clear_cache(void *start, void *end) {   * so there is nothing to do   */  #elif defined(__arm__) && !defined(__APPLE__) -    #if defined(__NetBSD__) +    #if defined(__FreeBSD__) || defined(__NetBSD__)          struct arm_sync_icache_args arg;          arg.addr = (uintptr_t)start; @@ -47,7 +97,7 @@ void __clear_cache(void *start, void *end) {          sysarch(ARM_SYNC_ICACHE, &arg);      #elif defined(__ANDROID__) -         const register int start_reg __asm("r0") = (int) (intptr_t) start; +         register int start_reg __asm("r0") = (int) (intptr_t) start;           const register int end_reg __asm("r1") = (int) (intptr_t) end;           const register int flags __asm("r2") = 0;           const register int syscall_nr __asm("r7") = __ARM_NR_cacheflush; @@ -62,7 +112,17 @@ void __clear_cache(void *start, void *end) {  #elif defined(__ANDROID__) && defined(__mips__)    const uintptr_t start_int = (uintptr_t) start;    const uintptr_t end_int = (uintptr_t) end; -  _flush_cache(start, (end_int - start_int), BCACHE); +    #ifdef __LP64__ +        // Call synci implementation for short address range. +        const uintptr_t address_range_limit = 256; +        if ((end_int - start_int) <= address_range_limit) { +            clear_mips_cache(start, (end_int - start_int)); +        } else { +            syscall(__NR_cacheflush, start, (end_int - start_int), BCACHE); +        } +    #else +        syscall(__NR_cacheflush, start, (end_int - start_int), BCACHE); +    #endif  #elif defined(__aarch64__) && !defined(__APPLE__)    uint64_t xstart = (uint64_t)(uintptr_t) start;    uint64_t xend = (uint64_t)(uintptr_t) end; diff --git a/lib/builtins/gcc_personality_v0.c b/lib/builtins/gcc_personality_v0.c index 869f4178e853..4b95cfd43b05 100644 --- a/lib/builtins/gcc_personality_v0.c +++ b/lib/builtins/gcc_personality_v0.c @@ -11,47 +11,7 @@  #include "int_lib.h" -/* - * _Unwind_* stuff based on C++ ABI public documentation - * http://refspecs.freestandards.org/abi-eh-1.21.html - */ - -typedef enum { -    _URC_NO_REASON = 0, -    _URC_FOREIGN_EXCEPTION_CAUGHT = 1, -    _URC_FATAL_PHASE2_ERROR = 2, -    _URC_FATAL_PHASE1_ERROR = 3, -    _URC_NORMAL_STOP = 4, -    _URC_END_OF_STACK = 5, -    _URC_HANDLER_FOUND = 6, -    _URC_INSTALL_CONTEXT = 7, -    _URC_CONTINUE_UNWIND = 8 -} _Unwind_Reason_Code; - -typedef enum { -    _UA_SEARCH_PHASE = 1, -    _UA_CLEANUP_PHASE = 2, -    _UA_HANDLER_FRAME = 4, -    _UA_FORCE_UNWIND = 8, -    _UA_END_OF_STACK = 16 -} _Unwind_Action; - -typedef struct _Unwind_Context* _Unwind_Context_t; - -struct _Unwind_Exception { -    uint64_t                exception_class; -    void                    (*exception_cleanup)(_Unwind_Reason_Code reason,  -                                                 struct _Unwind_Exception* exc); -    uintptr_t                private_1;     -    uintptr_t                private_2;     -}; - -COMPILER_RT_ABI  const uint8_t*    _Unwind_GetLanguageSpecificData(_Unwind_Context_t c); -COMPILER_RT_ABI  void              _Unwind_SetGR(_Unwind_Context_t c, int i, uintptr_t n); -COMPILER_RT_ABI  void              _Unwind_SetIP(_Unwind_Context_t, uintptr_t new_value); -COMPILER_RT_ABI  uintptr_t         _Unwind_GetIP(_Unwind_Context_t context); -COMPILER_RT_ABI  uintptr_t         _Unwind_GetRegionStart(_Unwind_Context_t context); - +#include <unwind.h>  /*   * Pointer encodings documented at: @@ -185,12 +145,12 @@ static uintptr_t readEncodedPointer(const uint8_t** data, uint8_t encoding)  COMPILER_RT_ABI _Unwind_Reason_Code  __gcc_personality_sj0(int version, _Unwind_Action actions,           uint64_t exceptionClass, struct _Unwind_Exception* exceptionObject, -         _Unwind_Context_t context) +         struct _Unwind_Context *context)  #else  COMPILER_RT_ABI _Unwind_Reason_Code  __gcc_personality_v0(int version, _Unwind_Action actions,           uint64_t exceptionClass, struct _Unwind_Exception* exceptionObject, -         _Unwind_Context_t context) +         struct _Unwind_Context *context)  #endif  {      /* Since C does not have catch clauses, there is nothing to do during */ @@ -199,7 +159,7 @@ __gcc_personality_v0(int version, _Unwind_Action actions,          return _URC_CONTINUE_UNWIND;      /* There is nothing to do if there is no LSDA for this frame. */ -    const uint8_t* lsda = _Unwind_GetLanguageSpecificData(context); +    const uint8_t* lsda = (uint8_t*)_Unwind_GetLanguageSpecificData(context);      if ( lsda == (uint8_t*) 0 )          return _URC_CONTINUE_UNWIND; diff --git a/lib/builtins/int_types.h b/lib/builtins/int_types.h index 5107f71550ac..aedae14b2046 100644 --- a/lib/builtins/int_types.h +++ b/lib/builtins/int_types.h @@ -56,7 +56,8 @@ typedef union      }s;  } udwords; -#if __LP64__ +/* MIPS64 issue: PR 20098 */ +#if defined(__LP64__) && !(defined(__mips__) && defined(__clang__))  #define CRT_HAS_128BIT  #endif | 
