#pragma once
#if ENABLE(DFG_JIT)
namespace JSC {
class ExecState;
using EncodedJSValue = int64_t;
namespace DFG {
namespace Arith {
enum Mode {
NotSet, Unchecked, CheckOverflow, CheckOverflowAndNegativeZero, DoOverflow };
enum class RoundingMode {
Int32, Int32WithNegativeZeroCheck, Double };
#define FOR_EACH_DFG_ARITH_UNARY_OP(macro) \
macro(Sin, sin) \
macro(Sinh, sinh) \
macro(Cos, cos) \
macro(Cosh, cosh) \
macro(Tan, tan) \
macro(Tanh, tanh) \
macro(ASin, asin) \
macro(ASinh, asinh) \
macro(ACos, acos) \
macro(ACosh, acosh) \
macro(ATan, atan) \
macro(ATanh, atanh) \
macro(Log, log) \
macro(Log10, log10) \
macro(Log1p, log1p) \
macro(Log2, log2) \
macro(Cbrt, cbrt) \
macro(Exp, exp) \
macro(Expm1, expm1) \
enum class UnaryType : uint32_t {
#define DFG_ARITH_UNARY_ENUM(capitalizedName, lowerName) capitalizedName,
FOR_EACH_DFG_ARITH_UNARY_OP(DFG_ARITH_UNARY_ENUM)
#undef DFG_ARITH_UNARY_ENUM
};
typedef double (*UnaryFunction)(double);
typedef double (*UnaryOperation)(ExecState*, EncodedJSValue);
}
inline bool doesOverflow(Arith::Mode mode)
{
switch (mode) {
case Arith::NotSet:
ASSERT_NOT_REACHED();
#if ASSERT_DISABLED
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)