summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/x86/predecoder.cc32
1 files changed, 25 insertions, 7 deletions
diff --git a/src/arch/x86/predecoder.cc b/src/arch/x86/predecoder.cc
index 407a09ec0..1d415ffea 100644
--- a/src/arch/x86/predecoder.cc
+++ b/src/arch/x86/predecoder.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * Copyright (c) 2007-2008 The Hewlett-Packard Development Company
* All rights reserved.
*
* Redistribution and use of this software in source and binary forms,
@@ -55,9 +55,11 @@
* Authors: Gabe Black
*/
+#include "arch/x86/miscregs.hh"
#include "arch/x86/predecoder.hh"
#include "base/misc.hh"
#include "base/trace.hh"
+#include "cpu/thread_context.hh"
#include "sim/host.hh"
namespace X86ISA
@@ -78,7 +80,9 @@ namespace X86ISA
emi.modRM = 0;
emi.sib = 0;
- emi.mode = 0;
+ HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
+ emi.mode.mode = m5reg.mode;
+ emi.mode.submode = m5reg.submode;
}
void Predecoder::process()
@@ -209,10 +213,12 @@ namespace X86ISA
DPRINTF(Predecoder, "Found opcode %#x.\n", nextByte);
emi.opcode.op = nextByte;
+ SegAttr csAttr = tc->readMiscRegNoEffect(MISCREG_CS_ATTR);
+
//Figure out the effective operand size. This can be overriden to
//a fixed value at the decoder level.
int logOpSize;
- if(/*FIXME long mode*/1)
+ if (emi.mode.submode == SixtyFourBitMode)
{
if(emi.rex.w)
logOpSize = 3; // 64 bit operand size
@@ -221,7 +227,7 @@ namespace X86ISA
else
logOpSize = 2; // 32 bit operand size
}
- else if(/*FIXME default 32*/1)
+ else if(csAttr.defaultSize)
{
if(emi.legacy.op)
logOpSize = 1; // 16 bit operand size
@@ -242,14 +248,14 @@ namespace X86ISA
//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.mode.submode == SixtyFourBitMode)
{
if(emi.legacy.addr)
logAddrSize = 2; // 32 bit address size
else
logAddrSize = 3; // 64 bit address size
}
- else if(/*FIXME default 32*/1)
+ else if(csAttr.defaultSize)
{
if(emi.legacy.addr)
logAddrSize = 1; // 16 bit address size
@@ -264,6 +270,16 @@ namespace X86ISA
logAddrSize = 1; // 16 bit address size
}
+ SegAttr ssAttr = tc->readMiscRegNoEffect(MISCREG_SS_ATTR);
+ //Figure out the effective stack width. This can be overriden to
+ //a fixed value at the decoder level.
+ if(emi.mode.submode == SixtyFourBitMode)
+ emi.stackSize = 8; // 64 bit stack width
+ else if(ssAttr.defaultSize)
+ emi.stackSize = 4; // 32 bit stack width
+ else
+ emi.stackSize = 2; // 16 bit stack width
+
//Set the actual address size
emi.addrSize = 1 << logAddrSize;
@@ -299,7 +315,9 @@ namespace X86ISA
ModRM modRM;
modRM = nextByte;
DPRINTF(Predecoder, "Found modrm byte %#x.\n", nextByte);
- if (0) {//FIXME in 16 bit mode
+ SegAttr csAttr = tc->readMiscRegNoEffect(MISCREG_CS_ATTR);
+ if (emi.mode.submode != SixtyFourBitMode &&
+ !csAttr.defaultSize) {
//figure out 16 bit displacement size
if(modRM.mod == 0 && modRM.rm == 6 || modRM.mod == 2)
displacementSize = 2;