summaryrefslogtreecommitdiff
path: root/src/arch/x86/predecoder.cc
diff options
context:
space:
mode:
authorSteve Reinhardt <stever@eecs.umich.edu>2007-07-22 08:10:59 -0700
committerSteve Reinhardt <stever@eecs.umich.edu>2007-07-22 08:10:59 -0700
commitd5c74657c986a1c6730393d76da6d8859ae7fca4 (patch)
tree9de36c35735432220f010b98a25b0f380d13ef6a /src/arch/x86/predecoder.cc
parent1c2d5f5e64387527efe495a59f6946e7b539a543 (diff)
parent03730edc45e2e00bdec58dabc84e94c632634a1a (diff)
downloadgem5-d5c74657c986a1c6730393d76da6d8859ae7fca4.tar.xz
Merge more changes in from head.
--HG-- extra : convert_revision : 8f170f2754eccdb424a35b5b077225abcf6eee72
Diffstat (limited to 'src/arch/x86/predecoder.cc')
-rw-r--r--src/arch/x86/predecoder.cc51
1 files changed, 42 insertions, 9 deletions
diff --git a/src/arch/x86/predecoder.cc b/src/arch/x86/predecoder.cc
index 49f76699b..295ca10a4 100644
--- a/src/arch/x86/predecoder.cc
+++ b/src/arch/x86/predecoder.cc
@@ -72,7 +72,6 @@ namespace X86ISA
immediateCollected = 0;
emi.immediate = 0;
- displacementCollected = 0;
emi.displacement = 0;
emi.modRM = 0;
@@ -235,14 +234,42 @@ namespace X86ISA
logOpSize = 1; // 16 bit operand size
}
+ //Set the actual op size
+ emi.opSize = 1 << logOpSize;
+
+ //Figure out the effective address size. This can be overriden to
+ //a fixed value at the decoder level.
+ int logAddrSize;
+ if(/*FIXME 64-bit mode*/1)
+ {
+ if(emi.legacy.addr)
+ logAddrSize = 2; // 32 bit address size
+ else
+ logAddrSize = 3; // 64 bit address size
+ }
+ else if(/*FIXME default 32*/1)
+ {
+ if(emi.legacy.addr)
+ logAddrSize = 1; // 16 bit address size
+ else
+ logAddrSize = 2; // 32 bit address size
+ }
+ else // 16 bit default operand size
+ {
+ if(emi.legacy.addr)
+ logAddrSize = 2; // 32 bit address size
+ else
+ logAddrSize = 1; // 16 bit address size
+ }
+
+ //Set the actual address size
+ emi.addrSize = 1 << logAddrSize;
+
//Figure out how big of an immediate we'll retreive based
//on the opcode.
int immType = ImmediateType[emi.opcode.num - 1][nextByte];
immediateSize = SizeTypeToSize[logOpSize - 1][immType];
- //Set the actual op size
- emi.opSize = 1 << logOpSize;
-
//Determine what to expect next
if (UsesModRM[emi.opcode.num - 1][nextByte]) {
nextState = ModRMState;
@@ -277,8 +304,7 @@ namespace X86ISA
displacementSize = 0;
} else {
//figure out 32/64 bit displacement size
- if(modRM.mod == 0 && (modRM.rm == 4 || modRM.rm == 5)
- || modRM.mod == 2)
+ if(modRM.mod == 0 && modRM.rm == 5 || modRM.mod == 2)
displacementSize = 4;
else if(modRM.mod == 1)
displacementSize = 1;
@@ -313,6 +339,8 @@ namespace X86ISA
emi.sib = nextByte;
DPRINTF(Predecoder, "Found SIB byte %#x.\n", nextByte);
consumeByte();
+ if(emi.modRM.mod == 0 && emi.sib.base == 5)
+ displacementSize = 4;
if(displacementSize) {
nextState = DisplacementState;
} else if(immediateSize) {
@@ -330,14 +358,16 @@ namespace X86ISA
{
State nextState = ErrorState;
- getImmediate(displacementCollected,
+ getImmediate(immediateCollected,
emi.displacement,
displacementSize);
DPRINTF(Predecoder, "Collecting %d byte displacement, got %d bytes.\n",
- displacementSize, displacementCollected);
+ displacementSize, immediateCollected);
- if(displacementSize == displacementCollected) {
+ if(displacementSize == immediateCollected) {
+ //Reset this for other immediates.
+ immediateCollected = 0;
//Sign extend the displacement
switch(displacementSize)
{
@@ -382,6 +412,9 @@ namespace X86ISA
if(immediateSize == immediateCollected)
{
+ //Reset this for other immediates.
+ immediateCollected = 0;
+
//XXX Warning! The following is an observed pattern and might
//not always be true!