mirror of
https://github.com/ZDoom/zdbsp.git
synced 2024-11-21 19:32:31 +00:00
- Enable backpatching for VC++ builds of ZDBSP.
SVN r2411 (trunk)
This commit is contained in:
parent
2de2b094ec
commit
08216817e5
3 changed files with 47 additions and 6 deletions
|
@ -31,11 +31,15 @@ if( CMAKE_SIZEOF_VOID_P MATCHES "4" )
|
|||
endif( CMAKE_SIZEOF_VOID_P MATCHES "4" )
|
||||
|
||||
if( SSE_MATTERS )
|
||||
if( CMAKE_COMPILER_IS_GNUCXX AND WIN32 )
|
||||
if( WIN32 )
|
||||
set( BACKPATCH 1 CACHE BOOL "Enable backpatching." )
|
||||
endif( CMAKE_COMPILER_IS_GNUCXX AND WIN32 )
|
||||
else( WIN32 )
|
||||
set( BACKPATCH 0 )
|
||||
endif( WIN32 )
|
||||
set( FULL_SSE2 0 CACHE BOOL "Use SSE2 math everywhere." )
|
||||
set( SSE 1 CACHE BOOL "Build SSE and SSE2 versions of key code." )
|
||||
else( SSE_MATTERS )
|
||||
set( BACKPATCH 0 )
|
||||
endif( SSE_MATTERS )
|
||||
|
||||
if( CMAKE_COMPILER_IS_GNUCXX )
|
||||
|
@ -99,6 +103,10 @@ else( ZLIB_FOUND )
|
|||
set( ZLIB_LIBRARY z )
|
||||
endif( ZLIB_FOUND )
|
||||
|
||||
if( BACKPATCH )
|
||||
add_definitions( -DBACKPATCH )
|
||||
endif( BACKPATCH )
|
||||
|
||||
CHECK_FUNCTION_EXISTS( stricmp STRICMP_EXISTS )
|
||||
if( NOT STRICMP_EXISTS )
|
||||
add_definitions( -Dstricmp=strcasecmp )
|
||||
|
|
|
@ -1053,19 +1053,29 @@ void FNodeBuilder::PrintSet (int l, DWORD set)
|
|||
Printf ("*\n");
|
||||
}
|
||||
|
||||
#if defined(_WIN32) && !defined(__SSE2__) && !defined(DISABLE_SSE) && !defined(DISABLE_BACKPATCH) && defined(__i386__) && defined(__GNUC__)
|
||||
#ifdef BACKPATCH
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
extern "C" int ClassifyLineBackpatch (node_t &node, const FSimpleVert *v1, const FSimpleVert *v2, int sidev[2])
|
||||
#else
|
||||
static int *CallerOffset;
|
||||
int ClassifyLineBackpatchC (node_t &node, const FSimpleVert *v1, const FSimpleVert *v2, int sidev[2])
|
||||
#endif
|
||||
{
|
||||
// Select the routine based on SSELevel and patch the caller so that
|
||||
// they call that routine directly next time instead of going through here.
|
||||
int *calleroffset = (int *)__builtin_return_address(0) - 1;
|
||||
int *calleroffset;
|
||||
int diff;
|
||||
int (*func)(node_t &, const FSimpleVert *, const FSimpleVert *, int[2]);
|
||||
DWORD oldprotect;
|
||||
|
||||
#ifdef __GNUC__
|
||||
calleroffset = (int *)__builtin_return_address(0) - 1;
|
||||
#else
|
||||
calleroffset = CallerOffset;
|
||||
#endif
|
||||
// printf ("Patching for SSE %d\n", SSELevel);
|
||||
|
||||
if (SSELevel == 2)
|
||||
|
@ -1094,4 +1104,23 @@ extern "C" int ClassifyLineBackpatch (node_t &node, const FSimpleVert *v1, const
|
|||
// And return by calling the real function.
|
||||
return func (node, v1, v2, sidev);
|
||||
}
|
||||
|
||||
#ifndef __GNUC__
|
||||
// The ClassifyLineBackpatch() function here is a stub that uses inline assembly and nakedness
|
||||
// to retrieve the return address of the stack before sending control to the real
|
||||
// ClassifyLineBackpatchC() function. Since BACKPATCH shouldn't be defined on 64-bit builds,
|
||||
// we're okay that VC++ can't do inline assembly on that target.
|
||||
|
||||
extern "C" __declspec(noinline) __declspec(naked) int ClassifyLineBackpatch (node_t &node, const FSimpleVert *v1, const FSimpleVert *v2, int sidev[2])
|
||||
{
|
||||
// We store the return address in a global, so as not to need to mess with the parameter list.
|
||||
__asm
|
||||
{
|
||||
mov eax, [esp]
|
||||
sub eax, 4
|
||||
mov CallerOffset, eax
|
||||
jmp ClassifyLineBackpatchC
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -56,8 +56,12 @@ extern "C"
|
|||
#ifndef DISABLE_SSE
|
||||
int ClassifyLineSSE1 (node_t &node, const FSimpleVert *v1, const FSimpleVert *v2, int sidev[2]);
|
||||
int ClassifyLineSSE2 (node_t &node, const FSimpleVert *v1, const FSimpleVert *v2, int sidev[2]);
|
||||
#if defined(_WIN32) && defined(__GNUC__) && !defined(DISABLE_BACKPATCH)
|
||||
#ifdef BACKPATCH
|
||||
#ifdef __GNUC__
|
||||
int ClassifyLineBackpatch (node_t &node, const FSimpleVert *v1, const FSimpleVert *v2, int sidev[2]) __attribute__((noinline));
|
||||
#else
|
||||
int __declspec(noinline) ClassifyLineBackpatch (node_t &node, const FSimpleVert *v1, const FSimpleVert *v2, int sidev[2]);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
@ -300,7 +304,7 @@ inline int FNodeBuilder::ClassifyLine (node_t &node, const FPrivVert *v1, const
|
|||
return ClassifyLine2 (node, v1, v2, sidev);
|
||||
#else
|
||||
// Select the routine based on our flag.
|
||||
#if defined(_WIN32) && defined(__GNUC__) && !defined(DISABLE_BACKPATCH)
|
||||
#ifdef BACKPATCH
|
||||
return ClassifyLineBackpatch (node, v1, v2, sidev);
|
||||
#else
|
||||
if (SSELevel == 2)
|
||||
|
|
Loading…
Reference in a new issue