X86: Take advantage of the new meta register.
authorGabe Black <gblack@eecs.umich.edu>
Thu, 12 Jun 2008 04:51:14 +0000 (00:51 -0400)
committerGabe Black <gblack@eecs.umich.edu>
Thu, 12 Jun 2008 04:51:14 +0000 (00:51 -0400)
src/arch/x86/predecoder.cc

index 407a09ec037c1b96b75ede56da95f9a167c9dc97..1d415ffea38c20989092de2b3e1a718ecd4c7d59 100644 (file)
@@ -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,
  * 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;