1# Copyright (c) 2014, 2016 ARM Limited 2# All rights reserved 3# 4# The license below extends only to copyright in the software and shall 5# not be construed as granting a license to any other intellectual 6# property including but not limited to intellectual property relating 7# to a hardware implementation of the functionality of the software 8# licensed hereunder. You may use the software subject to the license --- 479 unchanged lines hidden (view full) --- 488 return 0 489 490 def isCCReg(self): 491 return 0 492 493 def isControlReg(self): 494 return 0 495 |
496 def isVecReg(self): 497 return 0 498 499 def isVecElem(self): 500 return 0 501 |
502 def isPCState(self): 503 return 0 504 505 def isPCPart(self): 506 return self.isPCState() and self.reg_spec 507 508 def hasReadPred(self): 509 return self.read_predicate != None --- 149 unchanged lines hidden (view full) --- 659 wb = ''' 660 { 661 %s final_val = %s; 662 %s\n 663 if (traceData) { traceData->setData(final_val); } 664 }''' % (self.ctype, self.base_name, wp) 665 return wb 666 |
667class VecRegOperand(Operand): 668 reg_class = 'VecRegClass' 669 670 def __init__(self, parser, full_name, ext, is_src, is_dest): 671 Operand.__init__(self, parser, full_name, ext, is_src, is_dest) 672 self.elemExt = None 673 self.parser = parser 674 675 def isReg(self): 676 return 1 677 678 def isVecReg(self): 679 return 1 680 681 def makeDeclElem(self, elem_op): 682 (elem_name, elem_ext) = elem_op 683 (elem_spec, dflt_elem_ext, zeroing) = self.elems[elem_name] 684 if elem_ext: 685 ext = elem_ext 686 else: 687 ext = dflt_elem_ext 688 ctype = self.parser.operandTypeMap[ext] 689 return '\n\t%s %s = 0;' % (ctype, elem_name) 690 691 def makeDecl(self): 692 if not self.is_dest and self.is_src: 693 c_decl = '\t/* Vars for %s*/' % (self.base_name) 694 if hasattr(self, 'active_elems'): 695 if self.active_elems: 696 for elem in self.active_elems: 697 c_decl += self.makeDeclElem(elem) 698 return c_decl + '\t/* End vars for %s */\n' % (self.base_name) 699 else: 700 return '' 701 702 def makeConstructor(self, predRead, predWrite): 703 c_src = '' 704 c_dest = '' 705 706 numAccessNeeded = 1 707 708 if self.is_src: 709 c_src = src_reg_constructor % (self.reg_class, self.reg_spec) 710 711 if self.is_dest: 712 c_dest = dst_reg_constructor % (self.reg_class, self.reg_spec) 713 c_dest += '\n\t_numVecDestRegs++;' 714 715 return c_src + c_dest 716 717 # Read destination register to write 718 def makeReadWElem(self, elem_op): 719 (elem_name, elem_ext) = elem_op 720 (elem_spec, dflt_elem_ext, zeroing) = self.elems[elem_name] 721 if elem_ext: 722 ext = elem_ext 723 else: 724 ext = dflt_elem_ext 725 ctype = self.parser.operandTypeMap[ext] 726 c_read = '\t\t%s& %s = %s[%s];\n' % \ 727 (ctype, elem_name, self.base_name, elem_spec) 728 return c_read 729 730 def makeReadW(self, predWrite): 731 func = 'getWritableVecRegOperand' 732 if self.read_code != None: 733 return self.buildReadCode(func) 734 735 if predWrite: 736 rindex = '_destIndex++' 737 else: 738 rindex = '%d' % self.dest_reg_idx 739 740 c_readw = '\t\t%s& tmp_d%s = xc->%s(this, %s);\n'\ 741 % ('TheISA::VecRegContainer', rindex, func, rindex) 742 if self.elemExt: 743 c_readw += '\t\tauto %s = tmp_d%s.as<%s>();\n' % (self.base_name, 744 rindex, self.parser.operandTypeMap[self.elemExt]) 745 if self.ext: 746 c_readw += '\t\tauto %s = tmp_d%s.as<%s>();\n' % (self.base_name, 747 rindex, self.parser.operandTypeMap[self.ext]) 748 if hasattr(self, 'active_elems'): 749 if self.active_elems: 750 for elem in self.active_elems: 751 c_readw += self.makeReadWElem(elem) 752 return c_readw 753 754 # Normal source operand read 755 def makeReadElem(self, elem_op, name): 756 (elem_name, elem_ext) = elem_op 757 (elem_spec, dflt_elem_ext, zeroing) = self.elems[elem_name] 758 759 if elem_ext: 760 ext = elem_ext 761 else: 762 ext = dflt_elem_ext 763 ctype = self.parser.operandTypeMap[ext] 764 c_read = '\t\t%s = %s[%s];\n' % \ 765 (elem_name, name, elem_spec) 766 return c_read 767 768 def makeRead(self, predRead): 769 func = 'readVecRegOperand' 770 if self.read_code != None: 771 return self.buildReadCode(func) 772 773 if predRead: 774 rindex = '_sourceIndex++' 775 else: 776 rindex = '%d' % self.src_reg_idx 777 778 name = self.base_name 779 if self.is_dest and self.is_src: 780 name += '_merger' 781 782 c_read = '\t\t%s& tmp_s%s = xc->%s(this, %s);\n' \ 783 % ('const TheISA::VecRegContainer', rindex, func, rindex) 784 # If the parser has detected that elements are being access, create 785 # the appropriate view 786 if self.elemExt: 787 c_read += '\t\tauto %s = tmp_s%s.as<%s>();\n' % \ 788 (name, rindex, self.parser.operandTypeMap[self.elemExt]) 789 if self.ext: 790 c_read += '\t\tauto %s = tmp_s%s.as<%s>();\n' % \ 791 (name, rindex, self.parser.operandTypeMap[self.ext]) 792 if hasattr(self, 'active_elems'): 793 if self.active_elems: 794 for elem in self.active_elems: 795 c_read += self.makeReadElem(elem, name) 796 return c_read 797 798 def makeWrite(self, predWrite): 799 func = 'setVecRegOperand' 800 if self.write_code != None: 801 return self.buildWriteCode(func) 802 803 wb = ''' 804 if (traceData) { 805 panic("Vectors not supported yet in tracedata"); 806 /*traceData->setData(final_val);*/ 807 } 808 ''' 809 return wb 810 811 def finalize(self, predRead, predWrite): 812 super(VecRegOperand, self).finalize(predRead, predWrite) 813 if self.is_dest: 814 self.op_rd = self.makeReadW(predWrite) + self.op_rd 815 816class VecElemOperand(Operand): 817 reg_class = 'VectorElemClass' 818 819 def isReg(self): 820 return 1 821 822 def isVecElem(self): 823 return 1 824 825 def makeDecl(self): 826 if self.is_dest and not self.is_src: 827 return '\n\t%s %s;' % (self.ctype, self.base_name) 828 else: 829 return '' 830 831 def makeConstructor(self, predRead, predWrite): 832 c_src = '' 833 c_dest = '' 834 835 numAccessNeeded = 1 836 regId = 'RegId(%s, %s * numVecElemPerVecReg + elemIdx, %s)' % \ 837 (self.reg_class, self.reg_spec) 838 839 if self.is_src: 840 c_src = ('\n\t_srcRegIdx[_numSrcRegs++] = RegId(%s, %s, %s);' % 841 (self.reg_class, self.reg_spec, self.elem_spec)) 842 843 if self.is_dest: 844 c_dest = ('\n\t_destRegIdx[_numDestRegs++] = RegId(%s, %s, %s);' % 845 (self.reg_class, self.reg_spec, self.elem_spec)) 846 c_dest += '\n\t_numVecElemDestRegs++;' 847 return c_src + c_dest 848 849 def makeRead(self, predRead): 850 c_read = ('\n/* Elem is kept inside the operand description */' + 851 '\n\tVecElem %s = xc->readVecElemOperand(this, %d);' % 852 (self.base_name, self.src_reg_idx)) 853 return c_read 854 855 def makeWrite(self, predWrite): 856 c_write = ('\n/* Elem is kept inside the operand description */' + 857 '\n\txc->setVecElemOperand(this, %d, %s);' % 858 (self.dest_reg_idx, self.base_name)) 859 return c_write 860 |
861class CCRegOperand(Operand): 862 reg_class = 'CCRegClass' 863 864 def isReg(self): 865 return 1 866 867 def isCCReg(self): 868 return 1 --- 183 unchanged lines hidden (view full) --- 1052 while 1: 1053 match = parser.operandsRE.search(code, next_pos) 1054 if not match: 1055 # no more matches: we're done 1056 break 1057 op = match.groups() 1058 # regexp groups are operand full name, base, and extension 1059 (op_full, op_base, op_ext) = op |
1060 # If is a elem operand, define or update the corresponding 1061 # vector operand 1062 isElem = False 1063 if op_base in parser.elemToVector: 1064 isElem = True 1065 elem_op = (op_base, op_ext) 1066 op_base = parser.elemToVector[op_base] 1067 op_ext = '' # use the default one |
1068 # if the token following the operand is an assignment, this is 1069 # a destination (LHS), else it's a source (RHS) 1070 is_dest = (assignRE.match(code, match.end()) != None) 1071 is_src = not is_dest |
1072 |
1073 # see if we've already seen this one 1074 op_desc = self.find_base(op_base) 1075 if op_desc: |
1076 if op_ext and op_ext != '' and op_desc.ext != op_ext: 1077 error ('Inconsistent extensions for operand %s: %s - %s' \ 1078 % (op_base, op_desc.ext, op_ext)) |
1079 op_desc.is_src = op_desc.is_src or is_src 1080 op_desc.is_dest = op_desc.is_dest or is_dest |
1081 if isElem: 1082 (elem_base, elem_ext) = elem_op 1083 found = False 1084 for ae in op_desc.active_elems: 1085 (ae_base, ae_ext) = ae 1086 if ae_base == elem_base: 1087 if ae_ext != elem_ext: 1088 error('Inconsistent extensions for elem' 1089 ' operand %s' % elem_base) 1090 else: 1091 found = True 1092 if not found: 1093 op_desc.active_elems.append(elem_op) |
1094 else: 1095 # new operand: create new descriptor 1096 op_desc = parser.operandNameMap[op_base](parser, 1097 op_full, op_ext, is_src, is_dest) |
1098 # if operand is a vector elem, add the corresponding vector 1099 # operand if not already done 1100 if isElem: 1101 op_desc.elemExt = elem_op[1] 1102 op_desc.active_elems = [elem_op] |
1103 self.append(op_desc) 1104 # start next search after end of current match 1105 next_pos = match.end() 1106 self.sort() 1107 # enumerate source & dest register operands... used in building 1108 # constructor later 1109 self.numSrcRegs = 0 1110 self.numDestRegs = 0 1111 self.numFPDestRegs = 0 1112 self.numIntDestRegs = 0 |
1113 self.numVecDestRegs = 0 |
1114 self.numCCDestRegs = 0 1115 self.numMiscDestRegs = 0 1116 self.memOperand = None 1117 1118 # Flags to keep track if one or more operands are to be read/written 1119 # conditionally. 1120 self.predRead = False 1121 self.predWrite = False --- 5 unchanged lines hidden (view full) --- 1127 self.numSrcRegs += 1 1128 if op_desc.is_dest: 1129 op_desc.dest_reg_idx = self.numDestRegs 1130 self.numDestRegs += 1 1131 if op_desc.isFloatReg(): 1132 self.numFPDestRegs += 1 1133 elif op_desc.isIntReg(): 1134 self.numIntDestRegs += 1 |
1135 elif op_desc.isVecReg(): 1136 self.numVecDestRegs += 1 |
1137 elif op_desc.isCCReg(): 1138 self.numCCDestRegs += 1 1139 elif op_desc.isControlReg(): 1140 self.numMiscDestRegs += 1 1141 elif op_desc.isMem(): 1142 if self.memOperand: 1143 error("Code block has more than one memory operand.") 1144 self.memOperand = op_desc --- 74 unchanged lines hidden (view full) --- 1219 while 1: 1220 match = parser.operandsRE.search(code, next_pos) 1221 if not match: 1222 # no more matches: we're done 1223 break 1224 op = match.groups() 1225 # regexp groups are operand full name, base, and extension 1226 (op_full, op_base, op_ext) = op |
1227 # If is a elem operand, define or update the corresponding 1228 # vector operand 1229 if op_base in parser.elemToVector: 1230 elem_op = op_base 1231 op_base = parser.elemToVector[elem_op] |
1232 # find this op in the master list 1233 op_desc = master_list.find_base(op_base) 1234 if not op_desc: 1235 error('Found operand %s which is not in the master list!' 1236 % op_base) 1237 else: 1238 # See if we've already found this operand 1239 op_desc = self.find_base(op_base) --- 95 unchanged lines hidden (view full) --- 1335 self.operands = OperandList(parser, compositeCode) 1336 1337 # The header of the constructor declares the variables to be used 1338 # in the body of the constructor. 1339 header = '' 1340 header += '\n\t_numSrcRegs = 0;' 1341 header += '\n\t_numDestRegs = 0;' 1342 header += '\n\t_numFPDestRegs = 0;' |
1343 header += '\n\t_numVecDestRegs = 0;' 1344 header += '\n\t_numVecElemDestRegs = 0;' |
1345 header += '\n\t_numIntDestRegs = 0;' 1346 header += '\n\t_numCCDestRegs = 0;' 1347 1348 self.constructor = header + \ 1349 self.operands.concatAttrStrings('constructor') 1350 1351 self.flags = self.operands.concatAttrLists('flags') 1352 --- 28 unchanged lines hidden (view full) --- 1381 # usually set in FP instructions because of the base 1382 # register 1383 if 'IsFloating' in self.flags: 1384 self.op_class = 'FloatMemReadOp' 1385 else: 1386 self.op_class = 'MemReadOp' 1387 elif 'IsFloating' in self.flags: 1388 self.op_class = 'FloatAddOp' |
1389 elif 'IsVector' in self.flags: 1390 self.op_class = 'SimdAddOp' |
1391 else: 1392 self.op_class = 'IntAluOp' 1393 1394 # add flag initialization to contructor here to include 1395 # any flags added via opt_args 1396 self.constructor += makeFlagConstructor(self.flags) 1397 1398 # if 'IsFloating' is set, add call to the FP enable check 1399 # function (which should be provided by isa_desc via a declare) |
1400 # if 'IsVector' is set, add call to the Vector enable check 1401 # function (which should be provided by isa_desc via a declare) |
1402 if 'IsFloating' in self.flags: 1403 self.fp_enable_check = 'fault = checkFpEnableFault(xc);' |
1404 elif 'IsVector' in self.flags: 1405 self.fp_enable_check = 'fault = checkVecEnableFault(xc);' |
1406 else: 1407 self.fp_enable_check = '' 1408 1409############## 1410# Stack: a simple stack object. Used for both formats (formatStack) 1411# and default cases (defaultStack). Simply wraps a list to give more 1412# stack-like syntax and enable initialization with an argument list 1413# (as opposed to an argument that's a list). --- 1124 unchanged lines hidden (view full) --- 2538 # Accumulate attributes of new operand class in tmp_dict 2539 tmp_dict = {} 2540 attrList = ['reg_spec', 'flags', 'sort_pri', 2541 'read_code', 'write_code', 2542 'read_predicate', 'write_predicate'] 2543 if dflt_ext: 2544 dflt_ctype = self.operandTypeMap[dflt_ext] 2545 attrList.extend(['dflt_ctype', 'dflt_ext']) |
2546 # reg_spec is either just a string or a dictionary 2547 # (for elems of vector) 2548 if isinstance(reg_spec, tuple): 2549 (reg_spec, elem_spec) = reg_spec 2550 if isinstance(elem_spec, str): 2551 attrList.append('elem_spec') 2552 else: 2553 assert(isinstance(elem_spec, dict)) 2554 elems = elem_spec 2555 attrList.append('elems') |
2556 for attr in attrList: 2557 tmp_dict[attr] = eval(attr) 2558 tmp_dict['base_name'] = op_name 2559 2560 # New class name will be e.g. "IntReg_Ra" 2561 cls_name = base_cls_name + '_' + op_name 2562 # Evaluate string arg to get class object. Note that the 2563 # actual base class for "IntReg" is "IntRegOperand", i.e. we --- 7 unchanged lines hidden (view full) --- 2571 # <cls_name> as a subclass of <base_cls> with the attributes 2572 # in tmp_dict, just as if we evaluated a class declaration. 2573 operand_name[op_name] = type(cls_name, (base_cls,), tmp_dict) 2574 2575 self.operandNameMap = operand_name 2576 2577 # Define operand variables. 2578 operands = user_dict.keys() |
2579 # Add the elems defined in the vector operands and 2580 # build a map elem -> vector (used in OperandList) 2581 elem_to_vec = {} 2582 for op in user_dict.keys(): 2583 if hasattr(self.operandNameMap[op], 'elems'): 2584 for elem in self.operandNameMap[op].elems.keys(): 2585 operands.append(elem) 2586 elem_to_vec[elem] = op 2587 self.elemToVector = elem_to_vec |
2588 extensions = self.operandTypeMap.keys() 2589 2590 operandsREString = r''' 2591 (?<!\w) # neg. lookbehind assertion: prevent partial matches 2592 ((%s)(?:_(%s))?) # match: operand with optional '_' then suffix 2593 (?!\w) # neg. lookahead assertion: prevent partial matches 2594 ''' % (string.join(operands, '|'), string.join(extensions, '|')) 2595 --- 121 unchanged lines hidden --- |