This change to Gv_DivVar() is faster when benchmarked

git-svn-id: https://svn.eduke32.com/eduke32@8396 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
terminx 2019-12-07 23:52:10 +00:00 committed by Christoph Oelckers
parent a2fd43da2f
commit 0b2f550f09

View file

@ -208,82 +208,74 @@ static FORCE_INLINE void __fastcall VM_SetStruct(uint32_t const flags, intptr_t
}
}
#define VM_GAMEVAR_OPERATOR(func, operator) \
static FORCE_INLINE void __fastcall func(int const id, int32_t const operand) \
{ \
auto &var = aGameVars[id]; \
\
switch (var.flags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK)) \
{ \
default: var.global operator operand; break; \
case GAMEVAR_PERPLAYER: \
if (EDUKE32_PREDICT_FALSE((unsigned)vm.playerNum > MAXPLAYERS - 1)) \
break; \
var.pValues[vm.playerNum] operator operand; \
break; \
case GAMEVAR_PERACTOR: \
if (EDUKE32_PREDICT_FALSE((unsigned)vm.spriteNum > MAXSPRITES - 1)) \
break; \
var.pValues[vm.spriteNum] operator operand; \
break; \
case GAMEVAR_INT32PTR: *(int32_t *)var.pValues operator(int32_t) operand; break; \
case GAMEVAR_INT16PTR: *(int16_t *)var.pValues operator(int16_t) operand; break; \
case GAMEVAR_Q16PTR: \
{ \
Fix16 *pfix = (Fix16 *)var.global; \
*pfix operator fix16_from_int(operand); \
break; \
} \
} \
#define VM_GAMEVAR_OPERATOR(func, operator) \
static FORCE_INLINE ATTRIBUTE((flatten)) void __fastcall func(int const id, int32_t const operand) \
{ \
auto &var = aGameVars[id]; \
\
switch (var.flags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK)) \
{ \
default: \
var.global operator operand; \
break; \
case GAMEVAR_PERPLAYER: \
var.pValues[vm.playerNum & (MAXPLAYERS-1)] operator operand; \
break; \
case GAMEVAR_PERACTOR: \
var.pValues[vm.spriteNum & (MAXSPRITES-1)] operator operand; \
break; \
case GAMEVAR_INT32PTR: *(int32_t *)var.pValues operator(int32_t) operand; break; \
case GAMEVAR_INT16PTR: *(int16_t *)var.pValues operator(int16_t) operand; break; \
case GAMEVAR_Q16PTR: \
{ \
Fix16 *pfix = (Fix16 *)var.global; \
*pfix operator fix16_from_int(operand); \
break; \
} \
} \
}
static FORCE_INLINE void __fastcall Gv_DivVar(int const id, int32_t const operand)
static FORCE_INLINE void __fastcall Gv_DivVar(int const id, int32_t const d)
{
auto &var = aGameVars[id];
using namespace libdivide;
if (EDUKE32_PREDICT_FALSE((var.flags & GAMEVAR_PERPLAYER && (unsigned) vm.playerNum > MAXPLAYERS - 1) ||
(var.flags & GAMEVAR_PERACTOR && (unsigned) vm.spriteNum > MAXSPRITES - 1)))
return;
int const foundInTable = (unsigned) operand < DIVTABLESIZE;
static libdivide::libdivide_s32_t sdiv;
intptr_t *iptr = &var.global;
static libdivide_s32_t sdiv;
static int32_t lastValue;
auto dptr = foundInTable ? (libdivide::libdivide_s32_t *) &divtable32[operand] : &sdiv;
if (operand == lastValue || foundInTable)
goto skip;
auto &var = aGameVars[id];
auto *dptr = &sdiv;
auto iptr = &var.global;
sdiv = libdivide::libdivide_s32_gen((lastValue = operand));
skip:
if ((unsigned)d < DIVTABLESIZE)
dptr = &divtable32[d];
else if (d != lastValue)
sdiv = libdivide_s32_gen((lastValue = d));
switch (var.flags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK))
{
case GAMEVAR_PERACTOR: iptr = &var.pValues[vm.spriteNum]; break;
case GAMEVAR_PERPLAYER: iptr = &var.pValues[vm.playerNum];
default: break;
case GAMEVAR_PERACTOR: iptr = &var.pValues[vm.spriteNum & (MAXSPRITES-1)]; goto jmp;
case GAMEVAR_PERPLAYER: iptr = &var.pValues[vm.playerNum & (MAXPLAYERS-1)]; fallthrough__;
jmp: default: *iptr = libdivide_s32_do(*iptr, dptr); break;
case GAMEVAR_INT32PTR:
{
int32_t &value = *(int32_t *)var.pValues;
value = (int32_t)libdivide::libdivide_s32_do(value, dptr);
return;
auto &value = *(int32_t *)var.pValues;
value = libdivide_s32_do(value, dptr);
break;
}
case GAMEVAR_INT16PTR:
{
int16_t &value = *(int16_t *)var.pValues;
value = (int16_t)libdivide::libdivide_s32_do(value, dptr);
return;
auto &value = *(int16_t *)var.pValues;
value = (int16_t)libdivide_s32_do(value, dptr);
break;
}
case GAMEVAR_Q16PTR:
{
fix16_t &value = *(fix16_t *)var.pValues;
value = fix16_div(value, fix16_from_int(operand));
return;
auto &value = *(fix16_t *)var.pValues;
value = fix16_div(value, fix16_from_int(d));
break;
}
}
*iptr = libdivide_s32_do(*iptr, dptr);
}
VM_GAMEVAR_OPERATOR(Gv_AddVar, +=)