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