/*
 * 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/generic/decoder.hh"
#include "arch/x86/microcode_rom.hh"
#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"
#include "params/X86Decoder.hh"

namespace gem5
{

namespace X86ISA
{

class ISA;
class Decoder : public InstDecoder
{
  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];

    static X86ISAInst::MicrocodeRom microcodeRom;

  protected:
    using MachInst = uint64_t;

    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 = &dummy;
    int chunkIdx;
    // The pc of the start of fetchChunk.
    Addr basePC = 0;
    // The pc the current instruction started at.
    Addr origPC = 0;
    // The offset into fetchChunk of current processing.
    int offset = 0;
    // The extended machine instruction being generated.
    ExtMachInst emi;
    // Predecoding state.
    X86Mode mode = LongMode;
    X86SubMode submode = SixtyFourBitMode;
    uint8_t altOp = 0;
    uint8_t defOp = 0;
    uint8_t altAddr = 0;
    uint8_t defAddr = 0;
    uint8_t stack = 0;

    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:
    // 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 = ResetState;

    // 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 decode_cache::AddrMap<Decoder::InstBytes> DecodePages;
    DecodePages *decodePages = nullptr;
    typedef std::unordered_map<CacheKey, DecodePages *> AddrCacheMap;
    AddrCacheMap addrCacheMap;

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

    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);

    void process();

  public:
    Decoder(const X86DecoderParams &p) : InstDecoder(p, &fetchChunk)
    {
        emi.reset();
        emi.mode.mode = mode;
        emi.mode.submode = submode;
    }

    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 decode_cache::InstMap<ExtMachInst>;
            instCacheMap[m5Reg] = instMap;
        }
    }

    void
    takeOverFrom(InstDecoder *old) override
    {
        InstDecoder::takeOverFrom(old);

        Decoder *dec = dynamic_cast<Decoder *>(old);
        assert(dec);

        mode = dec->mode;
        submode = dec->submode;
        emi.mode.mode = mode;
        emi.mode.submode = submode;
        altOp = dec->altOp;
        defOp = dec->defOp;
        altAddr = dec->altAddr;
        defAddr = dec->defAddr;
        stack = dec->stack;
    }

    void
    reset() override
    {
        InstDecoder::reset();
        state = ResetState;
    }

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

    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 decode(PCStateBase &next_pc) override;

    StaticInstPtr fetchRomMicroop(
            MicroPC micropc, StaticInstPtr curMacroop) override;
};

} // namespace X86ISA
} // namespace gem5

#endif // __ARCH_X86_DECODER_HH__
