/*
 * Copyright (C) 2015-2019 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

#if ENABLE(B3_JIT)

#include "B3ArgumentRegValue.h"
#include "B3AtomicValue.h"
#include "B3BottomTupleValue.h"
#include "B3CCallValue.h"
#include "B3CheckValue.h"
#include "B3Const32Value.h"
#include "B3Const64Value.h"
#include "B3ConstDoubleValue.h"
#include "B3ConstFloatValue.h"
#include "B3ExtractValue.h"
#include "B3FenceValue.h"
#include "B3MemoryValue.h"
#include "B3PatchpointValue.h"
#include "B3PhiChildren.h"
#include "B3Procedure.h"
#include "B3SlotBaseValue.h"
#include "B3SwitchValue.h"
#include "B3UpsilonValue.h"
#include "B3Value.h"
#include "B3VariableValue.h"
#include "B3WasmAddressValue.h"
#include "B3WasmBoundsCheckValue.h"
#include <wtf/GraphNodeWorklist.h>

namespace JSC { namespace B3 {

#define DISPATCH_ON_KIND(MACRO) \
    switch (kind().opcode()) { \
    case FramePointer: \
    case Nop: \
    case Phi: \
    case Jump: \
    case Oops: \
    case EntrySwitch: \
    case Return: \
    case Identity: \
    case Opaque: \
    case Neg: \
    case Clz: \
    case Abs: \
    case Ceil: \
    case Floor: \
    case Sqrt: \
    case SExt8: \
    case SExt16: \
    case Trunc: \
    case SExt32: \
    case ZExt32: \
    case FloatToDouble: \
    case IToD: \
    case DoubleToFloat: \
    case IToF: \
    case BitwiseCast: \
    case Branch: \
    case Depend: \
    case Add: \
    case Sub: \
    case Mul: \
    case Div: \
    case UDiv: \
    case Mod: \
    case UMod: \
    case BitAnd: \
    case BitOr: \
    case BitXor: \
    case Shl: \
    case SShr: \
    case ZShr: \
    case RotR: \
    case RotL: \
    case Equal: \
    case NotEqual: \
    case LessThan: \
    case GreaterThan: \
    case LessEqual: \
    case GreaterEqual: \
    case Above: \
    case Below: \
    case AboveEqual: \
    case BelowEqual: \
    case EqualOrUnordered: \
    case Select: \
        return MACRO(Value); \
    case ArgumentReg: \
        return MACRO(ArgumentRegValue); \
    case Const32: \
        return MACRO(Const32Value); \
    case Const64: \
        return MACRO(Const64Value); \
    case ConstFloat: \
        return MACRO(ConstFloatValue); \
    case ConstDouble: \
        return MACRO(ConstDoubleValue); \
    case BottomTuple: \
        return MACRO(BottomTupleValue); \
    case Fence: \
        return MACRO(FenceValue); \
    case SlotBase: \
        return MACRO(SlotBaseValue); \
    case Get: \
    case Set: \
        return MACRO(VariableValue); \
    case Load8Z: \
    case Load8S: \
    case Load16Z: \
    case Load16S: \
    case Load: \
    case Store8: \
    case Store16: \
    case Store: \
        return MACRO(MemoryValue); \
    case Switch: \
        return MACRO(SwitchValue); \
    case Upsilon: \
        return MACRO(UpsilonValue); \
    case Extract: \
        return MACRO(ExtractValue); \
    case WasmAddress: \
        return MACRO(WasmAddressValue); \
    case WasmBoundsCheck: \
        return MACRO(WasmBoundsCheckValue); \
    case AtomicXchgAdd: \
    case AtomicXchgAnd: \
    case AtomicXchgOr: \
    case AtomicXchgSub: \
    case AtomicXchgXor: \
    case AtomicXchg: \
    case AtomicWeakCAS: \
    case AtomicStrongCAS: \
        return MACRO(AtomicValue); \
    case CCall: \
        return MACRO(CCallValue); \
    case Check: \
    case CheckAdd: \
    case CheckSub: \
    case CheckMul: \
        return MACRO(CheckValue); \
    case Patchpoint: \
        return MACRO(PatchpointValue); \
    default: \
        RELEASE_ASSERT_NOT_REACHED(); \
    }

ALWAYS_INLINE size_t Value::adjacencyListOffset() const
{
#define VALUE_TYPE_SIZE(ValueType) sizeof(ValueType)
    DISPATCH_ON_KIND(VALUE_TYPE_SIZE);
#undef VALUE_TYPE_SIZE
}

ALWAYS_INLINE Value* Value::cloneImpl() const
{
#define VALUE_TYPE_CLONE(ValueType) allocate<ValueType>(*static_cast<const ValueType*>(this))
    DISPATCH_ON_KIND(VALUE_TYPE_CLONE);
#undef VALUE_TYPE_CLONE
}

template<typename BottomProvider>
void Value::replaceWithBottom(const BottomProvider& bottomProvider)
{
    if (m_type == Void) {
        replaceWithNop();
        return;
    }
    
    if (isConstant())
        return;
    
    replaceWithIdentity(bottomProvider(m_origin, m_type));
}

template<typename T>
inline T* Value::as()
{
    if (T::accepts(kind()))
        return static_cast<T*>(this);
    return nullptr;
}

template<typename T>
inline const T* Value::as() const
{
    return const_cast<Value*>(this)->as<T>();
}

inline bool Value::isConstant() const
{
    return B3::isConstant(opcode());
}

inline bool Value::isInteger() const
{
    return type() == Int32 || type() == Int64;
}

inline bool Value::hasInt32() const
{
    return !!as<Const32Value>();
}

inline int32_t Value::asInt32() const
{
    return as<Const32Value>()->value();
}

inline bool Value::isInt32(int32_t value) const
{
    return hasInt32() && asInt32() == value;
}

inline bool Value::hasInt64() const
{
    return !!as<Const64Value>();
}

inline int64_t Value::asInt64() const
{
    return as<Const64Value>()->value();
}

inline bool Value::isInt64(int64_t value) const
{
    return hasInt64() && asInt64() == value;
}

inline bool Value::hasInt() const
{
    return hasInt32() || hasInt64();
}

inline int64_t Value::asInt() const
{
    return hasInt32() ? asInt32() : asInt64();
}

inline bool Value::isInt(int64_t value) const
{
    return hasInt() && asInt() == value;
}

inline bool Value::hasIntPtr() const
{
    if (is64Bit())
        return hasInt64();
    return hasInt32();
}

inline intptr_t Value::asIntPtr() const
{
    if (is64Bit())
        return asInt64();
    return asInt32();
}

inline bool Value::isIntPtr(intptr_t value) const
{
    return hasIntPtr() && asIntPtr() == value;
}

inline bool Value::hasDouble() const
{
    return !!as<ConstDoubleValue>();
}

inline double Value::asDouble() const
{
    return as<ConstDoubleValue>()->value();
}

inline bool Value::isEqualToDouble(double value) const
{
    return hasDouble() && asDouble() == value;
}

inline bool Value::hasFloat() const
{
    return !!as<ConstFloatValue>();
}

inline float Value::asFloat() const
{
    return as<ConstFloatValue>()->value();
}

inline bool Value::hasNumber() const
{
    return hasInt() || hasDouble() || hasFloat();
}

inline bool Value::isNegativeZero() const
{
    if (hasDouble()) {
        double value = asDouble();
        return !value && std::signbit(value);
    }
    if (hasFloat()) {
        float value = asFloat();
        return !value && std::signbit(value);
    }
    return false;
}

template<typename T>
inline bool Value::isRepresentableAs() const
{
    switch (opcode()) {
    case Const32:
        return B3::isRepresentableAs<T>(asInt32());
    case Const64:
        return B3::isRepresentableAs<T>(asInt64());
    case ConstDouble:
        return B3::isRepresentableAs<T>(asDouble());
    case ConstFloat:
        return B3::isRepresentableAs<T>(asFloat());
    default:
        return false;
    }
}

template<typename T>
inline T Value::asNumber() const
{
    switch (opcode()) {
    case Const32:
        return static_cast<T>(asInt32());
    case Const64:
        return static_cast<T>(asInt64());
    case ConstDouble:
        return static_cast<T>(asDouble());
    case ConstFloat:
        return static_cast<T>(asFloat());
    default:
        return T();
    }
}

template<typename Functor>
void Value::walk(const Functor& functor, PhiChildren* phiChildren)
{
    GraphNodeWorklist<Value*> worklist;
    worklist.push(this);
    while (Value* value = worklist.pop()) {
        WalkStatus status = functor(value);
        switch (status) {
        case Continue:
            if (value->opcode() == Phi) {
                if (phiChildren)
                    worklist.pushAll(phiChildren->at(value).values());
            } else
                worklist.pushAll(value->children());
            break;
        case IgnoreChildren:
            break;
        case Stop:
            return;
        }
    }
}

} } // namespace JSC::B3

#endif // ENABLE(B3_JIT)
