diff options
Diffstat (limited to 'xc/programs/Xserver/hw/xfree86/loader/loader.c')
-rw-r--r-- | xc/programs/Xserver/hw/xfree86/loader/loader.c | 78 |
1 files changed, 73 insertions, 5 deletions
diff --git a/xc/programs/Xserver/hw/xfree86/loader/loader.c b/xc/programs/Xserver/hw/xfree86/loader/loader.c index 44c279166..60acebe02 100644 --- a/xc/programs/Xserver/hw/xfree86/loader/loader.c +++ b/xc/programs/Xserver/hw/xfree86/loader/loader.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/loader.c,v 1.44 2000/10/02 02:32:15 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/loader.c,v 1.46 2000/11/03 18:46:16 eich Exp $ */ /* * @@ -85,11 +85,75 @@ static char freeHandles[MAX_HANDLE] ; static int refCount[MAX_HANDLE] ; #endif -#ifdef __sparc__ -extern LOOKUP SparcLookupTab[]; +#if defined(__sparc__) && defined(__GNUC__) +# define SYMFUNCDOT(func) { "." #func, (funcptr)&__sparc_dot_ ## func }, +# define SYMFUNCDOT89(func) { "." #func, (funcptr)&func ## _sparcv89 }, +# define DEFFUNCDOT(func) \ +extern void __sparc_dot_ ## func (void) __asm__ ("." #func); \ +extern void func ## _sparcv89 (void); +DEFFUNCDOT(rem) +DEFFUNCDOT(urem) +DEFFUNCDOT(mul) +DEFFUNCDOT(umul) +DEFFUNCDOT(div) +DEFFUNCDOT(udiv) +static LOOKUP SparcV89LookupTab[] = { + SYMFUNCDOT89(rem) + SYMFUNCDOT89(urem) + SYMFUNCDOT89(mul) + SYMFUNCDOT89(umul) + SYMFUNCDOT89(div) + SYMFUNCDOT89(udiv) + { 0, 0 } +}; +static LOOKUP SparcLookupTab[] = { + SYMFUNCDOT(rem) + SYMFUNCDOT(urem) + SYMFUNCDOT(mul) + SYMFUNCDOT(umul) + SYMFUNCDOT(div) + SYMFUNCDOT(udiv) + { 0, 0 } +}; #ifdef linux -extern int sparcUseHWMulDiv(void); -extern LOOKUP SparcV89LookupTab[]; +#if defined(__GNUC__) && defined(__GLIBC__) +#define HWCAP_SPARC_MULDIV 8 +extern unsigned long int _dl_hwcap; +#endif + +static int +sparcUseHWMulDiv(void) +{ + FILE *f; + char buffer[1024]; + char *p; +#if defined(__GNUC__) && defined(__GLIBC__) + unsigned long *hwcap; + __asm(".weak _dl_hwcap"); + + hwcap = &_dl_hwcap; + __asm("" : "=r" (hwcap) : "0" (hwcap)); + if (hwcap) { + if (*hwcap & HWCAP_SPARC_MULDIV) + return 1; + else + return 0; + } +#endif + f = fopen("/proc/cpuinfo","r"); + if (!f) return 0; + while (fgets(buffer, 1024, f) != NULL) { + if (!strncmp (buffer, "type", 4)) { + p = strstr (buffer, "sun4"); + if (p && (p[4] == 'u' || p[4] == 'd' || p[4] == 'm')) { + fclose(f); + return 1; + } + } + } + fclose(f); + return 0; +} #endif #endif @@ -404,6 +468,10 @@ _LoaderFileToMem(int fd, unsigned long offset,int size, char *label) FatalError("\n_LoaderFileToMem() read() failed: %s\n",strerror(errno)); #if defined(linux) && defined(__powerpc__) + /* + * Keep the instruction cache in sync with changes in the + * main memory. + */ { int i; for (i = 0; i < size; i += 16) |