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

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