isa_parser.py (7756:846fb3ffe0dc) isa_parser.py (7788:4dd870e2c91d)
1# Copyright (c) 2003-2005 The Regents of The University of Michigan
2# All rights reserved.
3#
4# Redistribution and use in source and binary forms, with or without
5# modification, are permitted provided that the following conditions are
6# met: redistributions of source code must retain the above copyright
7# notice, this list of conditions and the following disclaimer;
8# redistributions in binary form must reproduce the above copyright

--- 157 unchanged lines hidden (view full) ---

166
167 # Add in template itself in case it references any
168 # operands explicitly (like Mem)
169 compositeCode += ' ' + template
170
171 operands = SubOperandList(self.parser, compositeCode, d.operands)
172
173 myDict['op_decl'] = operands.concatAttrStrings('op_decl')
1# Copyright (c) 2003-2005 The Regents of The University of Michigan
2# All rights reserved.
3#
4# Redistribution and use in source and binary forms, with or without
5# modification, are permitted provided that the following conditions are
6# met: redistributions of source code must retain the above copyright
7# notice, this list of conditions and the following disclaimer;
8# redistributions in binary form must reproduce the above copyright

--- 157 unchanged lines hidden (view full) ---

166
167 # Add in template itself in case it references any
168 # operands explicitly (like Mem)
169 compositeCode += ' ' + template
170
171 operands = SubOperandList(self.parser, compositeCode, d.operands)
172
173 myDict['op_decl'] = operands.concatAttrStrings('op_decl')
174 if operands.readPC or operands.setPC:
175 myDict['op_decl'] += 'TheISA::PCState __parserAutoPCState;\n'
174
175 is_src = lambda op: op.is_src
176 is_dest = lambda op: op.is_dest
177
178 myDict['op_src_decl'] = \
179 operands.concatSomeAttrStrings(is_src, 'op_src_decl')
180 myDict['op_dest_decl'] = \
181 operands.concatSomeAttrStrings(is_dest, 'op_dest_decl')
182
183 myDict['op_rd'] = operands.concatAttrStrings('op_rd')
176
177 is_src = lambda op: op.is_src
178 is_dest = lambda op: op.is_dest
179
180 myDict['op_src_decl'] = \
181 operands.concatSomeAttrStrings(is_src, 'op_src_decl')
182 myDict['op_dest_decl'] = \
183 operands.concatSomeAttrStrings(is_dest, 'op_dest_decl')
184
185 myDict['op_rd'] = operands.concatAttrStrings('op_rd')
184 myDict['op_wb'] = operands.concatAttrStrings('op_wb')
186 if operands.readPC:
187 myDict['op_rd'] = '__parserAutoPCState = xc->pcState();\n' + \
188 myDict['op_rd']
185
189
190 # Compose the op_wb string. If we're going to write back the
191 # PC state because we changed some of its elements, we'll need to
192 # do that as early as possible. That allows later uncoordinated
193 # modifications to the PC to layer appropriately.
194 reordered = list(operands.items)
195 reordered.reverse()
196 op_wb_str = ''
197 pcWbStr = 'xc->pcState(__parserAutoPCState);\n'
198 for op_desc in reordered:
199 if op_desc.isPCPart() and op_desc.is_dest:
200 op_wb_str = op_desc.op_wb + pcWbStr + op_wb_str
201 pcWbStr = ''
202 else:
203 op_wb_str = op_desc.op_wb + op_wb_str
204 myDict['op_wb'] = op_wb_str
205
186 if d.operands.memOperand:
187 myDict['mem_acc_size'] = d.operands.memOperand.mem_acc_size
188 myDict['mem_acc_type'] = d.operands.memOperand.mem_acc_type
189
190 elif isinstance(d, dict):
191 # if the argument is a dictionary, we just use it.
192 myDict.update(d)
193 elif hasattr(d, '__dict__'):

--- 234 unchanged lines hidden (view full) ---

428 self.full_name = full_name
429 self.ext = ext
430 self.is_src = is_src
431 self.is_dest = is_dest
432 # The 'effective extension' (eff_ext) is either the actual
433 # extension, if one was explicitly provided, or the default.
434 if ext:
435 self.eff_ext = ext
206 if d.operands.memOperand:
207 myDict['mem_acc_size'] = d.operands.memOperand.mem_acc_size
208 myDict['mem_acc_type'] = d.operands.memOperand.mem_acc_type
209
210 elif isinstance(d, dict):
211 # if the argument is a dictionary, we just use it.
212 myDict.update(d)
213 elif hasattr(d, '__dict__'):

--- 234 unchanged lines hidden (view full) ---

448 self.full_name = full_name
449 self.ext = ext
450 self.is_src = is_src
451 self.is_dest = is_dest
452 # The 'effective extension' (eff_ext) is either the actual
453 # extension, if one was explicitly provided, or the default.
454 if ext:
455 self.eff_ext = ext
436 else:
456 elif hasattr(self, 'dflt_ext'):
437 self.eff_ext = self.dflt_ext
438
457 self.eff_ext = self.dflt_ext
458
439 self.size, self.ctype, self.is_signed = \
440 parser.operandTypeMap[self.eff_ext]
459 if hasattr(self, 'eff_ext'):
460 self.size, self.ctype, self.is_signed = \
461 parser.operandTypeMap[self.eff_ext]
441
442 # note that mem_acc_size is undefined for non-mem operands...
443 # template must be careful not to use it if it doesn't apply.
444 if self.isMem():
445 self.mem_acc_size = self.makeAccSize()
446 if self.ctype in ['Twin32_t', 'Twin64_t']:
447 self.mem_acc_type = 'Twin'
448 else:

--- 32 unchanged lines hidden (view full) ---

481 return 0
482
483 def isIntReg(self):
484 return 0
485
486 def isControlReg(self):
487 return 0
488
462
463 # note that mem_acc_size is undefined for non-mem operands...
464 # template must be careful not to use it if it doesn't apply.
465 if self.isMem():
466 self.mem_acc_size = self.makeAccSize()
467 if self.ctype in ['Twin32_t', 'Twin64_t']:
468 self.mem_acc_type = 'Twin'
469 else:

--- 32 unchanged lines hidden (view full) ---

502 return 0
503
504 def isIntReg(self):
505 return 0
506
507 def isControlReg(self):
508 return 0
509
510 def isPCState(self):
511 return 0
512
513 def isPCPart(self):
514 return self.isPCState() and self.reg_spec
515
489 def getFlags(self):
490 # note the empty slice '[:]' gives us a copy of self.flags[0]
491 # instead of a reference to it
492 my_flags = self.flags[0][:]
493 if self.is_src:
494 my_flags += self.flags[1]
495 if self.is_dest:
496 my_flags += self.flags[2]

--- 184 unchanged lines hidden (view full) ---

681 def makeAccSize(self):
682 return self.size
683
684class PCStateOperand(Operand):
685 def makeConstructor(self):
686 return ''
687
688 def makeRead(self):
516 def getFlags(self):
517 # note the empty slice '[:]' gives us a copy of self.flags[0]
518 # instead of a reference to it
519 my_flags = self.flags[0][:]
520 if self.is_src:
521 my_flags += self.flags[1]
522 if self.is_dest:
523 my_flags += self.flags[2]

--- 184 unchanged lines hidden (view full) ---

708 def makeAccSize(self):
709 return self.size
710
711class PCStateOperand(Operand):
712 def makeConstructor(self):
713 return ''
714
715 def makeRead(self):
689 return '%s = xc->pcState();\n' % self.base_name
716 if self.reg_spec:
717 # A component of the PC state.
718 return '%s = __parserAutoPCState.%s();\n' % \
719 (self.base_name, self.reg_spec)
720 else:
721 # The whole PC state itself.
722 return '%s = xc->pcState();\n' % self.base_name
690
691 def makeWrite(self):
723
724 def makeWrite(self):
692 return 'xc->pcState(%s);\n' % self.base_name
725 if self.reg_spec:
726 # A component of the PC state.
727 return '__parserAutoPCState.%s(%s);\n' % \
728 (self.reg_spec, self.base_name)
729 else:
730 # The whole PC state itself.
731 return 'xc->pcState(%s);\n' % self.base_name
693
694 def makeDecl(self):
732
733 def makeDecl(self):
695 return 'TheISA::PCState ' + self.base_name + ' M5_VAR_USED;\n';
734 ctype = 'TheISA::PCState'
735 if self.isPCPart():
736 ctype = self.ctype
737 return "%s %s;\n" % (ctype, self.base_name)
696
738
697class PCOperand(Operand):
698 def makeConstructor(self):
699 return ''
739 def isPCState(self):
740 return 1
700
741
701 def makeRead(self):
702 return '%s = xc->instAddr();\n' % self.base_name
703
704class UPCOperand(Operand):
705 def makeConstructor(self):
706 return ''
707
708 def makeRead(self):
709 if self.read_code != None:
710 return self.buildReadCode('microPC')
711 return '%s = xc->microPC();\n' % self.base_name
712
713class NPCOperand(Operand):
714 def makeConstructor(self):
715 return ''
716
717 def makeRead(self):
718 if self.read_code != None:
719 return self.buildReadCode('nextInstAddr')
720 return '%s = xc->nextInstAddr();\n' % self.base_name
721
722class OperandList(object):
723 '''Find all the operands in the given code block. Returns an operand
724 descriptor list (instance of class OperandList).'''
725 def __init__(self, parser, code):
726 self.items = []
727 self.bases = {}
728 # delete comments so we don't match on reg specifiers inside
729 code = commentRE.sub('', code)

--- 133 unchanged lines hidden (view full) ---

863 if not op_desc:
864 # if not, add a reference to it to this sub list
865 self.append(master_list.bases[op_base])
866
867 # start next search after end of current match
868 next_pos = match.end()
869 self.sort()
870 self.memOperand = None
742class OperandList(object):
743 '''Find all the operands in the given code block. Returns an operand
744 descriptor list (instance of class OperandList).'''
745 def __init__(self, parser, code):
746 self.items = []
747 self.bases = {}
748 # delete comments so we don't match on reg specifiers inside
749 code = commentRE.sub('', code)

--- 133 unchanged lines hidden (view full) ---

883 if not op_desc:
884 # if not, add a reference to it to this sub list
885 self.append(master_list.bases[op_base])
886
887 # start next search after end of current match
888 next_pos = match.end()
889 self.sort()
890 self.memOperand = None
891 # Whether the whole PC needs to be read so parts of it can be accessed
892 self.readPC = False
893 # Whether the whole PC needs to be written after parts of it were
894 # changed
895 self.setPC = False
896 # Whether this instruction manipulates the whole PC or parts of it.
897 # Mixing the two is a bad idea and flagged as an error.
898 self.pcPart = None
871 for op_desc in self.items:
899 for op_desc in self.items:
900 if op_desc.isPCPart():
901 self.readPC = True
902 if op_desc.is_dest:
903 self.setPC = True
904 if op_desc.isPCState():
905 if self.pcPart is not None:
906 if self.pcPart and not op_desc.isPCPart() or \
907 not self.pcPart and op_desc.isPCPart():
908 error("Mixed whole and partial PC state operands.")
909 self.pcPart = op_desc.isPCPart()
872 if op_desc.isMem():
873 if self.memOperand:
874 error("Code block has more than one memory operand.")
875 self.memOperand = op_desc
876
877# Regular expression object to match C++ comments
878# (used in findOperands())
879commentRE = re.compile(r'//.*\n')

--- 962 unchanged lines hidden (view full) ---

1842 write_code = val[6]
1843 else:
1844 write_code = None
1845 if len(val) > 7:
1846 error(lineno,
1847 'error: too many attributes for operand "%s"' %
1848 base_cls_name)
1849
910 if op_desc.isMem():
911 if self.memOperand:
912 error("Code block has more than one memory operand.")
913 self.memOperand = op_desc
914
915# Regular expression object to match C++ comments
916# (used in findOperands())
917commentRE = re.compile(r'//.*\n')

--- 962 unchanged lines hidden (view full) ---

1880 write_code = val[6]
1881 else:
1882 write_code = None
1883 if len(val) > 7:
1884 error(lineno,
1885 'error: too many attributes for operand "%s"' %
1886 base_cls_name)
1887
1850 (dflt_size, dflt_ctype, dflt_is_signed) = \
1851 self.operandTypeMap[dflt_ext]
1852 # Canonical flag structure is a triple of lists, where each list
1853 # indicates the set of flags implied by this operand always, when
1854 # used as a source, and when used as a dest, respectively.
1855 # For simplicity this can be initialized using a variety of fairly
1856 # obvious shortcuts; we convert these to canonical form here.
1857 if not flags:
1858 # no flags specified (e.g., 'None')
1859 flags = ( [], [], [] )

--- 6 unchanged lines hidden (view full) ---

1866 elif isinstance(flags, tuple):
1867 # it's a tuple: it should be a triple,
1868 # but each item could be a single string or a list
1869 (uncond_flags, src_flags, dest_flags) = flags
1870 flags = (makeList(uncond_flags),
1871 makeList(src_flags), makeList(dest_flags))
1872 # Accumulate attributes of new operand class in tmp_dict
1873 tmp_dict = {}
1888 # Canonical flag structure is a triple of lists, where each list
1889 # indicates the set of flags implied by this operand always, when
1890 # used as a source, and when used as a dest, respectively.
1891 # For simplicity this can be initialized using a variety of fairly
1892 # obvious shortcuts; we convert these to canonical form here.
1893 if not flags:
1894 # no flags specified (e.g., 'None')
1895 flags = ( [], [], [] )

--- 6 unchanged lines hidden (view full) ---

1902 elif isinstance(flags, tuple):
1903 # it's a tuple: it should be a triple,
1904 # but each item could be a single string or a list
1905 (uncond_flags, src_flags, dest_flags) = flags
1906 flags = (makeList(uncond_flags),
1907 makeList(src_flags), makeList(dest_flags))
1908 # Accumulate attributes of new operand class in tmp_dict
1909 tmp_dict = {}
1874 for attr in ('dflt_ext', 'reg_spec', 'flags', 'sort_pri',
1875 'dflt_size', 'dflt_ctype', 'dflt_is_signed',
1876 'read_code', 'write_code'):
1910 attrList = ['reg_spec', 'flags', 'sort_pri',
1911 'read_code', 'write_code']
1912 if dflt_ext:
1913 (dflt_size, dflt_ctype, dflt_is_signed) = \
1914 self.operandTypeMap[dflt_ext]
1915 attrList.extend(['dflt_size', 'dflt_ctype',
1916 'dflt_is_signed', 'dflt_ext'])
1917 for attr in attrList:
1877 tmp_dict[attr] = eval(attr)
1878 tmp_dict['base_name'] = op_name
1879 # New class name will be e.g. "IntReg_Ra"
1880 cls_name = base_cls_name + '_' + op_name
1881 # Evaluate string arg to get class object. Note that the
1882 # actual base class for "IntReg" is "IntRegOperand", i.e. we
1883 # have to append "Operand".
1884 try:

--- 170 unchanged lines hidden ---
1918 tmp_dict[attr] = eval(attr)
1919 tmp_dict['base_name'] = op_name
1920 # New class name will be e.g. "IntReg_Ra"
1921 cls_name = base_cls_name + '_' + op_name
1922 # Evaluate string arg to get class object. Note that the
1923 # actual base class for "IntReg" is "IntRegOperand", i.e. we
1924 # have to append "Operand".
1925 try:

--- 170 unchanged lines hidden ---