diff --git a/src/common/scripting/backend/codegen.cpp b/src/common/scripting/backend/codegen.cpp index 2fcdb118b..3ff45c335 100644 --- a/src/common/scripting/backend/codegen.cpp +++ b/src/common/scripting/backend/codegen.cpp @@ -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); diff --git a/src/common/scripting/backend/vmbuilder.cpp b/src/common/scripting/backend/vmbuilder.cpp index b64950e34..259055dc9 100644 --- a/src/common/scripting/backend/vmbuilder.cpp +++ b/src/common/scripting/backend/vmbuilder.cpp @@ -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++) diff --git a/src/common/scripting/backend/vmbuilder.h b/src/common/scripting/backend/vmbuilder.h index f1c8d889f..2ead8f906 100644 --- a/src/common/scripting/backend/vmbuilder.h +++ b/src/common/scripting/backend/vmbuilder.h @@ -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);