fix int assign optimization constants generating broken code because they weren't expected

This commit is contained in:
Ricardo Luís Vaz Silva 2023-10-31 21:21:08 -03:00 committed by Christoph Oelckers
parent f1017ef362
commit e26f9fb13d
3 changed files with 77 additions and 5 deletions

View file

@ -916,6 +916,17 @@ FxExpression *FxBoolCast::Resolve(FCompileContext &ctx)
ExpEmit FxBoolCast::Emit(VMFunctionBuilder *build)
{
ExpEmit from = basex->Emit(build);
if(from.Konst && from.RegType == REGT_INT)
{ // this is needed here because the int const assign optimization returns a constant
ExpEmit to;
to.Konst = true;
to.RegType = REGT_INT;
to.RegNum = build->GetConstantInt(!!build->FindConstantInt(from.RegNum));
return to;
}
assert(!from.Konst);
assert(basex->ValueType->GetRegType() == REGT_INT || basex->ValueType->GetRegType() == REGT_FLOAT || basex->ValueType->GetRegType() == REGT_POINTER);
@ -1140,7 +1151,15 @@ FxExpression *FxFloatCast::Resolve(FCompileContext &ctx)
ExpEmit FxFloatCast::Emit(VMFunctionBuilder *build)
{
ExpEmit from = basex->Emit(build);
//assert(!from.Konst);
if(from.Konst && from.RegType == REGT_INT)
{ // this is needed here because the int const assign optimization returns a constant
ExpEmit to;
to.Konst = true;
to.RegType = REGT_FLOAT;
to.RegNum = build->GetConstantFloat(build->FindConstantInt(from.RegNum));
return to;
}
assert(basex->ValueType->GetRegType() == REGT_INT);
from.Free(build);
ExpEmit to(build, REGT_FLOAT);
@ -1973,7 +1992,17 @@ ExpEmit FxMinusSign::Emit(VMFunctionBuilder *build)
{
//assert(ValueType == Operand->ValueType);
ExpEmit from = Operand->Emit(build);
if(from.Konst && from.RegType == REGT_INT)
{ // this is needed here because the int const assign optimization returns a constant
ExpEmit to;
to.Konst = true;
to.RegType = REGT_INT;
to.RegNum = build->GetConstantInt(-build->FindConstantInt(from.RegNum));
return to;
}
ExpEmit to;
assert(from.Konst == 0);
assert(ValueType->GetRegCount() == from.RegCount);
// Do it in-place, unless a local variable
@ -2093,6 +2122,16 @@ ExpEmit FxUnaryNotBitwise::Emit(VMFunctionBuilder *build)
{
assert(Operand->ValueType->GetRegType() == REGT_INT);
ExpEmit from = Operand->Emit(build);
if(from.Konst && from.RegType == REGT_INT)
{ // this is needed here because the int const assign optimization returns a constant
ExpEmit to;
to.Konst = true;
to.RegType = REGT_INT;
to.RegNum = build->GetConstantInt(~build->FindConstantInt(from.RegNum));
return to;
}
from.Free(build);
ExpEmit to(build, REGT_INT);
assert(!from.Konst);
@ -2164,6 +2203,16 @@ ExpEmit FxUnaryNotBoolean::Emit(VMFunctionBuilder *build)
assert(Operand->ValueType == TypeBool);
assert(ValueType == TypeBool || IsInteger()); // this may have been changed by an int cast.
ExpEmit from = Operand->Emit(build);
if(from.Konst && from.RegType == REGT_INT)
{ // this is needed here because the int const assign optimization returns a constant
ExpEmit to;
to.Konst = true;
to.RegType = REGT_INT;
to.RegNum = build->GetConstantInt(!build->FindConstantInt(from.RegNum));
return to;
}
from.Free(build);
ExpEmit to(build, REGT_INT);
assert(!from.Konst);

View file

@ -290,6 +290,24 @@ unsigned VMFunctionBuilder::GetConstantAddress(void *ptr)
}
}
//==========================================================================
//
// VMFunctionBuilder :: FindConstantInt
//
// Returns a constant register initialized with the given value.
//
//==========================================================================
int VMFunctionBuilder::FindConstantInt(unsigned index)
{
if(IntConstantList.Size() < index)
{
return IntConstantList[index];
}
return 0;
}
//==========================================================================
//
// VMFunctionBuilder :: AllocConstants*
@ -298,7 +316,7 @@ unsigned VMFunctionBuilder::GetConstantAddress(void *ptr)
//
//==========================================================================
unsigned VMFunctionBuilder::AllocConstantsInt(unsigned count, int *values)
unsigned VMFunctionBuilder::AllocConstantsInt(unsigned int count, int *values)
{
unsigned addr = IntConstantList.Reserve(count);
memcpy(&IntConstantList[addr], values, count * sizeof(int));
@ -309,7 +327,7 @@ unsigned VMFunctionBuilder::AllocConstantsInt(unsigned count, int *values)
return addr;
}
unsigned VMFunctionBuilder::AllocConstantsFloat(unsigned count, double *values)
unsigned VMFunctionBuilder::AllocConstantsFloat(unsigned int count, double *values)
{
unsigned addr = FloatConstantList.Reserve(count);
memcpy(&FloatConstantList[addr], values, count * sizeof(double));
@ -320,7 +338,7 @@ unsigned VMFunctionBuilder::AllocConstantsFloat(unsigned count, double *values)
return addr;
}
unsigned VMFunctionBuilder::AllocConstantsAddress(unsigned count, void **ptrs)
unsigned VMFunctionBuilder::AllocConstantsAddress(unsigned int count, void **ptrs)
{
unsigned addr = AddressConstantList.Reserve(count);
memcpy(&AddressConstantList[addr], ptrs, count * sizeof(void *));
@ -331,7 +349,7 @@ unsigned VMFunctionBuilder::AllocConstantsAddress(unsigned count, void **ptrs)
return addr;
}
unsigned VMFunctionBuilder::AllocConstantsString(unsigned count, FString *ptrs)
unsigned VMFunctionBuilder::AllocConstantsString(unsigned int count, FString *ptrs)
{
unsigned addr = StringConstantList.Reserve(count);
for (unsigned i = 0; i < count; i++)

View file

@ -65,6 +65,11 @@ public:
unsigned GetConstantAddress(void *ptr);
unsigned GetConstantString(FString str);
int FindConstantInt(unsigned index);
//double FindConstantFloat(unsigned index);
//void * FindConstantAddress(unsigned index);
//const FString& FindConstantString(unsigned index);
unsigned AllocConstantsInt(unsigned int count, int *values);
unsigned AllocConstantsFloat(unsigned int count, double *values);
unsigned AllocConstantsAddress(unsigned int count, void **ptrs);