/*
 * Copyright (c) 2007-2008 The Hewlett-Packard Development Company
 * All rights reserved.
 *
 * Redistribution and use of this software in source and binary forms,
 * with or without modification, are permitted provided that the
 * following conditions are met:
 *
 * The software must be used only for Non-Commercial Use which means any
 * use which is NOT directed to receiving any direct monetary
 * compensation for, or commercial advantage from such use.  Illustrative
 * examples of non-commercial use are academic research, personal study,
 * teaching, education and corporate research & development.
 * Illustrative examples of commercial use are distributing products for
 * commercial advantage and providing services using the software for
 * commercial advantage.
 *
 * If you wish to use this software or functionality therein that may be
 * covered by patents for commercial use, please contact:
 *     Director of Intellectual Property Licensing
 *     Office of Strategy and Technology
 *     Hewlett-Packard Company
 *     1501 Page Mill Road
 *     Palo Alto, California  94304
 *
 * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.  No right of
 * sublicense is granted herewith.  Derivatives of the software and
 * output created using the software may be prepared, but only for
 * Non-Commercial Uses.  Derivatives of the software may be shared with
 * others provided: (i) the others agree to abide by the list of
 * conditions herein which includes the Non-Commercial Use restrictions;
 * and (ii) such Derivatives of the software include the above copyright
 * notice to acknowledge the contribution from this software where
 * applicable, this list of conditions and the disclaimer below.
 *
 * 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.
 *
 * Authors: Gabe Black
 */

#include "arch/x86/miscregs.hh"
#include "arch/x86/predecoder.hh"
#include "base/misc.hh"
#include "base/trace.hh"
#include "base/types.hh"
#include "cpu/thread_context.hh"

namespace X86ISA
{
    void Predecoder::doReset()
    {
        origPC = basePC + offset;
        DPRINTF(Predecoder, "Setting origPC to %#x\n", origPC);
        emi.rex = 0;
        emi.legacy = 0;
        emi.opcode.num = 0;
        emi.opcode.op = 0;
        emi.opcode.prefixA = emi.opcode.prefixB = 0;

        immediateCollected = 0;
        emi.immediate = 0;
        emi.displacement = 0;
        emi.dispSize = 0;

        emi.modRM = 0;
        emi.sib = 0;
        m5Reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
        emi.mode.mode = m5Reg.mode;
        emi.mode.submode = m5Reg.submode;
    }

    void Predecoder::process()
    {
        //This function drives the predecoder state machine.

        //Some sanity checks. You shouldn't try to process more bytes if
        //there aren't any, and you shouldn't overwrite an already
        //predecoder ExtMachInst.
        assert(!outOfBytes);
        assert(!emiIsReady);

        //While there's still something to do...
        while(!emiIsReady && !outOfBytes)
        {
            uint8_t nextByte = getNextByte();
            switch(state)
            {
              case ResetState:
                doReset();
                state = PrefixState;
              case PrefixState:
                state = doPrefixState(nextByte);
                break;
              case OpcodeState:
                state = doOpcodeState(nextByte);
                break;
              case ModRMState:
                state = doModRMState(nextByte);
                break;
              case SIBState:
                state = doSIBState(nextByte);
                break;
              case DisplacementState:
                state = doDisplacementState();
                break;
              case ImmediateState:
                state = doImmediateState();
                break;
              case ErrorState:
                panic("Went to the error state in the predecoder.\n");
              default:
                panic("Unrecognized state! %d\n", state);
            }
        }
    }

    //Either get a prefix and record it in the ExtMachInst, or send the
    //state machine on to get the opcode(s).
    Predecoder::State Predecoder::doPrefixState(uint8_t nextByte)
    {
        uint8_t prefix = Prefixes[nextByte];
        State nextState = PrefixState;
        // REX prefixes are only recognized in 64 bit mode.
        if (prefix == RexPrefix && emi.mode.submode != SixtyFourBitMode)
            prefix = 0;
        if (prefix)
            consumeByte();
        switch(prefix)
        {
            //Operand size override prefixes
          case OperandSizeOverride:
            DPRINTF(Predecoder, "Found operand size override prefix.\n");
            emi.legacy.op = true;
            break;
          case AddressSizeOverride:
            DPRINTF(Predecoder, "Found address size override prefix.\n");
            emi.legacy.addr = true;
            break;
            //Segment override prefixes
          case CSOverride:
          case DSOverride:
          case ESOverride:
          case FSOverride:
          case GSOverride:
          case SSOverride:
            DPRINTF(Predecoder, "Found segment override.\n");
            emi.legacy.seg = prefix;
            break;
          case Lock:
            DPRINTF(Predecoder, "Found lock prefix.\n");
            emi.legacy.lock = true;
            break;
          case Rep:
            DPRINTF(Predecoder, "Found rep prefix.\n");
            emi.legacy.rep = true;
            break;
          case Repne:
            DPRINTF(Predecoder, "Found repne prefix.\n");
            emi.legacy.repne = true;
            break;
          case RexPrefix:
            DPRINTF(Predecoder, "Found Rex prefix %#x.\n", nextByte);
            emi.rex = nextByte;
            break;
          case 0:
            nextState = OpcodeState;
            break;
          default:
            panic("Unrecognized prefix %#x\n", nextByte);
        }
        return nextState;
    }

    //Load all the opcodes (currently up to 2) and then figure out
    //what immediate and/or ModRM is needed.
    Predecoder::State Predecoder::doOpcodeState(uint8_t nextByte)
    {
        State nextState = ErrorState;
        emi.opcode.num++;
        //We can't handle 3+ byte opcodes right now
        assert(emi.opcode.num < 4);
        consumeByte();
        if(emi.opcode.num == 1 && nextByte == 0x0f)
        {
            nextState = OpcodeState;
            DPRINTF(Predecoder, "Found two byte opcode.\n");
            emi.opcode.prefixA = nextByte;
        }
        else if(emi.opcode.num == 2 && (nextByte == 0x38 || nextByte == 0x3F))
        {
            nextState = OpcodeState;
            DPRINTF(Predecoder, "Found three byte opcode.\n");
            emi.opcode.prefixB = nextByte;
        }
        else
        {
            DPRINTF(Predecoder, "Found opcode %#x.\n", nextByte);
            emi.opcode.op = nextByte;

            //Figure out the effective operand size. This can be overriden to
            //a fixed value at the decoder level.
            int logOpSize;
            if (emi.rex.w)
                logOpSize = 3; // 64 bit operand size
            else if (emi.legacy.op)
                logOpSize = m5Reg.altOp;
            else
                logOpSize = m5Reg.defOp;

            //Set the actual op size
            emi.opSize = 1 << logOpSize;

            //Figure out the effective address size. This can be overriden to
            //a fixed value at the decoder level.
            int logAddrSize;
            if(emi.legacy.addr)
                logAddrSize = m5Reg.altAddr;
            else
                logAddrSize = m5Reg.defAddr;

            //Set the actual address size
            emi.addrSize = 1 << logAddrSize;

            //Figure out the effective stack width. This can be overriden to
            //a fixed value at the decoder level.
            emi.stackSize = 1 << m5Reg.stack;

            //Figure out how big of an immediate we'll retreive based
            //on the opcode.
            int immType = ImmediateType[emi.opcode.num - 1][nextByte];
            if (emi.opcode.num == 1 && nextByte >= 0xA0 && nextByte <= 0xA3)
                immediateSize = SizeTypeToSize[logAddrSize - 1][immType];
            else
                immediateSize = SizeTypeToSize[logOpSize - 1][immType];

            //Determine what to expect next
            if (UsesModRM[emi.opcode.num - 1][nextByte]) {
                nextState = ModRMState;
            } else {
                if(immediateSize) {
                    nextState = ImmediateState;
                } else {
                    emiIsReady = true;
                    nextState = ResetState;
                }
            }
        }
        return nextState;
    }

    //Get the ModRM byte and determine what displacement, if any, there is.
    //Also determine whether or not to get the SIB byte, displacement, or
    //immediate next.
    Predecoder::State Predecoder::doModRMState(uint8_t nextByte)
    {
        State nextState = ErrorState;
        ModRM modRM;
        modRM = nextByte;
        DPRINTF(Predecoder, "Found modrm byte %#x.\n", nextByte);
        if (m5Reg.defOp == 1) {
            //figure out 16 bit displacement size
            if ((modRM.mod == 0 && modRM.rm == 6) || modRM.mod == 2)
                displacementSize = 2;
            else if (modRM.mod == 1)
                displacementSize = 1;
            else
                displacementSize = 0;
        } else {
            //figure out 32/64 bit displacement size
            if ((modRM.mod == 0 && modRM.rm == 5) || modRM.mod == 2)
                displacementSize = 4;
            else if (modRM.mod == 1)
                displacementSize = 1;
            else
                displacementSize = 0;
        }

        // The "test" instruction in group 3 needs an immediate, even though
        // the other instructions with the same actual opcode don't.
        if (emi.opcode.num == 1 && (modRM.reg & 0x6) == 0) {
           if (emi.opcode.op == 0xF6)
               immediateSize = 1;
           else if (emi.opcode.op == 0xF7)
               immediateSize = (emi.opSize == 8) ? 4 : emi.opSize;
        }

        //If there's an SIB, get that next.
        //There is no SIB in 16 bit mode.
        if (modRM.rm == 4 && modRM.mod != 3) {
                // && in 32/64 bit mode)
            nextState = SIBState;
        } else if(displacementSize) {
            nextState = DisplacementState;
        } else if(immediateSize) {
            nextState = ImmediateState;
        } else {
            emiIsReady = true;
            nextState = ResetState;
        }
        //The ModRM byte is consumed no matter what
        consumeByte();
        emi.modRM = modRM;
        return nextState;
    }

    //Get the SIB byte. We don't do anything with it at this point, other
    //than storing it in the ExtMachInst. Determine if we need to get a
    //displacement or immediate next.
    Predecoder::State Predecoder::doSIBState(uint8_t nextByte)
    {
        State nextState = ErrorState;
        emi.sib = nextByte;
        DPRINTF(Predecoder, "Found SIB byte %#x.\n", nextByte);
        consumeByte();
        if (emi.modRM.mod == 0 && emi.sib.base == 5)
            displacementSize = 4;
        if (displacementSize) {
            nextState = DisplacementState;
        } else if(immediateSize) {
            nextState = ImmediateState;
        } else {
            emiIsReady = true;
            nextState = ResetState;
        }
        return nextState;
    }

    //Gather up the displacement, or at least as much of it
    //as we can get.
    Predecoder::State Predecoder::doDisplacementState()
    {
        State nextState = ErrorState;

        getImmediate(immediateCollected,
                emi.displacement,
                displacementSize);

        DPRINTF(Predecoder, "Collecting %d byte displacement, got %d bytes.\n",
                displacementSize, immediateCollected);

        if(displacementSize == immediateCollected) {
            //Reset this for other immediates.
            immediateCollected = 0;
            //Sign extend the displacement
            switch(displacementSize)
            {
              case 1:
                emi.displacement = sext<8>(emi.displacement);
                break;
              case 2:
                emi.displacement = sext<16>(emi.displacement);
                break;
              case 4:
                emi.displacement = sext<32>(emi.displacement);
                break;
              default:
                panic("Undefined displacement size!\n");
            }
            DPRINTF(Predecoder, "Collected displacement %#x.\n",
                    emi.displacement);
            if(immediateSize) {
                nextState = ImmediateState;
            } else {
                emiIsReady = true;
                nextState = ResetState;
            }

            emi.dispSize = displacementSize;
        }
        else
            nextState = DisplacementState;
        return nextState;
    }

    //Gather up the immediate, or at least as much of it
    //as we can get
    Predecoder::State Predecoder::doImmediateState()
    {
        State nextState = ErrorState;

        getImmediate(immediateCollected,
                emi.immediate,
                immediateSize);

        DPRINTF(Predecoder, "Collecting %d byte immediate, got %d bytes.\n",
                immediateSize, immediateCollected);

        if(immediateSize == immediateCollected)
        {
            //Reset this for other immediates.
            immediateCollected = 0;

            //XXX Warning! The following is an observed pattern and might
            //not always be true!

            //Instructions which use 64 bit operands but 32 bit immediates
            //need to have the immediate sign extended to 64 bits.
            //Instructions which use true 64 bit immediates won't be
            //affected, and instructions that use true 32 bit immediates
            //won't notice.
            switch(immediateSize)
            {
              case 4:
                emi.immediate = sext<32>(emi.immediate);
                break;
              case 1:
                emi.immediate = sext<8>(emi.immediate);
            }

            DPRINTF(Predecoder, "Collected immediate %#x.\n",
                    emi.immediate);
            emiIsReady = true;
            nextState = ResetState;
        }
        else
            nextState = ImmediateState;
        return nextState;
    }
}
