#pragma once
#include "MathCommon.h"
#if ENABLE(DFG_JIT)
namespace JSC {
class CallFrame;
class JSGlobalObject;
using EncodedJSValue = int64_t;
namespace DFG {
namespace Arith {
enum Mode {
NotSet, Unchecked, CheckOverflow, CheckOverflowAndNegativeZero, DoOverflow };
enum class RoundingMode {
Int32, Int32WithNegativeZeroCheck, Double };
enum class UnaryType : uint32_t {
#define DFG_ARITH_UNARY_ENUM(capitalizedName, lowerName) capitalizedName,
FOR_EACH_ARITH_UNARY_OP(DFG_ARITH_UNARY_ENUM)
#undef DFG_ARITH_UNARY_ENUM
};
using UnaryFunction = double(JIT_OPERATION_ATTRIBUTES*)(double);
using UnaryOperation = double(JIT_OPERATION_ATTRIBUTES*)(JSGlobalObject*, EncodedJSValue);
}
inline bool doesOverflow(Arith::Mode mode)
{
switch (mode) {
case Arith::NotSet:
ASSERT_NOT_REACHED();
#if !ASSERT_ENABLED
FALLTHROUGH;
#endif
case Arith::Unchecked:
case Arith::CheckOverflow:
case Arith::CheckOverflowAndNegativeZero:
return false;
case Arith::DoOverflow:
return true;
}
ASSERT_NOT_REACHED();
return true;
}
inline bool shouldCheckOverflow(Arith::Mode mode)
{
switch (mode) {
case Arith::NotSet:
case Arith::DoOverflow:
ASSERT_NOT_REACHED();
return true;
case Arith::Unchecked:
return false;
case Arith::CheckOverflow:
case Arith::CheckOverflowAndNegativeZero:
return true;
}
ASSERT_NOT_REACHED();
return true;
}
inline bool shouldCheckNegativeZero(Arith::Mode mode)
{
switch (mode) {
case Arith::NotSet:
case Arith::DoOverflow:
ASSERT_NOT_REACHED();
return true;
case Arith::Unchecked:
case Arith::CheckOverflow:
return false;
case Arith::CheckOverflowAndNegativeZero:
return true;
}
ASSERT_NOT_REACHED();
return true;
}
inline bool subsumes(Arith::Mode earlier, Arith::Mode later)
{
switch (earlier) {
case Arith::CheckOverflow:
switch (later) {
case Arith::Unchecked:
case Arith::CheckOverflow:
return true;
default:
return false;
}
case Arith::CheckOverflowAndNegativeZero:
switch (later) {
case Arith::Unchecked:
case Arith::CheckOverflow:
case Arith::CheckOverflowAndNegativeZero:
return true;
default:
return false;
}
default:
return earlier == later;
}
}
inline bool producesInteger(Arith::RoundingMode mode)
{
return mode == Arith::RoundingMode::Int32WithNegativeZeroCheck || mode == Arith::RoundingMode::Int32;
}
inline bool shouldCheckNegativeZero(Arith::RoundingMode mode)
{
return mode == Arith::RoundingMode::Int32WithNegativeZeroCheck;
}
Arith::UnaryFunction arithUnaryFunction(Arith::UnaryType);
Arith::UnaryOperation arithUnaryOperation(Arith::UnaryType);
} }
namespace WTF {
class PrintStream;
void printInternal(PrintStream&, JSC::DFG::Arith::Mode);
void printInternal(PrintStream&, JSC::DFG::Arith::RoundingMode);
void printInternal(PrintStream&, JSC::DFG::Arith::UnaryType);
}
#endif // ENABLE(DFG_JIT)