/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * 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.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "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 THE COPYRIGHT
// OWNER 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.

#ifndef jit_mips32_Simulator_mips32_h
#define jit_mips32_Simulator_mips32_h

#ifdef JS_SIMULATOR_MIPS32

#include "jslock.h"

#include "jit/IonTypes.h"

namespace js {
namespace jit {

class Simulator;
class Redirection;
class CachePage;
class AutoLockSimulator;

const intptr_t kPointerAlignment = 4;
const intptr_t kPointerAlignmentMask = kPointerAlignment - 1;

const intptr_t kDoubleAlignment = 8;
const intptr_t kDoubleAlignmentMask = kDoubleAlignment - 1;


// Number of general purpose registers.
const int kNumRegisters = 32;

// In the simulator, the PC register is simulated as the 34th register.
const int kPCRegister = 34;

// Number coprocessor registers.
const int kNumFPURegisters = 32;

// FPU (coprocessor 1) control registers. Currently only FCSR is implemented.
const int kFCSRRegister = 31;
const int kInvalidFPUControlRegister = -1;
const uint32_t kFPUInvalidResult = static_cast<uint32_t>(1 << 31) - 1;

// FCSR constants.
const uint32_t kFCSRInexactFlagBit = 2;
const uint32_t kFCSRUnderflowFlagBit = 3;
const uint32_t kFCSROverflowFlagBit = 4;
const uint32_t kFCSRDivideByZeroFlagBit = 5;
const uint32_t kFCSRInvalidOpFlagBit = 6;

const uint32_t kFCSRInexactFlagMask = 1 << kFCSRInexactFlagBit;
const uint32_t kFCSRUnderflowFlagMask = 1 << kFCSRUnderflowFlagBit;
const uint32_t kFCSROverflowFlagMask = 1 << kFCSROverflowFlagBit;
const uint32_t kFCSRDivideByZeroFlagMask = 1 << kFCSRDivideByZeroFlagBit;
const uint32_t kFCSRInvalidOpFlagMask = 1 << kFCSRInvalidOpFlagBit;

const uint32_t kFCSRFlagMask =
    kFCSRInexactFlagMask |
    kFCSRUnderflowFlagMask |
    kFCSROverflowFlagMask |
    kFCSRDivideByZeroFlagMask |
    kFCSRInvalidOpFlagMask;

const uint32_t kFCSRExceptionFlagMask = kFCSRFlagMask ^ kFCSRInexactFlagMask;

// On MIPS Simulator breakpoints can have different codes:
// - Breaks between 0 and kMaxWatchpointCode are treated as simple watchpoints,
//   the simulator will run through them and print the registers.
// - Breaks between kMaxWatchpointCode and kMaxStopCode are treated as stop()
//   instructions (see Assembler::stop()).
// - Breaks larger than kMaxStopCode are simple breaks, dropping you into the
//   debugger.
const uint32_t kMaxWatchpointCode = 31;
const uint32_t kMaxStopCode = 127;

// -----------------------------------------------------------------------------
// Utility functions

typedef uint32_t Instr;
class SimInstruction;

class Simulator {
    friend class Redirection;
    friend class MipsDebugger;
    friend class AutoLockSimulatorCache;
  public:

    // Registers are declared in order. See "See MIPS Run Linux" chapter 2.
    enum Register {
        no_reg = -1,
        zero_reg = 0,
        at,
        v0, v1,
        a0, a1, a2, a3,
        t0, t1, t2, t3, t4, t5, t6, t7,
        s0, s1, s2, s3, s4, s5, s6, s7,
        t8, t9,
        k0, k1,
        gp,
        sp,
        s8,
        ra,
        // LO, HI, and pc.
        LO,
        HI,
        pc,   // pc must be the last register.
        kNumSimuRegisters,
        // aliases
        fp = s8
    };

    // Coprocessor registers.
    enum FPURegister {
        f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11,
        f12, f13, f14, f15,   // f12 and f14 are arguments FPURegisters.
        f16, f17, f18, f19, f20, f21, f22, f23, f24, f25,
        f26, f27, f28, f29, f30, f31,
        kNumFPURegisters
    };

    // Returns nullptr on OOM.
    static Simulator* Create();

    static void Destroy(Simulator* simulator);

    // Constructor/destructor are for internal use only; use the static methods above.
    Simulator();
    ~Simulator();

    // The currently executing Simulator instance. Potentially there can be one
    // for each native thread.
    static Simulator* Current();

    static inline uintptr_t StackLimit() {
        return Simulator::Current()->stackLimit();
    }

    uintptr_t* addressOfStackLimit();

    // Accessors for register state. Reading the pc value adheres to the MIPS
    // architecture specification and is off by a 8 from the currently executing
    // instruction.
    void setRegister(int reg, int32_t value);
    int32_t getRegister(int reg) const;
    double getDoubleFromRegisterPair(int reg);
    // Same for FPURegisters.
    void setFpuRegister(int fpureg, int32_t value);
    void setFpuRegisterFloat(int fpureg, float value);
    void setFpuRegisterFloat(int fpureg, int64_t value);
    void setFpuRegisterDouble(int fpureg, double value);
    void setFpuRegisterDouble(int fpureg, int64_t value);
    int32_t getFpuRegister(int fpureg) const;
    int64_t getFpuRegisterLong(int fpureg) const;
    float getFpuRegisterFloat(int fpureg) const;
    double getFpuRegisterDouble(int fpureg) const;
    void setFCSRBit(uint32_t cc, bool value);
    bool testFCSRBit(uint32_t cc);
    bool setFCSRRoundError(double original, double rounded);

    // Special case of set_register and get_register to access the raw PC value.
    void set_pc(int32_t value);
    int32_t get_pc() const;

    template <typename T>
    T get_pc_as() const { return reinterpret_cast<T>(get_pc()); }

    void set_resume_pc(void* value) {
        resume_pc_ = int32_t(value);
    }

    // Accessor to the internal simulator stack area.
    uintptr_t stackLimit() const;
    bool overRecursed(uintptr_t newsp = 0) const;
    bool overRecursedWithExtra(uint32_t extra) const;

    // Executes MIPS instructions until the PC reaches end_sim_pc.
    template<bool enableStopSimAt>
    void execute();

    // Sets up the simulator state and grabs the result on return.
    int32_t call(uint8_t* entry, int argument_count, ...);

    // Push an address onto the JS stack.
    uintptr_t pushAddress(uintptr_t address);

    // Pop an address from the JS stack.
    uintptr_t popAddress();

    // Debugger input.
    void setLastDebuggerInput(char* input);
    char* lastDebuggerInput() { return lastDebuggerInput_; }
    // ICache checking.
    static void FlushICache(void* start, size_t size);

    // Returns true if pc register contains one of the 'SpecialValues' defined
    // below (bad_ra, end_sim_pc).
    bool has_bad_pc() const;

  private:
    enum SpecialValues {
        // Known bad pc value to ensure that the simulator does not execute
        // without being properly setup.
        bad_ra = -1,
        // A pc value used to signal the simulator to stop execution.  Generally
        // the ra is set to this value on transition from native C code to
        // simulated execution, so that the simulator can "return" to the native
        // C code.
        end_sim_pc = -2,
        // Unpredictable value.
        Unpredictable = 0xbadbeaf
    };

    bool init();

    // Unsupported instructions use Format to print an error and stop execution.
    void format(SimInstruction* instr, const char* format);

    // Read and write memory.
    inline uint32_t readBU(uint32_t addr);
    inline int32_t readB(uint32_t addr);
    inline void writeB(uint32_t addr, uint8_t value);
    inline void writeB(uint32_t addr, int8_t value);

    inline uint16_t readHU(uint32_t addr, SimInstruction* instr);
    inline int16_t readH(uint32_t addr, SimInstruction* instr);
    // Note: Overloaded on the sign of the value.
    inline void writeH(uint32_t addr, uint16_t value, SimInstruction* instr);
    inline void writeH(uint32_t addr, int16_t value, SimInstruction* instr);

    inline int readW(uint32_t addr, SimInstruction* instr);
    inline void writeW(uint32_t addr, int value, SimInstruction* instr);

    inline double readD(uint32_t addr, SimInstruction* instr);
    inline void writeD(uint32_t addr, double value, SimInstruction* instr);

    // Executing is handled based on the instruction type.
    void decodeTypeRegister(SimInstruction* instr);

    // Helper function for decodeTypeRegister.
    void configureTypeRegister(SimInstruction* instr,
                               int32_t& alu_out,
                               int64_t& i64hilo,
                               uint64_t& u64hilo,
                               int32_t& next_pc,
                               int32_t& return_addr_reg,
                               bool& do_interrupt);

    void decodeTypeImmediate(SimInstruction* instr);
    void decodeTypeJump(SimInstruction* instr);

    // Used for breakpoints and traps.
    void softwareInterrupt(SimInstruction* instr);

    // Stop helper functions.
    bool isWatchpoint(uint32_t code);
    void printWatchpoint(uint32_t code);
    void handleStop(uint32_t code, SimInstruction* instr);
    bool isStopInstruction(SimInstruction* instr);
    bool isEnabledStop(uint32_t code);
    void enableStop(uint32_t code);
    void disableStop(uint32_t code);
    void increaseStopCounter(uint32_t code);
    void printStopInfo(uint32_t code);


    // Executes one instruction.
    void instructionDecode(SimInstruction* instr);
    // Execute one instruction placed in a branch delay slot.
    void branchDelayInstructionDecode(SimInstruction* instr);

  public:
    static bool ICacheCheckingEnabled;

    static int StopSimAt;

    // Runtime call support.
    static void* RedirectNativeFunction(void* nativeFunction, ABIFunctionType type);

  private:
    enum Exception {
        kNone,
        kIntegerOverflow,
        kIntegerUnderflow,
        kDivideByZero,
        kNumExceptions
    };
    int16_t exceptions[kNumExceptions];

    // Exceptions.
    void signalExceptions();

    // Handle arguments and return value for runtime FP functions.
    void getFpArgs(double* x, double* y, int32_t* z);
    void getFpFromStack(int32_t* stack, double* x);

    void setCallResultDouble(double result);
    void setCallResultFloat(float result);
    void setCallResult(int64_t res);

    void callInternal(uint8_t* entry);

    // Architecture state.
    // Registers.
    int32_t registers_[kNumSimuRegisters];
    // Coprocessor Registers.
    int32_t FPUregisters_[kNumFPURegisters];
    // FPU control register.
    uint32_t FCSR_;

    // Simulator support.
    char* stack_;
    uintptr_t stackLimit_;
    bool pc_modified_;
    int icount_;
    int break_count_;

    int32_t resume_pc_;

    // Debugger input.
    char* lastDebuggerInput_;

    // Registered breakpoints.
    SimInstruction* break_pc_;
    Instr break_instr_;

    // A stop is watched if its code is less than kNumOfWatchedStops.
    // Only watched stops support enabling/disabling and the counter feature.
    static const uint32_t kNumOfWatchedStops = 256;


    // Stop is disabled if bit 31 is set.
    static const uint32_t kStopDisabledBit = 1U << 31;

    // A stop is enabled, meaning the simulator will stop when meeting the
    // instruction, if bit 31 of watchedStops_[code].count is unset.
    // The value watchedStops_[code].count & ~(1 << 31) indicates how many times
    // the breakpoint was hit or gone through.
    struct StopCountAndDesc {
        uint32_t count_;
        char* desc_;
    };
    StopCountAndDesc watchedStops_[kNumOfWatchedStops];

  private:
    // ICache checking.
    struct ICacheHasher {
        typedef void* Key;
        typedef void* Lookup;
        static HashNumber hash(const Lookup& l);
        static bool match(const Key& k, const Lookup& l);
    };

  public:
    typedef HashMap<void*, CachePage*, ICacheHasher, SystemAllocPolicy> ICacheMap;

  private:
    // This lock creates a critical section around 'redirection_' and
    // 'icache_', which are referenced both by the execution engine
    // and by the off-thread compiler (see Redirection::Get in the cpp file).
    PRLock* cacheLock_;
#ifdef DEBUG
    PRThread* cacheLockHolder_;
#endif

    Redirection* redirection_;
    ICacheMap icache_;

  public:
    ICacheMap& icache() {
        // Technically we need the lock to access the innards of the
        // icache, not to take its address, but the latter condition
        // serves as a useful complement to the former.
        MOZ_ASSERT(cacheLockHolder_);
        return icache_;
    }

    Redirection* redirection() const {
        MOZ_ASSERT(cacheLockHolder_);
        return redirection_;
    }

    void setRedirection(js::jit::Redirection* redirection) {
        MOZ_ASSERT(cacheLockHolder_);
        redirection_ = redirection;
    }
};

#define JS_CHECK_SIMULATOR_RECURSION_WITH_EXTRA(cx, extra, onerror)             \
    JS_BEGIN_MACRO                                                              \
        if (cx->mainThread().simulator()->overRecursedWithExtra(extra)) {       \
            js::ReportOverRecursed(cx);                                         \
            onerror;                                                            \
        }                                                                       \
    JS_END_MACRO

} // namespace jit
} // namespace js

#endif /* JS_SIMULATOR_MIPS32 */

#endif /* jit_mips32_Simulator_mips32_h */
