/*
 * Copyright (C) 2014 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

#pragma once

#include "MathCommon.h"

#if ENABLE(DFG_JIT)

namespace JSC {

class CallFrame;
class JSGlobalObject;
using EncodedJSValue = int64_t;

namespace DFG {

// Arith::Mode describes the mode of an arithmetic operation that speculates integer.
// Note that not all modes are valid for all operations.
namespace Arith {
enum Mode {
    NotSet, // Arithmetic mode is either not relevant because we're using doubles anyway or we are at a phase in compilation where we don't know what we're doing, yet. Should never see this after FixupPhase except for nodes that take doubles as inputs already.
    Unchecked, // Don't check anything and just do the direct hardware operation.
    CheckOverflow, // Check for overflow but don't bother with negative zero.
    CheckOverflowAndNegativeZero, // Check for both overflow and negative zero.
    DoOverflow // Up-convert to the smallest type that soundly represents all possible results after input type speculation.
};

// Define the type of operation the rounding operation will perform.
enum class RoundingMode {
    Int32, // The round operation produces a integer and -0 is considered as 0.
    Int32WithNegativeZeroCheck, // The round operation produces a integer and checks for -0.
    Double // The round operation produce a double. The result can be -0, NaN or (+/-)Infinity.
};

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);

} // namespace Arith

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;
}

// It's only valid to call this once you've determined that you don't need to *do*
// overflow. For most nodes, that's implicit.
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 JSC::DFG

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);

} // namespace WTF

#endif // ENABLE(DFG_JIT)
