x86 work that hadn't been checked in.
authorGabe Black <gblack@eecs.umich.edu>
Thu, 31 May 2007 13:50:35 +0000 (13:50 +0000)
committerGabe Black <gblack@eecs.umich.edu>
Thu, 31 May 2007 13:50:35 +0000 (13:50 +0000)
src/arch/x86/isa/decoder/one_byte_opcodes.isa:
    Give the "MOV" instruction the format of it's arguments. This will likely need to be completely overhauled in the near future.
src/arch/x86/predecoder.cc:
src/arch/x86/predecoder.hh:
    Make the predecoder explicitly reset itself rather than counting on it happening naturally.
src/arch/x86/predecoder_tables.cc:
    Fix the immediate size table
src/arch/x86/regfile.cc:
    nextnpc is bogus

--HG--
extra : convert_revision : 0926701fedaab41817e64bb05410a25174484a5a

src/arch/x86/isa/decoder/one_byte_opcodes.isa
src/arch/x86/predecoder.cc
src/arch/x86/predecoder.hh
src/arch/x86/predecoder_tables.cc
src/arch/x86/regfile.cc

index 4e044363b5021a18645af2d54f00e68e59422081..12f3c5f96b8411bf73409f977d215b2a5acc7708 100644 (file)
             0x7: xchg_Ev_Gv();
         }
         0x11: decode OPCODE_OP_BOTTOM3 {
-            0x0: Inst::MOV(); //mov_Eb_Gb();
-            0x1: Inst::MOV(); //mov_Ev_Gv();
-            0x2: Inst::MOV(); //mov_Gb_Eb();
-            0x3: Inst::MOV(); //mov_Gv_Ev();
-            0x4: Inst::MOV(); //mov_MwRv_Sw();
+            0x0: Inst::MOV(Eb, Gb);
+            0x1: Inst::MOV(Ev, Gv);
+            0x2: Inst::MOV(Gb, Eb);
+            0x3: Inst::MOV(Gv, Ev);
+            0x4: mov_MwRv_Sw(); //What to do with this one?
             0x5: lea_Gv_M();
             0x6: mov_Sw_MwRv();
             0x7: group10_Ev(); //Make sure this is Ev
index 573012ee6d3cf3e9b94fd500974b33c4d1ed5207..65f951f44ea162ade6c54376a0c27f78a581978d 100644 (file)
 
 namespace X86ISA
 {
+    void Predecoder::reset()
+    {
+        origPC = basePC + offset;
+        DPRINTF(Predecoder, "Setting origPC to %#x\n", origPC);
+        emi.opcode.num = 0;
+
+        immediateCollected = 0;
+        emi.immediate = 0;
+        displacementCollected = 0;
+        emi.displacement = 0;
+
+        emi.modRM = 0;
+        emi.sib = 0;
+    }
+
     void Predecoder::process()
     {
         //This function drives the predecoder state machine.
@@ -78,6 +93,9 @@ namespace X86ISA
             uint8_t nextByte = getNextByte();
             switch(state)
             {
+              case ResetState:
+                reset();
+                state = PrefixState;
               case PrefixState:
                 state = doPrefixState(nextByte);
                 break;
@@ -150,7 +168,6 @@ namespace X86ISA
             emi.rex = nextByte;
             break;
           case 0:
-            emi.opcode.num = 0;
             nextState = OpcodeState;
             break;
           default:
@@ -188,12 +205,6 @@ namespace X86ISA
             DPRINTF(Predecoder, "Found opcode %#x.\n", nextByte);
             emi.opcode.op = nextByte;
 
-            //Prepare for any immediate/displacement we might need
-            immediateCollected = 0;
-            emi.immediate = 0;
-            displacementCollected = 0;
-            emi.displacement = 0;
-
             //Figure out the effective operand size. This can be overriden to
             //a fixed value at the decoder level.
             if(/*FIXME long mode*/1)
@@ -229,14 +240,11 @@ namespace X86ISA
             if (UsesModRM[emi.opcode.num - 1][nextByte]) {
                 nextState = ModRMState;
             } else {
-                //If there's no modRM byte, set it to 0 so we can detect
-                //that later.
-                emi.modRM = 0;
                 if(immediateSize) {
                     nextState = ImmediateState;
                 } else {
                     emiIsReady = true;
-                    nextState = PrefixState;
+                    nextState = ResetState;
                 }
             }
         }
@@ -282,7 +290,7 @@ namespace X86ISA
             nextState = ImmediateState;
         } else {
             emiIsReady = true;
-            nextState = PrefixState;
+            nextState = ResetState;
         }
         //The ModRM byte is consumed no matter what
         consumeByte();
@@ -304,7 +312,7 @@ namespace X86ISA
             nextState = ImmediateState;
         } else {
             emiIsReady = true;
-            nextState = PrefixState;
+            nextState = ResetState;
         }
         return nextState;
     }
@@ -344,7 +352,7 @@ namespace X86ISA
                 nextState = ImmediateState;
             } else {
                 emiIsReady = true;
-                nextState = PrefixState;
+                nextState = ResetState;
             }
         }
         else
@@ -380,7 +388,7 @@ namespace X86ISA
             DPRINTF(Predecoder, "Collected immediate %#x.\n",
                     emi.immediate);
             emiIsReady = true;
-            nextState = PrefixState;
+            nextState = ResetState;
         }
         else
             nextState = ImmediateState;
index 6562ab9f5e8754f4006be09c2a1e118de4add23a..9b4d36d4ae64e932c65c985766c0cda74ae358f0 100644 (file)
@@ -60,6 +60,8 @@
 
 #include "arch/x86/types.hh"
 #include "base/bitfield.hh"
+#include "base/misc.hh"
+#include "base/trace.hh"
 #include "sim/host.hh"
 
 class ThreadContext;
@@ -81,6 +83,8 @@ namespace X86ISA
         MachInst fetchChunk;
         //The pc of the start of fetchChunk
         Addr basePC;
+        //The pc the current instruction started at
+        Addr origPC;
         //The offset into fetchChunk of current processing
         int offset;
         //The extended machine instruction being generated
@@ -130,6 +134,8 @@ namespace X86ISA
                 outOfBytes = true;
         }
 
+        void reset();
+
         //State machine state
       protected:
         //Whether or not we're out of bytes
@@ -144,6 +150,7 @@ namespace X86ISA
         int immediateCollected;
 
         enum State {
+            ResetState,
             PrefixState,
             OpcodeState,
             ModRMState,
@@ -166,9 +173,9 @@ namespace X86ISA
 
       public:
         Predecoder(ThreadContext * _tc) :
-            tc(_tc), basePC(0), offset(0),
+            tc(_tc), basePC(0), origPC(0), offset(0),
             outOfBytes(true), emiIsReady(false),
-            state(PrefixState)
+            state(ResetState)
         {}
 
         ThreadContext * getTC()
@@ -219,6 +226,15 @@ namespace X86ISA
             emiIsReady = false;
             return emi;
         }
+
+        int getInstSize()
+        {
+            DPRINTF(Predecoder,
+                    "Calculating the instruction size: "
+                    "basePC: %#x offset: %#x origPC: %#x\n",
+                    basePC, offset, origPC);
+            return basePC + offset - origPC;
+        }
     };
 };
 
index 38b9c57a389caf4de98ec8f91314d95e399cf5ee..6fe54b719c334615ef77e59c7d7cdc6f6e0d9d07 100644 (file)
@@ -170,7 +170,7 @@ namespace X86ISA
 //       noimm byte word dword qword oword vword zword enter pointer
         {0,    1,   2,   4,    8,    16,   2,    2,    3,    4      }, //16 bit
         {0,    1,   2,   4,    8,    16,   4,    4,    3,    6      }, //32 bit
-        {0,    1,   2,   4,    8,    16,   4,    8,    3,    0      }  //64 bit
+        {0,    1,   2,   4,    8,    16,   8,    4,    3,    0      }  //64 bit
     };
 
     //This table determines the immediate type. The first index is the
index 568eb1d94464b03d340f5e9ee6ba02e2d390b915..f54f531e212ed4bc7925bdc5dfa29d5026c74a61 100644 (file)
@@ -117,7 +117,8 @@ void RegFile::setNextPC(Addr val)
 
 Addr RegFile::readNextNPC()
 {
-    return nextRip + sizeof(MachInst);
+    //There's no way to know how big the -next- instruction will be.
+    return nextRip + 1;
 }
 
 void RegFile::setNextNPC(Addr val)