diff --git a/Engine/source/console/compiledEval.cpp b/Engine/source/console/compiledEval.cpp index 4f1a197d9..018a82b21 100644 --- a/Engine/source/console/compiledEval.cpp +++ b/Engine/source/console/compiledEval.cpp @@ -444,6 +444,172 @@ void ExprEvalState::setStringVariable(const char *val) //----------------------------------------------------------------------------- +enum class FloatOperation +{ + Add, + Sub, + Mul, + Div, + + LT, + LE, + GR, + GE, + EQ, + NE +}; + +template +TORQUE_FORCEINLINE void doFloatMathOperation() +{ + ConsoleValue& a = stack[_STK]; + ConsoleValue& b = stack[_STK - 1]; + + S32 fastIf = (a.getType() == ConsoleValueType::cvFloat) & (b.getType() == ConsoleValueType::cvFloat); + if (fastIf) + { + // Arithmetic + if constexpr (Op == FloatOperation::Add) + stack[_STK - 1].setFastFloat(a.getFastFloat() + b.getFastFloat()); + if constexpr (Op == FloatOperation::Sub) + stack[_STK - 1].setFastFloat(a.getFastFloat() - b.getFastFloat()); + if constexpr (Op == FloatOperation::Mul) + stack[_STK - 1].setFastFloat(a.getFastFloat() * b.getFastFloat()); + if constexpr (Op == FloatOperation::Div) + stack[_STK - 1].setFastFloat(a.getFastFloat() / b.getFastFloat()); + + // Logical + if constexpr (Op == FloatOperation::LT) + stack[_STK - 1].setFastInt(a.getFastFloat() < b.getFastFloat()); + if constexpr (Op == FloatOperation::LE) + stack[_STK - 1].setFastInt(a.getFastFloat() <= b.getFastFloat()); + if constexpr (Op == FloatOperation::GR) + stack[_STK - 1].setFastInt(a.getFastFloat() > b.getFastFloat()); + if constexpr (Op == FloatOperation::GE) + stack[_STK - 1].setFastInt(a.getFastFloat() >= b.getFastFloat()); + if constexpr (Op == FloatOperation::EQ) + stack[_STK - 1].setFastInt(a.getFastFloat() == b.getFastFloat()); + if constexpr (Op == FloatOperation::NE) + stack[_STK - 1].setFastInt(a.getFastFloat() != b.getFastFloat()); + + _STK--; + } + else + { + doSlowMathOp(); + } +} + +template +TORQUE_NOINLINE void doSlowMathOp() +{ + ConsoleValue& a = stack[_STK]; + ConsoleValue& b = stack[_STK - 1]; + + // Arithmetic + if constexpr (Op == FloatOperation::Add) + stack[_STK - 1].setFloat(a.getFloat() + b.getFloat()); + else if constexpr (Op == FloatOperation::Sub) + stack[_STK - 1].setFloat(a.getFloat() - b.getFloat()); + else if constexpr (Op == FloatOperation::Mul) + stack[_STK - 1].setFloat(a.getFloat() * b.getFloat()); + else if constexpr (Op == FloatOperation::Div) + stack[_STK - 1].setFloat(a.getFloat() / b.getFloat()); + + // Logical + if constexpr (Op == FloatOperation::LT) + stack[_STK - 1].setFastInt(a.getFloat() < b.getFloat()); + if constexpr (Op == FloatOperation::LE) + stack[_STK - 1].setFastInt(a.getFloat() <= b.getFloat()); + if constexpr (Op == FloatOperation::GR) + stack[_STK - 1].setFastInt(a.getFloat() > b.getFloat()); + if constexpr (Op == FloatOperation::GE) + stack[_STK - 1].setFastInt(a.getFloat() >= b.getFloat()); + if constexpr (Op == FloatOperation::EQ) + stack[_STK - 1].setFastInt(a.getFloat() == b.getFloat()); + if constexpr (Op == FloatOperation::NE) + stack[_STK - 1].setFastInt(a.getFloat() != b.getFloat()); + + _STK--; +} + +//----------------------------------------------------------------------------- + +enum class IntegerOperation +{ + BitAnd, + BitOr, + Xor, + LShift, + RShift, + + LogicalAnd, + LogicalOr +}; + +template +TORQUE_FORCEINLINE void doIntOperation() +{ + ConsoleValue& a = stack[_STK]; + ConsoleValue& b = stack[_STK - 1]; + + if (a.isNumberType() && b.isNumberType()) + { + // Bitwise Op + if constexpr (Op == IntegerOperation::BitAnd) + stack[_STK - 1].setFastInt(a.getFastInt() & b.getFastInt()); + if constexpr (Op == IntegerOperation::BitOr) + stack[_STK - 1].setFastInt(a.getFastInt() | b.getFastInt()); + if constexpr (Op == IntegerOperation::Xor) + stack[_STK - 1].setFastInt(a.getFastInt() ^ b.getFastInt()); + if constexpr (Op == IntegerOperation::LShift) + stack[_STK - 1].setFastInt(a.getFastInt() << b.getFastInt()); + if constexpr (Op == IntegerOperation::RShift) + stack[_STK - 1].setFastInt(a.getFastInt() >> b.getFastInt()); + + // Logical Op + if constexpr (Op == IntegerOperation::LogicalAnd) + stack[_STK - 1].setFastInt(a.getFastInt() && b.getFastInt()); + if constexpr (Op == IntegerOperation::LogicalOr) + stack[_STK - 1].setFastInt(a.getFastInt() || b.getFastInt()); + + _STK--; + } + else + { + doSlowIntegerOp(); + } +} + +template +TORQUE_NOINLINE void doSlowIntegerOp() +{ + ConsoleValue& a = stack[_STK]; + ConsoleValue& b = stack[_STK - 1]; + + // Bitwise Op + if constexpr (Op == IntegerOperation::BitAnd) + stack[_STK - 1].setInt(a.getInt() & b.getInt()); + if constexpr (Op == IntegerOperation::BitOr) + stack[_STK - 1].setInt(a.getInt() | b.getInt()); + if constexpr (Op == IntegerOperation::Xor) + stack[_STK - 1].setInt(a.getInt() ^ b.getInt()); + if constexpr (Op == IntegerOperation::LShift) + stack[_STK - 1].setInt(a.getInt() << b.getInt()); + if constexpr (Op == IntegerOperation::RShift) + stack[_STK - 1].setInt(a.getInt() >> b.getInt()); + + // Logical Op + if constexpr (Op == IntegerOperation::LogicalAnd) + stack[_STK - 1].setInt(a.getInt() && b.getInt()); + if constexpr (Op == IntegerOperation::LogicalOr) + stack[_STK - 1].setInt(a.getInt() || b.getInt()); + + _STK--; +} + +//----------------------------------------------------------------------------- + U32 gExecCount = 0; ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNamespace, U32 argc, ConsoleValue* argv, bool noCalls, StringTableEntry packageName, S32 setFrame) { @@ -1151,56 +1317,39 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa goto execFinished; case OP_CMPEQ: - stack[_STK - 1].setInt(stack[_STK].getFloat() == stack[_STK - 1].getFloat()); - _STK--; + doFloatMathOperation(); break; case OP_CMPGR: - stack[_STK - 1].setInt(stack[_STK].getFloat() > stack[_STK - 1].getFloat()); - _STK--; + doFloatMathOperation(); break; case OP_CMPGE: - stack[_STK - 1].setInt(stack[_STK].getFloat() >= stack[_STK - 1].getFloat()); - _STK--; + doFloatMathOperation(); break; case OP_CMPLT: - stack[_STK - 1].setInt(stack[_STK].getFloat() < stack[_STK - 1].getFloat()); - _STK--; + doFloatMathOperation(); break; case OP_CMPLE: - stack[_STK - 1].setInt(stack[_STK].getFloat() <= stack[_STK - 1].getFloat()); - _STK--; + doFloatMathOperation(); break; case OP_CMPNE: - stack[_STK - 1].setInt(stack[_STK].getFloat() != stack[_STK - 1].getFloat()); - _STK--; + doFloatMathOperation(); break; case OP_XOR: - stack[_STK - 1].setInt(stack[_STK].getInt() ^ stack[_STK - 1].getInt()); - _STK--; - break; - - case OP_MOD: - if (stack[_STK - 1].getInt() != 0) - stack[_STK - 1].setInt(stack[_STK].getInt() % stack[_STK - 1].getInt()); - else - stack[_STK - 1].setInt(0); - _STK--; + doIntOperation(); break; case OP_BITAND: - stack[_STK - 1].setInt(stack[_STK].getInt() & stack[_STK - 1].getInt()); - _STK--; + doIntOperation(); break; case OP_BITOR: - stack[_STK - 1].setInt(stack[_STK].getInt() | stack[_STK - 1].getInt()); - _STK--; + doIntOperation(); break; case OP_NOT: @@ -1216,44 +1365,47 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa break; case OP_SHR: - stack[_STK - 1].setInt(stack[_STK].getInt() >> stack[_STK - 1].getInt()); - _STK--; + doIntOperation(); break; case OP_SHL: - stack[_STK - 1].setInt(stack[_STK].getInt() << stack[_STK - 1].getInt()); - _STK--; + doIntOperation(); break; case OP_AND: - stack[_STK - 1].setInt(stack[_STK].getInt() && stack[_STK - 1].getInt()); - _STK--; + doIntOperation(); break; case OP_OR: - stack[_STK - 1].setInt(stack[_STK].getInt() || stack[_STK - 1].getInt()); - _STK--; + doIntOperation(); break; case OP_ADD: - stack[_STK - 1].setFloat(stack[_STK].getFloat() + stack[_STK - 1].getFloat()); - _STK--; + doFloatMathOperation(); break; case OP_SUB: - stack[_STK - 1].setFloat(stack[_STK].getFloat() - stack[_STK - 1].getFloat()); - _STK--; + doFloatMathOperation(); break; case OP_MUL: - stack[_STK - 1].setFloat(stack[_STK].getFloat() * stack[_STK - 1].getFloat()); - _STK--; + doFloatMathOperation(); break; case OP_DIV: - stack[_STK - 1].setFloat(stack[_STK].getFloat() / stack[_STK - 1].getFloat()); + doFloatMathOperation(); + break; + + case OP_MOD: + { + S64 divisor = stack[_STK - 1].getInt(); + if (divisor != 0) + stack[_STK - 1].setInt(stack[_STK].getInt() % divisor); + else + stack[_STK - 1].setInt(0); _STK--; break; + } case OP_NEG: stack[_STK].setFloat(-stack[_STK].getFloat()); diff --git a/Engine/source/console/console.h b/Engine/source/console/console.h index f7d077ae0..db9af8a23 100644 --- a/Engine/source/console/console.h +++ b/Engine/source/console/console.h @@ -365,6 +365,28 @@ public: return type >= ConsoleValueType::cvConsoleValueType; } + TORQUE_FORCEINLINE void setFastFloat(F64 flt) + { + type = ConsoleValueType::cvFloat; + f = flt; + } + + TORQUE_FORCEINLINE F64 getFastFloat() const + { + return f; + } + + TORQUE_FORCEINLINE void setFastInt(S64 flt) + { + type = ConsoleValueType::cvInteger; + i = flt; + } + + TORQUE_FORCEINLINE S64 getFastInt() const + { + return i; + } + static void init(); }; diff --git a/Engine/source/platform/types.visualc.h b/Engine/source/platform/types.visualc.h index 89fd38d4b..4ccc6ce42 100644 --- a/Engine/source/platform/types.visualc.h +++ b/Engine/source/platform/types.visualc.h @@ -105,6 +105,7 @@ typedef unsigned _int64 U64; #pragma warning(disable: 4291) #define TORQUE_FORCEINLINE __forceinline +#define TORQUE_NOINLINE __declspec(noinline) #if __cplusplus >= 201703L #define TORQUE_CASE_FALLTHROUGH [[fallthrough]];