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" 3211793Sbrandon.potter@amd.com 339023Sgblack@eecs.umich.edu#include "arch/x86/regs/misc.hh" 3412334Sgabeblack@google.com#include "base/logging.hh" 359023Sgblack@eecs.umich.edu#include "base/trace.hh" 369023Sgblack@eecs.umich.edu#include "base/types.hh" 379023Sgblack@eecs.umich.edu#include "debug/Decoder.hh" 389022Sgblack@eecs.umich.edu 399022Sgblack@eecs.umich.edunamespace X86ISA 409022Sgblack@eecs.umich.edu{ 419376Sgblack@eecs.umich.edu 429376Sgblack@eecs.umich.eduDecoder::State 439376Sgblack@eecs.umich.eduDecoder::doResetState() 449023Sgblack@eecs.umich.edu{ 459023Sgblack@eecs.umich.edu origPC = basePC + offset; 469023Sgblack@eecs.umich.edu DPRINTF(Decoder, "Setting origPC to %#x\n", origPC); 479376Sgblack@eecs.umich.edu instBytes = &decodePages->lookup(origPC); 489376Sgblack@eecs.umich.edu chunkIdx = 0; 499376Sgblack@eecs.umich.edu 509023Sgblack@eecs.umich.edu emi.rex = 0; 519023Sgblack@eecs.umich.edu emi.legacy = 0; 5210924Snilay@cs.wisc.edu emi.vex = 0; 5310924Snilay@cs.wisc.edu 5410593Sgabeblack@google.com emi.opcode.type = BadOpcode; 559023Sgblack@eecs.umich.edu emi.opcode.op = 0; 569023Sgblack@eecs.umich.edu 579023Sgblack@eecs.umich.edu immediateCollected = 0; 589023Sgblack@eecs.umich.edu emi.immediate = 0; 599023Sgblack@eecs.umich.edu emi.displacement = 0; 609023Sgblack@eecs.umich.edu emi.dispSize = 0; 619023Sgblack@eecs.umich.edu 629023Sgblack@eecs.umich.edu emi.modRM = 0; 639023Sgblack@eecs.umich.edu emi.sib = 0; 649376Sgblack@eecs.umich.edu 659376Sgblack@eecs.umich.edu if (instBytes->si) { 669376Sgblack@eecs.umich.edu return FromCacheState; 679376Sgblack@eecs.umich.edu } else { 689376Sgblack@eecs.umich.edu instBytes->chunks.clear(); 699376Sgblack@eecs.umich.edu return PrefixState; 709376Sgblack@eecs.umich.edu } 719023Sgblack@eecs.umich.edu} 729023Sgblack@eecs.umich.edu 739376Sgblack@eecs.umich.eduvoid 749376Sgblack@eecs.umich.eduDecoder::process() 759023Sgblack@eecs.umich.edu{ 769023Sgblack@eecs.umich.edu //This function drives the decoder state machine. 779023Sgblack@eecs.umich.edu 789023Sgblack@eecs.umich.edu //Some sanity checks. You shouldn't try to process more bytes if 799023Sgblack@eecs.umich.edu //there aren't any, and you shouldn't overwrite an already 809023Sgblack@eecs.umich.edu //decoder ExtMachInst. 819023Sgblack@eecs.umich.edu assert(!outOfBytes); 829023Sgblack@eecs.umich.edu assert(!instDone); 839023Sgblack@eecs.umich.edu 849376Sgblack@eecs.umich.edu if (state == ResetState) 859376Sgblack@eecs.umich.edu state = doResetState(); 869376Sgblack@eecs.umich.edu if (state == FromCacheState) { 879376Sgblack@eecs.umich.edu state = doFromCacheState(); 889376Sgblack@eecs.umich.edu } else { 899376Sgblack@eecs.umich.edu instBytes->chunks.push_back(fetchChunk); 909376Sgblack@eecs.umich.edu } 919376Sgblack@eecs.umich.edu 929023Sgblack@eecs.umich.edu //While there's still something to do... 939376Sgblack@eecs.umich.edu while (!instDone && !outOfBytes) { 949023Sgblack@eecs.umich.edu uint8_t nextByte = getNextByte(); 959376Sgblack@eecs.umich.edu switch (state) { 969023Sgblack@eecs.umich.edu case PrefixState: 979023Sgblack@eecs.umich.edu state = doPrefixState(nextByte); 989023Sgblack@eecs.umich.edu break; 9912045Sgabeblack@google.com case Vex2Of2State: 10012045Sgabeblack@google.com state = doVex2Of2State(nextByte); 10110924Snilay@cs.wisc.edu break; 10212045Sgabeblack@google.com case Vex2Of3State: 10312045Sgabeblack@google.com state = doVex2Of3State(nextByte); 10410924Snilay@cs.wisc.edu break; 10512045Sgabeblack@google.com case Vex3Of3State: 10612045Sgabeblack@google.com state = doVex3Of3State(nextByte); 10710924Snilay@cs.wisc.edu break; 10812045Sgabeblack@google.com case VexOpcodeState: 10912045Sgabeblack@google.com state = doVexOpcodeState(nextByte); 11012045Sgabeblack@google.com break; 11110593Sgabeblack@google.com case OneByteOpcodeState: 11210593Sgabeblack@google.com state = doOneByteOpcodeState(nextByte); 11310593Sgabeblack@google.com break; 11410593Sgabeblack@google.com case TwoByteOpcodeState: 11510593Sgabeblack@google.com state = doTwoByteOpcodeState(nextByte); 11610593Sgabeblack@google.com break; 11710593Sgabeblack@google.com case ThreeByte0F38OpcodeState: 11810593Sgabeblack@google.com state = doThreeByte0F38OpcodeState(nextByte); 11910593Sgabeblack@google.com break; 12010593Sgabeblack@google.com case ThreeByte0F3AOpcodeState: 12110593Sgabeblack@google.com state = doThreeByte0F3AOpcodeState(nextByte); 1229023Sgblack@eecs.umich.edu break; 1239023Sgblack@eecs.umich.edu case ModRMState: 1249023Sgblack@eecs.umich.edu state = doModRMState(nextByte); 1259023Sgblack@eecs.umich.edu break; 1269023Sgblack@eecs.umich.edu case SIBState: 1279023Sgblack@eecs.umich.edu state = doSIBState(nextByte); 1289023Sgblack@eecs.umich.edu break; 1299023Sgblack@eecs.umich.edu case DisplacementState: 1309023Sgblack@eecs.umich.edu state = doDisplacementState(); 1319023Sgblack@eecs.umich.edu break; 1329023Sgblack@eecs.umich.edu case ImmediateState: 1339023Sgblack@eecs.umich.edu state = doImmediateState(); 1349023Sgblack@eecs.umich.edu break; 1359023Sgblack@eecs.umich.edu case ErrorState: 1369023Sgblack@eecs.umich.edu panic("Went to the error state in the decoder.\n"); 1379023Sgblack@eecs.umich.edu default: 1389023Sgblack@eecs.umich.edu panic("Unrecognized state! %d\n", state); 1399023Sgblack@eecs.umich.edu } 1409023Sgblack@eecs.umich.edu } 1419023Sgblack@eecs.umich.edu} 1429023Sgblack@eecs.umich.edu 1439376Sgblack@eecs.umich.eduDecoder::State 1449376Sgblack@eecs.umich.eduDecoder::doFromCacheState() 1459376Sgblack@eecs.umich.edu{ 1469376Sgblack@eecs.umich.edu DPRINTF(Decoder, "Looking at cache state.\n"); 1479376Sgblack@eecs.umich.edu if ((fetchChunk & instBytes->masks[chunkIdx]) != 1489376Sgblack@eecs.umich.edu instBytes->chunks[chunkIdx]) { 1499376Sgblack@eecs.umich.edu DPRINTF(Decoder, "Decode cache miss.\n"); 1509376Sgblack@eecs.umich.edu // The chached chunks didn't match what was fetched. Fall back to the 1519376Sgblack@eecs.umich.edu // predecoder. 1529376Sgblack@eecs.umich.edu instBytes->chunks[chunkIdx] = fetchChunk; 1539376Sgblack@eecs.umich.edu instBytes->chunks.resize(chunkIdx + 1); 1549376Sgblack@eecs.umich.edu instBytes->si = NULL; 1559376Sgblack@eecs.umich.edu chunkIdx = 0; 1569376Sgblack@eecs.umich.edu fetchChunk = instBytes->chunks[0]; 1579376Sgblack@eecs.umich.edu offset = origPC % sizeof(MachInst); 1589376Sgblack@eecs.umich.edu basePC = origPC - offset; 1599376Sgblack@eecs.umich.edu return PrefixState; 1609376Sgblack@eecs.umich.edu } else if (chunkIdx == instBytes->chunks.size() - 1) { 1619376Sgblack@eecs.umich.edu // We matched the cache, so use its value. 1629376Sgblack@eecs.umich.edu instDone = true; 1639376Sgblack@eecs.umich.edu offset = instBytes->lastOffset; 1649376Sgblack@eecs.umich.edu if (offset == sizeof(MachInst)) 1659376Sgblack@eecs.umich.edu outOfBytes = true; 1669376Sgblack@eecs.umich.edu return ResetState; 1679376Sgblack@eecs.umich.edu } else { 1689376Sgblack@eecs.umich.edu // We matched so far, but need to check more chunks. 1699376Sgblack@eecs.umich.edu chunkIdx++; 1709376Sgblack@eecs.umich.edu outOfBytes = true; 1719376Sgblack@eecs.umich.edu return FromCacheState; 1729376Sgblack@eecs.umich.edu } 1739376Sgblack@eecs.umich.edu} 1749376Sgblack@eecs.umich.edu 1759023Sgblack@eecs.umich.edu//Either get a prefix and record it in the ExtMachInst, or send the 1769023Sgblack@eecs.umich.edu//state machine on to get the opcode(s). 1779376Sgblack@eecs.umich.eduDecoder::State 1789376Sgblack@eecs.umich.eduDecoder::doPrefixState(uint8_t nextByte) 1799023Sgblack@eecs.umich.edu{ 1809023Sgblack@eecs.umich.edu uint8_t prefix = Prefixes[nextByte]; 1819023Sgblack@eecs.umich.edu State nextState = PrefixState; 1829023Sgblack@eecs.umich.edu // REX prefixes are only recognized in 64 bit mode. 1839023Sgblack@eecs.umich.edu if (prefix == RexPrefix && emi.mode.submode != SixtyFourBitMode) 1849023Sgblack@eecs.umich.edu prefix = 0; 1859023Sgblack@eecs.umich.edu if (prefix) 1869023Sgblack@eecs.umich.edu consumeByte(); 1879023Sgblack@eecs.umich.edu switch(prefix) 1889023Sgblack@eecs.umich.edu { 1899023Sgblack@eecs.umich.edu //Operand size override prefixes 1909023Sgblack@eecs.umich.edu case OperandSizeOverride: 1919023Sgblack@eecs.umich.edu DPRINTF(Decoder, "Found operand size override prefix.\n"); 1929023Sgblack@eecs.umich.edu emi.legacy.op = true; 1939023Sgblack@eecs.umich.edu break; 1949023Sgblack@eecs.umich.edu case AddressSizeOverride: 1959023Sgblack@eecs.umich.edu DPRINTF(Decoder, "Found address size override prefix.\n"); 1969023Sgblack@eecs.umich.edu emi.legacy.addr = true; 1979023Sgblack@eecs.umich.edu break; 1989023Sgblack@eecs.umich.edu //Segment override prefixes 1999023Sgblack@eecs.umich.edu case CSOverride: 2009023Sgblack@eecs.umich.edu case DSOverride: 2019023Sgblack@eecs.umich.edu case ESOverride: 2029023Sgblack@eecs.umich.edu case FSOverride: 2039023Sgblack@eecs.umich.edu case GSOverride: 2049023Sgblack@eecs.umich.edu case SSOverride: 2059023Sgblack@eecs.umich.edu DPRINTF(Decoder, "Found segment override.\n"); 2069023Sgblack@eecs.umich.edu emi.legacy.seg = prefix; 2079023Sgblack@eecs.umich.edu break; 2089023Sgblack@eecs.umich.edu case Lock: 2099023Sgblack@eecs.umich.edu DPRINTF(Decoder, "Found lock prefix.\n"); 2109023Sgblack@eecs.umich.edu emi.legacy.lock = true; 2119023Sgblack@eecs.umich.edu break; 2129023Sgblack@eecs.umich.edu case Rep: 2139023Sgblack@eecs.umich.edu DPRINTF(Decoder, "Found rep prefix.\n"); 2149023Sgblack@eecs.umich.edu emi.legacy.rep = true; 2159023Sgblack@eecs.umich.edu break; 2169023Sgblack@eecs.umich.edu case Repne: 2179023Sgblack@eecs.umich.edu DPRINTF(Decoder, "Found repne prefix.\n"); 2189023Sgblack@eecs.umich.edu emi.legacy.repne = true; 2199023Sgblack@eecs.umich.edu break; 2209023Sgblack@eecs.umich.edu case RexPrefix: 2219023Sgblack@eecs.umich.edu DPRINTF(Decoder, "Found Rex prefix %#x.\n", nextByte); 2229023Sgblack@eecs.umich.edu emi.rex = nextByte; 2239023Sgblack@eecs.umich.edu break; 22410924Snilay@cs.wisc.edu case Vex2Prefix: 22510924Snilay@cs.wisc.edu DPRINTF(Decoder, "Found VEX two-byte prefix %#x.\n", nextByte); 22612045Sgabeblack@google.com emi.vex.present = 1; 22712045Sgabeblack@google.com nextState = Vex2Of2State; 22810924Snilay@cs.wisc.edu break; 22910924Snilay@cs.wisc.edu case Vex3Prefix: 23010924Snilay@cs.wisc.edu DPRINTF(Decoder, "Found VEX three-byte prefix %#x.\n", nextByte); 23112045Sgabeblack@google.com emi.vex.present = 1; 23212045Sgabeblack@google.com nextState = Vex2Of3State; 23310924Snilay@cs.wisc.edu break; 2349023Sgblack@eecs.umich.edu case 0: 23510593Sgabeblack@google.com nextState = OneByteOpcodeState; 2369023Sgblack@eecs.umich.edu break; 23710924Snilay@cs.wisc.edu 2389023Sgblack@eecs.umich.edu default: 2399023Sgblack@eecs.umich.edu panic("Unrecognized prefix %#x\n", nextByte); 2409023Sgblack@eecs.umich.edu } 2419023Sgblack@eecs.umich.edu return nextState; 2429023Sgblack@eecs.umich.edu} 2439023Sgblack@eecs.umich.edu 24410924Snilay@cs.wisc.eduDecoder::State 24512045Sgabeblack@google.comDecoder::doVex2Of2State(uint8_t nextByte) 24610924Snilay@cs.wisc.edu{ 24710924Snilay@cs.wisc.edu consumeByte(); 24812045Sgabeblack@google.com Vex2Of2 vex = nextByte; 24910924Snilay@cs.wisc.edu 25012045Sgabeblack@google.com emi.rex.r = !vex.r; 25110924Snilay@cs.wisc.edu 25212045Sgabeblack@google.com emi.vex.l = vex.l; 25312045Sgabeblack@google.com emi.vex.v = ~vex.v; 25410924Snilay@cs.wisc.edu 25512045Sgabeblack@google.com switch (vex.p) { 25612045Sgabeblack@google.com case 0: 25712045Sgabeblack@google.com break; 25812045Sgabeblack@google.com case 1: 25912045Sgabeblack@google.com emi.legacy.op = 1; 26012045Sgabeblack@google.com break; 26112045Sgabeblack@google.com case 2: 26212045Sgabeblack@google.com emi.legacy.rep = 1; 26312045Sgabeblack@google.com break; 26412045Sgabeblack@google.com case 3: 26512045Sgabeblack@google.com emi.legacy.repne = 1; 26612045Sgabeblack@google.com break; 26712045Sgabeblack@google.com } 26812045Sgabeblack@google.com 26912045Sgabeblack@google.com emi.opcode.type = TwoByteOpcode; 27012045Sgabeblack@google.com 27112045Sgabeblack@google.com return VexOpcodeState; 27210924Snilay@cs.wisc.edu} 27310924Snilay@cs.wisc.edu 27410924Snilay@cs.wisc.eduDecoder::State 27512045Sgabeblack@google.comDecoder::doVex2Of3State(uint8_t nextByte) 27610924Snilay@cs.wisc.edu{ 27712045Sgabeblack@google.com if (emi.mode.submode != SixtyFourBitMode && bits(nextByte, 7, 6) == 0x3) { 27812045Sgabeblack@google.com // This was actually an LDS instruction. Reroute to that path. 27912045Sgabeblack@google.com emi.vex.present = 0; 28012045Sgabeblack@google.com emi.opcode.type = OneByteOpcode; 28112045Sgabeblack@google.com emi.opcode.op = 0xC4; 28212045Sgabeblack@google.com return processOpcode(ImmediateTypeOneByte, UsesModRMOneByte, 28312045Sgabeblack@google.com nextByte >= 0xA0 && nextByte <= 0xA3); 28412045Sgabeblack@google.com } 28512045Sgabeblack@google.com 28610924Snilay@cs.wisc.edu consumeByte(); 28712045Sgabeblack@google.com Vex2Of3 vex = nextByte; 28812045Sgabeblack@google.com 28912045Sgabeblack@google.com emi.rex.r = !vex.r; 29012045Sgabeblack@google.com emi.rex.x = !vex.x; 29112045Sgabeblack@google.com emi.rex.b = !vex.b; 29212045Sgabeblack@google.com 29312045Sgabeblack@google.com switch (vex.m) { 29412045Sgabeblack@google.com case 1: 29512045Sgabeblack@google.com emi.opcode.type = TwoByteOpcode; 29612045Sgabeblack@google.com break; 29712045Sgabeblack@google.com case 2: 29812045Sgabeblack@google.com emi.opcode.type = ThreeByte0F38Opcode; 29912045Sgabeblack@google.com break; 30012045Sgabeblack@google.com case 3: 30112045Sgabeblack@google.com emi.opcode.type = ThreeByte0F3AOpcode; 30212045Sgabeblack@google.com break; 30312045Sgabeblack@google.com default: 30412045Sgabeblack@google.com // These encodings are reserved. Pretend this was an undefined 30512045Sgabeblack@google.com // instruction so the main decoder will behave correctly, and stop 30612045Sgabeblack@google.com // trying to interpret bytes. 30712045Sgabeblack@google.com emi.opcode.type = TwoByteOpcode; 30812045Sgabeblack@google.com emi.opcode.op = 0x0B; 30912045Sgabeblack@google.com instDone = true; 31012045Sgabeblack@google.com return ResetState; 31112045Sgabeblack@google.com } 31212045Sgabeblack@google.com return Vex3Of3State; 31310924Snilay@cs.wisc.edu} 31410924Snilay@cs.wisc.edu 31510924Snilay@cs.wisc.eduDecoder::State 31612045Sgabeblack@google.comDecoder::doVex3Of3State(uint8_t nextByte) 31710924Snilay@cs.wisc.edu{ 31812045Sgabeblack@google.com if (emi.mode.submode != SixtyFourBitMode && bits(nextByte, 7, 6) == 0x3) { 31912045Sgabeblack@google.com // This was actually an LES instruction. Reroute to that path. 32012045Sgabeblack@google.com emi.vex.present = 0; 32112045Sgabeblack@google.com emi.opcode.type = OneByteOpcode; 32212045Sgabeblack@google.com emi.opcode.op = 0xC5; 32312045Sgabeblack@google.com return processOpcode(ImmediateTypeOneByte, UsesModRMOneByte, 32412045Sgabeblack@google.com nextByte >= 0xA0 && nextByte <= 0xA3); 32512045Sgabeblack@google.com } 32612045Sgabeblack@google.com 32710924Snilay@cs.wisc.edu consumeByte(); 32812045Sgabeblack@google.com Vex3Of3 vex = nextByte; 32912045Sgabeblack@google.com 33012045Sgabeblack@google.com emi.rex.w = vex.w; 33112045Sgabeblack@google.com 33212045Sgabeblack@google.com emi.vex.l = vex.l; 33312045Sgabeblack@google.com emi.vex.v = ~vex.v; 33412045Sgabeblack@google.com 33512045Sgabeblack@google.com switch (vex.p) { 33612045Sgabeblack@google.com case 0: 33712045Sgabeblack@google.com break; 33812045Sgabeblack@google.com case 1: 33912045Sgabeblack@google.com emi.legacy.op = 1; 34012045Sgabeblack@google.com break; 34112045Sgabeblack@google.com case 2: 34212045Sgabeblack@google.com emi.legacy.rep = 1; 34312045Sgabeblack@google.com break; 34412045Sgabeblack@google.com case 3: 34512045Sgabeblack@google.com emi.legacy.repne = 1; 34612045Sgabeblack@google.com break; 34712045Sgabeblack@google.com } 34812045Sgabeblack@google.com 34912045Sgabeblack@google.com return VexOpcodeState; 35012045Sgabeblack@google.com} 35112045Sgabeblack@google.com 35212045Sgabeblack@google.comDecoder::State 35312045Sgabeblack@google.comDecoder::doVexOpcodeState(uint8_t nextByte) 35412045Sgabeblack@google.com{ 35512045Sgabeblack@google.com DPRINTF(Decoder, "Found VEX opcode %#x.\n", nextByte); 35612045Sgabeblack@google.com 35712045Sgabeblack@google.com emi.opcode.op = nextByte; 35812229Sgabeblack@google.com consumeByte(); 35912045Sgabeblack@google.com 36012045Sgabeblack@google.com switch (emi.opcode.type) { 36112045Sgabeblack@google.com case TwoByteOpcode: 36212045Sgabeblack@google.com return processOpcode(ImmediateTypeTwoByte, UsesModRMTwoByte); 36312045Sgabeblack@google.com case ThreeByte0F38Opcode: 36412045Sgabeblack@google.com return processOpcode(ImmediateTypeThreeByte0F38, 36512045Sgabeblack@google.com UsesModRMThreeByte0F38); 36612045Sgabeblack@google.com case ThreeByte0F3AOpcode: 36712045Sgabeblack@google.com return processOpcode(ImmediateTypeThreeByte0F3A, 36812045Sgabeblack@google.com UsesModRMThreeByte0F3A); 36912045Sgabeblack@google.com default: 37012045Sgabeblack@google.com panic("Unrecognized opcode type %d.\n", emi.opcode.type); 37112045Sgabeblack@google.com } 37210924Snilay@cs.wisc.edu} 37310924Snilay@cs.wisc.edu 37410593Sgabeblack@google.com// Load the first opcode byte. Determine if there are more opcode bytes, and 37510593Sgabeblack@google.com// if not, what immediate and/or ModRM is needed. 3769376Sgblack@eecs.umich.eduDecoder::State 37710593Sgabeblack@google.comDecoder::doOneByteOpcodeState(uint8_t nextByte) 3789023Sgblack@eecs.umich.edu{ 3799023Sgblack@eecs.umich.edu State nextState = ErrorState; 3809023Sgblack@eecs.umich.edu consumeByte(); 38110924Snilay@cs.wisc.edu 38212045Sgabeblack@google.com if (nextByte == 0x0f) { 38312045Sgabeblack@google.com DPRINTF(Decoder, "Found opcode escape byte %#x.\n", nextByte); 38410593Sgabeblack@google.com nextState = TwoByteOpcodeState; 38510593Sgabeblack@google.com } else { 38610593Sgabeblack@google.com DPRINTF(Decoder, "Found one byte opcode %#x.\n", nextByte); 38710593Sgabeblack@google.com emi.opcode.type = OneByteOpcode; 3889023Sgblack@eecs.umich.edu emi.opcode.op = nextByte; 3899023Sgblack@eecs.umich.edu 39010593Sgabeblack@google.com nextState = processOpcode(ImmediateTypeOneByte, UsesModRMOneByte, 39110593Sgabeblack@google.com nextByte >= 0xA0 && nextByte <= 0xA3); 39210593Sgabeblack@google.com } 39310593Sgabeblack@google.com return nextState; 39410593Sgabeblack@google.com} 3959023Sgblack@eecs.umich.edu 39610593Sgabeblack@google.com// Load the second opcode byte. Determine if there are more opcode bytes, and 39710593Sgabeblack@google.com// if not, what immediate and/or ModRM is needed. 39810593Sgabeblack@google.comDecoder::State 39910593Sgabeblack@google.comDecoder::doTwoByteOpcodeState(uint8_t nextByte) 40010593Sgabeblack@google.com{ 40110593Sgabeblack@google.com State nextState = ErrorState; 40210593Sgabeblack@google.com consumeByte(); 40310593Sgabeblack@google.com if (nextByte == 0x38) { 40410593Sgabeblack@google.com nextState = ThreeByte0F38OpcodeState; 40510593Sgabeblack@google.com DPRINTF(Decoder, "Found opcode escape byte %#x.\n", nextByte); 40610593Sgabeblack@google.com } else if (nextByte == 0x3a) { 40710593Sgabeblack@google.com nextState = ThreeByte0F3AOpcodeState; 40810593Sgabeblack@google.com DPRINTF(Decoder, "Found opcode escape byte %#x.\n", nextByte); 40910593Sgabeblack@google.com } else { 41010593Sgabeblack@google.com DPRINTF(Decoder, "Found two byte opcode %#x.\n", nextByte); 41110593Sgabeblack@google.com emi.opcode.type = TwoByteOpcode; 41210593Sgabeblack@google.com emi.opcode.op = nextByte; 4139023Sgblack@eecs.umich.edu 41410593Sgabeblack@google.com nextState = processOpcode(ImmediateTypeTwoByte, UsesModRMTwoByte); 41510593Sgabeblack@google.com } 41610593Sgabeblack@google.com return nextState; 41710593Sgabeblack@google.com} 4189023Sgblack@eecs.umich.edu 41910593Sgabeblack@google.com// Load the third opcode byte and determine what immediate and/or ModRM is 42010593Sgabeblack@google.com// needed. 42110593Sgabeblack@google.comDecoder::State 42210593Sgabeblack@google.comDecoder::doThreeByte0F38OpcodeState(uint8_t nextByte) 42310593Sgabeblack@google.com{ 42410593Sgabeblack@google.com consumeByte(); 4259023Sgblack@eecs.umich.edu 42610593Sgabeblack@google.com DPRINTF(Decoder, "Found three byte 0F38 opcode %#x.\n", nextByte); 42710593Sgabeblack@google.com emi.opcode.type = ThreeByte0F38Opcode; 42810593Sgabeblack@google.com emi.opcode.op = nextByte; 4299023Sgblack@eecs.umich.edu 43010593Sgabeblack@google.com return processOpcode(ImmediateTypeThreeByte0F38, UsesModRMThreeByte0F38); 43110593Sgabeblack@google.com} 4329023Sgblack@eecs.umich.edu 43310593Sgabeblack@google.com// Load the third opcode byte and determine what immediate and/or ModRM is 43410593Sgabeblack@google.com// needed. 43510593Sgabeblack@google.comDecoder::State 43610593Sgabeblack@google.comDecoder::doThreeByte0F3AOpcodeState(uint8_t nextByte) 43710593Sgabeblack@google.com{ 43810593Sgabeblack@google.com consumeByte(); 43910593Sgabeblack@google.com 44010593Sgabeblack@google.com DPRINTF(Decoder, "Found three byte 0F3A opcode %#x.\n", nextByte); 44110593Sgabeblack@google.com emi.opcode.type = ThreeByte0F3AOpcode; 44210593Sgabeblack@google.com emi.opcode.op = nextByte; 44310593Sgabeblack@google.com 44410593Sgabeblack@google.com return processOpcode(ImmediateTypeThreeByte0F3A, UsesModRMThreeByte0F3A); 44510593Sgabeblack@google.com} 44610593Sgabeblack@google.com 44710593Sgabeblack@google.com// Generic opcode processing which determines the immediate size, and whether 44810593Sgabeblack@google.com// or not there's a modrm byte. 44910593Sgabeblack@google.comDecoder::State 45010593Sgabeblack@google.comDecoder::processOpcode(ByteTable &immTable, ByteTable &modrmTable, 45110593Sgabeblack@google.com bool addrSizedImm) 45210593Sgabeblack@google.com{ 45310593Sgabeblack@google.com State nextState = ErrorState; 45410593Sgabeblack@google.com const uint8_t opcode = emi.opcode.op; 45510593Sgabeblack@google.com 45610593Sgabeblack@google.com //Figure out the effective operand size. This can be overriden to 45710593Sgabeblack@google.com //a fixed value at the decoder level. 45810593Sgabeblack@google.com int logOpSize; 45910593Sgabeblack@google.com if (emi.rex.w) 46010593Sgabeblack@google.com logOpSize = 3; // 64 bit operand size 46110593Sgabeblack@google.com else if (emi.legacy.op) 46210593Sgabeblack@google.com logOpSize = altOp; 46310593Sgabeblack@google.com else 46410593Sgabeblack@google.com logOpSize = defOp; 46510593Sgabeblack@google.com 46610593Sgabeblack@google.com //Set the actual op size 46710593Sgabeblack@google.com emi.opSize = 1 << logOpSize; 46810593Sgabeblack@google.com 46910593Sgabeblack@google.com //Figure out the effective address size. This can be overriden to 47010593Sgabeblack@google.com //a fixed value at the decoder level. 47110593Sgabeblack@google.com int logAddrSize; 47211321Ssteve.reinhardt@amd.com if (emi.legacy.addr) 47310593Sgabeblack@google.com logAddrSize = altAddr; 47410593Sgabeblack@google.com else 47510593Sgabeblack@google.com logAddrSize = defAddr; 47610593Sgabeblack@google.com 47710593Sgabeblack@google.com //Set the actual address size 47810593Sgabeblack@google.com emi.addrSize = 1 << logAddrSize; 47910593Sgabeblack@google.com 48010593Sgabeblack@google.com //Figure out the effective stack width. This can be overriden to 48110593Sgabeblack@google.com //a fixed value at the decoder level. 48210593Sgabeblack@google.com emi.stackSize = 1 << stack; 48310593Sgabeblack@google.com 48410593Sgabeblack@google.com //Figure out how big of an immediate we'll retreive based 48510593Sgabeblack@google.com //on the opcode. 48610593Sgabeblack@google.com int immType = immTable[opcode]; 48710593Sgabeblack@google.com if (addrSizedImm) 48810593Sgabeblack@google.com immediateSize = SizeTypeToSize[logAddrSize - 1][immType]; 48910593Sgabeblack@google.com else 49010593Sgabeblack@google.com immediateSize = SizeTypeToSize[logOpSize - 1][immType]; 49110593Sgabeblack@google.com 49210593Sgabeblack@google.com //Determine what to expect next 49310593Sgabeblack@google.com if (modrmTable[opcode]) { 49410593Sgabeblack@google.com nextState = ModRMState; 49510593Sgabeblack@google.com } else { 49611321Ssteve.reinhardt@amd.com if (immediateSize) { 49710593Sgabeblack@google.com nextState = ImmediateState; 4989023Sgblack@eecs.umich.edu } else { 49910593Sgabeblack@google.com instDone = true; 50010593Sgabeblack@google.com nextState = ResetState; 5019023Sgblack@eecs.umich.edu } 5029023Sgblack@eecs.umich.edu } 5039023Sgblack@eecs.umich.edu return nextState; 5049023Sgblack@eecs.umich.edu} 5059023Sgblack@eecs.umich.edu 5069023Sgblack@eecs.umich.edu//Get the ModRM byte and determine what displacement, if any, there is. 5079023Sgblack@eecs.umich.edu//Also determine whether or not to get the SIB byte, displacement, or 5089023Sgblack@eecs.umich.edu//immediate next. 5099376Sgblack@eecs.umich.eduDecoder::State 5109376Sgblack@eecs.umich.eduDecoder::doModRMState(uint8_t nextByte) 5119023Sgblack@eecs.umich.edu{ 5129023Sgblack@eecs.umich.edu State nextState = ErrorState; 51310924Snilay@cs.wisc.edu ModRM modRM = nextByte; 5149023Sgblack@eecs.umich.edu DPRINTF(Decoder, "Found modrm byte %#x.\n", nextByte); 5159376Sgblack@eecs.umich.edu if (defOp == 1) { 5169023Sgblack@eecs.umich.edu //figure out 16 bit displacement size 5179023Sgblack@eecs.umich.edu if ((modRM.mod == 0 && modRM.rm == 6) || modRM.mod == 2) 5189023Sgblack@eecs.umich.edu displacementSize = 2; 5199023Sgblack@eecs.umich.edu else if (modRM.mod == 1) 5209023Sgblack@eecs.umich.edu displacementSize = 1; 5219023Sgblack@eecs.umich.edu else 5229023Sgblack@eecs.umich.edu displacementSize = 0; 5239023Sgblack@eecs.umich.edu } else { 5249023Sgblack@eecs.umich.edu //figure out 32/64 bit displacement size 5259023Sgblack@eecs.umich.edu if ((modRM.mod == 0 && modRM.rm == 5) || modRM.mod == 2) 5269023Sgblack@eecs.umich.edu displacementSize = 4; 5279023Sgblack@eecs.umich.edu else if (modRM.mod == 1) 5289023Sgblack@eecs.umich.edu displacementSize = 1; 5299023Sgblack@eecs.umich.edu else 5309023Sgblack@eecs.umich.edu displacementSize = 0; 5319023Sgblack@eecs.umich.edu } 5329023Sgblack@eecs.umich.edu 5339023Sgblack@eecs.umich.edu // The "test" instruction in group 3 needs an immediate, even though 5349023Sgblack@eecs.umich.edu // the other instructions with the same actual opcode don't. 53510593Sgabeblack@google.com if (emi.opcode.type == OneByteOpcode && (modRM.reg & 0x6) == 0) { 5369023Sgblack@eecs.umich.edu if (emi.opcode.op == 0xF6) 5379023Sgblack@eecs.umich.edu immediateSize = 1; 5389023Sgblack@eecs.umich.edu else if (emi.opcode.op == 0xF7) 5399023Sgblack@eecs.umich.edu immediateSize = (emi.opSize == 8) ? 4 : emi.opSize; 5409023Sgblack@eecs.umich.edu } 5419023Sgblack@eecs.umich.edu 5429023Sgblack@eecs.umich.edu //If there's an SIB, get that next. 5439023Sgblack@eecs.umich.edu //There is no SIB in 16 bit mode. 5449023Sgblack@eecs.umich.edu if (modRM.rm == 4 && modRM.mod != 3) { 5459023Sgblack@eecs.umich.edu // && in 32/64 bit mode) 5469023Sgblack@eecs.umich.edu nextState = SIBState; 54711321Ssteve.reinhardt@amd.com } else if (displacementSize) { 5489023Sgblack@eecs.umich.edu nextState = DisplacementState; 54911321Ssteve.reinhardt@amd.com } else if (immediateSize) { 5509023Sgblack@eecs.umich.edu nextState = ImmediateState; 5519023Sgblack@eecs.umich.edu } else { 5529023Sgblack@eecs.umich.edu instDone = true; 5539023Sgblack@eecs.umich.edu nextState = ResetState; 5549023Sgblack@eecs.umich.edu } 5559023Sgblack@eecs.umich.edu //The ModRM byte is consumed no matter what 5569023Sgblack@eecs.umich.edu consumeByte(); 5579023Sgblack@eecs.umich.edu emi.modRM = modRM; 5589023Sgblack@eecs.umich.edu return nextState; 5599023Sgblack@eecs.umich.edu} 5609023Sgblack@eecs.umich.edu 5619023Sgblack@eecs.umich.edu//Get the SIB byte. We don't do anything with it at this point, other 5629023Sgblack@eecs.umich.edu//than storing it in the ExtMachInst. Determine if we need to get a 5639023Sgblack@eecs.umich.edu//displacement or immediate next. 5649376Sgblack@eecs.umich.eduDecoder::State 5659376Sgblack@eecs.umich.eduDecoder::doSIBState(uint8_t nextByte) 5669023Sgblack@eecs.umich.edu{ 5679023Sgblack@eecs.umich.edu State nextState = ErrorState; 5689023Sgblack@eecs.umich.edu emi.sib = nextByte; 5699023Sgblack@eecs.umich.edu DPRINTF(Decoder, "Found SIB byte %#x.\n", nextByte); 5709023Sgblack@eecs.umich.edu consumeByte(); 5719023Sgblack@eecs.umich.edu if (emi.modRM.mod == 0 && emi.sib.base == 5) 5729023Sgblack@eecs.umich.edu displacementSize = 4; 5739023Sgblack@eecs.umich.edu if (displacementSize) { 5749023Sgblack@eecs.umich.edu nextState = DisplacementState; 57511321Ssteve.reinhardt@amd.com } else if (immediateSize) { 5769023Sgblack@eecs.umich.edu nextState = ImmediateState; 5779023Sgblack@eecs.umich.edu } else { 5789023Sgblack@eecs.umich.edu instDone = true; 5799023Sgblack@eecs.umich.edu nextState = ResetState; 5809023Sgblack@eecs.umich.edu } 5819023Sgblack@eecs.umich.edu return nextState; 5829023Sgblack@eecs.umich.edu} 5839023Sgblack@eecs.umich.edu 5849023Sgblack@eecs.umich.edu//Gather up the displacement, or at least as much of it 5859023Sgblack@eecs.umich.edu//as we can get. 5869376Sgblack@eecs.umich.eduDecoder::State 5879376Sgblack@eecs.umich.eduDecoder::doDisplacementState() 5889023Sgblack@eecs.umich.edu{ 5899023Sgblack@eecs.umich.edu State nextState = ErrorState; 5909023Sgblack@eecs.umich.edu 5919023Sgblack@eecs.umich.edu getImmediate(immediateCollected, 5929023Sgblack@eecs.umich.edu emi.displacement, 5939023Sgblack@eecs.umich.edu displacementSize); 5949023Sgblack@eecs.umich.edu 5959023Sgblack@eecs.umich.edu DPRINTF(Decoder, "Collecting %d byte displacement, got %d bytes.\n", 5969023Sgblack@eecs.umich.edu displacementSize, immediateCollected); 5979023Sgblack@eecs.umich.edu 59811321Ssteve.reinhardt@amd.com if (displacementSize == immediateCollected) { 5999023Sgblack@eecs.umich.edu //Reset this for other immediates. 6009023Sgblack@eecs.umich.edu immediateCollected = 0; 6019023Sgblack@eecs.umich.edu //Sign extend the displacement 6029023Sgblack@eecs.umich.edu switch(displacementSize) 6039023Sgblack@eecs.umich.edu { 6049023Sgblack@eecs.umich.edu case 1: 6059023Sgblack@eecs.umich.edu emi.displacement = sext<8>(emi.displacement); 6069023Sgblack@eecs.umich.edu break; 6079023Sgblack@eecs.umich.edu case 2: 6089023Sgblack@eecs.umich.edu emi.displacement = sext<16>(emi.displacement); 6099023Sgblack@eecs.umich.edu break; 6109023Sgblack@eecs.umich.edu case 4: 6119023Sgblack@eecs.umich.edu emi.displacement = sext<32>(emi.displacement); 6129023Sgblack@eecs.umich.edu break; 6139023Sgblack@eecs.umich.edu default: 6149023Sgblack@eecs.umich.edu panic("Undefined displacement size!\n"); 6159023Sgblack@eecs.umich.edu } 6169023Sgblack@eecs.umich.edu DPRINTF(Decoder, "Collected displacement %#x.\n", 6179023Sgblack@eecs.umich.edu emi.displacement); 61811321Ssteve.reinhardt@amd.com if (immediateSize) { 6199023Sgblack@eecs.umich.edu nextState = ImmediateState; 6209023Sgblack@eecs.umich.edu } else { 6219023Sgblack@eecs.umich.edu instDone = true; 6229023Sgblack@eecs.umich.edu nextState = ResetState; 6239023Sgblack@eecs.umich.edu } 6249023Sgblack@eecs.umich.edu 6259023Sgblack@eecs.umich.edu emi.dispSize = displacementSize; 6269023Sgblack@eecs.umich.edu } 6279023Sgblack@eecs.umich.edu else 6289023Sgblack@eecs.umich.edu nextState = DisplacementState; 6299023Sgblack@eecs.umich.edu return nextState; 6309023Sgblack@eecs.umich.edu} 6319023Sgblack@eecs.umich.edu 6329023Sgblack@eecs.umich.edu//Gather up the immediate, or at least as much of it 6339023Sgblack@eecs.umich.edu//as we can get 6349376Sgblack@eecs.umich.eduDecoder::State 6359376Sgblack@eecs.umich.eduDecoder::doImmediateState() 6369023Sgblack@eecs.umich.edu{ 6379023Sgblack@eecs.umich.edu State nextState = ErrorState; 6389023Sgblack@eecs.umich.edu 6399023Sgblack@eecs.umich.edu getImmediate(immediateCollected, 6409023Sgblack@eecs.umich.edu emi.immediate, 6419023Sgblack@eecs.umich.edu immediateSize); 6429023Sgblack@eecs.umich.edu 6439023Sgblack@eecs.umich.edu DPRINTF(Decoder, "Collecting %d byte immediate, got %d bytes.\n", 6449023Sgblack@eecs.umich.edu immediateSize, immediateCollected); 6459023Sgblack@eecs.umich.edu 64611321Ssteve.reinhardt@amd.com if (immediateSize == immediateCollected) 6479023Sgblack@eecs.umich.edu { 6489023Sgblack@eecs.umich.edu //Reset this for other immediates. 6499023Sgblack@eecs.umich.edu immediateCollected = 0; 6509023Sgblack@eecs.umich.edu 6519023Sgblack@eecs.umich.edu //XXX Warning! The following is an observed pattern and might 6529023Sgblack@eecs.umich.edu //not always be true! 6539023Sgblack@eecs.umich.edu 6549023Sgblack@eecs.umich.edu //Instructions which use 64 bit operands but 32 bit immediates 6559023Sgblack@eecs.umich.edu //need to have the immediate sign extended to 64 bits. 6569023Sgblack@eecs.umich.edu //Instructions which use true 64 bit immediates won't be 6579023Sgblack@eecs.umich.edu //affected, and instructions that use true 32 bit immediates 6589023Sgblack@eecs.umich.edu //won't notice. 6599023Sgblack@eecs.umich.edu switch(immediateSize) 6609023Sgblack@eecs.umich.edu { 6619023Sgblack@eecs.umich.edu case 4: 6629023Sgblack@eecs.umich.edu emi.immediate = sext<32>(emi.immediate); 6639023Sgblack@eecs.umich.edu break; 6649023Sgblack@eecs.umich.edu case 1: 6659023Sgblack@eecs.umich.edu emi.immediate = sext<8>(emi.immediate); 6669023Sgblack@eecs.umich.edu } 6679023Sgblack@eecs.umich.edu 6689023Sgblack@eecs.umich.edu DPRINTF(Decoder, "Collected immediate %#x.\n", 6699023Sgblack@eecs.umich.edu emi.immediate); 6709023Sgblack@eecs.umich.edu instDone = true; 6719023Sgblack@eecs.umich.edu nextState = ResetState; 6729023Sgblack@eecs.umich.edu } 6739023Sgblack@eecs.umich.edu else 6749023Sgblack@eecs.umich.edu nextState = ImmediateState; 6759023Sgblack@eecs.umich.edu return nextState; 6769023Sgblack@eecs.umich.edu} 6779022Sgblack@eecs.umich.edu 6789376Sgblack@eecs.umich.eduDecoder::InstBytes Decoder::dummy; 6799376Sgblack@eecs.umich.eduDecoder::InstCacheMap Decoder::instCacheMap; 6809024Sgblack@eecs.umich.edu 6819024Sgblack@eecs.umich.eduStaticInstPtr 6829024Sgblack@eecs.umich.eduDecoder::decode(ExtMachInst mach_inst, Addr addr) 6839024Sgblack@eecs.umich.edu{ 68412621Sgabeblack@google.com auto iter = instMap->find(mach_inst); 6859376Sgblack@eecs.umich.edu if (iter != instMap->end()) 6869376Sgblack@eecs.umich.edu return iter->second; 6879376Sgblack@eecs.umich.edu 6889376Sgblack@eecs.umich.edu StaticInstPtr si = decodeInst(mach_inst); 6899376Sgblack@eecs.umich.edu (*instMap)[mach_inst] = si; 6909376Sgblack@eecs.umich.edu return si; 6919376Sgblack@eecs.umich.edu} 6929376Sgblack@eecs.umich.edu 6939376Sgblack@eecs.umich.eduStaticInstPtr 6949376Sgblack@eecs.umich.eduDecoder::decode(PCState &nextPC) 6959376Sgblack@eecs.umich.edu{ 6969376Sgblack@eecs.umich.edu if (!instDone) 6979376Sgblack@eecs.umich.edu return NULL; 6989376Sgblack@eecs.umich.edu instDone = false; 6999376Sgblack@eecs.umich.edu updateNPC(nextPC); 7009376Sgblack@eecs.umich.edu 7019376Sgblack@eecs.umich.edu StaticInstPtr &si = instBytes->si; 7029376Sgblack@eecs.umich.edu if (si) 7039024Sgblack@eecs.umich.edu return si; 7049024Sgblack@eecs.umich.edu 7059376Sgblack@eecs.umich.edu // We didn't match in the AddrMap, but we still populated an entry. Fix 7069376Sgblack@eecs.umich.edu // up its byte masks. 7079376Sgblack@eecs.umich.edu const int chunkSize = sizeof(MachInst); 7089376Sgblack@eecs.umich.edu 7099376Sgblack@eecs.umich.edu instBytes->lastOffset = offset; 7109376Sgblack@eecs.umich.edu 7119376Sgblack@eecs.umich.edu Addr firstBasePC = basePC - (instBytes->chunks.size() - 1) * chunkSize; 7129376Sgblack@eecs.umich.edu Addr firstOffset = origPC - firstBasePC; 7139376Sgblack@eecs.umich.edu Addr totalSize = instBytes->lastOffset - firstOffset + 7149376Sgblack@eecs.umich.edu (instBytes->chunks.size() - 1) * chunkSize; 7159376Sgblack@eecs.umich.edu int start = firstOffset; 7169376Sgblack@eecs.umich.edu instBytes->masks.clear(); 7179376Sgblack@eecs.umich.edu 7189376Sgblack@eecs.umich.edu while (totalSize) { 7199376Sgblack@eecs.umich.edu int end = start + totalSize; 7209376Sgblack@eecs.umich.edu end = (chunkSize < end) ? chunkSize : end; 7219376Sgblack@eecs.umich.edu int size = end - start; 7229376Sgblack@eecs.umich.edu int idx = instBytes->masks.size(); 7239376Sgblack@eecs.umich.edu 7249376Sgblack@eecs.umich.edu MachInst maskVal = mask(size * 8) << (start * 8); 7259376Sgblack@eecs.umich.edu assert(maskVal); 7269376Sgblack@eecs.umich.edu 7279376Sgblack@eecs.umich.edu instBytes->masks.push_back(maskVal); 7289376Sgblack@eecs.umich.edu instBytes->chunks[idx] &= instBytes->masks[idx]; 7299376Sgblack@eecs.umich.edu totalSize -= size; 7309376Sgblack@eecs.umich.edu start = 0; 7319024Sgblack@eecs.umich.edu } 7329024Sgblack@eecs.umich.edu 7339376Sgblack@eecs.umich.edu si = decode(emi, origPC); 7349024Sgblack@eecs.umich.edu return si; 7359024Sgblack@eecs.umich.edu} 7369022Sgblack@eecs.umich.edu 7379022Sgblack@eecs.umich.edu} 738