summaryrefslogtreecommitdiff
path: root/src/arch/x86/predecoder.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/x86/predecoder.cc')
-rw-r--r--src/arch/x86/predecoder.cc79
1 files changed, 46 insertions, 33 deletions
diff --git a/src/arch/x86/predecoder.cc b/src/arch/x86/predecoder.cc
index 5ea960b36..fbed4fe41 100644
--- a/src/arch/x86/predecoder.cc
+++ b/src/arch/x86/predecoder.cc
@@ -78,22 +78,22 @@ namespace X86ISA
uint8_t nextByte = getNextByte();
switch(state)
{
- case Prefix:
+ case PrefixState:
state = doPrefixState(nextByte);
break;
- case Opcode:
+ case OpcodeState:
state = doOpcodeState(nextByte);
break;
- case ModRM:
+ case ModRMState:
state = doModRMState(nextByte);
break;
- case SIB:
+ case SIBState:
state = doSIBState(nextByte);
break;
- case Displacement:
+ case DisplacementState:
state = doDisplacementState();
break;
- case Immediate:
+ case ImmediateState:
state = doImmediateState();
break;
case ErrorState:
@@ -109,7 +109,7 @@ namespace X86ISA
Predecoder::State Predecoder::doPrefixState(uint8_t nextByte)
{
uint8_t prefix = Prefixes[nextByte];
- State nextState = Prefix;
+ State nextState = PrefixState;
if(prefix)
consumeByte();
switch(prefix)
@@ -149,13 +149,13 @@ namespace X86ISA
case Repne:
DPRINTF(Predecoder, "Found repne prefix.\n");
break;
- case Rex:
+ case RexPrefix:
DPRINTF(Predecoder, "Found Rex prefix %#x.\n", nextByte);
- emi.rexPrefix = nextByte;
+ emi.rex = nextByte;
break;
case 0:
- emi.numOpcodes = 0;
- nextState = Opcode;
+ emi.opcode.num = 0;
+ nextState = OpcodeState;
break;
default:
panic("Unrecognized prefix %#x\n", nextByte);
@@ -168,18 +168,29 @@ namespace X86ISA
Predecoder::State Predecoder::doOpcodeState(uint8_t nextByte)
{
State nextState = ErrorState;
- emi.numOpcodes++;
+ emi.opcode.num++;
//We can't handle 3+ byte opcodes right now
- assert(emi.numOpcodes < 2);
+ assert(emi.opcode.num < 3);
consumeByte();
- if(nextByte == 0xf0)
+ if(emi.opcode.num == 1 && nextByte == 0x0f)
{
- nextState = Opcode;
+ nextState = OpcodeState;
DPRINTF(Predecoder, "Found two byte opcode.\n");
+ emi.opcode.prefixA = nextByte;
+ }
+ else if(emi.opcode.num == 2 &&
+ (nextByte == 0x0f ||
+ (nextByte & 0xf8) == 0x38))
+ {
+ panic("Three byte opcodes aren't yet supported!\n");
+ nextState = OpcodeState;
+ DPRINTF(Predecoder, "Found three byte opcode.\n");
+ emi.opcode.prefixB = nextByte;
}
else
{
DPRINTF(Predecoder, "Found opcode %#x.\n", nextByte);
+ emi.opcode.op = nextByte;
//Prepare for any immediate/displacement we might need
immediateCollected = 0;
@@ -190,22 +201,22 @@ namespace X86ISA
//Figure out how big of an immediate we'll retreive based
//on the opcode.
int immType = ImmediateType[
- emi.numOpcodes - 1][nextByte];
+ emi.opcode.num - 1][nextByte];
if(0) //16 bit mode
immediateSize = ImmediateTypeToSize[0][immType];
- else if(!(emi.rexPrefix & 0x4)) //32 bit mode
+ else if(!(emi.rex & 0x4)) //32 bit mode
immediateSize = ImmediateTypeToSize[1][immType];
else //64 bit mode
immediateSize = ImmediateTypeToSize[2][immType];
//Determine what to expect next
- if (UsesModRM[emi.numOpcodes - 1][nextByte]) {
- nextState = ModRM;
+ if (UsesModRM[emi.opcode.num - 1][nextByte]) {
+ nextState = ModRMState;
} else if(immediateSize) {
- nextState = Immediate;
+ nextState = ImmediateState;
} else {
emiIsReady = true;
- nextState = Prefix;
+ nextState = PrefixState;
}
}
return nextState;
@@ -217,6 +228,7 @@ namespace X86ISA
Predecoder::State Predecoder::doModRMState(uint8_t nextByte)
{
State nextState = ErrorState;
+ emi.modRM = nextByte;
DPRINTF(Predecoder, "Found modrm byte %#x.\n", nextByte);
if (0) {//FIXME in 16 bit mode
//figure out 16 bit displacement size
@@ -242,14 +254,14 @@ namespace X86ISA
if(nextByte & 0x7 == 4 &&
nextByte & 0xC0 != 0xC0) {
// && in 32/64 bit mode)
- nextState = SIB;
+ nextState = SIBState;
} else if(displacementSize) {
- nextState = Displacement;
+ nextState = DisplacementState;
} else if(immediateSize) {
- nextState = Immediate;
+ nextState = ImmediateState;
} else {
emiIsReady = true;
- nextState = Prefix;
+ nextState = PrefixState;
}
//The ModRM byte is consumed no matter what
consumeByte();
@@ -262,15 +274,16 @@ namespace X86ISA
Predecoder::State Predecoder::doSIBState(uint8_t nextByte)
{
State nextState = ErrorState;
+ emi.sib = nextByte;
DPRINTF(Predecoder, "Found SIB byte %#x.\n", nextByte);
consumeByte();
if(displacementSize) {
- nextState = Displacement;
+ nextState = DisplacementState;
} else if(immediateSize) {
- nextState = Immediate;
+ nextState = ImmediateState;
} else {
emiIsReady = true;
- nextState = Prefix;
+ nextState = PrefixState;
}
return nextState;
}
@@ -307,14 +320,14 @@ namespace X86ISA
DPRINTF(Predecoder, "Collected displacement %#x.\n",
emi.displacement);
if(immediateSize) {
- nextState = Immediate;
+ nextState = ImmediateState;
} else {
emiIsReady = true;
- nextState = Prefix;
+ nextState = PrefixState;
}
}
else
- nextState = Displacement;
+ nextState = DisplacementState;
return nextState;
}
@@ -336,10 +349,10 @@ namespace X86ISA
DPRINTF(Predecoder, "Collected immediate %#x.\n",
emi.immediate);
emiIsReady = true;
- nextState = Prefix;
+ nextState = PrefixState;
}
else
- nextState = Immediate;
+ nextState = ImmediateState;
return nextState;
}
}