# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Steve Reinhardt
-# Korey Sewell
import os
import sys
t_DOT = r'\.'
t_COLON = r':'
t_DBLCOLON = r'::'
-t_ASTERISK = r'\*'
+t_ASTERISK = r'\*'
# Identifiers and reserved words
reserved_map = { }
#
# A decode block looks like:
-# decode <field1> [, <field2>]* [default <inst>] { ... }
+# decode <field1> [, <field2>]* [default <inst>] { ... }
#
def p_decode_block(t):
'decode_block : DECODE ID opt_default LBRACE decode_stmt_list RBRACE'
ctype = 'uint%d_t' % size
is_signed = 0
elif desc == 'float':
- is_signed = 1 # shouldn't really matter
+ is_signed = 1 # shouldn't really matter
if size == 32:
ctype = 'float'
elif size == 64:
def isControlReg(self):
return 0
+ def isIControlReg(self):
+ return 0
+
def getFlags(self):
# note the empty slice '[:]' gives us a copy of self.flags[0]
# instead of a reference to it
self.base_name
return wb
+class IControlRegOperand(Operand):
+ def isReg(self):
+ return 1
+
+ def isIControlReg(self):
+ return 1
+
+ def makeConstructor(self):
+ c = ''
+ if self.is_src:
+ c += '\n\t_srcRegIdx[%d] = %s + Ctrl_Base_DepTag;' % \
+ (self.src_reg_idx, 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
+
+ def makeRead(self):
+ bit_select = 0
+ if (self.ctype == 'float' or self.ctype == 'double'):
+ error(0, 'Attempt to read control register as FP')
+ base = 'xc->readMiscReg(%s)' % self.reg_spec
+ if self.size == self.dflt_size:
+ return '%s = %s;\n' % (self.base_name, base)
+ else:
+ return '%s = bits(%s, %d, 0);\n' % \
+ (self.base_name, base, self.size-1)
+
+ def makeWrite(self):
+ if (self.ctype == 'float' or self.ctype == 'double'):
+ error(0, 'Attempt to write control register as FP')
+ wb = 'xc->setMiscReg(%s, %s);\n' % \
+ (self.reg_spec, self.base_name)
+ wb += 'if (traceData) { traceData->setData(%s); }' % \
+ self.base_name
+ return wb
+
class ControlBitfieldOperand(ControlRegOperand):
def makeRead(self):
bit_select = 0
def makeAccSize(self):
return self.size
+class UPCOperand(Operand):
+ def makeConstructor(self):
+ return ''
+
+ def makeRead(self):
+ return '%s = xc->readMicroPC();\n' % self.base_name
+
+ def makeWrite(self):
+ return 'xc->setMicroPC(%s);\n' % self.base_name
+
+class NUPCOperand(Operand):
+ def makeConstructor(self):
+ return ''
+
+ def makeRead(self):
+ return '%s = xc->readNextMicroPC();\n' % self.base_name
+
+ def makeWrite(self):
+ return 'xc->setNextMicroPC(%s);\n' % self.base_name
class NPCOperand(Operand):
def makeConstructor(self):
operands = userDict.keys()
operandsREString = (r'''
- (?<![\w\.]) # neg. lookbehind assertion: prevent partial matches
+ (?<![\w\.]) # neg. lookbehind assertion: prevent partial matches
((%s)(?:\.(\w+))?) # match: operand with optional '.' then suffix
- (?![\w\.]) # neg. lookahead assertion: prevent partial matches
+ (?![\w\.]) # neg. lookahead assertion: prevent partial matches
'''
% string.join(operands, '|'))
global operandsWithExtRE
operandsWithExtRE = re.compile(operandsWithExtREString, re.MULTILINE)
+maxInstSrcRegs = 0
+maxInstDestRegs = 0
class OperandList:
if self.memOperand:
error(0, "Code block has more than one memory operand.")
self.memOperand = op_desc
+ global maxInstSrcRegs
+ global maxInstDestRegs
+ if maxInstSrcRegs < self.numSrcRegs:
+ maxInstSrcRegs = self.numSrcRegs
+ if maxInstDestRegs < self.numDestRegs:
+ maxInstDestRegs = self.numDestRegs
# now make a final pass to finalize op_desc fields that may depend
# on the register enumeration
for op_desc in self.items:
%(decode_function)s
'''
+max_inst_regs_template = '''
+/*
+ * DO NOT EDIT THIS FILE!!!
+ *
+ * It was automatically generated from the ISA description in %(filename)s
+ */
+
+namespace %(namespace)s {
+
+ const int MaxInstSrcRegs = %(MaxInstSrcRegs)d;
+ const int MaxInstDestRegs = %(MaxInstDestRegs)d;
+
+} // namespace %(namespace)s
+
+'''
+
# Update the output file only if the new contents are different from
# the current contents. Minimizes the files that need to be rebuilt
update_if_needed(output_dir + '/' + cpu.filename,
file_template % vars())
+ # The variable names here are hacky, but this will creat local variables
+ # which will be referenced in vars() which have the value of the globals.
+ global maxInstSrcRegs
+ MaxInstSrcRegs = maxInstSrcRegs
+ global maxInstDestRegs
+ MaxInstDestRegs = maxInstDestRegs
+ # max_inst_regs.hh
+ update_if_needed(output_dir + '/max_inst_regs.hh', \
+ max_inst_regs_template % vars())
+
# global list of CpuModel objects (see cpu_models.py)
cpu_models = []