/*
 * Copyright (C) 2011 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. 
 */

#ifndef DFGGPRInfo_h
#define DFGGPRInfo_h

#include <wtf/Platform.h>

#if ENABLE(DFG_JIT)

#include "DFGRegisterBank.h"
#include "MacroAssembler.h"

namespace JSC { namespace DFG {

typedef MacroAssembler::RegisterID GPRReg;
#define InvalidGPRReg ((GPRReg)-1)

#if USE(JSVALUE64)
class JSValueRegs {
public:
    JSValueRegs()
        : m_gpr(InvalidGPRReg)
    {
    }
    
    explicit JSValueRegs(GPRReg gpr)
        : m_gpr(gpr)
    {
    }
    
    bool operator!() const { return m_gpr == InvalidGPRReg; }
    
    GPRReg gpr() const { return m_gpr; }
    
private:
    GPRReg m_gpr;
};

class JSValueSource {
public:
    JSValueSource()
        : m_offset(notAddress())
        , m_base(InvalidGPRReg)
    {
    }
    
    JSValueSource(JSValueRegs regs)
        : m_offset(notAddress())
        , m_base(regs.gpr())
    {
    }
    
    explicit JSValueSource(GPRReg gpr)
        : m_offset(notAddress())
        , m_base(gpr)
    {
    }
    
    JSValueSource(MacroAssembler::Address address)
        : m_offset(address.offset)
        , m_base(address.base)
    {
        ASSERT(m_offset != notAddress());
        ASSERT(m_base != InvalidGPRReg);
    }
    
    static JSValueSource unboxedCell(GPRReg payloadGPR)
    {
        return JSValueSource(payloadGPR);
    }
    
    bool operator!() const { return m_base == InvalidGPRReg; }
    
    bool isAddress() const { return m_offset != notAddress(); }
    
    int32_t offset() const
    {
        ASSERT(isAddress());
        return m_offset;
    }
    
    GPRReg base() const
    {
        ASSERT(isAddress());
        return m_base;
    }
    
    GPRReg gpr() const
    {
        ASSERT(!isAddress());
        return m_base;
    }
    
    MacroAssembler::Address asAddress() const { return MacroAssembler::Address(base(), offset()); }
    
private:
    static inline int32_t notAddress() { return 0x80000000; }     
          
    int32_t m_offset;
    GPRReg m_base;
};
#endif

#if USE(JSVALUE32_64)
class JSValueRegs {
public:
    JSValueRegs()
        : m_tagGPR(static_cast<int8_t>(InvalidGPRReg))
        , m_payloadGPR(static_cast<int8_t>(InvalidGPRReg))
    {
    }
    
    JSValueRegs(GPRReg tagGPR, GPRReg payloadGPR)
        : m_tagGPR(tagGPR)
        , m_payloadGPR(payloadGPR)
    {
        ASSERT((static_cast<GPRReg>(m_tagGPR) == InvalidGPRReg) == (static_cast<GPRReg>(payloadGPR) == InvalidGPRReg));
    }
    
    bool operator!() const { return static_cast<GPRReg>(m_tagGPR) == InvalidGPRReg; }
    
    GPRReg tagGPR() const { return static_cast<GPRReg>(m_tagGPR); }
    GPRReg payloadGPR() const { return static_cast<GPRReg>(m_payloadGPR); }

private:
    int8_t m_tagGPR;
    int8_t m_payloadGPR;
};

class JSValueSource {
public:
    JSValueSource()
        : m_offset(notAddress())
        , m_baseOrTag(static_cast<int8_t>(InvalidGPRReg))
        , m_payload(static_cast<int8_t>(InvalidGPRReg))
        , m_tagType(0)
    {
    }
    
    JSValueSource(JSValueRegs regs)
        : m_offset(notAddress())
        , m_baseOrTag(regs.tagGPR())
        , m_payload(regs.payloadGPR())
        , m_tagType(0)
    {
    }
    
    JSValueSource(GPRReg tagGPR, GPRReg payloadGPR)
        : m_offset(notAddress())
        , m_baseOrTag(static_cast<int8_t>(tagGPR))
        , m_payload(static_cast<int8_t>(payloadGPR))
        , m_tagType(0)
    {
    }
    
    JSValueSource(MacroAssembler::Address address)
        : m_offset(address.offset)
        , m_baseOrTag(static_cast<int8_t>(address.base))
        , m_payload(static_cast<int8_t>(InvalidGPRReg))
        , m_tagType(0)
    {
        ASSERT(m_offset != notAddress());
        ASSERT(static_cast<GPRReg>(m_baseOrTag) != InvalidGPRReg);
    }
    
    static JSValueSource unboxedCell(GPRReg payloadGPR)
    {
        JSValueSource result;
        result.m_offset = notAddress();
        result.m_baseOrTag = static_cast<int8_t>(InvalidGPRReg);
        result.m_payload = static_cast<int8_t>(payloadGPR);
        result.m_tagType = static_cast<int8_t>(JSValue::CellTag);
        return result;
    }
    
    bool operator!() const { return static_cast<GPRReg>(m_baseOrTag) == InvalidGPRReg && static_cast<GPRReg>(m_payload) == InvalidGPRReg; }
    
    bool isAddress() const
    {
        ASSERT(!!*this);
        return m_offset != notAddress();
    }
    
    int32_t offset() const
    {
        ASSERT(isAddress());
        return m_offset;
    }
    
    GPRReg base() const
    {
        ASSERT(isAddress());
        return static_cast<GPRReg>(m_baseOrTag);
    }
    
    GPRReg tagGPR() const
    {
        ASSERT(!isAddress() && static_cast<GPRReg>(m_baseOrTag) != InvalidGPRReg);
        return static_cast<GPRReg>(m_baseOrTag);
    }
    
    GPRReg payloadGPR() const
    {
        ASSERT(!isAddress());
        return static_cast<GPRReg>(m_payload);
    }
    
    bool hasKnownTag() const
    {
        ASSERT(!!*this);
        ASSERT(!isAddress());
        return static_cast<GPRReg>(m_baseOrTag) == InvalidGPRReg;
    }
    
    uint32_t tag() const
    {
        return static_cast<int32_t>(m_tagType);
    }
    
    MacroAssembler::Address asAddress(unsigned additionalOffset = 0) const { return MacroAssembler::Address(base(), offset() + additionalOffset); }
    
private:
    static inline int32_t notAddress() { return 0x80000000; }     
          
    int32_t m_offset;
    int8_t m_baseOrTag;
    int8_t m_payload; 
    int8_t m_tagType; // Contains the low bits of the tag.
};
#endif

#if CPU(X86)
#define NUMBER_OF_ARGUMENT_REGISTERS 0

class GPRInfo {
public:
    typedef GPRReg RegisterType;
    static const unsigned numberOfRegisters = 5;

    // Temporary registers.
    static const GPRReg regT0 = X86Registers::eax;
    static const GPRReg regT1 = X86Registers::edx;
    static const GPRReg regT2 = X86Registers::ecx;
    static const GPRReg regT3 = X86Registers::ebx;
    static const GPRReg regT4 = X86Registers::esi;
    // These registers match the baseline JIT.
    static const GPRReg cachedResultRegister = regT0;
    static const GPRReg cachedResultRegister2 = regT1;
    static const GPRReg callFrameRegister = X86Registers::edi;
    // These constants provide the names for the general purpose argument & return value registers.
    static const GPRReg argumentGPR0 = X86Registers::ecx; // regT2
    static const GPRReg argumentGPR1 = X86Registers::edx; // regT1
    static const GPRReg nonArgGPR0 = X86Registers::eax; // regT0
    static const GPRReg nonArgGPR1 = X86Registers::ebx; // regT3
    static const GPRReg nonArgGPR2 = X86Registers::esi; // regT4
    static const GPRReg returnValueGPR = X86Registers::eax; // regT0
    static const GPRReg returnValueGPR2 = X86Registers::edx; // regT1
    static const GPRReg nonPreservedNonReturnGPR = X86Registers::ecx;

    static GPRReg toRegister(unsigned index)
    {
        ASSERT(index < numberOfRegisters);
        static const GPRReg registerForIndex[numberOfRegisters] = { regT0, regT1, regT2, regT3, regT4 };
        return registerForIndex[index];
    }

    static unsigned toIndex(GPRReg reg)
    {
        ASSERT(reg != InvalidGPRReg);
        ASSERT(static_cast<int>(reg) < 8);
        static const unsigned indexForRegister[8] = { 0, 2, 1, 3, InvalidIndex, InvalidIndex, 4, InvalidIndex };
        unsigned result = indexForRegister[reg];
        ASSERT(result != InvalidIndex);
        return result;
    }

    static const char* debugName(GPRReg reg)
    {
        ASSERT(reg != InvalidGPRReg);
        ASSERT(static_cast<int>(reg) < 8);
        static const char* nameForRegister[8] = {
            "eax", "ecx", "edx", "ebx",
            "esp", "ebp", "esi", "edi",
        };
        return nameForRegister[reg];
    }
private:

    static const unsigned InvalidIndex = 0xffffffff;
};

#endif

#if CPU(X86_64)
#define NUMBER_OF_ARGUMENT_REGISTERS 6

class GPRInfo {
public:
    typedef GPRReg RegisterType;
    static const unsigned numberOfRegisters = 9;

    // These registers match the baseline JIT.
    static const GPRReg cachedResultRegister = X86Registers::eax;
    static const GPRReg timeoutCheckRegister = X86Registers::r12;
    static const GPRReg callFrameRegister = X86Registers::r13;
    static const GPRReg tagTypeNumberRegister = X86Registers::r14;
    static const GPRReg tagMaskRegister = X86Registers::r15;
    // Temporary registers.
    static const GPRReg regT0 = X86Registers::eax;
    static const GPRReg regT1 = X86Registers::edx;
    static const GPRReg regT2 = X86Registers::ecx;
    static const GPRReg regT3 = X86Registers::ebx;
    static const GPRReg regT4 = X86Registers::edi;
    static const GPRReg regT5 = X86Registers::esi;
    static const GPRReg regT6 = X86Registers::r8;
    static const GPRReg regT7 = X86Registers::r9;
    static const GPRReg regT8 = X86Registers::r10;
    // These constants provide the names for the general purpose argument & return value registers.
    static const GPRReg argumentGPR0 = X86Registers::edi; // regT4
    static const GPRReg argumentGPR1 = X86Registers::esi; // regT5
    static const GPRReg argumentGPR2 = X86Registers::edx; // regT1
    static const GPRReg argumentGPR3 = X86Registers::ecx; // regT2
    static const GPRReg argumentGPR4 = X86Registers::r8;  // regT6
    static const GPRReg argumentGPR5 = X86Registers::r9;  // regT7
    static const GPRReg nonArgGPR0 = X86Registers::eax; // regT0
    static const GPRReg nonArgGPR1 = X86Registers::ebx; // regT3
    static const GPRReg nonArgGPR2 = X86Registers::r10; // regT8
    static const GPRReg returnValueGPR = X86Registers::eax; // regT0
    static const GPRReg returnValueGPR2 = X86Registers::edx; // regT1
    static const GPRReg nonPreservedNonReturnGPR = X86Registers::esi;

    static GPRReg toRegister(unsigned index)
    {
        ASSERT(index < numberOfRegisters);
        static const GPRReg registerForIndex[numberOfRegisters] = { regT0, regT1, regT2, regT3, regT4, regT5, regT6, regT7, regT8 };
        return registerForIndex[index];
    }

    static unsigned toIndex(GPRReg reg)
    {
        ASSERT(reg != InvalidGPRReg);
        ASSERT(static_cast<int>(reg) < 16);
        static const unsigned indexForRegister[16] = { 0, 2, 1, 3, InvalidIndex, InvalidIndex, 5, 4, 6, 7, 8, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex };
        unsigned result = indexForRegister[reg];
        ASSERT(result != InvalidIndex);
        return result;
    }

    static const char* debugName(GPRReg reg)
    {
        ASSERT(reg != InvalidGPRReg);
        ASSERT(static_cast<int>(reg) < 16);
        static const char* nameForRegister[16] = {
            "rax", "rcx", "rdx", "rbx",
            "rsp", "rbp", "rsi", "rdi",
            "r8", "r9", "r10", "r11",
            "r12", "r13", "r14", "r15"
        };
        return nameForRegister[reg];
    }
private:

    static const unsigned InvalidIndex = 0xffffffff;
};

#endif

#if CPU(ARM)
#define NUMBER_OF_ARGUMENT_REGISTERS 4

class GPRInfo {
public:
    typedef GPRReg RegisterType;
    static const unsigned numberOfRegisters = 8;

    // Temporary registers.
    static const GPRReg regT0 = ARMRegisters::r0;
    static const GPRReg regT1 = ARMRegisters::r1;
    static const GPRReg regT2 = ARMRegisters::r2;
    static const GPRReg regT3 = ARMRegisters::r4;
    static const GPRReg regT4 = ARMRegisters::r8;
    static const GPRReg regT5 = ARMRegisters::r9;
    static const GPRReg regT6 = ARMRegisters::r10;
    static const GPRReg regT7 = ARMRegisters::r11;
    // These registers match the baseline JIT.
    static const GPRReg cachedResultRegister = regT0;
    static const GPRReg cachedResultRegister2 = regT1;
    static const GPRReg callFrameRegister = ARMRegisters::r5;
    // These constants provide the names for the general purpose argument & return value registers.
    static const GPRReg argumentGPR0 = ARMRegisters::r0; // regT0
    static const GPRReg argumentGPR1 = ARMRegisters::r1; // regT1
    static const GPRReg argumentGPR2 = ARMRegisters::r2; // regT2
    // FIXME: r3 is currently used be the MacroAssembler as a temporary - it seems
    // This could threoretically be a problem if this is used in code generation
    // between the arguments being set up, and the call being made. That said,
    // any change introducing a problem here is likely to be immediately apparent!
    static const GPRReg argumentGPR3 = ARMRegisters::r3; // FIXME!
    static const GPRReg nonArgGPR0 = ARMRegisters::r4; // regT3
    static const GPRReg nonArgGPR1 = ARMRegisters::r8; // regT4
    static const GPRReg nonArgGPR2 = ARMRegisters::r9; // regT5
    static const GPRReg returnValueGPR = ARMRegisters::r0; // regT0
    static const GPRReg returnValueGPR2 = ARMRegisters::r1; // regT1
    static const GPRReg nonPreservedNonReturnGPR = ARMRegisters::r2;

    static GPRReg toRegister(unsigned index)
    {
        ASSERT(index < numberOfRegisters);
        static const GPRReg registerForIndex[numberOfRegisters] = { regT0, regT1, regT2, regT3, regT4, regT5, regT6, regT7 };
        return registerForIndex[index];
    }

    static unsigned toIndex(GPRReg reg)
    {
        ASSERT(reg != InvalidGPRReg);
        ASSERT(reg < 16);
        static const unsigned indexForRegister[16] = { 0, 1, 2, InvalidIndex, 3, InvalidIndex, InvalidIndex, InvalidIndex, 4, 5, 6, 7, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex };
        unsigned result = indexForRegister[reg];
        ASSERT(result != InvalidIndex);
        return result;
    }

    static const char* debugName(GPRReg reg)
    {
        ASSERT(reg != InvalidGPRReg);
        ASSERT(reg < 16);
        static const char* nameForRegister[16] = {
            "r0", "r1", "r2", "r3",
            "r4", "r5", "r6", "r7",
            "r8", "r9", "r10", "r11",
            "r12", "r13", "r14", "r15"
        };
        return nameForRegister[reg];
    }
private:

    static const unsigned InvalidIndex = 0xffffffff;
};

#endif

typedef RegisterBank<GPRInfo>::iterator gpr_iterator;

} } // namespace JSC::DFG

#endif
#endif
