Gives separate methods for initiating and completing a memory access, which will...
authorKevin Lim <ktlim@umich.edu>
Wed, 15 Feb 2006 18:05:21 +0000 (13:05 -0500)
committerKevin Lim <ktlim@umich.edu>
Wed, 15 Feb 2006 18:05:21 +0000 (13:05 -0500)
arch/alpha/isa/mem.isa:
    Include methods that allow a memory operation to be split between the part that initiates the access, and the part that completes the access.  In these functions the Mem variable is explicitly declared; in the default execute functions, the Mem variable is still handled through %(op_decl)s.
arch/isa_parser.py:
    Include recording the type of the memory access variable so that it can be used if it needs to be explicitly declared in a template.

    Have memory operands consider themselves neither a source nor a destination to avoid including themselves on the op_src_decl list or the op_dest_decl list.

    Record op_src_decl and op_dest_decl lists to allow for declaring only source or destination operands.  This is needed for the split memory access methods.

--HG--
extra : convert_revision : f674f7a2f747ae40ba8c3a0933b0337c87ee0b6c

arch/alpha/isa/mem.isa
arch/isa_parser.py

index 45afd378c5767ea42eadde710f57e099fb22044f..1889daefcd4ecd934095eb62090886103f305212 100644 (file)
@@ -164,9 +164,24 @@ def template LoadStoreDeclare {{
         %(class_name)s(MachInst machInst);
 
         %(BasicExecDeclare)s
+
+        %(InitiateAccDeclare)s
+
+        %(CompleteAccDeclare)s
     };
 }};
 
+
+def template InitiateAccDeclare {{
+    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
+}};
+
+
+def template CompleteAccDeclare {{
+    Fault completeAcc(uint8_t *, %(CPU_exec_context)s *, Trace::InstRecord *) const;
+}};
+
+
 def template LoadStoreConstructor {{
     /** TODO: change op_class to AddrGenOp or something (requires
      * creating new member of OpClass enum in op_class.hh, updating
@@ -267,6 +282,54 @@ def template LoadExecute {{
 }};
 
 
+def template LoadInitiateAcc {{
+    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
+                                      Trace::InstRecord *traceData) const
+    {
+        Addr EA;
+        Fault fault = No_Fault;
+        %(mem_acc_type)s Mem = 0;
+
+        %(fp_enable_check)s;
+        %(op_src_decl)s;
+        %(op_rd)s;
+        %(ea_code)s;
+
+        if (fault == No_Fault) {
+            fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
+        }
+
+        return fault;
+    }
+}};
+
+
+def template LoadCompleteAcc {{
+    Fault %(class_name)s::completeAcc(uint8_t *data,
+                                      %(CPU_exec_context)s *xc,
+                                      Trace::InstRecord *traceData) const
+    {
+        Fault fault = No_Fault;
+        %(mem_acc_type)s Mem = 0;
+
+        %(fp_enable_check)s;
+        %(op_dest_decl)s;
+
+        memcpy(&Mem, data, sizeof(Mem));
+
+        if (fault == No_Fault) {
+            %(memacc_code)s;
+        }
+
+        if (fault == No_Fault) {
+            %(op_wb)s;
+        }
+
+        return fault;
+    }
+}};
+
+
 def template StoreMemAccExecute {{
     Fault
     %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
@@ -339,6 +402,60 @@ def template StoreExecute {{
     }
 }};
 
+def template StoreInitiateAcc {{
+    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
+                                      Trace::InstRecord *traceData) const
+    {
+        Addr EA;
+        Fault fault = No_Fault;
+        uint64_t write_result = 0;
+        %(mem_acc_type)s Mem = 0;
+
+        %(fp_enable_check)s;
+        %(op_src_decl)s;
+        %(op_rd)s;
+        %(ea_code)s;
+
+        if (fault == No_Fault) {
+            %(memacc_code)s;
+        }
+
+        if (fault == No_Fault) {
+            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
+                              memAccessFlags, &write_result);
+            if (traceData) { traceData->setData(Mem); }
+        }
+
+        return fault;
+    }
+}};
+
+
+def template StoreCompleteAcc {{
+    Fault %(class_name)s::completeAcc(uint8_t *data,
+                                      %(CPU_exec_context)s *xc,
+                                      Trace::InstRecord *traceData) const
+    {
+        Fault fault = No_Fault;
+        uint64_t write_result = 0;
+
+        %(fp_enable_check)s;
+        %(op_dest_decl)s;
+
+        memcpy(&write_result, data, sizeof(write_result));
+
+        if (fault == No_Fault) {
+            %(postacc_code)s;
+        }
+
+        if (fault == No_Fault) {
+            %(op_wb)s;
+        }
+
+        return fault;
+    }
+}};
+
 
 def template MiscMemAccExecute {{
     Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
@@ -380,6 +497,36 @@ def template MiscExecute {{
     }
 }};
 
+def template MiscInitiateAcc {{
+    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
+                                      Trace::InstRecord *traceData) const
+    {
+        Addr EA;
+        Fault fault = No_Fault;
+
+        %(fp_enable_check)s;
+        %(op_decl)s;
+        %(op_rd)s;
+        %(ea_code)s;
+
+        if (fault == No_Fault) {
+            %(memacc_code)s;
+        }
+
+        return No_Fault;
+    }
+}};
+
+
+def template MiscCompleteAcc {{
+    Fault %(class_name)s::completeAcc(uint8_t *data,
+                                      %(CPU_exec_context)s *xc,
+                                      Trace::InstRecord *traceData) const
+    {
+        return No_Fault;
+    }
+}};
+
 // load instructions use Ra as dest, so check for
 // Ra == 31 to detect nops
 def template LoadNopCheckDecode {{
@@ -455,13 +602,17 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
     # select templates
     memAccExecTemplate = eval(exec_template_base + 'MemAccExecute')
     fullExecTemplate = eval(exec_template_base + 'Execute')
+    initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
+    completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
 
     # (header_output, decoder_output, decode_block, exec_output)
     return (LoadStoreDeclare.subst(iop), LoadStoreConstructor.subst(iop),
             decode_template.subst(iop),
             EACompExecute.subst(ea_iop)
             + memAccExecTemplate.subst(memacc_iop)
-            + fullExecTemplate.subst(iop))
+            + fullExecTemplate.subst(iop)
+            + initiateAccTemplate.subst(iop)
+            + completeAccTemplate.subst(iop))
 }};
 
 
index 030bb5a7ce47cc8570513d37dec08326847d8685..96d3e84382e8f3d5d88759afc9d2ae4f6c420623 100755 (executable)
@@ -1138,6 +1138,7 @@ class Operand(object):
         # template must be careful not to use it if it doesn't apply.
         if self.isMem():
             self.mem_acc_size = self.makeAccSize()
+            self.mem_acc_type = self.ctype
 
     # Finalize additional fields (primarily code fields).  This step
     # is done separately since some of these fields may depend on the
@@ -1148,15 +1149,23 @@ class Operand(object):
         self.constructor = self.makeConstructor()
         self.op_decl = self.makeDecl()
 
+        if self.isMem():
+            self.is_src = ''
+            self.is_dest = ''
+
         if self.is_src:
             self.op_rd = self.makeRead()
+            self.op_src_decl = self.makeDecl()
         else:
             self.op_rd = ''
+            self.op_src_decl = ''
 
         if self.is_dest:
             self.op_wb = self.makeWrite()
+            self.op_dest_decl = self.makeDecl()
         else:
             self.op_wb = ''
+            self.op_dest_decl = ''
 
     def isMem(self):
         return 0
@@ -1589,6 +1598,14 @@ class CodeBlock:
 
         self.op_decl = self.operands.concatAttrStrings('op_decl')
 
+        is_src = lambda op: op.is_src
+        is_dest = lambda op: op.is_dest
+
+        self.op_src_decl = \
+                  self.operands.concatSomeAttrStrings(is_src, 'op_src_decl')
+        self.op_dest_decl = \
+                  self.operands.concatSomeAttrStrings(is_dest, 'op_dest_decl')
+
         self.op_rd = self.operands.concatAttrStrings('op_rd')
         self.op_wb = self.operands.concatAttrStrings('op_wb')
 
@@ -1596,6 +1613,7 @@ class CodeBlock:
 
         if self.operands.memOperand:
             self.mem_acc_size = self.operands.memOperand.mem_acc_size
+            self.mem_acc_type = self.operands.memOperand.mem_acc_type
 
         # Make a basic guess on the operand class (function unit type).
         # These are good enough for most cases, and will be overridden