/*
 * Copyright (C) 2016-2017 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 "AirCode.h"
#include "AirGenerationContext.h"
#include "AirInst.h"
#include "AirSpecial.h"
#include "B3ValueInlines.h"
#include "B3WasmBoundsCheckValue.h"

namespace JSC { namespace B3 { namespace Air {

// This defines the behavior of custom instructions - i.e. those whose behavior cannot be
// described using AirOpcode.opcodes. If you define an opcode as "custom Foo" in that file, then
// you will need to create a "struct FooCustom" here that implements the custom behavior
// methods.
//
// The customizability granted by the custom instruction mechanism is strictly less than what
// you get using the Patch instruction and implementing a Special. However, that path requires
// allocating a Special object and ensuring that it's the first operand. For many instructions,
// that is not as convenient as using Custom, which makes the instruction look like any other
// instruction. Note that both of those extra powers of the Patch instruction happen because we
// special-case that instruction in many phases and analyses. Non-special-cased behaviors of
// Patch are implemented using the custom instruction mechanism.
//
// Specials are still more flexible if you need to list extra clobbered registers and you'd like
// that to be expressed as a bitvector rather than an arglist. They are also more flexible if
// you need to carry extra state around with the instruction. Also, Specials mean that you
// always have access to Code& even in methods that don't take a GenerationContext.

// Definition of Patch instruction. Patch is used to delegate the behavior of the instruction to the
// Special object, which will be the first argument to the instruction.
struct PatchCustom {
    static void forEachArg(Inst& inst, ScopedLambda<Inst::EachArgCallback> lambda)
    {
        // This is basically bogus, but it works for analyses that model Special as an
        // immediate.
        lambda(inst.args[0], Arg::Use, GP, pointerWidth());
        
        inst.args[0].special()->forEachArg(inst, lambda);
    }

    template<typename... Arguments>
    static bool isValidFormStatic(Arguments...)
    {
        return false;
    }

    static bool isValidForm(Inst& inst);

    static bool admitsStack(Inst& inst, unsigned argIndex)
    {
        if (!argIndex)
            return false;
        return inst.args[0].special()->admitsStack(inst, argIndex);
    }

    static bool admitsExtendedOffsetAddr(Inst& inst, unsigned argIndex)
    {
        if (!argIndex)
            return false;
        return inst.args[0].special()->admitsExtendedOffsetAddr(inst, argIndex);
    }

    static std::optional<unsigned> shouldTryAliasingDef(Inst& inst)
    {
        return inst.args[0].special()->shouldTryAliasingDef(inst);
    }
    
    static bool isTerminal(Inst& inst)
    {
        return inst.args[0].special()->isTerminal(inst);
    }

    static bool hasNonArgEffects(Inst& inst)
    {
        return inst.args[0].special()->hasNonArgEffects(inst);
    }

    static bool hasNonArgNonControlEffects(Inst& inst)
    {
        return inst.args[0].special()->hasNonArgNonControlEffects(inst);
    }

    static CCallHelpers::Jump generate(
        Inst& inst, CCallHelpers& jit, GenerationContext& context)
    {
        return inst.args[0].special()->generate(inst, jit, context);
    }
};

template<typename Subtype>
struct CommonCustomBase {
    static bool hasNonArgEffects(Inst& inst)
    {
        return Subtype::isTerminal(inst) || Subtype::hasNonArgNonControlEffects(inst);
    }
};

// Definition of CCall instruction. CCall is used for hot path C function calls. It's lowered to a
// Patch with an Air CCallSpecial along with code to marshal instructions. The lowering happens
// before register allocation, so that the register allocator sees the clobbers.
struct CCallCustom : public CommonCustomBase<CCallCustom> {
    template<typename Functor>
    static void forEachArg(Inst& inst, const Functor& functor)
    {
        Value* value = inst.origin;

        unsigned index = 0;

        functor(inst.args[index++], Arg::Use, GP, pointerWidth()); // callee
        
        if (value->type() != Void) {
            functor(
                inst.args[index++], Arg::Def,
                bankForType(value->type()),
                widthForType(value->type()));
        }

        for (unsigned i = 1; i < value->numChildren(); ++i) {
            Value* child = value->child(i);
            functor(
                inst.args[index++], Arg::Use,
                bankForType(child->type()),
                widthForType(child->type()));
        }
    }

    template<typename... Arguments>
    static bool isValidFormStatic(Arguments...)
    {
        return false;
    }

    static bool isValidForm(Inst&);

    static bool admitsStack(Inst&, unsigned)
    {
        return true;
    }

    static bool admitsExtendedOffsetAddr(Inst&, unsigned)
    {
        return false;
    }
    
    static bool isTerminal(Inst&)
    {
        return false;
    }

    static bool hasNonArgNonControlEffects(Inst&)
    {
        return true;
    }

    // This just crashes, since we expect C calls to be lowered before generation.
    static CCallHelpers::Jump generate(Inst&, CCallHelpers&, GenerationContext&);
};

struct ColdCCallCustom : CCallCustom {
    template<typename Functor>
    static void forEachArg(Inst& inst, const Functor& functor)
    {
        // This is just like a call, but uses become cold.
        CCallCustom::forEachArg(
            inst,
            [&] (Arg& arg, Arg::Role role, Bank bank, Width width) {
                functor(arg, Arg::cooled(role), bank, width);
            });
    }
};

struct ShuffleCustom : public CommonCustomBase<ShuffleCustom> {
    template<typename Functor>
    static void forEachArg(Inst& inst, const Functor& functor)
    {
        unsigned limit = inst.args.size() / 3 * 3;
        for (unsigned i = 0; i < limit; i += 3) {
            Arg& src = inst.args[i + 0];
            Arg& dst = inst.args[i + 1];
            Arg& widthArg = inst.args[i + 2];
            Width width = widthArg.width();
            Bank bank = src.isGP() && dst.isGP() ? GP : FP;
            functor(src, Arg::Use, bank, width);
            functor(dst, Arg::Def, bank, width);
            functor(widthArg, Arg::Use, GP, Width8);
        }
    }

    template<typename... Arguments>
    static bool isValidFormStatic(Arguments...)
    {
        return false;
    }

    static bool isValidForm(Inst&);
    
    static bool admitsStack(Inst&, unsigned index)
    {
        switch (index % 3) {
        case 0:
        case 1:
            return true;
        default:
            return false;
        }
    }

    static bool admitsExtendedOffsetAddr(Inst&, unsigned)
    {
        return false;
    }

    static bool isTerminal(Inst&)
    {
        return false;
    }

    static bool hasNonArgNonControlEffects(Inst&)
    {
        return false;
    }

    static CCallHelpers::Jump generate(Inst&, CCallHelpers&, GenerationContext&);
};

struct EntrySwitchCustom : public CommonCustomBase<EntrySwitchCustom> {
    template<typename Func>
    static void forEachArg(Inst&, const Func&)
    {
    }
    
    template<typename... Arguments>
    static bool isValidFormStatic(Arguments...)
    {
        return !sizeof...(Arguments);
    }
    
    static bool isValidForm(Inst& inst)
    {
        return inst.args.isEmpty();
    }
    
    static bool admitsStack(Inst&, unsigned)
    {
        return false;
    }

    static bool admitsExtendedOffsetAddr(Inst&, unsigned)
    {
        return false;
    }
    
    static bool isTerminal(Inst&)
    {
        return true;
    }
    
    static bool hasNonArgNonControlEffects(Inst&)
    {
        return false;
    }

    static CCallHelpers::Jump generate(Inst&, CCallHelpers&, GenerationContext&)
    {
        // This should never be reached because we should have lowered EntrySwitch before
        // generation.
        UNREACHABLE_FOR_PLATFORM();
        return CCallHelpers::Jump();
    }
};

struct WasmBoundsCheckCustom : public CommonCustomBase<WasmBoundsCheckCustom> {
    template<typename Func>
    static void forEachArg(Inst& inst, const Func& functor)
    {
        functor(inst.args[0], Arg::Use, GP, Width64);
        functor(inst.args[1], Arg::Use, GP, Width64);
    }

    template<typename... Arguments>
    static bool isValidFormStatic(Arguments...)
    {
        return false;
    }

    static bool isValidForm(Inst&);

    static bool admitsStack(Inst&, unsigned)
    {
        return false;
    }

    static bool admitsExtendedOffsetAddr(Inst&, unsigned)
    {
        return false;
    }

    static bool isTerminal(Inst&)
    {
        return false;
    }
    
    static bool hasNonArgNonControlEffects(Inst&)
    {
        return true;
    }

    static CCallHelpers::Jump generate(Inst& inst, CCallHelpers& jit, GenerationContext& context)
    {
        WasmBoundsCheckValue* value = inst.origin->as<WasmBoundsCheckValue>();
        CCallHelpers::Jump outOfBounds = Inst(Air::Branch64, value, Arg::relCond(CCallHelpers::AboveOrEqual), inst.args[0], inst.args[1]).generate(jit, context);

        context.latePaths.append(createSharedTask<GenerationContext::LatePathFunction>(
            [outOfBounds, value] (CCallHelpers& jit, Air::GenerationContext& context) {
                outOfBounds.link(&jit);
                switch (value->boundsType()) {
                case WasmBoundsCheckValue::Type::Pinned:
                    context.code->wasmBoundsCheckGenerator()->run(jit, value->bounds().pinnedSize);
                    break;

                case WasmBoundsCheckValue::Type::Maximum:
                    context.code->wasmBoundsCheckGenerator()->run(jit, InvalidGPRReg);
                    break;
                }
            }));

        // We said we were not a terminal.
        return CCallHelpers::Jump();
    }
};

} } } // namespace JSC::B3::Air

#endif // ENABLE(B3_JIT)
