diff options
| author | José Fonseca <jfonseca@vmware.com> | 2010-07-22 18:37:46 +0100 | 
|---|---|---|
| committer | José Fonseca <jfonseca@vmware.com> | 2010-07-29 19:10:59 +0100 | 
| commit | e3d2ebac115f7b7899664fefc2652fb829acfa27 (patch) | |
| tree | 135cfc368ae426c6c6a485cb4a544098d636fedb /src | |
| parent | 38f5b1bc38fde041162e90e0ba3955ac661e1abf (diff) | |
llvmpipe: Avoid corrupting the FPU stack with MMX instructions on 32bit OSes.
Unfortunately LLVM doesn't emit EMMS itself, and there is no
easy/effective way to disable MMX.
http://llvm.org/bugs/show_bug.cgi?id=3287
Diffstat (limited to 'src')
| -rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_misc.cpp | 24 | ||||
| -rw-r--r-- | src/gallium/drivers/llvmpipe/lp_state_fs.c | 5 | 
2 files changed, 29 insertions, 0 deletions
| diff --git a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp index 5a9488b5f7..072408b268 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp +++ b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp @@ -39,6 +39,7 @@  #include <llvm/Target/TargetOptions.h>  #include <llvm/ExecutionEngine/ExecutionEngine.h>  #include <llvm/ExecutionEngine/JITEventListener.h> +#include <llvm/Support/CommandLine.h>  #include "pipe/p_config.h"  #include "util/u_debug.h" @@ -141,4 +142,27 @@ lp_set_target_options(void)  #if 0     llvm::UnsafeFPMath = true;  #endif + +#if 0 +   /* +    * LLVM will generate MMX instructions for vectors <= 64 bits, leading to +    * innefficient code, and in 32bit systems, to the corruption of the FPU +    * stack given that it expects the user to generate the EMMS instructions. +    * +    * See also: +    * - http://llvm.org/bugs/show_bug.cgi?id=3287 +    * - http://l4.me.uk/post/2009/06/07/llvm-wrinkle-3-configuration-what-configuration/ +    * +    * XXX: Unfortunately this is not working. +    */ +   static boolean first = FALSE; +   if (first) { +      static const char* options[] = { +         "prog", +         "-disable-mmx" +      }; +      llvm::cl::ParseCommandLineOptions(2, const_cast<char**>(options)); +      first = FALSE; +   } +#endif  } diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 5953d690a4..dbcc286417 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -676,6 +676,11 @@ generate_fragment(struct llvmpipe_context *lp,  		     color_ptr);     } +#ifdef PIPE_ARCH_X86 +   /* Avoid corrupting the FPU stack on 32bit OSes. */ +   lp_build_intrinsic(builder, "llvm.x86.mmx.emms", LLVMVoidType(), NULL, 0); +#endif +     LLVMBuildRetVoid(builder);     LLVMDisposeBuilder(builder); | 
