github.com/afumu/libc@v0.0.6/musl/src/thread/sh/__set_thread_area.c (about)

     1  #include "pthread_impl.h"
     2  #include "libc.h"
     3  #include <elf.h>
     4  
     5  /* Also perform sh-specific init */
     6  
     7  #define CPU_HAS_LLSC 0x0040
     8  #define CPU_HAS_CAS_L 0x0400
     9  
    10  extern hidden const char __sh_cas_gusa[], __sh_cas_llsc[], __sh_cas_imask[], __sh_cas_cas_l[];
    11  
    12  hidden const void *__sh_cas_ptr;
    13  
    14  hidden unsigned __sh_nommu;
    15  
    16  int __set_thread_area(void *p)
    17  {
    18  	size_t *aux;
    19  	__asm__ __volatile__ ( "ldc %0, gbr" : : "r"(p) : "memory" );
    20  #ifndef __SH4A__
    21  	__sh_cas_ptr = __sh_cas_gusa;
    22  #if !defined(__SH3__) && !defined(__SH4__)
    23  	for (aux=libc.auxv; *aux; aux+=2) {
    24  		if (*aux != AT_PLATFORM) continue;
    25  		const char *s = (void *)aux[1];
    26  		if (s[0]!='s' || s[1]!='h' || s[2]!='2' || s[3]-'0'<10u) break;
    27  		__sh_cas_ptr = __sh_cas_imask;
    28  		__sh_nommu = 1;
    29  	}
    30  #endif
    31  	if (__hwcap & CPU_HAS_CAS_L)
    32  		__sh_cas_ptr = __sh_cas_cas_l;
    33  	else if (__hwcap & CPU_HAS_LLSC)
    34  		__sh_cas_ptr = __sh_cas_llsc;
    35  #endif
    36  	return 0;
    37  }