summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2009-04-19 04:14:31 -0700
committerGabe Black <gblack@eecs.umich.edu>2009-04-19 04:14:31 -0700
commit5f164ba720f16b93324f54d979bffef15f3c0f25 (patch)
tree72fb23035e250c523219c850d2b3d3b2c9c579bf /src/arch
parent93cccf7d198c8bf6a53481bc34ca9c19b1503196 (diff)
downloadgem5-5f164ba720f16b93324f54d979bffef15f3c0f25.tar.xz
X86: Actually handle 16 bit mode modrm.
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/x86/emulenv.cc27
1 files changed, 26 insertions, 1 deletions
diff --git a/src/arch/x86/emulenv.cc b/src/arch/x86/emulenv.cc
index 0d7b32130..8e4600a14 100644
--- a/src/arch/x86/emulenv.cc
+++ b/src/arch/x86/emulenv.cc
@@ -79,7 +79,32 @@ void EmulEnv::doModRM(const ExtMachInst & machInst)
index = NUM_INTREGS;
} else {
if (machInst.addrSize == 2) {
- warn("I'm not really using 16 bit MODRM like I'm supposed to!\n");
+ unsigned rm = machInst.modRM.rm;
+ if (rm <= 3) {
+ scale = 1;
+ if (rm < 2) {
+ base = INTREG_RBX;
+ } else {
+ base = INTREG_RBP;
+ }
+ index = (rm % 2) ? INTREG_RDI : INTREG_RSI;
+ } else {
+ scale = 0;
+ switch (rm) {
+ case 4:
+ base = INTREG_RSI;
+ break;
+ case 5:
+ base = INTREG_RDI;
+ break;
+ case 6:
+ base = INTREG_RBP;
+ break;
+ case 7:
+ base = INTREG_RBX;
+ break;
+ }
+ }
} else {
scale = 0;
base = machInst.modRM.rm | (machInst.rex.b << 3);