/*
 * 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 ValueRecovery_h
#define ValueRecovery_h

#include "DataFormat.h"
#include "JSValue.h"
#include "MacroAssembler.h"
#include "VirtualRegister.h"
#include <stdio.h>
#include <wtf/Platform.h>

namespace JSC {

// Describes how to recover a given bytecode virtual register at a given
// code point.
enum ValueRecoveryTechnique {
    // It's already in the stack at the right location.
    AlreadyInJSStack,
    // It's already in the stack but unboxed.
    AlreadyInJSStackAsUnboxedInt32,
    AlreadyInJSStackAsUnboxedCell,
    AlreadyInJSStackAsUnboxedBoolean,
    AlreadyInJSStackAsUnboxedDouble,
    // It's in a register.
    InGPR,
    UnboxedInt32InGPR,
    UnboxedBooleanInGPR,
#if USE(JSVALUE32_64)
    InPair,
#endif
    InFPR,
    UInt32InGPR,
    // It's in the stack, but at a different location.
    DisplacedInJSStack,
    // It's in the stack, at a different location, and it's unboxed.
    Int32DisplacedInJSStack,
    DoubleDisplacedInJSStack,
    CellDisplacedInJSStack,
    BooleanDisplacedInJSStack,
    // It's an Arguments object.
    ArgumentsThatWereNotCreated,
    // It's a constant.
    Constant,
    // Don't know how to recover it.
    DontKnow
};

class ValueRecovery {
public:
    ValueRecovery()
        : m_technique(DontKnow)
    {
    }
    
    bool isSet() const { return m_technique != DontKnow; }
    bool operator!() const { return !isSet(); }
    
    static ValueRecovery alreadyInJSStack()
    {
        ValueRecovery result;
        result.m_technique = AlreadyInJSStack;
        return result;
    }
    
    static ValueRecovery alreadyInJSStackAsUnboxedInt32()
    {
        ValueRecovery result;
        result.m_technique = AlreadyInJSStackAsUnboxedInt32;
        return result;
    }
    
    static ValueRecovery alreadyInJSStackAsUnboxedCell()
    {
        ValueRecovery result;
        result.m_technique = AlreadyInJSStackAsUnboxedCell;
        return result;
    }
    
    static ValueRecovery alreadyInJSStackAsUnboxedBoolean()
    {
        ValueRecovery result;
        result.m_technique = AlreadyInJSStackAsUnboxedBoolean;
        return result;
    }
    
    static ValueRecovery alreadyInJSStackAsUnboxedDouble()
    {
        ValueRecovery result;
        result.m_technique = AlreadyInJSStackAsUnboxedDouble;
        return result;
    }
    
    static ValueRecovery inGPR(MacroAssembler::RegisterID gpr, DataFormat dataFormat)
    {
        ASSERT(dataFormat != DataFormatNone);
#if USE(JSVALUE32_64)
        ASSERT(dataFormat == DataFormatInteger || dataFormat == DataFormatCell || dataFormat == DataFormatBoolean);
#endif
        ValueRecovery result;
        if (dataFormat == DataFormatInteger)
            result.m_technique = UnboxedInt32InGPR;
        else if (dataFormat == DataFormatBoolean)
            result.m_technique = UnboxedBooleanInGPR;
        else
            result.m_technique = InGPR;
        result.m_source.gpr = gpr;
        return result;
    }
    
    static ValueRecovery uint32InGPR(MacroAssembler::RegisterID gpr)
    {
        ValueRecovery result;
        result.m_technique = UInt32InGPR;
        result.m_source.gpr = gpr;
        return result;
    }
    
#if USE(JSVALUE32_64)
    static ValueRecovery inPair(MacroAssembler::RegisterID tagGPR, MacroAssembler::RegisterID payloadGPR)
    {
        ValueRecovery result;
        result.m_technique = InPair;
        result.m_source.pair.tagGPR = tagGPR;
        result.m_source.pair.payloadGPR = payloadGPR;
        return result;
    }
#endif

    static ValueRecovery inFPR(MacroAssembler::FPRegisterID fpr)
    {
        ValueRecovery result;
        result.m_technique = InFPR;
        result.m_source.fpr = fpr;
        return result;
    }
    
    static ValueRecovery displacedInJSStack(VirtualRegister virtualReg, DataFormat dataFormat)
    {
        ValueRecovery result;
        switch (dataFormat) {
        case DataFormatInteger:
            result.m_technique = Int32DisplacedInJSStack;
            break;
            
        case DataFormatDouble:
            result.m_technique = DoubleDisplacedInJSStack;
            break;

        case DataFormatCell:
            result.m_technique = CellDisplacedInJSStack;
            break;
            
        case DataFormatBoolean:
            result.m_technique = BooleanDisplacedInJSStack;
            break;
            
        default:
            ASSERT(dataFormat != DataFormatNone && dataFormat != DataFormatStorage);
            result.m_technique = DisplacedInJSStack;
            break;
        }
        result.m_source.virtualReg = virtualReg;
        return result;
    }
    
    static ValueRecovery constant(JSValue value)
    {
        ValueRecovery result;
        result.m_technique = Constant;
        result.m_source.constant = JSValue::encode(value);
        return result;
    }
    
    static ValueRecovery argumentsThatWereNotCreated()
    {
        ValueRecovery result;
        result.m_technique = ArgumentsThatWereNotCreated;
        return result;
    }
    
    ValueRecoveryTechnique technique() const { return m_technique; }
    
    bool isConstant() const { return m_technique == Constant; }
    
    bool isInRegisters() const
    {
        switch (m_technique) {
        case InGPR:
        case UnboxedInt32InGPR:
        case UnboxedBooleanInGPR:
#if USE(JSVALUE32_64)
        case InPair:
#endif
        case InFPR:
            return true;
        default:
            return false;
        }
    }
    
    bool isAlreadyInJSStack() const
    {
        switch (technique()) {
        case AlreadyInJSStack:
        case AlreadyInJSStackAsUnboxedInt32:
        case AlreadyInJSStackAsUnboxedCell:
        case AlreadyInJSStackAsUnboxedBoolean:
        case AlreadyInJSStackAsUnboxedDouble:
            return true;
        default:
            return false;
        }
    }
    
    MacroAssembler::RegisterID gpr() const
    {
        ASSERT(m_technique == InGPR || m_technique == UnboxedInt32InGPR || m_technique == UnboxedBooleanInGPR || m_technique == UInt32InGPR);
        return m_source.gpr;
    }
    
#if USE(JSVALUE32_64)
    MacroAssembler::RegisterID tagGPR() const
    {
        ASSERT(m_technique == InPair);
        return m_source.pair.tagGPR;
    }
    
    MacroAssembler::RegisterID payloadGPR() const
    {
        ASSERT(m_technique == InPair);
        return m_source.pair.payloadGPR;
    }
#endif
    
    MacroAssembler::FPRegisterID fpr() const
    {
        ASSERT(m_technique == InFPR);
        return m_source.fpr;
    }
    
    VirtualRegister virtualRegister() const
    {
        ASSERT(m_technique == DisplacedInJSStack || m_technique == Int32DisplacedInJSStack || m_technique == DoubleDisplacedInJSStack || m_technique == CellDisplacedInJSStack || m_technique == BooleanDisplacedInJSStack);
        return m_source.virtualReg;
    }
    
    JSValue constant() const
    {
        ASSERT(m_technique == Constant);
        return JSValue::decode(m_source.constant);
    }
    
    void dump(PrintStream& out) const
    {
        switch (technique()) {
        case AlreadyInJSStack:
            out.printf("-");
            break;
        case AlreadyInJSStackAsUnboxedInt32:
            out.printf("(int32)");
            break;
        case AlreadyInJSStackAsUnboxedCell:
            out.printf("(cell)");
            break;
        case AlreadyInJSStackAsUnboxedBoolean:
            out.printf("(bool)");
            break;
        case AlreadyInJSStackAsUnboxedDouble:
            out.printf("(double)");
            break;
        case InGPR:
            out.printf("%%r%d", gpr());
            break;
        case UnboxedInt32InGPR:
            out.printf("int32(%%r%d)", gpr());
            break;
        case UnboxedBooleanInGPR:
            out.printf("bool(%%r%d)", gpr());
            break;
        case UInt32InGPR:
            out.printf("uint32(%%r%d)", gpr());
            break;
        case InFPR:
            out.printf("%%fr%d", fpr());
            break;
#if USE(JSVALUE32_64)
        case InPair:
            out.printf("pair(%%r%d, %%r%d)", tagGPR(), payloadGPR());
            break;
#endif
        case DisplacedInJSStack:
            out.printf("*%d", virtualRegister());
            break;
        case Int32DisplacedInJSStack:
            out.printf("*int32(%d)", virtualRegister());
            break;
        case DoubleDisplacedInJSStack:
            out.printf("*double(%d)", virtualRegister());
            break;
        case CellDisplacedInJSStack:
            out.printf("*cell(%d)", virtualRegister());
            break;
        case BooleanDisplacedInJSStack:
            out.printf("*bool(%d)", virtualRegister());
            break;
        case ArgumentsThatWereNotCreated:
            out.printf("arguments");
            break;
        case Constant:
            out.print("[", constant(), "]");
            break;
        case DontKnow:
            out.printf("!");
            break;
        default:
            out.printf("?%d", technique());
            break;
        }
    }
    
private:
    ValueRecoveryTechnique m_technique;
    union {
        MacroAssembler::RegisterID gpr;
        MacroAssembler::FPRegisterID fpr;
#if USE(JSVALUE32_64)
        struct {
            MacroAssembler::RegisterID tagGPR;
            MacroAssembler::RegisterID payloadGPR;
        } pair;
#endif
        VirtualRegister virtualReg;
        EncodedJSValue constant;
    } m_source;
};

} // namespace JSC

#endif // ValueRecovery_h
