changeset ea379b718ff4 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=ea379b718ff4
description:
        ISA Parser: Allow predication of source and destination registers
        This patch is meant for allowing predicated reads and writes. Note that 
this
        predication is different from the ISA provided predication. They way we
        currently provide the ISA description for X86, we read/write registers 
that
        do not need to be actually read/written. This is likely to be true for 
other
        ISAs as well. This patch allows for read and write predicates to be 
associated
        with operands. It allows for the register indices for source and 
destination
        registers to be decided at the time when the microop is constructed. The
        run time indicies come in to play only when the at least one of the
        predicates has been provided. This patch will not affect any of the 
ISAs that
        do not provide these predicates. Also the patch assumes that the order 
in
        which operands appear in any function of the microop is same across all 
the
        functions of the microops. A subsequent patch will enable predication 
for the
        x86 ISA.

diffstat:

 src/arch/isa_parser.py |  258 +++++++++++++++++++++++++++++++++++-------------
 1 files changed, 188 insertions(+), 70 deletions(-)

diffs (truncated from 477 to 300 lines):

diff -r f9633070689b -r ea379b718ff4 src/arch/isa_parser.py
--- a/src/arch/isa_parser.py    Tue Sep 11 09:24:45 2012 -0500
+++ b/src/arch/isa_parser.py    Sun Jun 03 10:59:04 2012 -0500
@@ -174,6 +174,16 @@
             if operands.readPC or operands.setPC:
                 myDict['op_decl'] += 'TheISA::PCState __parserAutoPCState;\n'
 
+            # In case there are predicated register reads and write, declare
+            # the variables for register indicies. It is being assumed that
+            # all the operands in the OperandList are also in the
+            # SubOperandList and in the same order. Otherwise, it is
+            # expected that predication would not be used for the operands.
+            if operands.predRead:
+                myDict['op_decl'] += 'uint8_t _sourceIndex = 0;\n'
+            if operands.predWrite:
+                myDict['op_decl'] += 'uint8_t M5_VAR_USED _destIndex = 0;\n'
+
             is_src = lambda op: op.is_src
             is_dest = lambda op: op.is_dest
 
@@ -453,21 +463,23 @@
     # Finalize additional fields (primarily code fields).  This step
     # is done separately since some of these fields may depend on the
     # register index enumeration that hasn't been performed yet at the
-    # time of __init__().
-    def finalize(self):
+    # time of __init__(). The register index enumeration is affected
+    # by predicated register reads/writes. Hence, we forward the flags
+    # that indicate whether or not predication is in use.
+    def finalize(self, predRead, predWrite):
         self.flags = self.getFlags()
-        self.constructor = self.makeConstructor()
+        self.constructor = self.makeConstructor(predRead, predWrite)
         self.op_decl = self.makeDecl()
 
         if self.is_src:
-            self.op_rd = self.makeRead()
+            self.op_rd = self.makeRead(predRead)
             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_wb = self.makeWrite(predWrite)
             self.op_dest_decl = self.makeDecl()
         else:
             self.op_wb = ''
@@ -494,6 +506,12 @@
     def isPCPart(self):
         return self.isPCState() and self.reg_spec
 
+    def hasReadPred(self):
+        return self.read_predicate != None
+
+    def hasWritePred(self):
+        return self.write_predicate != None
+
     def getFlags(self):
         # note the empty slice '[:]' gives us a copy of self.flags[0]
         # instead of a reference to it
@@ -516,35 +534,68 @@
     def isIntReg(self):
         return 1
 
-    def makeConstructor(self):
-        c = ''
+    def makeConstructor(self, predRead, predWrite):
+        c_src = ''
+        c_dest = ''
+
         if self.is_src:
-            c += '\n\t_srcRegIdx[%d] = %s;' % \
-                 (self.src_reg_idx, self.reg_spec)
+            c_src = '\n\t_srcRegIdx[_numSrcRegs++] = %s;' % (self.reg_spec)
+            if self.hasReadPred():
+                c_src = '\n\tif (%s) {%s\n\t}' % \
+                        (self.read_predicate, c_src)
+
         if self.is_dest:
-            c += '\n\t_destRegIdx[%d] = %s;' % \
-                 (self.dest_reg_idx, self.reg_spec)
-        return c
+            c_dest = '\n\t_destRegIdx[_numDestRegs++] = %s;' % \
+                    (self.reg_spec)
+            c_dest += '\n\t_numIntDestRegs++;'
+            if self.hasWritePred():
+                c_dest = '\n\tif (%s) {%s\n\t}' % \
+                         (self.write_predicate, c_dest)
 
-    def makeRead(self):
+        return c_src + c_dest
+
+    def makeRead(self, predRead):
         if (self.ctype == 'float' or self.ctype == 'double'):
             error('Attempt to read integer register as FP')
         if self.read_code != None:
             return self.buildReadCode('readIntRegOperand')
-        int_reg_val = 'xc->readIntRegOperand(this, %d)' % self.src_reg_idx
+
+        int_reg_val = ''
+        if predRead:
+            int_reg_val = 'xc->readIntRegOperand(this, _sourceIndex++)'
+            if self.hasReadPred():
+                int_reg_val = '(%s) ? %s : 0' % \
+                              (self.read_predicate, int_reg_val)
+        else:
+            int_reg_val = 'xc->readIntRegOperand(this, %d)' % self.src_reg_idx
+
         return '%s = %s;\n' % (self.base_name, int_reg_val)
 
-    def makeWrite(self):
+    def makeWrite(self, predWrite):
         if (self.ctype == 'float' or self.ctype == 'double'):
             error('Attempt to write integer register as FP')
         if self.write_code != None:
             return self.buildWriteCode('setIntRegOperand')
+
+        if predWrite:
+            wp = 'true'
+            if self.hasWritePred():
+                wp = self.write_predicate
+
+            wcond = 'if (%s)' % (wp)
+            windex = '_destIndex++'
+        else:
+            wcond = ''
+            windex = '%d' % self.dest_reg_idx
+
         wb = '''
+        %s
         {
             %s final_val = %s;
-            xc->setIntRegOperand(this, %d, final_val);\n
+            xc->setIntRegOperand(this, %s, final_val);\n
             if (traceData) { traceData->setData(final_val); }
-        }''' % (self.ctype, self.base_name, self.dest_reg_idx)
+        }''' % (wcond, self.ctype, self.base_name, windex)
+
         return wb
 
 class FloatRegOperand(Operand):
@@ -554,17 +605,23 @@
     def isFloatReg(self):
         return 1
 
-    def makeConstructor(self):
-        c = ''
+    def makeConstructor(self, predRead, predWrite):
+        c_src = ''
+        c_dest = ''
+
         if self.is_src:
-            c += '\n\t_srcRegIdx[%d] = %s + FP_Base_DepTag;' % \
-                 (self.src_reg_idx, self.reg_spec)
+            c_src = '\n\t_srcRegIdx[_numSrcRegs++] = %s + FP_Base_DepTag;' % \
+                    (self.reg_spec)
+
         if self.is_dest:
-            c += '\n\t_destRegIdx[%d] = %s + FP_Base_DepTag;' % \
-                 (self.dest_reg_idx, self.reg_spec)
-        return c
+            c_dest = \
+              '\n\t_destRegIdx[_numDestRegs++] = %s + FP_Base_DepTag;' % \
+              (self.reg_spec)
+            c_dest += '\n\t_numFPDestRegs++;'
 
-    def makeRead(self):
+        return c_src + c_dest
+
+    def makeRead(self, predRead):
         bit_select = 0
         if (self.ctype == 'float' or self.ctype == 'double'):
             func = 'readFloatRegOperand'
@@ -572,22 +629,35 @@
             func = 'readFloatRegOperandBits'
         if self.read_code != None:
             return self.buildReadCode(func)
-        return '%s = xc->%s(this, %d);\n' % \
-            (self.base_name, func, self.src_reg_idx)
 
-    def makeWrite(self):
+        if predRead:
+            rindex = '_sourceIndex++'
+        else:
+            rindex = '%d' % self.src_reg_idx
+
+        return '%s = xc->%s(this, %s);\n' % \
+            (self.base_name, func, rindex)
+
+    def makeWrite(self, predWrite):
         if (self.ctype == 'float' or self.ctype == 'double'):
             func = 'setFloatRegOperand'
         else:
             func = 'setFloatRegOperandBits'
         if self.write_code != None:
             return self.buildWriteCode(func)
+
+        if predWrite:
+            wp = '_destIndex++'
+        else:
+            wp = '%d' % self.dest_reg_idx
+        wp = 'xc->%s(this, %s, final_val);' % (func, wp)
+
         wb = '''
         {
             %s final_val = %s;
-            xc->%s(this, %d, final_val);\n
+            %s\n
             if (traceData) { traceData->setData(final_val); }
-        }''' % (self.ctype, self.base_name, func, self.dest_reg_idx)
+        }''' % (self.ctype, self.base_name, wp)
         return wb
 
 class ControlRegOperand(Operand):
@@ -597,41 +667,60 @@
     def isControlReg(self):
         return 1
 
-    def makeConstructor(self):
-        c = ''
+    def makeConstructor(self, predRead, predWrite):
+        c_src = ''
+        c_dest = ''
+
         if self.is_src:
-            c += '\n\t_srcRegIdx[%d] = %s + Ctrl_Base_DepTag;' % \
-                 (self.src_reg_idx, self.reg_spec)
+            c_src = \
+              '\n\t_srcRegIdx[_numSrcRegs++] = %s + Ctrl_Base_DepTag;' % \
+              (self.reg_spec)
+
         if self.is_dest:
-            c += '\n\t_destRegIdx[%d] = %s + Ctrl_Base_DepTag;' % \
-                 (self.dest_reg_idx, self.reg_spec)
-        return c
+            c_dest = \
+              '\n\t_destRegIdx[_numDestRegs++] = %s + Ctrl_Base_DepTag;' % \
+              (self.reg_spec)
 
-    def makeRead(self):
+        return c_src + c_dest
+
+    def makeRead(self, predRead):
         bit_select = 0
         if (self.ctype == 'float' or self.ctype == 'double'):
             error('Attempt to read control register as FP')
         if self.read_code != None:
             return self.buildReadCode('readMiscRegOperand')
+
+        if predRead:
+            rindex = '_sourceIndex++'
+        else:
+            rindex = '%d' % self.src_reg_idx
+
         return '%s = xc->readMiscRegOperand(this, %s);\n' % \
-            (self.base_name, self.src_reg_idx)
+            (self.base_name, rindex)
 
-    def makeWrite(self):
+    def makeWrite(self, predWrite):
         if (self.ctype == 'float' or self.ctype == 'double'):
             error('Attempt to write control register as FP')
         if self.write_code != None:
             return self.buildWriteCode('setMiscRegOperand')
+
+        if predWrite:
+            windex = '_destIndex++'
+        else:
+            windex = '%d' % self.dest_reg_idx
+
         wb = 'xc->setMiscRegOperand(this, %s, %s);\n' % \
-             (self.dest_reg_idx, self.base_name)
+             (windex, self.base_name)
         wb += 'if (traceData) { traceData->setData(%s); }' % \
               self.base_name
+
         return wb
 
 class MemOperand(Operand):
     def isMem(self):
         return 1
 
-    def makeConstructor(self):
+    def makeConstructor(self, predRead, predWrite):
         return ''
 
     def makeDecl(self):
@@ -640,21 +729,21 @@
         # Declare memory data variable.
         return '%s %s = 0;\n' % (self.ctype, self.base_name)
 
-    def makeRead(self):
+    def makeRead(self, predRead):
         if self.read_code != None:
             return self.buildReadCode()
         return ''
 
-    def makeWrite(self):
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to