mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-29 15:22:08 +00:00
- added implicit initialization of reused register variables in ZScript
This commit is contained in:
parent
d3e6ed3c9b
commit
6f1df5b5ab
3 changed files with 57 additions and 2 deletions
|
@ -11350,8 +11350,51 @@ ExpEmit FxLocalVariableDeclaration::Emit(VMFunctionBuilder *build)
|
||||||
{
|
{
|
||||||
if (RegNum == -1)
|
if (RegNum == -1)
|
||||||
{
|
{
|
||||||
if (!(VarFlags & VARF_Out)) RegNum = build->Registers[ValueType->GetRegType()].Get(RegCount);
|
if (!(VarFlags & VARF_Out))
|
||||||
else RegNum = build->Registers[REGT_POINTER].Get(1);
|
{
|
||||||
|
const int regType = ValueType->GetRegType();
|
||||||
|
assert(regType <= REGT_TYPE);
|
||||||
|
|
||||||
|
auto& registers = build->Registers[regType];
|
||||||
|
RegNum = registers.Get(RegCount);
|
||||||
|
|
||||||
|
for (int reg = RegNum, end = RegNum + RegCount; reg < end; ++reg)
|
||||||
|
{
|
||||||
|
if (!registers.IsDirty(reg))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ScriptPosition.Message(MSG_DEBUGMSG, "Implicit initialization of variable %s\n", Name.GetChars());
|
||||||
|
|
||||||
|
switch (regType)
|
||||||
|
{
|
||||||
|
case REGT_INT:
|
||||||
|
build->Emit(OP_LI, reg, 0, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REGT_FLOAT:
|
||||||
|
build->Emit(OP_LKF, reg, build->GetConstantFloat(0.0));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REGT_STRING:
|
||||||
|
build->Emit(OP_LKS, reg, build->GetConstantString(nullptr));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REGT_POINTER:
|
||||||
|
build->Emit(OP_LKP, reg, build->GetConstantAddress(nullptr));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RegNum = build->Registers[REGT_POINTER].Get(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -367,6 +367,7 @@ void VMFunctionBuilder::ParamChange(int delta)
|
||||||
VMFunctionBuilder::RegAvailability::RegAvailability()
|
VMFunctionBuilder::RegAvailability::RegAvailability()
|
||||||
{
|
{
|
||||||
memset(Used, 0, sizeof(Used));
|
memset(Used, 0, sizeof(Used));
|
||||||
|
memset(Dirty, 0, sizeof(Dirty));
|
||||||
MostUsed = 0;
|
MostUsed = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -493,16 +494,19 @@ void VMFunctionBuilder::RegAvailability::Return(int reg, int count)
|
||||||
// because for that case it pushes the self pointer a second time without reallocating, so it gets freed twice.
|
// because for that case it pushes the self pointer a second time without reallocating, so it gets freed twice.
|
||||||
//assert((Used[firstword] & mask) == mask);
|
//assert((Used[firstword] & mask) == mask);
|
||||||
Used[firstword] &= ~mask;
|
Used[firstword] &= ~mask;
|
||||||
|
Dirty[firstword] |= mask;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // Range is in two words.
|
{ // Range is in two words.
|
||||||
partialmask = mask << firstbit;
|
partialmask = mask << firstbit;
|
||||||
assert((Used[firstword] & partialmask) == partialmask);
|
assert((Used[firstword] & partialmask) == partialmask);
|
||||||
Used[firstword] &= ~partialmask;
|
Used[firstword] &= ~partialmask;
|
||||||
|
Dirty[firstword] |= partialmask;
|
||||||
|
|
||||||
partialmask = mask >> (32 - firstbit);
|
partialmask = mask >> (32 - firstbit);
|
||||||
assert((Used[firstword + 1] & partialmask) == partialmask);
|
assert((Used[firstword + 1] & partialmask) == partialmask);
|
||||||
Used[firstword + 1] &= ~partialmask;
|
Used[firstword + 1] &= ~partialmask;
|
||||||
|
Dirty[firstword + 1] |= partialmask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,8 +37,16 @@ public:
|
||||||
void Return(int reg, int count);
|
void Return(int reg, int count);
|
||||||
bool Reuse(int regnum);
|
bool Reuse(int regnum);
|
||||||
|
|
||||||
|
bool IsDirty(int reg) const
|
||||||
|
{
|
||||||
|
const int firstword = reg / 32;
|
||||||
|
const int firstbit = reg & 31;
|
||||||
|
return Dirty[firstword] & (1 << firstbit);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VM_UWORD Used[256/32]; // Bitmap of used registers (bit set means reg is used)
|
VM_UWORD Used[256/32]; // Bitmap of used registers (bit set means reg is used)
|
||||||
|
VM_UWORD Dirty[256/32];
|
||||||
int MostUsed;
|
int MostUsed;
|
||||||
|
|
||||||
friend class VMFunctionBuilder;
|
friend class VMFunctionBuilder;
|
||||||
|
|
Loading…
Reference in a new issue