diff options
Diffstat (limited to 'src/arch/x86')
-rw-r--r-- | src/arch/x86/SConscript | 1 | ||||
-rw-r--r-- | src/arch/x86/predecoder.hh | 242 |
2 files changed, 2 insertions, 241 deletions
diff --git a/src/arch/x86/SConscript b/src/arch/x86/SConscript index f693caf6f..2e2c5b006 100644 --- a/src/arch/x86/SConscript +++ b/src/arch/x86/SConscript @@ -88,6 +88,7 @@ if env['TARGET_ISA'] == 'x86': Source('floatregfile.cc') Source('intregfile.cc') Source('miscregfile.cc') + Source('predecoder.cc') Source('predecoder_tables.cc') Source('regfile.cc') Source('remote_gdb.cc') diff --git a/src/arch/x86/predecoder.hh b/src/arch/x86/predecoder.hh index f1dee6bf4..a1d0905c5 100644 --- a/src/arch/x86/predecoder.hh +++ b/src/arch/x86/predecoder.hh @@ -59,9 +59,6 @@ #define __ARCH_X86_PREDECODER_HH__ #include "arch/x86/types.hh" -#include "base/bitfield.hh" -#include "base/misc.hh" -#include "base/trace.hh" #include "sim/host.hh" class ThreadContext; @@ -135,244 +132,7 @@ namespace X86ISA tc = _tc; } - void process() - { - assert(!outOfBytes); - assert(!emiIsReady); - while(!emiIsReady && !outOfBytes) - { - uint8_t nextByte = (fetchChunk >> (offset * 8)) & 0xff; - switch(state) - { - case Prefix: - uint8_t prefix = Prefixes[nextByte]; - if(prefix) - offset++; - switch(prefix) - { - //Operand size override prefixes - case OperandSizeOverride: - DPRINTF(Predecoder, "Found operand size override prefix.\n"); - break; - case AddressSizeOverride: - DPRINTF(Predecoder, "Found address size override prefix.\n"); - break; - //Segment override prefixes - case CSOverride: - DPRINTF(Predecoder, "Found cs segment override.\n"); - break; - case DSOverride: - DPRINTF(Predecoder, "Found ds segment override.\n"); - break; - case ESOverride: - DPRINTF(Predecoder, "Found es segment override.\n"); - break; - case FSOverride: - DPRINTF(Predecoder, "Found fs segment override.\n"); - break; - case GSOverride: - DPRINTF(Predecoder, "Found gs segment override.\n"); - break; - case SSOverride: - DPRINTF(Predecoder, "Found ss segment override.\n"); - break; - case Lock: - DPRINTF(Predecoder, "Found lock prefix.\n"); - break; - case Rep: - DPRINTF(Predecoder, "Found rep prefix.\n"); - break; - case Repne: - DPRINTF(Predecoder, "Found repne prefix.\n"); - break; - case Rex: - DPRINTF(Predecoder, "Found Rex prefix %#x.\n", nextByte); - emi.rexPrefix = nextByte; - break; - case 0: - emi.numOpcodes = 0; - state = Opcode; - break; - default: - panic("Unrecognized prefix %#x\n", nextByte); - } - break; - case Opcode: - emi.numOpcodes++; - assert(emi.numOpcodes < 2); - if(nextByte == 0xf0) - { - DPRINTF(Predecoder, "Found two byte opcode.\n"); - } - else - { - immediateCollected = 0; - displacementCollected = 0; - emi.immediate = 0; - emi.displacement = 0; - int immType = ImmediateType[ - emi.numOpcodes - 1][nextByte]; - if(0) //16 bit mode - immediateSize = ImmediateTypeToSize[0][immType]; - else if(!(emi.rexPrefix & 0x4)) //32 bit mode - immediateSize = ImmediateTypeToSize[1][immType]; - else //64 bit mode - immediateSize = ImmediateTypeToSize[2][immType]; - DPRINTF(Predecoder, "Found opcode %#x.\n", nextByte); - if (UsesModRM[emi.numOpcodes - 1][nextByte]) { - state = ModRM; - } else if(immediateSize) { - state = Immediate; - } else { - emiIsReady = true; - state = Prefix; - } - } - offset++; - break; - case ModRM: - DPRINTF(Predecoder, "Found modrm byte %#x.\n", nextByte); - if (0) {//in 16 bit mode - //figure out 16 bit displacement size - if(nextByte & 0xC7 == 0x06 || - nextByte & 0xC0 == 0x80) - displacementSize = 2; - else if(nextByte & 0xC0 == 0x40) - displacementSize = 1; - else - displacementSize = 0; - } else { - //figure out 32/64 bit displacement size - if(nextByte & 0xC7 == 0x05 || - nextByte & 0xC0 == 0x80) - displacementSize = 4; - else if(nextByte & 0xC0 == 0x40) - displacementSize = 2; - else - displacementSize = 0; - } - //If there's an SIB, get that next. - //There is no SIB in 16 bit mode. - if(nextByte & 0x7 == 4 && - nextByte & 0xC0 != 0xC0) { - // && in 32/64 bit mode) - state = SIB; - } else if(displacementSize) { - state = Displacement; - } else if(immediateSize) { - state = Immediate; - } else { - emiIsReady = true; - state = Prefix; - } - //The ModRM byte is consumed no matter what - offset++; - break; - case SIB: - DPRINTF(Predecoder, "Found SIB byte %#x.\n", nextByte); - offset++; - if(displacementSize) { - state = Displacement; - } else if(immediateSize) { - state = Immediate; - } else { - emiIsReady = true; - state = Prefix; - } - break; - case Displacement: - //Gather up the displacement, or at least as much of it - //as we can get. - - //Figure out how many bytes we still need to get for the - //displacement. - toGet = displacementSize - displacementCollected; - //Figure out how many bytes are left in our "buffer" - remaining = sizeof(MachInst) - offset; - //Get as much as we need, up to the amount available. - toGet = toGet > remaining ? remaining : toGet; - - //Shift the bytes we want to be all the way to the right - partialDisp = fetchChunk >> (offset * 8); - //Mask off what we don't want - partialDisp &= mask(toGet * 8); - //Shift it over to overlay with our displacement. - partialDisp <<= (displacementCollected * 8); - //Put it into our displacement - emi.displacement |= partialDisp; - //Update how many bytes we've collected. - displacementCollected += toGet; - offset += toGet; - DPRINTF(Predecoder, "Collecting %d byte displacement, got %d bytes.\n", - displacementSize, displacementCollected); - - if(displacementSize == displacementCollected) { - //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) { - state = Immediate; - } else { - emiIsReady = true; - state = Prefix; - } - } - break; - case Immediate: - //Gather up the displacement, or at least as much of it - //as we can get - - //Figure out how many bytes we still need to get for the - //immediate. - toGet = immediateSize - immediateCollected; - //Figure out how many bytes are left in our "buffer" - remaining = sizeof(MachInst) - offset; - //Get as much as we need, up to the amount available. - toGet = toGet > remaining ? remaining : toGet; - - //Shift the bytes we want to be all the way to the right - partialDisp = fetchChunk >> (offset * 8); - //Mask off what we don't want - partialDisp &= mask(toGet * 8); - //Shift it over to overlay with our immediate. - partialDisp <<= (immediateCollected * 8); - //Put it into our immediate - emi.immediate |= partialDisp; - //Update how many bytes we've collected. - immediateCollected += toGet; - offset += toGet; - DPRINTF(Predecoder, "Collecting %d byte immediate, got %d bytes.\n", - immediateSize, immediateCollected); - - if(immediateSize == immediateCollected) - { - DPRINTF(Predecoder, "Collected immediate %#x.\n", - emi.immediate); - emiIsReady = true; - state = Prefix; - } - break; - default: - panic("Unrecognized state! %d\n", state); - } - if(offset == sizeof(MachInst)) - outOfBytes = true; - } - } + void process(); //Use this to give data to the predecoder. This should be used //when there is control flow. |