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