aboutsummaryrefslogtreecommitdiffstats
path: root/code
diff options
context:
space:
mode:
Diffstat (limited to 'code')
-rw-r--r--code/unix/unix_main.c42
1 files changed, 34 insertions, 8 deletions
diff --git a/code/unix/unix_main.c b/code/unix/unix_main.c
index 58e1a08..b673ca5 100644
--- a/code/unix/unix_main.c
+++ b/code/unix/unix_main.c
@@ -362,23 +362,49 @@ void Sys_Quit (void) {
Sys_Exit(0);
}
+
+#if idppc_altivec && !MACOS_X
+/* This is the brute force way of detecting instruction sets...
+ the code is borrowed from SDL, which got the idea from the libmpeg2
+ library - thanks!
+ */
+#include <signal.h>
+#include <setjmp.h>
+static jmp_buf jmpbuf;
+static void illegal_instruction(int sig)
+{
+ longjmp(jmpbuf, 1);
+}
+#endif
+
static void Sys_DetectAltivec(void)
{
// Only detect if user hasn't forcibly disabled it.
+ qboolean altivec = qfalse;
if (com_altivec->integer) {
#if idppc_altivec
-#ifdef MACOS_X
+ #ifdef MACOS_X
long feat = 0;
OSErr err = Gestalt(gestaltPowerPCProcessorFeatures, &feat);
if ((err==noErr) && ((1 << gestaltPowerPCHasVectorInstructions) & feat)) {
- Cvar_Set( "com_altivec", "1" );
+ altivec = qtrue;
+ }
+ #else
+ void (*handler)(int sig);
+ handler = signal(SIGILL, illegal_instruction);
+ if ( setjmp(jmpbuf) == 0 ) {
+ asm volatile ("mtspr 256, %0\n\t"
+ "vand %%v0, %%v0, %%v0"
+ :
+ : "r" (-1));
+ altivec = qtrue;
+ }
+ signal(SIGILL, handler);
+ #endif
+
+ if (!altivec) {
+ Cvar_Set( "com_altivec", "0" ); // we don't have it! Disable support!
}
-#else // !!! FIXME: PowerPC Linux, etc: how to detect?
- Cvar_Set( "com_altivec", "1" );
-#endif
-#else
- // not an Altivec system, so never use it.
- Cvar_Set( "com_altivec", "0" );
#endif
}
}