X86: Add functions to read and write to an exec context.
authorGabe Black <gblack@eecs.umich.edu>
Fri, 27 Jul 2007 05:08:35 +0000 (22:08 -0700)
committerGabe Black <gblack@eecs.umich.edu>
Fri, 27 Jul 2007 05:08:35 +0000 (22:08 -0700)
These functions take care of calling the thread contexts read and write functions with the right sized data type, and handle unaligned accesses.

--HG--
extra : convert_revision : b4b59ab2b22559333035185946bae3eab316c879

src/arch/x86/insts/microldstop.hh
src/arch/x86/isa/microops/ldstop.isa

index f90d6670ef7bd1d81b524f080025cbf87546e1ad..ae03d176e99c8002f7a87d5941e964c3087213c6 100644 (file)
@@ -96,6 +96,62 @@ namespace X86ISA
 
         std::string generateDisassembly(Addr pc,
             const SymbolTable *symtab) const;
+
+        template<class Context, class MemType>
+        Fault read(Context *xc, Addr EA, MemType & Mem, unsigned flags) const
+        {
+            Fault fault = NoFault;
+            int size = dataSize;
+            Addr alignedEA = EA & ~(dataSize - 1);
+            if (EA != alignedEA)
+                size *= 2;
+            switch(size)
+            {
+              case 1:
+                fault = xc->read(alignedEA, (uint8_t&)Mem, flags);
+                break;
+              case 2:
+                fault = xc->read(alignedEA, (uint16_t&)Mem, flags);
+                break;
+              case 4:
+                fault = xc->read(alignedEA, (uint32_t&)Mem, flags);
+                break;
+              case 8:
+                fault = xc->read(alignedEA, (uint64_t&)Mem, flags);
+                break;
+              default:
+                panic("Bad operand size %d!\n", size);
+            }
+            return fault;
+        }
+
+        template<class Context, class MemType>
+        Fault write(Context *xc, MemType & Mem, Addr EA, unsigned flags) const
+        {
+            Fault fault = NoFault;
+            int size = dataSize;
+            Addr alignedEA = EA & ~(dataSize - 1);
+            if (EA != alignedEA)
+                size *= 2;
+            switch(size)
+            {
+              case 1:
+                fault = xc->write((uint8_t&)Mem, alignedEA, flags, 0);
+                break;
+              case 2:
+                fault = xc->write((uint16_t&)Mem, alignedEA, flags, 0);
+                break;
+              case 4:
+                fault = xc->write((uint32_t&)Mem, alignedEA, flags, 0);
+                break;
+              case 8:
+                fault = xc->write((uint64_t&)Mem, alignedEA, flags, 0);
+                break;
+              default:
+                panic("Bad operand size %d!\n", size);
+            }
+            return fault;
+        }
     };
 }
 
index ccf519963c72498db5b773390723bb467bac5575..18cbc6082742e854e2eaae89817e85c34250201c 100644 (file)
@@ -123,24 +123,9 @@ def template MicroLoadExecute {{
         %(ea_code)s;
         DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
 
-        unsigned flags = 0;
-        switch(dataSize)
-        {
-          case 1:
-            fault = xc->read(EA, (uint8_t&)Mem, flags);
-            break;
-          case 2:
-            fault = xc->read(EA, (uint16_t&)Mem, flags);
-            break;
-          case 4:
-            fault = xc->read(EA, (uint32_t&)Mem, flags);
-            break;
-          case 8:
-            fault = xc->read(EA, (uint64_t&)Mem, flags);
-            break;
-          default:
-            panic("Bad operand size!\n");
-        }
+        fault = read(xc, EA, Mem, 0);
+        int offset = EA & (dataSize - 1);
+        Mem = bits(Mem, (offset + dataSize) * 8 - 1,  offset * 8);
 
         if(fault == NoFault)
         {
@@ -167,24 +152,8 @@ def template MicroLoadInitiateAcc {{
         %(ea_code)s;
         DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
 
-        unsigned flags = 0;
-        switch(dataSize)
-        {
-          case 1:
-            fault = xc->read(EA, (uint8_t&)Mem, flags);
-            break;
-          case 2:
-            fault = xc->read(EA, (uint16_t&)Mem, flags);
-            break;
-          case 4:
-            fault = xc->read(EA, (uint32_t&)Mem, flags);
-            break;
-          case 8:
-            fault = xc->read(EA, (uint64_t&)Mem, flags);
-            break;
-          default:
-            panic("Bad operand size!\n");
-        }
+        int offset = EA & (dataSize - 1);
+        fault = read(xc, EA, Mem, offset);
 
         return fault;
     }
@@ -201,6 +170,8 @@ def template MicroLoadCompleteAcc {{
         %(op_rd)s;
 
         Mem = pkt->get<typeof(Mem)>();
+        int offset = pkt->flags;
+        Mem = bits(Mem, (offset + dataSize) * 8 - 1,  offset * 8);
         %(code)s;
 
         if(fault == NoFault)
@@ -230,30 +201,13 @@ def template MicroStoreExecute {{
 
         if(fault == NoFault)
         {
-            unsigned flags = 0;
-            uint64_t *res = 0;
-            switch(dataSize)
+            Mem = Mem << ((EA & (dataSize - 1)) * 8);
+            fault = write(xc, Mem, EA, 0);
+            if(fault == NoFault)
             {
-              case 1:
-                fault = xc->write((uint8_t&)Mem, EA, flags, res);
-                break;
-              case 2:
-                fault = xc->write((uint16_t&)Mem, EA, flags, res);
-                break;
-              case 4:
-                fault = xc->write((uint32_t&)Mem, EA, flags, res);
-                break;
-              case 8:
-                fault = xc->write((uint64_t&)Mem, EA, flags, res);
-                break;
-              default:
-                panic("Bad operand size!\n");
+                %(op_wb)s;
             }
         }
-        if(fault == NoFault)
-        {
-            %(op_wb)s;
-        }
 
         return fault;
     }
@@ -275,30 +229,13 @@ def template MicroStoreInitiateAcc {{
 
         if(fault == NoFault)
         {
-            unsigned flags = 0;
-            uint64_t *res = 0;
-            switch(dataSize)
+            Mem = Mem << ((EA & (dataSize - 1)) * 8);
+            fault = write(xc, Mem, EA, 0);
+            if(fault == NoFault)
             {
-              case 1:
-                fault = xc->write((uint8_t&)Mem, EA, flags, res);
-                break;
-              case 2:
-                fault = xc->write((uint16_t&)Mem, EA, flags, res);
-                break;
-              case 4:
-                fault = xc->write((uint32_t&)Mem, EA, flags, res);
-                break;
-              case 8:
-                fault = xc->write((uint64_t&)Mem, EA, flags, res);
-                break;
-              default:
-                panic("Bad operand size!\n");
+                %(op_wb)s;
             }
         }
-        if(fault == NoFault)
-        {
-            %(op_wb)s;
-        }
         return fault;
     }
 }};