aboutsummaryrefslogtreecommitdiffstats
path: root/code/unix/unix_main.c
diff options
context:
space:
mode:
authoricculus <icculus@edf5b092-35ff-0310-97b2-ce42778d08ea>2005-12-01 11:49:02 +0000
committericculus <icculus@edf5b092-35ff-0310-97b2-ce42778d08ea>2005-12-01 11:49:02 +0000
commit02470e9506b3d4c51dfdab407968600b486e7e54 (patch)
tree060111e5c44b2fa34e47d4b9f2f5aed8c274afe2 /code/unix/unix_main.c
parent90bf7c94bc7814ef7c9dc7c24c601b867c953e2e (diff)
downloadioquake3-aero-02470e9506b3d4c51dfdab407968600b486e7e54.tar.gz
ioquake3-aero-02470e9506b3d4c51dfdab407968600b486e7e54.zip
Fixed detection of Altivec on Mac OS X, and added attempt at general detection
with SIGILL/setjmp hackery for PowerPC Linux, etc. git-svn-id: svn://svn.icculus.org/quake3/trunk@398 edf5b092-35ff-0310-97b2-ce42778d08ea
Diffstat (limited to 'code/unix/unix_main.c')
-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
}
}