mirror of
https://github.com/s1lentq/ReGameDLL_CS.git
synced 2025-01-13 23:28:04 +03:00
GCC port and new defines for new ARM port (#294)
* Put SSE code under HAVE_SSE define * Fix circular dependency on GCC 7.3 * Provide a way to disable AMXX related hacks, when it's not needed * Fix ASM inline for GCC * Fix compiling with MSVC * Fix compiling with MSVC and ICC * Check for HAVE_SSE in sse_mathfun.cpp after including precompiled, so SSE state will be determined * Better check for SSE availability * Missing call ::ClientCommand_ Make CSaveRestoreBuffer::m_Sizes as const Cosmetic changes * Gradle: Add GCC Toolchain * GCC: Fix compile * Gradle: Add -fno-devirtualize to compiler flags for GCC
This commit is contained in:
parent
fe0ea9a1bc
commit
2b4eb6c137
@ -24,6 +24,7 @@ import org.apache.commons.compress.archivers.ArchiveInputStream
|
||||
|
||||
apply plugin: 'cpp'
|
||||
apply plugin: IccCompilerPlugin
|
||||
apply plugin: GccCompilerPlugin
|
||||
apply plugin: RegamedllPlayTestPlugin
|
||||
apply plugin: gradlecpp.CppUnitTestPlugin
|
||||
|
||||
@ -59,11 +60,11 @@ void createIntergrationTestTask(NativeBinarySpec b) {
|
||||
testDemos = project.configurations.regamedll_tests
|
||||
testFor = b
|
||||
|
||||
//inputs/outputs for up-to-date check
|
||||
// inputs/outputs for up-to-date check
|
||||
inputs.files testDemos.files
|
||||
outputs.dir regamedllTestLogs
|
||||
|
||||
//dependencies on test executable
|
||||
// dependencies on test executable
|
||||
if (unitTestTask) {
|
||||
dependsOn unitTestTask
|
||||
}
|
||||
@ -90,6 +91,7 @@ void postEvaluate(NativeBinarySpec b) {
|
||||
|
||||
void setupToolchain(NativeBinarySpec b)
|
||||
{
|
||||
boolean useGcc = project.hasProperty("useGcc")
|
||||
boolean unitTestExecutable = b.component.name.endsWith('_tests')
|
||||
boolean regamedllFixes = b.flavor.name.contains('regamedllFixes')
|
||||
|
||||
@ -127,10 +129,13 @@ void setupToolchain(NativeBinarySpec b)
|
||||
}
|
||||
else if (cfg instanceof GccToolchainConfig)
|
||||
{
|
||||
cfg.compilerOptions.pchConfig = new GccToolchainConfig.PrecompilerHeaderOptions(
|
||||
enabled: true,
|
||||
pchSourceSet: 'regamedll_pch'
|
||||
);
|
||||
if (!useGcc)
|
||||
{
|
||||
cfg.compilerOptions.pchConfig = new GccToolchainConfig.PrecompilerHeaderOptions(
|
||||
enabled: true,
|
||||
pchSourceSet: 'regamedll_pch'
|
||||
);
|
||||
}
|
||||
|
||||
cfg.compilerOptions.languageStandard = 'c++14'
|
||||
cfg.defines([
|
||||
@ -145,8 +150,22 @@ void setupToolchain(NativeBinarySpec b)
|
||||
'_access' : 'access'
|
||||
])
|
||||
|
||||
cfg.linkerOptions.args '-no-opt-class-analysis'
|
||||
cfg.compilerOptions.args '-Qoption,cpp,--treat_func_as_string_literal_cpp', '-g0', '-fno-rtti', '-fno-exceptions'
|
||||
if (useGcc) {
|
||||
// Produce code optimized for the most common IA32/AMD64/EM64T processors.
|
||||
// As new processors are deployed in the marketplace, the behavior of this option will change.
|
||||
cfg.compilerOptions.args '-mtune=generic', '-msse3', '-Wno-write-strings', '-Wno-invalid-offsetof', '-fpermissive', '-fno-devirtualize'
|
||||
} else {
|
||||
cfg.compilerOptions.args '-Qoption,cpp,--treat_func_as_string_literal_cpp'
|
||||
|
||||
// Not use c++ class hierarchy for analyze and resolve C++ virtual function calls at compile time.
|
||||
//
|
||||
// Example issue:
|
||||
// Expected: FF .. call dword ptr + offset, pEntity->Spawn();
|
||||
// Got: E8 .. call CBaseEntity::Spawn();
|
||||
cfg.linkerOptions.args '-qno-opt-class-analysis'
|
||||
}
|
||||
|
||||
cfg.compilerOptions.args '-g0', '-fno-rtti', '-fno-exceptions'
|
||||
cfg.projectLibpath(project, '/lib/linux32')
|
||||
cfg.extraLibs 'dl', 'm', 'stdc++', 'aelf32'
|
||||
}
|
||||
@ -243,7 +262,10 @@ model {
|
||||
toolChains {
|
||||
visualCpp(VisualCpp) {
|
||||
}
|
||||
icc(Icc) {
|
||||
if (project.hasProperty("useGcc")) {
|
||||
gcc(Gcc)
|
||||
} else {
|
||||
icc(Icc)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef PLAY_GAMEDLL
|
||||
// NOTE: In some cases we need high precision of floating-point,
|
||||
// NOTE: In some cases we need high precision of floating-point,
|
||||
// so use double instead of float, otherwise unittest will fail
|
||||
typedef double real_t;
|
||||
#else
|
||||
@ -85,6 +85,7 @@ const T& clamp(const T& a, const T& min, const T& max) { return (a > max) ? max
|
||||
#define clamp(val, min, max) (((val) > (max)) ? (max) : (((val) < (min)) ? (min) : (val)))
|
||||
#endif // __cplusplus
|
||||
|
||||
#ifdef HAVE_SSE
|
||||
inline float M_sqrt(float value) {
|
||||
return _mm_cvtss_f32(_mm_sqrt_ss(_mm_load_ss(&value)));
|
||||
}
|
||||
@ -93,12 +94,14 @@ inline double M_sqrt(double value) {
|
||||
auto v = _mm_load_sd(&value);
|
||||
return _mm_cvtsd_f64(_mm_sqrt_sd(v, v));
|
||||
}
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
inline double M_sqrt(T value) {
|
||||
return sqrt(value);
|
||||
}
|
||||
|
||||
#ifdef HAVE_SSE
|
||||
inline float M_min(float a, float b) {
|
||||
return _mm_cvtss_f32(_mm_min_ss(_mm_load_ss(&a), _mm_load_ss(&b)));
|
||||
}
|
||||
@ -106,12 +109,14 @@ inline float M_min(float a, float b) {
|
||||
inline double M_min(double a, double b) {
|
||||
return _mm_cvtsd_f64(_mm_min_sd(_mm_load_sd(&a), _mm_load_sd(&b)));
|
||||
}
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
inline T M_min(T a, T b) {
|
||||
return min(a, b);
|
||||
}
|
||||
|
||||
#ifdef HAVE_SSE
|
||||
inline float M_max(float a, float b) {
|
||||
return _mm_cvtss_f32(_mm_max_ss(_mm_load_ss(&a), _mm_load_ss(&b)));
|
||||
}
|
||||
@ -119,12 +124,14 @@ inline float M_max(float a, float b) {
|
||||
inline double M_max(double a, double b) {
|
||||
return _mm_cvtsd_f64(_mm_max_sd(_mm_load_sd(&a), _mm_load_sd(&b)));
|
||||
}
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
inline T M_max(T a, T b) {
|
||||
return max(a, b);
|
||||
}
|
||||
|
||||
#ifdef HAVE_SSE
|
||||
inline float M_clamp(float a, float min, float max) {
|
||||
return _mm_cvtss_f32(_mm_min_ss(_mm_max_ss(_mm_load_ss(&a), _mm_load_ss(&min)), _mm_load_ss(&max)));
|
||||
}
|
||||
@ -132,6 +139,7 @@ inline float M_clamp(float a, float min, float max) {
|
||||
inline double M_clamp(double a, double min, double max) {
|
||||
return _mm_cvtsd_f64(_mm_min_sd(_mm_max_sd(_mm_load_sd(&a), _mm_load_sd(&min)), _mm_load_sd(&max)));
|
||||
}
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
inline T M_clamp(T a, T min, T max) {
|
||||
|
@ -527,7 +527,7 @@ C_DLLEXPORT int Server_GetBlendingInterface(int version, struct sv_blending_inte
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef REGAMEDLL_FIXES // SSE2 version
|
||||
#if defined(REGAMEDLL_FIXES) && defined(HAVE_SSE) // SSE2 version
|
||||
void AngleQuaternion(vec_t *angles, vec_t *quaternion)
|
||||
{
|
||||
static const ALIGN16_BEG size_t ps_signmask[4] ALIGN16_END = { 0x80000000, 0, 0x80000000, 0 };
|
||||
|
@ -8296,6 +8296,9 @@ void CBasePlayer::ClientCommand(const char *cmd, const char *arg1, const char *a
|
||||
|
||||
auto pEntity = ENT(pev);
|
||||
|
||||
#ifdef NO_AMXX_HACKS // a1ba: not needed for non-x86 port
|
||||
::ClientCommand_(pEntity);
|
||||
#else // NO_AMXX_HACKS
|
||||
// NOTE: force __cdecl to allow cstrike amxx module to hook ClientCommand
|
||||
#if defined _MSC_VER || defined __INTEL_COMPILER
|
||||
__asm
|
||||
@ -8307,13 +8310,13 @@ void CBasePlayer::ClientCommand(const char *cmd, const char *arg1, const char *a
|
||||
#else
|
||||
asm volatile (
|
||||
"pushl %0\n\t"
|
||||
"call %1\n\t"
|
||||
"addl %%esp, $4\n\t"
|
||||
::
|
||||
"g" (pEntity),
|
||||
"g" (ClientCommand_),
|
||||
"call *%1\n\t"
|
||||
"addl $4, %%esp\n\t"
|
||||
: /* no outputs */
|
||||
: "g" (pEntity), "g" (ClientCommand_)
|
||||
);
|
||||
#endif // _MSC_VER || defined __INTEL_COMPILER
|
||||
#endif // NO_AMXX_HACKS
|
||||
|
||||
UseBotArgs = false;
|
||||
}
|
||||
|
@ -160,6 +160,28 @@ void EntvarsKeyvalue(entvars_t *pev, KeyValueData *pkvd)
|
||||
}
|
||||
}
|
||||
|
||||
const int CSaveRestoreBuffer::m_Sizes[] =
|
||||
{
|
||||
sizeof(float), // FIELD_FLOAT
|
||||
sizeof(int), // FIELD_STRING
|
||||
sizeof(int), // FIELD_ENTITY
|
||||
sizeof(int), // FIELD_CLASSPTR
|
||||
sizeof(int), // FIELD_EHANDLE
|
||||
sizeof(int), // FIELD_entvars_t
|
||||
sizeof(int), // FIELD_EDICT
|
||||
sizeof(float) * 3, // FIELD_VECTOR
|
||||
sizeof(float) * 3, // FIELD_POSITION_VECTOR
|
||||
sizeof(int *), // FIELD_POINTER
|
||||
sizeof(int), // FIELD_INTEGER
|
||||
sizeof(int *), // FIELD_FUNCTION
|
||||
sizeof(int), // FIELD_BOOLEAN
|
||||
sizeof(short), // FIELD_SHORT
|
||||
sizeof(char), // FIELD_CHARACTER
|
||||
sizeof(float), // FIELD_TIME
|
||||
sizeof(int), // FIELD_MODELNAME
|
||||
sizeof(int), // FIELD_SOUNDNAME
|
||||
};
|
||||
|
||||
CSaveRestoreBuffer::CSaveRestoreBuffer()
|
||||
{
|
||||
m_pData = nullptr;
|
||||
|
@ -85,26 +85,7 @@ public:
|
||||
unsigned short TokenHash(const char *pszToken);
|
||||
|
||||
protected:
|
||||
static constexpr int m_Sizes[] = {
|
||||
sizeof(float), // FIELD_FLOAT
|
||||
sizeof(int), // FIELD_STRING
|
||||
sizeof(int), // FIELD_ENTITY
|
||||
sizeof(int), // FIELD_CLASSPTR
|
||||
sizeof(int), // FIELD_EHANDLE
|
||||
sizeof(int), // FIELD_entvars_t
|
||||
sizeof(int), // FIELD_EDICT
|
||||
sizeof(float) * 3, // FIELD_VECTOR
|
||||
sizeof(float) * 3, // FIELD_POSITION_VECTOR
|
||||
sizeof(int *), // FIELD_POINTER
|
||||
sizeof(int), // FIELD_INTEGER
|
||||
sizeof(int *), // FIELD_FUNCTION
|
||||
sizeof(int), // FIELD_BOOLEAN
|
||||
sizeof(short), // FIELD_SHORT
|
||||
sizeof(char), // FIELD_CHARACTER
|
||||
sizeof(float), // FIELD_TIME
|
||||
sizeof(int), // FIELD_MODELNAME
|
||||
sizeof(int), // FIELD_SOUNDNAME
|
||||
};
|
||||
static const int m_Sizes[];
|
||||
|
||||
SAVERESTOREDATA *m_pData;
|
||||
void BufferRewind(int size);
|
||||
|
@ -323,7 +323,8 @@ inline T *UTIL_FindEntityInSphere(T *pStartEntity, const Vector &vecCenter, floa
|
||||
pentEntity = FIND_ENTITY_IN_SPHERE(pentEntity, vecCenter, flRadius);
|
||||
if (!FNullEnt(pentEntity))
|
||||
{
|
||||
return (T *)CBaseEntity::Instance(pentEntity);
|
||||
// a1ba: can't use CBaseEntity::Instance here, because circular dependency in cbase.h
|
||||
return GET_PRIVATE<T>(pentEntity);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
@ -47,6 +47,12 @@
|
||||
#include <deque>
|
||||
#include <functional>
|
||||
|
||||
// enable SSE code only if it's enabled in compiler options
|
||||
#if defined(__SSE__) || defined(__SSE2__) || defined(_M_IX86_FP) || defined(_M_AMD64) || defined(_M_X64)
|
||||
// #error "SSE enabled"
|
||||
#define HAVE_SSE
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32 // WINDOWS
|
||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||
#include <windows.h>
|
||||
@ -87,9 +93,10 @@
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
|
||||
#ifdef HAVE_SSE
|
||||
#include <smmintrin.h>
|
||||
#include <xmmintrin.h>
|
||||
|
||||
#endif // HAVE_SSE
|
||||
|
||||
#ifdef _WIN32 // WINDOWS
|
||||
// Define __func__ on VS less than 2015
|
||||
@ -97,6 +104,8 @@
|
||||
#define __func__ __FUNCTION__
|
||||
#endif
|
||||
|
||||
// We'll not use __func__ on windows because we want 'A::foo' instead of 'foo'
|
||||
#define __FUNC__ __FUNCTION__
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
@ -151,6 +160,7 @@
|
||||
typedef unsigned int UNINT32;
|
||||
|
||||
#define FASTCALL
|
||||
#define __FUNC__ __func__
|
||||
#define CDECL __attribute__ ((cdecl))
|
||||
#define STDCALL __attribute__ ((stdcall))
|
||||
#define HIDDEN __attribute__((visibility("hidden")))
|
||||
|
@ -49,11 +49,11 @@ bool AbstractHookChainRegistry::findHook(void* hookFunc) const
|
||||
void AbstractHookChainRegistry::addHook(void* hookFunc, int priority)
|
||||
{
|
||||
if (!hookFunc) {
|
||||
Sys_Error("%s: Parameter hookFunc can't be a nullptr", __func__);
|
||||
Sys_Error("%s: Parameter hookFunc can't be a nullptr", __FUNC__);
|
||||
}
|
||||
|
||||
if (findHook(hookFunc)) {
|
||||
Sys_Error("%s: The same handler can't be used twice on the hookchain.", __func__);
|
||||
Sys_Error("%s: The same handler can't be used twice on the hookchain.", __FUNC__);
|
||||
}
|
||||
|
||||
for (auto i = 0; i < MAX_HOOKS_IN_CHAIN; i++)
|
||||
@ -72,7 +72,7 @@ void AbstractHookChainRegistry::addHook(void* hookFunc, int priority)
|
||||
}
|
||||
|
||||
if (m_NumHooks >= MAX_HOOKS_IN_CHAIN) {
|
||||
Sys_Error("%s: MAX_HOOKS_IN_CHAIN limit hit", __func__);
|
||||
Sys_Error("%s: MAX_HOOKS_IN_CHAIN limit hit", __FUNC__);
|
||||
}
|
||||
|
||||
m_NumHooks++;
|
||||
|
@ -54,7 +54,7 @@ public:
|
||||
IHookChainImpl(void** hooks, origfunc_t orig) : m_Hooks(hooks), m_OriginalFunc(orig)
|
||||
{
|
||||
if (orig == nullptr && !is_void(orig))
|
||||
Sys_Error("%s: Non-void HookChain without original function.", __func__);
|
||||
Sys_Error("%s: Non-void HookChain without original function.", __FUNC__);
|
||||
}
|
||||
|
||||
virtual ~IHookChainImpl() {}
|
||||
@ -90,7 +90,7 @@ public:
|
||||
IHookChainClassImpl(void** hooks, origfunc_t orig) : m_Hooks(hooks), m_OriginalFunc(orig)
|
||||
{
|
||||
if (orig == nullptr && !is_void(orig))
|
||||
Sys_Error("%s: Non-void HookChain without original function.", __func__);
|
||||
Sys_Error("%s: Non-void HookChain without original function.", __FUNC__);
|
||||
}
|
||||
|
||||
virtual ~IHookChainClassImpl() {}
|
||||
@ -126,7 +126,7 @@ public:
|
||||
IHookChainClassEmptyImpl(void** hooks, origfunc_t orig, t_class *object) : m_Hooks(hooks), m_OriginalFunc(orig), m_Object(object)
|
||||
{
|
||||
if (orig == nullptr && !is_void(orig))
|
||||
Sys_Error("%s: Non-void HookChain without original function.", __func__);
|
||||
Sys_Error("%s: Non-void HookChain without original function.", __FUNC__);
|
||||
}
|
||||
|
||||
virtual ~IHookChainClassEmptyImpl() {}
|
||||
|
@ -34,7 +34,9 @@
|
||||
#include "basetypes.h"
|
||||
|
||||
#include "archtypes.h"
|
||||
#ifdef HAVE_SSE
|
||||
#include "sse_mathfun.h"
|
||||
#endif
|
||||
#include "asmlib.h"
|
||||
|
||||
#include "MemPool.h"
|
||||
|
@ -31,6 +31,8 @@ misrepresented as being the original software.
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
#ifdef HAVE_SSE
|
||||
|
||||
/* natural logarithm computed for 4 simultaneous float
|
||||
return NaN for x <= 0
|
||||
*/
|
||||
@ -445,3 +447,4 @@ void sincos_ps(v4sf x, v4sf *s, v4sf *c) {
|
||||
*s = _mm_xor_ps(xmm1, sign_bit_sin);
|
||||
*c = _mm_xor_ps(xmm2, sign_bit_cos);
|
||||
}
|
||||
#endif // HAVE_SSE
|
||||
|
@ -8,6 +8,7 @@ import org.gradle.nativeplatform.toolchain.VisualCpp
|
||||
|
||||
apply from: 'shared_msvc.gradle'
|
||||
apply from: 'shared_icc.gradle'
|
||||
apply from: 'shared_gcc.gradle'
|
||||
|
||||
rootProject.ext.createToolchainConfig = { NativeBinarySpec bin ->
|
||||
BinaryKind binaryKind
|
||||
@ -37,6 +38,10 @@ rootProject.ext.createToolchainConfig = { NativeBinarySpec bin ->
|
||||
{
|
||||
return rootProject.createIccConfig(releaseBuild, binaryKind)
|
||||
}
|
||||
else if (bin.toolChain instanceof Gcc)
|
||||
{
|
||||
return rootProject.createGccConfig(releaseBuild, binaryKind)
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new RuntimeException("Unknown native toolchain: ${bin.toolChain.class.name}")
|
||||
|
55
shared_gcc.gradle
Normal file
55
shared_gcc.gradle
Normal file
@ -0,0 +1,55 @@
|
||||
import org.doomedsociety.gradlecpp.cfg.BinaryKind
|
||||
import org.doomedsociety.gradlecpp.gcc.GccToolchainConfig
|
||||
import org.doomedsociety.gradlecpp.gcc.OptimizationLevel
|
||||
|
||||
rootProject.ext.createGccConfig = { boolean release, BinaryKind binKind ->
|
||||
GccToolchainConfig cfg
|
||||
if (release) {
|
||||
cfg = new GccToolchainConfig(
|
||||
compilerOptions: new GccToolchainConfig.CompilerOptions(
|
||||
optimizationLevel: OptimizationLevel.LEVEL_3,
|
||||
stackProtector: false,
|
||||
noBuiltIn: true,
|
||||
positionIndependentCode: false,
|
||||
extraDefines: [
|
||||
'_GLIBCXX_USE_CXX11_ABI': 0,
|
||||
]
|
||||
),
|
||||
|
||||
linkerOptions: new GccToolchainConfig.LinkerOptions(
|
||||
stripSymbolTable: false,
|
||||
staticLibGcc: false,
|
||||
staticLibStdCpp: false,
|
||||
),
|
||||
|
||||
librarianOptions: new GccToolchainConfig.LibrarianOptions(
|
||||
|
||||
)
|
||||
)
|
||||
} else {
|
||||
//debug
|
||||
cfg = new GccToolchainConfig(
|
||||
compilerOptions: new GccToolchainConfig.CompilerOptions(
|
||||
optimizationLevel: OptimizationLevel.DISABLE,
|
||||
stackProtector: true,
|
||||
noBuiltIn: true,
|
||||
extraDefines: [
|
||||
'_GLIBCXX_USE_CXX11_ABI': 0,
|
||||
]
|
||||
),
|
||||
|
||||
linkerOptions: new GccToolchainConfig.LinkerOptions(
|
||||
stripSymbolTable: false,
|
||||
staticLibGcc: false,
|
||||
staticLibStdCpp: false,
|
||||
),
|
||||
|
||||
librarianOptions: new GccToolchainConfig.LibrarianOptions(
|
||||
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
cfg.singleDefines('LINUX', '_LINUX')
|
||||
return cfg
|
||||
}
|
@ -60,5 +60,6 @@ rootProject.ext.createIccConfig = { boolean release, BinaryKind binKind ->
|
||||
)
|
||||
}
|
||||
|
||||
cfg.singleDefines('LINUX', '_LINUX')
|
||||
return cfg
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user