mirror of
https://github.com/ZDoom/zdbsp.git
synced 2024-11-24 21:01:11 +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" )
|
endif( CMAKE_SIZEOF_VOID_P MATCHES "4" )
|
||||||
|
|
||||||
if( SSE_MATTERS )
|
if( SSE_MATTERS )
|
||||||
if( CMAKE_COMPILER_IS_GNUCXX AND WIN32 )
|
if( WIN32 )
|
||||||
set( BACKPATCH 1 CACHE BOOL "Enable backpatching." )
|
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( FULL_SSE2 0 CACHE BOOL "Use SSE2 math everywhere." )
|
||||||
set( SSE 1 CACHE BOOL "Build SSE and SSE2 versions of key code." )
|
set( SSE 1 CACHE BOOL "Build SSE and SSE2 versions of key code." )
|
||||||
|
else( SSE_MATTERS )
|
||||||
|
set( BACKPATCH 0 )
|
||||||
endif( SSE_MATTERS )
|
endif( SSE_MATTERS )
|
||||||
|
|
||||||
if( CMAKE_COMPILER_IS_GNUCXX )
|
if( CMAKE_COMPILER_IS_GNUCXX )
|
||||||
|
@ -99,6 +103,10 @@ else( ZLIB_FOUND )
|
||||||
set( ZLIB_LIBRARY z )
|
set( ZLIB_LIBRARY z )
|
||||||
endif( ZLIB_FOUND )
|
endif( ZLIB_FOUND )
|
||||||
|
|
||||||
|
if( BACKPATCH )
|
||||||
|
add_definitions( -DBACKPATCH )
|
||||||
|
endif( BACKPATCH )
|
||||||
|
|
||||||
CHECK_FUNCTION_EXISTS( stricmp STRICMP_EXISTS )
|
CHECK_FUNCTION_EXISTS( stricmp STRICMP_EXISTS )
|
||||||
if( NOT STRICMP_EXISTS )
|
if( NOT STRICMP_EXISTS )
|
||||||
add_definitions( -Dstricmp=strcasecmp )
|
add_definitions( -Dstricmp=strcasecmp )
|
||||||
|
|
|
@ -1053,19 +1053,29 @@ void FNodeBuilder::PrintSet (int l, DWORD set)
|
||||||
Printf ("*\n");
|
Printf ("*\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(_WIN32) && !defined(__SSE2__) && !defined(DISABLE_SSE) && !defined(DISABLE_BACKPATCH) && defined(__i386__) && defined(__GNUC__)
|
#ifdef BACKPATCH
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
extern "C" int ClassifyLineBackpatch (node_t &node, const FSimpleVert *v1, const FSimpleVert *v2, int sidev[2])
|
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
|
// Select the routine based on SSELevel and patch the caller so that
|
||||||
// they call that routine directly next time instead of going through here.
|
// 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 diff;
|
||||||
int (*func)(node_t &, const FSimpleVert *, const FSimpleVert *, int[2]);
|
int (*func)(node_t &, const FSimpleVert *, const FSimpleVert *, int[2]);
|
||||||
DWORD oldprotect;
|
DWORD oldprotect;
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
calleroffset = (int *)__builtin_return_address(0) - 1;
|
||||||
|
#else
|
||||||
|
calleroffset = CallerOffset;
|
||||||
|
#endif
|
||||||
// printf ("Patching for SSE %d\n", SSELevel);
|
// printf ("Patching for SSE %d\n", SSELevel);
|
||||||
|
|
||||||
if (SSELevel == 2)
|
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.
|
// And return by calling the real function.
|
||||||
return func (node, v1, v2, sidev);
|
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
|
#endif
|
||||||
|
|
|
@ -56,8 +56,12 @@ extern "C"
|
||||||
#ifndef DISABLE_SSE
|
#ifndef DISABLE_SSE
|
||||||
int ClassifyLineSSE1 (node_t &node, const FSimpleVert *v1, const FSimpleVert *v2, int sidev[2]);
|
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]);
|
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));
|
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
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -300,7 +304,7 @@ inline int FNodeBuilder::ClassifyLine (node_t &node, const FPrivVert *v1, const
|
||||||
return ClassifyLine2 (node, v1, v2, sidev);
|
return ClassifyLine2 (node, v1, v2, sidev);
|
||||||
#else
|
#else
|
||||||
// Select the routine based on our flag.
|
// Select the routine based on our flag.
|
||||||
#if defined(_WIN32) && defined(__GNUC__) && !defined(DISABLE_BACKPATCH)
|
#ifdef BACKPATCH
|
||||||
return ClassifyLineBackpatch (node, v1, v2, sidev);
|
return ClassifyLineBackpatch (node, v1, v2, sidev);
|
||||||
#else
|
#else
|
||||||
if (SSELevel == 2)
|
if (SSELevel == 2)
|
||||||
|
|
Loading…
Reference in a new issue