decoder.cc revision 9023
19022Sgblack@eecs.umich.edu/*
29022Sgblack@eecs.umich.edu * Copyright (c) 2011 Google
39022Sgblack@eecs.umich.edu * All rights reserved.
49022Sgblack@eecs.umich.edu *
59022Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
69022Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
79022Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
89022Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
99022Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
109022Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
119022Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
129022Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
139022Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
149022Sgblack@eecs.umich.edu * this software without specific prior written permission.
159022Sgblack@eecs.umich.edu *
169022Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
179022Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
189022Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
199022Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
209022Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
219022Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
229022Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
239022Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
249022Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
259022Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
269022Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
279022Sgblack@eecs.umich.edu *
289022Sgblack@eecs.umich.edu * Authors: Gabe Black
299022Sgblack@eecs.umich.edu */
309022Sgblack@eecs.umich.edu
319022Sgblack@eecs.umich.edu#include "arch/x86/decoder.hh"
329023Sgblack@eecs.umich.edu#include "arch/x86/regs/misc.hh"
339023Sgblack@eecs.umich.edu#include "base/misc.hh"
349023Sgblack@eecs.umich.edu#include "base/trace.hh"
359023Sgblack@eecs.umich.edu#include "base/types.hh"
369023Sgblack@eecs.umich.edu#include "cpu/thread_context.hh"
379023Sgblack@eecs.umich.edu#include "debug/Decoder.hh"
389022Sgblack@eecs.umich.edu
399022Sgblack@eecs.umich.edunamespace X86ISA
409022Sgblack@eecs.umich.edu{
419023Sgblack@eecs.umich.eduvoid Decoder::doReset()
429023Sgblack@eecs.umich.edu{
439023Sgblack@eecs.umich.edu    origPC = basePC + offset;
449023Sgblack@eecs.umich.edu    DPRINTF(Decoder, "Setting origPC to %#x\n", origPC);
459023Sgblack@eecs.umich.edu    emi.rex = 0;
469023Sgblack@eecs.umich.edu    emi.legacy = 0;
479023Sgblack@eecs.umich.edu    emi.opcode.num = 0;
489023Sgblack@eecs.umich.edu    emi.opcode.op = 0;
499023Sgblack@eecs.umich.edu    emi.opcode.prefixA = emi.opcode.prefixB = 0;
509023Sgblack@eecs.umich.edu
519023Sgblack@eecs.umich.edu    immediateCollected = 0;
529023Sgblack@eecs.umich.edu    emi.immediate = 0;
539023Sgblack@eecs.umich.edu    emi.displacement = 0;
549023Sgblack@eecs.umich.edu    emi.dispSize = 0;
559023Sgblack@eecs.umich.edu
569023Sgblack@eecs.umich.edu    emi.modRM = 0;
579023Sgblack@eecs.umich.edu    emi.sib = 0;
589023Sgblack@eecs.umich.edu    m5Reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
599023Sgblack@eecs.umich.edu    emi.mode.mode = m5Reg.mode;
609023Sgblack@eecs.umich.edu    emi.mode.submode = m5Reg.submode;
619023Sgblack@eecs.umich.edu}
629023Sgblack@eecs.umich.edu
639023Sgblack@eecs.umich.eduvoid Decoder::process()
649023Sgblack@eecs.umich.edu{
659023Sgblack@eecs.umich.edu    //This function drives the decoder state machine.
669023Sgblack@eecs.umich.edu
679023Sgblack@eecs.umich.edu    //Some sanity checks. You shouldn't try to process more bytes if
689023Sgblack@eecs.umich.edu    //there aren't any, and you shouldn't overwrite an already
699023Sgblack@eecs.umich.edu    //decoder ExtMachInst.
709023Sgblack@eecs.umich.edu    assert(!outOfBytes);
719023Sgblack@eecs.umich.edu    assert(!instDone);
729023Sgblack@eecs.umich.edu
739023Sgblack@eecs.umich.edu    //While there's still something to do...
749023Sgblack@eecs.umich.edu    while(!instDone && !outOfBytes)
759023Sgblack@eecs.umich.edu    {
769023Sgblack@eecs.umich.edu        uint8_t nextByte = getNextByte();
779023Sgblack@eecs.umich.edu        switch(state)
789023Sgblack@eecs.umich.edu        {
799023Sgblack@eecs.umich.edu          case ResetState:
809023Sgblack@eecs.umich.edu            doReset();
819023Sgblack@eecs.umich.edu            state = PrefixState;
829023Sgblack@eecs.umich.edu          case PrefixState:
839023Sgblack@eecs.umich.edu            state = doPrefixState(nextByte);
849023Sgblack@eecs.umich.edu            break;
859023Sgblack@eecs.umich.edu          case OpcodeState:
869023Sgblack@eecs.umich.edu            state = doOpcodeState(nextByte);
879023Sgblack@eecs.umich.edu            break;
889023Sgblack@eecs.umich.edu          case ModRMState:
899023Sgblack@eecs.umich.edu            state = doModRMState(nextByte);
909023Sgblack@eecs.umich.edu            break;
919023Sgblack@eecs.umich.edu          case SIBState:
929023Sgblack@eecs.umich.edu            state = doSIBState(nextByte);
939023Sgblack@eecs.umich.edu            break;
949023Sgblack@eecs.umich.edu          case DisplacementState:
959023Sgblack@eecs.umich.edu            state = doDisplacementState();
969023Sgblack@eecs.umich.edu            break;
979023Sgblack@eecs.umich.edu          case ImmediateState:
989023Sgblack@eecs.umich.edu            state = doImmediateState();
999023Sgblack@eecs.umich.edu            break;
1009023Sgblack@eecs.umich.edu          case ErrorState:
1019023Sgblack@eecs.umich.edu            panic("Went to the error state in the decoder.\n");
1029023Sgblack@eecs.umich.edu          default:
1039023Sgblack@eecs.umich.edu            panic("Unrecognized state! %d\n", state);
1049023Sgblack@eecs.umich.edu        }
1059023Sgblack@eecs.umich.edu    }
1069023Sgblack@eecs.umich.edu}
1079023Sgblack@eecs.umich.edu
1089023Sgblack@eecs.umich.edu//Either get a prefix and record it in the ExtMachInst, or send the
1099023Sgblack@eecs.umich.edu//state machine on to get the opcode(s).
1109023Sgblack@eecs.umich.eduDecoder::State Decoder::doPrefixState(uint8_t nextByte)
1119023Sgblack@eecs.umich.edu{
1129023Sgblack@eecs.umich.edu    uint8_t prefix = Prefixes[nextByte];
1139023Sgblack@eecs.umich.edu    State nextState = PrefixState;
1149023Sgblack@eecs.umich.edu    // REX prefixes are only recognized in 64 bit mode.
1159023Sgblack@eecs.umich.edu    if (prefix == RexPrefix && emi.mode.submode != SixtyFourBitMode)
1169023Sgblack@eecs.umich.edu        prefix = 0;
1179023Sgblack@eecs.umich.edu    if (prefix)
1189023Sgblack@eecs.umich.edu        consumeByte();
1199023Sgblack@eecs.umich.edu    switch(prefix)
1209023Sgblack@eecs.umich.edu    {
1219023Sgblack@eecs.umich.edu        //Operand size override prefixes
1229023Sgblack@eecs.umich.edu      case OperandSizeOverride:
1239023Sgblack@eecs.umich.edu        DPRINTF(Decoder, "Found operand size override prefix.\n");
1249023Sgblack@eecs.umich.edu        emi.legacy.op = true;
1259023Sgblack@eecs.umich.edu        break;
1269023Sgblack@eecs.umich.edu      case AddressSizeOverride:
1279023Sgblack@eecs.umich.edu        DPRINTF(Decoder, "Found address size override prefix.\n");
1289023Sgblack@eecs.umich.edu        emi.legacy.addr = true;
1299023Sgblack@eecs.umich.edu        break;
1309023Sgblack@eecs.umich.edu        //Segment override prefixes
1319023Sgblack@eecs.umich.edu      case CSOverride:
1329023Sgblack@eecs.umich.edu      case DSOverride:
1339023Sgblack@eecs.umich.edu      case ESOverride:
1349023Sgblack@eecs.umich.edu      case FSOverride:
1359023Sgblack@eecs.umich.edu      case GSOverride:
1369023Sgblack@eecs.umich.edu      case SSOverride:
1379023Sgblack@eecs.umich.edu        DPRINTF(Decoder, "Found segment override.\n");
1389023Sgblack@eecs.umich.edu        emi.legacy.seg = prefix;
1399023Sgblack@eecs.umich.edu        break;
1409023Sgblack@eecs.umich.edu      case Lock:
1419023Sgblack@eecs.umich.edu        DPRINTF(Decoder, "Found lock prefix.\n");
1429023Sgblack@eecs.umich.edu        emi.legacy.lock = true;
1439023Sgblack@eecs.umich.edu        break;
1449023Sgblack@eecs.umich.edu      case Rep:
1459023Sgblack@eecs.umich.edu        DPRINTF(Decoder, "Found rep prefix.\n");
1469023Sgblack@eecs.umich.edu        emi.legacy.rep = true;
1479023Sgblack@eecs.umich.edu        break;
1489023Sgblack@eecs.umich.edu      case Repne:
1499023Sgblack@eecs.umich.edu        DPRINTF(Decoder, "Found repne prefix.\n");
1509023Sgblack@eecs.umich.edu        emi.legacy.repne = true;
1519023Sgblack@eecs.umich.edu        break;
1529023Sgblack@eecs.umich.edu      case RexPrefix:
1539023Sgblack@eecs.umich.edu        DPRINTF(Decoder, "Found Rex prefix %#x.\n", nextByte);
1549023Sgblack@eecs.umich.edu        emi.rex = nextByte;
1559023Sgblack@eecs.umich.edu        break;
1569023Sgblack@eecs.umich.edu      case 0:
1579023Sgblack@eecs.umich.edu        nextState = OpcodeState;
1589023Sgblack@eecs.umich.edu        break;
1599023Sgblack@eecs.umich.edu      default:
1609023Sgblack@eecs.umich.edu        panic("Unrecognized prefix %#x\n", nextByte);
1619023Sgblack@eecs.umich.edu    }
1629023Sgblack@eecs.umich.edu    return nextState;
1639023Sgblack@eecs.umich.edu}
1649023Sgblack@eecs.umich.edu
1659023Sgblack@eecs.umich.edu//Load all the opcodes (currently up to 2) and then figure out
1669023Sgblack@eecs.umich.edu//what immediate and/or ModRM is needed.
1679023Sgblack@eecs.umich.eduDecoder::State Decoder::doOpcodeState(uint8_t nextByte)
1689023Sgblack@eecs.umich.edu{
1699023Sgblack@eecs.umich.edu    State nextState = ErrorState;
1709023Sgblack@eecs.umich.edu    emi.opcode.num++;
1719023Sgblack@eecs.umich.edu    //We can't handle 3+ byte opcodes right now
1729023Sgblack@eecs.umich.edu    assert(emi.opcode.num < 4);
1739023Sgblack@eecs.umich.edu    consumeByte();
1749023Sgblack@eecs.umich.edu    if(emi.opcode.num == 1 && nextByte == 0x0f)
1759023Sgblack@eecs.umich.edu    {
1769023Sgblack@eecs.umich.edu        nextState = OpcodeState;
1779023Sgblack@eecs.umich.edu        DPRINTF(Decoder, "Found two byte opcode.\n");
1789023Sgblack@eecs.umich.edu        emi.opcode.prefixA = nextByte;
1799023Sgblack@eecs.umich.edu    }
1809023Sgblack@eecs.umich.edu    else if(emi.opcode.num == 2 && (nextByte == 0x38 || nextByte == 0x3A))
1819023Sgblack@eecs.umich.edu    {
1829023Sgblack@eecs.umich.edu        nextState = OpcodeState;
1839023Sgblack@eecs.umich.edu        DPRINTF(Decoder, "Found three byte opcode.\n");
1849023Sgblack@eecs.umich.edu        emi.opcode.prefixB = nextByte;
1859023Sgblack@eecs.umich.edu    }
1869023Sgblack@eecs.umich.edu    else
1879023Sgblack@eecs.umich.edu    {
1889023Sgblack@eecs.umich.edu        DPRINTF(Decoder, "Found opcode %#x.\n", nextByte);
1899023Sgblack@eecs.umich.edu        emi.opcode.op = nextByte;
1909023Sgblack@eecs.umich.edu
1919023Sgblack@eecs.umich.edu        //Figure out the effective operand size. This can be overriden to
1929023Sgblack@eecs.umich.edu        //a fixed value at the decoder level.
1939023Sgblack@eecs.umich.edu        int logOpSize;
1949023Sgblack@eecs.umich.edu        if (emi.rex.w)
1959023Sgblack@eecs.umich.edu            logOpSize = 3; // 64 bit operand size
1969023Sgblack@eecs.umich.edu        else if (emi.legacy.op)
1979023Sgblack@eecs.umich.edu            logOpSize = m5Reg.altOp;
1989023Sgblack@eecs.umich.edu        else
1999023Sgblack@eecs.umich.edu            logOpSize = m5Reg.defOp;
2009023Sgblack@eecs.umich.edu
2019023Sgblack@eecs.umich.edu        //Set the actual op size
2029023Sgblack@eecs.umich.edu        emi.opSize = 1 << logOpSize;
2039023Sgblack@eecs.umich.edu
2049023Sgblack@eecs.umich.edu        //Figure out the effective address size. This can be overriden to
2059023Sgblack@eecs.umich.edu        //a fixed value at the decoder level.
2069023Sgblack@eecs.umich.edu        int logAddrSize;
2079023Sgblack@eecs.umich.edu        if(emi.legacy.addr)
2089023Sgblack@eecs.umich.edu            logAddrSize = m5Reg.altAddr;
2099023Sgblack@eecs.umich.edu        else
2109023Sgblack@eecs.umich.edu            logAddrSize = m5Reg.defAddr;
2119023Sgblack@eecs.umich.edu
2129023Sgblack@eecs.umich.edu        //Set the actual address size
2139023Sgblack@eecs.umich.edu        emi.addrSize = 1 << logAddrSize;
2149023Sgblack@eecs.umich.edu
2159023Sgblack@eecs.umich.edu        //Figure out the effective stack width. This can be overriden to
2169023Sgblack@eecs.umich.edu        //a fixed value at the decoder level.
2179023Sgblack@eecs.umich.edu        emi.stackSize = 1 << m5Reg.stack;
2189023Sgblack@eecs.umich.edu
2199023Sgblack@eecs.umich.edu        //Figure out how big of an immediate we'll retreive based
2209023Sgblack@eecs.umich.edu        //on the opcode.
2219023Sgblack@eecs.umich.edu        int immType = ImmediateType[emi.opcode.num - 1][nextByte];
2229023Sgblack@eecs.umich.edu        if (emi.opcode.num == 1 && nextByte >= 0xA0 && nextByte <= 0xA3)
2239023Sgblack@eecs.umich.edu            immediateSize = SizeTypeToSize[logAddrSize - 1][immType];
2249023Sgblack@eecs.umich.edu        else
2259023Sgblack@eecs.umich.edu            immediateSize = SizeTypeToSize[logOpSize - 1][immType];
2269023Sgblack@eecs.umich.edu
2279023Sgblack@eecs.umich.edu        //Determine what to expect next
2289023Sgblack@eecs.umich.edu        if (UsesModRM[emi.opcode.num - 1][nextByte]) {
2299023Sgblack@eecs.umich.edu            nextState = ModRMState;
2309023Sgblack@eecs.umich.edu        } else {
2319023Sgblack@eecs.umich.edu            if(immediateSize) {
2329023Sgblack@eecs.umich.edu                nextState = ImmediateState;
2339023Sgblack@eecs.umich.edu            } else {
2349023Sgblack@eecs.umich.edu                instDone = true;
2359023Sgblack@eecs.umich.edu                nextState = ResetState;
2369023Sgblack@eecs.umich.edu            }
2379023Sgblack@eecs.umich.edu        }
2389023Sgblack@eecs.umich.edu    }
2399023Sgblack@eecs.umich.edu    return nextState;
2409023Sgblack@eecs.umich.edu}
2419023Sgblack@eecs.umich.edu
2429023Sgblack@eecs.umich.edu//Get the ModRM byte and determine what displacement, if any, there is.
2439023Sgblack@eecs.umich.edu//Also determine whether or not to get the SIB byte, displacement, or
2449023Sgblack@eecs.umich.edu//immediate next.
2459023Sgblack@eecs.umich.eduDecoder::State Decoder::doModRMState(uint8_t nextByte)
2469023Sgblack@eecs.umich.edu{
2479023Sgblack@eecs.umich.edu    State nextState = ErrorState;
2489023Sgblack@eecs.umich.edu    ModRM modRM;
2499023Sgblack@eecs.umich.edu    modRM = nextByte;
2509023Sgblack@eecs.umich.edu    DPRINTF(Decoder, "Found modrm byte %#x.\n", nextByte);
2519023Sgblack@eecs.umich.edu    if (m5Reg.defOp == 1) {
2529023Sgblack@eecs.umich.edu        //figure out 16 bit displacement size
2539023Sgblack@eecs.umich.edu        if ((modRM.mod == 0 && modRM.rm == 6) || modRM.mod == 2)
2549023Sgblack@eecs.umich.edu            displacementSize = 2;
2559023Sgblack@eecs.umich.edu        else if (modRM.mod == 1)
2569023Sgblack@eecs.umich.edu            displacementSize = 1;
2579023Sgblack@eecs.umich.edu        else
2589023Sgblack@eecs.umich.edu            displacementSize = 0;
2599023Sgblack@eecs.umich.edu    } else {
2609023Sgblack@eecs.umich.edu        //figure out 32/64 bit displacement size
2619023Sgblack@eecs.umich.edu        if ((modRM.mod == 0 && modRM.rm == 5) || modRM.mod == 2)
2629023Sgblack@eecs.umich.edu            displacementSize = 4;
2639023Sgblack@eecs.umich.edu        else if (modRM.mod == 1)
2649023Sgblack@eecs.umich.edu            displacementSize = 1;
2659023Sgblack@eecs.umich.edu        else
2669023Sgblack@eecs.umich.edu            displacementSize = 0;
2679023Sgblack@eecs.umich.edu    }
2689023Sgblack@eecs.umich.edu
2699023Sgblack@eecs.umich.edu    // The "test" instruction in group 3 needs an immediate, even though
2709023Sgblack@eecs.umich.edu    // the other instructions with the same actual opcode don't.
2719023Sgblack@eecs.umich.edu    if (emi.opcode.num == 1 && (modRM.reg & 0x6) == 0) {
2729023Sgblack@eecs.umich.edu       if (emi.opcode.op == 0xF6)
2739023Sgblack@eecs.umich.edu           immediateSize = 1;
2749023Sgblack@eecs.umich.edu       else if (emi.opcode.op == 0xF7)
2759023Sgblack@eecs.umich.edu           immediateSize = (emi.opSize == 8) ? 4 : emi.opSize;
2769023Sgblack@eecs.umich.edu    }
2779023Sgblack@eecs.umich.edu
2789023Sgblack@eecs.umich.edu    //If there's an SIB, get that next.
2799023Sgblack@eecs.umich.edu    //There is no SIB in 16 bit mode.
2809023Sgblack@eecs.umich.edu    if (modRM.rm == 4 && modRM.mod != 3) {
2819023Sgblack@eecs.umich.edu            // && in 32/64 bit mode)
2829023Sgblack@eecs.umich.edu        nextState = SIBState;
2839023Sgblack@eecs.umich.edu    } else if(displacementSize) {
2849023Sgblack@eecs.umich.edu        nextState = DisplacementState;
2859023Sgblack@eecs.umich.edu    } else if(immediateSize) {
2869023Sgblack@eecs.umich.edu        nextState = ImmediateState;
2879023Sgblack@eecs.umich.edu    } else {
2889023Sgblack@eecs.umich.edu        instDone = true;
2899023Sgblack@eecs.umich.edu        nextState = ResetState;
2909023Sgblack@eecs.umich.edu    }
2919023Sgblack@eecs.umich.edu    //The ModRM byte is consumed no matter what
2929023Sgblack@eecs.umich.edu    consumeByte();
2939023Sgblack@eecs.umich.edu    emi.modRM = modRM;
2949023Sgblack@eecs.umich.edu    return nextState;
2959023Sgblack@eecs.umich.edu}
2969023Sgblack@eecs.umich.edu
2979023Sgblack@eecs.umich.edu//Get the SIB byte. We don't do anything with it at this point, other
2989023Sgblack@eecs.umich.edu//than storing it in the ExtMachInst. Determine if we need to get a
2999023Sgblack@eecs.umich.edu//displacement or immediate next.
3009023Sgblack@eecs.umich.eduDecoder::State Decoder::doSIBState(uint8_t nextByte)
3019023Sgblack@eecs.umich.edu{
3029023Sgblack@eecs.umich.edu    State nextState = ErrorState;
3039023Sgblack@eecs.umich.edu    emi.sib = nextByte;
3049023Sgblack@eecs.umich.edu    DPRINTF(Decoder, "Found SIB byte %#x.\n", nextByte);
3059023Sgblack@eecs.umich.edu    consumeByte();
3069023Sgblack@eecs.umich.edu    if (emi.modRM.mod == 0 && emi.sib.base == 5)
3079023Sgblack@eecs.umich.edu        displacementSize = 4;
3089023Sgblack@eecs.umich.edu    if (displacementSize) {
3099023Sgblack@eecs.umich.edu        nextState = DisplacementState;
3109023Sgblack@eecs.umich.edu    } else if(immediateSize) {
3119023Sgblack@eecs.umich.edu        nextState = ImmediateState;
3129023Sgblack@eecs.umich.edu    } else {
3139023Sgblack@eecs.umich.edu        instDone = true;
3149023Sgblack@eecs.umich.edu        nextState = ResetState;
3159023Sgblack@eecs.umich.edu    }
3169023Sgblack@eecs.umich.edu    return nextState;
3179023Sgblack@eecs.umich.edu}
3189023Sgblack@eecs.umich.edu
3199023Sgblack@eecs.umich.edu//Gather up the displacement, or at least as much of it
3209023Sgblack@eecs.umich.edu//as we can get.
3219023Sgblack@eecs.umich.eduDecoder::State Decoder::doDisplacementState()
3229023Sgblack@eecs.umich.edu{
3239023Sgblack@eecs.umich.edu    State nextState = ErrorState;
3249023Sgblack@eecs.umich.edu
3259023Sgblack@eecs.umich.edu    getImmediate(immediateCollected,
3269023Sgblack@eecs.umich.edu            emi.displacement,
3279023Sgblack@eecs.umich.edu            displacementSize);
3289023Sgblack@eecs.umich.edu
3299023Sgblack@eecs.umich.edu    DPRINTF(Decoder, "Collecting %d byte displacement, got %d bytes.\n",
3309023Sgblack@eecs.umich.edu            displacementSize, immediateCollected);
3319023Sgblack@eecs.umich.edu
3329023Sgblack@eecs.umich.edu    if(displacementSize == immediateCollected) {
3339023Sgblack@eecs.umich.edu        //Reset this for other immediates.
3349023Sgblack@eecs.umich.edu        immediateCollected = 0;
3359023Sgblack@eecs.umich.edu        //Sign extend the displacement
3369023Sgblack@eecs.umich.edu        switch(displacementSize)
3379023Sgblack@eecs.umich.edu        {
3389023Sgblack@eecs.umich.edu          case 1:
3399023Sgblack@eecs.umich.edu            emi.displacement = sext<8>(emi.displacement);
3409023Sgblack@eecs.umich.edu            break;
3419023Sgblack@eecs.umich.edu          case 2:
3429023Sgblack@eecs.umich.edu            emi.displacement = sext<16>(emi.displacement);
3439023Sgblack@eecs.umich.edu            break;
3449023Sgblack@eecs.umich.edu          case 4:
3459023Sgblack@eecs.umich.edu            emi.displacement = sext<32>(emi.displacement);
3469023Sgblack@eecs.umich.edu            break;
3479023Sgblack@eecs.umich.edu          default:
3489023Sgblack@eecs.umich.edu            panic("Undefined displacement size!\n");
3499023Sgblack@eecs.umich.edu        }
3509023Sgblack@eecs.umich.edu        DPRINTF(Decoder, "Collected displacement %#x.\n",
3519023Sgblack@eecs.umich.edu                emi.displacement);
3529023Sgblack@eecs.umich.edu        if(immediateSize) {
3539023Sgblack@eecs.umich.edu            nextState = ImmediateState;
3549023Sgblack@eecs.umich.edu        } else {
3559023Sgblack@eecs.umich.edu            instDone = true;
3569023Sgblack@eecs.umich.edu            nextState = ResetState;
3579023Sgblack@eecs.umich.edu        }
3589023Sgblack@eecs.umich.edu
3599023Sgblack@eecs.umich.edu        emi.dispSize = displacementSize;
3609023Sgblack@eecs.umich.edu    }
3619023Sgblack@eecs.umich.edu    else
3629023Sgblack@eecs.umich.edu        nextState = DisplacementState;
3639023Sgblack@eecs.umich.edu    return nextState;
3649023Sgblack@eecs.umich.edu}
3659023Sgblack@eecs.umich.edu
3669023Sgblack@eecs.umich.edu//Gather up the immediate, or at least as much of it
3679023Sgblack@eecs.umich.edu//as we can get
3689023Sgblack@eecs.umich.eduDecoder::State Decoder::doImmediateState()
3699023Sgblack@eecs.umich.edu{
3709023Sgblack@eecs.umich.edu    State nextState = ErrorState;
3719023Sgblack@eecs.umich.edu
3729023Sgblack@eecs.umich.edu    getImmediate(immediateCollected,
3739023Sgblack@eecs.umich.edu            emi.immediate,
3749023Sgblack@eecs.umich.edu            immediateSize);
3759023Sgblack@eecs.umich.edu
3769023Sgblack@eecs.umich.edu    DPRINTF(Decoder, "Collecting %d byte immediate, got %d bytes.\n",
3779023Sgblack@eecs.umich.edu            immediateSize, immediateCollected);
3789023Sgblack@eecs.umich.edu
3799023Sgblack@eecs.umich.edu    if(immediateSize == immediateCollected)
3809023Sgblack@eecs.umich.edu    {
3819023Sgblack@eecs.umich.edu        //Reset this for other immediates.
3829023Sgblack@eecs.umich.edu        immediateCollected = 0;
3839023Sgblack@eecs.umich.edu
3849023Sgblack@eecs.umich.edu        //XXX Warning! The following is an observed pattern and might
3859023Sgblack@eecs.umich.edu        //not always be true!
3869023Sgblack@eecs.umich.edu
3879023Sgblack@eecs.umich.edu        //Instructions which use 64 bit operands but 32 bit immediates
3889023Sgblack@eecs.umich.edu        //need to have the immediate sign extended to 64 bits.
3899023Sgblack@eecs.umich.edu        //Instructions which use true 64 bit immediates won't be
3909023Sgblack@eecs.umich.edu        //affected, and instructions that use true 32 bit immediates
3919023Sgblack@eecs.umich.edu        //won't notice.
3929023Sgblack@eecs.umich.edu        switch(immediateSize)
3939023Sgblack@eecs.umich.edu        {
3949023Sgblack@eecs.umich.edu          case 4:
3959023Sgblack@eecs.umich.edu            emi.immediate = sext<32>(emi.immediate);
3969023Sgblack@eecs.umich.edu            break;
3979023Sgblack@eecs.umich.edu          case 1:
3989023Sgblack@eecs.umich.edu            emi.immediate = sext<8>(emi.immediate);
3999023Sgblack@eecs.umich.edu        }
4009023Sgblack@eecs.umich.edu
4019023Sgblack@eecs.umich.edu        DPRINTF(Decoder, "Collected immediate %#x.\n",
4029023Sgblack@eecs.umich.edu                emi.immediate);
4039023Sgblack@eecs.umich.edu        instDone = true;
4049023Sgblack@eecs.umich.edu        nextState = ResetState;
4059023Sgblack@eecs.umich.edu    }
4069023Sgblack@eecs.umich.edu    else
4079023Sgblack@eecs.umich.edu        nextState = ImmediateState;
4089023Sgblack@eecs.umich.edu    return nextState;
4099023Sgblack@eecs.umich.edu}
4109022Sgblack@eecs.umich.edu
4119022Sgblack@eecs.umich.eduDecodeCache Decoder::defaultCache;
4129022Sgblack@eecs.umich.edu
4139022Sgblack@eecs.umich.edu}
414