/*
 * Copyright (c) 2012 Google
 * 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 the copyright holders 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 __ARCH_X86_DECODER_HH__
#define __ARCH_X86_DECODER_HH__

#include <cassert>
#include <unordered_map>
#include <vector>

#include "arch/x86/regs/misc.hh"
#include "arch/x86/types.hh"
#include "base/bitfield.hh"
#include "base/logging.hh"
#include "base/trace.hh"
#include "base/types.hh"
#include "cpu/decode_cache.hh"
#include "cpu/static_inst.hh"
#include "debug/Decoder.hh"

namespace X86ISA
{

class ISA;
class Decoder
{
  private:
    //These are defined and documented in decoder_tables.cc
    static const uint8_t SizeTypeToSize[3][10];
    typedef const uint8_t ByteTable[256];
    static ByteTable Prefixes;

    static ByteTable UsesModRMOneByte;
    static ByteTable UsesModRMTwoByte;
    static ByteTable UsesModRMThreeByte0F38;
    static ByteTable UsesModRMThreeByte0F3A;

    static ByteTable ImmediateTypeOneByte;
    static ByteTable ImmediateTypeTwoByte;
    static ByteTable ImmediateTypeThreeByte0F38;
    static ByteTable ImmediateTypeThreeByte0F3A;
    static ByteTable ImmediateTypeVex[10];

  protected:
    struct InstBytes
    {
        StaticInstPtr si;
        std::vector<MachInst> chunks;
        std::vector<MachInst> masks;
        int lastOffset;

        InstBytes() : lastOffset(0)
        {}
    };

    static InstBytes dummy;

    //The bytes to be predecoded
    MachInst fetchChunk;
    InstBytes *instBytes;
    int chunkIdx;
    //The pc of the start of fetchChunk
    Addr basePC;
    //The pc the current instruction started at
    Addr origPC;
    //The offset into fetchChunk of current processing
    int offset;
    //The extended machine instruction being generated
    ExtMachInst emi;
    //Predecoding state
    X86Mode mode;
    X86SubMode submode;
    uint8_t altOp;
    uint8_t defOp;
    uint8_t altAddr;
    uint8_t defAddr;
    uint8_t stack;

    uint8_t getNextByte()
    {
        return ((uint8_t *)&fetchChunk)[offset];
    }

    void getImmediate(int &collected, uint64_t &current, int size)
    {
        //Figure out how many bytes we still need to get for the
        //immediate.
        int toGet = size - collected;
        //Figure out how many bytes are left in our "buffer"
        int remaining = sizeof(MachInst) - offset;
        //Get as much as we need, up to the amount available.
        toGet = toGet > remaining ? remaining : toGet;

        //Shift the bytes we want to be all the way to the right
        uint64_t partialImm = fetchChunk >> (offset * 8);
        //Mask off what we don't want
        partialImm &= mask(toGet * 8);
        //Shift it over to overlay with our displacement.
        partialImm <<= (immediateCollected * 8);
        //Put it into our displacement
        current |= partialImm;
        //Update how many bytes we've collected.
        collected += toGet;
        consumeBytes(toGet);
    }

    void updateOffsetState()
    {
        assert(offset <= sizeof(MachInst));
        if (offset == sizeof(MachInst)) {
            DPRINTF(Decoder, "At the end of a chunk, idx = %d, chunks = %d.\n",
                    chunkIdx, instBytes->chunks.size());
            chunkIdx++;
            if (chunkIdx == instBytes->chunks.size()) {
                outOfBytes = true;
            } else {
                offset = 0;
                fetchChunk = instBytes->chunks[chunkIdx];
                basePC += sizeof(MachInst);
            }
        }
    }

    void consumeByte()
    {
        offset++;
        updateOffsetState();
    }

    void consumeBytes(int numBytes)
    {
        offset += numBytes;
        updateOffsetState();
    }

    //State machine state
  protected:
    //Whether or not we're out of bytes
    bool outOfBytes;
    //Whether we've completed generating an ExtMachInst
    bool instDone;
    //The size of the displacement value
    int displacementSize;
    //The size of the immediate value
    int immediateSize;
    //This is how much of any immediate value we've gotten. This is used
    //for both the actual immediate and the displacement.
    int immediateCollected;

    enum State {
        ResetState,
        FromCacheState,
        PrefixState,
        Vex2Of2State,
        Vex2Of3State,
        Vex3Of3State,
        VexOpcodeState,
        OneByteOpcodeState,
        TwoByteOpcodeState,
        ThreeByte0F38OpcodeState,
        ThreeByte0F3AOpcodeState,
        ModRMState,
        SIBState,
        DisplacementState,
        ImmediateState,
        //We should never get to this state. Getting here is an error.
        ErrorState
    };

    State state;

    //Functions to handle each of the states
    State doResetState();
    State doFromCacheState();
    State doPrefixState(uint8_t);
    State doVex2Of2State(uint8_t);
    State doVex2Of3State(uint8_t);
    State doVex3Of3State(uint8_t);
    State doVexOpcodeState(uint8_t);
    State doOneByteOpcodeState(uint8_t);
    State doTwoByteOpcodeState(uint8_t);
    State doThreeByte0F38OpcodeState(uint8_t);
    State doThreeByte0F3AOpcodeState(uint8_t);
    State doModRMState(uint8_t);
    State doSIBState(uint8_t);
    State doDisplacementState();
    State doImmediateState();

    //Process the actual opcode found earlier, using the supplied tables.
    State processOpcode(ByteTable &immTable, ByteTable &modrmTable,
                        bool addrSizedImm = false);
    // Process the opcode found with VEX / XOP prefix.
    State processExtendedOpcode(ByteTable &immTable);

  protected:
    /// Caching for decoded instruction objects.

    typedef RegVal CacheKey;

    typedef DecodeCache::AddrMap<Decoder::InstBytes> DecodePages;
    DecodePages *decodePages;
    typedef std::unordered_map<CacheKey, DecodePages *> AddrCacheMap;
    AddrCacheMap addrCacheMap;

    DecodeCache::InstMap<ExtMachInst> *instMap;
    typedef std::unordered_map<
            CacheKey, DecodeCache::InstMap<ExtMachInst> *> InstCacheMap;
    static InstCacheMap instCacheMap;

  public:
    Decoder(ISA* isa = nullptr) : basePC(0), origPC(0), offset(0),
        outOfBytes(true), instDone(false),
        state(ResetState)
    {
        emi.reset();
        mode = LongMode;
        submode = SixtyFourBitMode;
        emi.mode.mode = mode;
        emi.mode.submode = submode;
        altOp = 0;
        defOp = 0;
        altAddr = 0;
        defAddr = 0;
        stack = 0;
        instBytes = &dummy;
        decodePages = NULL;
        instMap = NULL;
    }

    void setM5Reg(HandyM5Reg m5Reg)
    {
        mode = (X86Mode)(uint64_t)m5Reg.mode;
        submode = (X86SubMode)(uint64_t)m5Reg.submode;
        emi.mode.mode = mode;
        emi.mode.submode = submode;
        altOp = m5Reg.altOp;
        defOp = m5Reg.defOp;
        altAddr = m5Reg.altAddr;
        defAddr = m5Reg.defAddr;
        stack = m5Reg.stack;

        AddrCacheMap::iterator amIter = addrCacheMap.find(m5Reg);
        if (amIter != addrCacheMap.end()) {
            decodePages = amIter->second;
        } else {
            decodePages = new DecodePages;
            addrCacheMap[m5Reg] = decodePages;
        }

        InstCacheMap::iterator imIter = instCacheMap.find(m5Reg);
        if (imIter != instCacheMap.end()) {
            instMap = imIter->second;
        } else {
            instMap = new DecodeCache::InstMap<ExtMachInst>;
            instCacheMap[m5Reg] = instMap;
        }
    }

    void takeOverFrom(Decoder *old)
    {
        mode = old->mode;
        submode = old->submode;
        emi.mode.mode = mode;
        emi.mode.submode = submode;
        altOp = old->altOp;
        defOp = old->defOp;
        altAddr = old->altAddr;
        defAddr = old->defAddr;
        stack = old->stack;
    }

    void reset()
    {
        state = ResetState;
    }

    void process();

    //Use this to give data to the decoder. This should be used
    //when there is control flow.
    void moreBytes(const PCState &pc, Addr fetchPC, MachInst data)
    {
        DPRINTF(Decoder, "Getting more bytes.\n");
        basePC = fetchPC;
        offset = (fetchPC >= pc.instAddr()) ? 0 : pc.instAddr() - fetchPC;
        fetchChunk = letoh(data);
        outOfBytes = false;
        process();
    }

    bool needMoreBytes()
    {
        return outOfBytes;
    }

    bool instReady()
    {
        return instDone;
    }

    void
    updateNPC(X86ISA::PCState &nextPC)
    {
        if (!nextPC.size()) {
            int size = basePC + offset - origPC;
            DPRINTF(Decoder,
                    "Calculating the instruction size: "
                    "basePC: %#x offset: %#x origPC: %#x size: %d\n",
                    basePC, offset, origPC, size);
            nextPC.size(size);
            nextPC.npc(nextPC.pc() + size);
        }
    }

  public:
    StaticInstPtr decodeInst(ExtMachInst mach_inst);

    /// Decode a machine instruction.
    /// @param mach_inst The binary instruction to decode.
    /// @retval A pointer to the corresponding StaticInst object.
    StaticInstPtr decode(ExtMachInst mach_inst, Addr addr);
    StaticInstPtr decode(X86ISA::PCState &nextPC);
};

} // namespace X86ISA

#endif // __ARCH_X86_DECODER_HH__
