__set_thread_area.c raw

   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  }
  38