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 --- |