isa_parser.py (3792:dae368e56d0e) isa_parser.py (3823:1c8f87aa103e)
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

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

803
804################
805# Format object.
806#
807# A format object encapsulates an instruction format. It must provide
808# a defineInst() method that generates the code for an instruction
809# definition.
810
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

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

803
804################
805# Format object.
806#
807# A format object encapsulates an instruction format. It must provide
808# a defineInst() method that generates the code for an instruction
809# definition.
810
811exportContextSymbols = ('InstObjParams', 'makeList', 're', 'string')
811exportContextSymbols = ('InstObjParams', 'CodeBlock',
812 'makeList', 're', 'string')
812
813exportContext = {}
814
815def updateExportContext():
816 exportContext.update(exportDict(*exportContextSymbols))
817 exportContext.update(templateMap)
818
819def exportDict(*symNames):

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

997
998
999####################
1000# Template objects.
1001#
1002# Template objects are format strings that allow substitution from
1003# the attribute spaces of other objects (e.g. InstObjParams instances).
1004
813
814exportContext = {}
815
816def updateExportContext():
817 exportContext.update(exportDict(*exportContextSymbols))
818 exportContext.update(templateMap)
819
820def exportDict(*symNames):

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

998
999
1000####################
1001# Template objects.
1002#
1003# Template objects are format strings that allow substitution from
1004# the attribute spaces of other objects (e.g. InstObjParams instances).
1005
1005labelRE = re.compile(r'[^%]%\(([^\)]+)\)[sd]')
1006
1007class Template:
1008 def __init__(self, t):
1009 self.template = t
1010
1011 def subst(self, d):
1006class Template:
1007 def __init__(self, t):
1008 self.template = t
1009
1010 def subst(self, d):
1012 myDict = None
1013
1011 # Start with the template namespace. Make a copy since we're
1012 # going to modify it.
1013 myDict = templateMap.copy()
1014 # if the argument is a dictionary, we just use it.
1015 if isinstance(d, dict):
1016 myDict.update(d)
1017 # if the argument is an object, we use its attribute map.
1018 elif hasattr(d, '__dict__'):
1019 myDict.update(d.__dict__)
1020 else:
1021 raise TypeError, "Template.subst() arg must be or have dictionary"
1014 # Protect non-Python-dict substitutions (e.g. if there's a printf
1015 # in the templated C++ code)
1016 template = protect_non_subst_percents(self.template)
1017 # CPU-model-specific substitutions are handled later (in GenCode).
1018 template = protect_cpu_symbols(template)
1022 # Protect non-Python-dict substitutions (e.g. if there's a printf
1023 # in the templated C++ code)
1024 template = protect_non_subst_percents(self.template)
1025 # CPU-model-specific substitutions are handled later (in GenCode).
1026 template = protect_cpu_symbols(template)
1019
1020 # if we're dealing with an InstObjParams object, we need to be a
1021 # little more sophisticated. Otherwise, just do what we've always
1022 # done
1023 if isinstance(d, InstObjParams):
1024 # The instruction wide parameters are already formed, but the
1025 # parameters which are only function wide still need to be
1026 # generated.
1027 perFuncNames = ['op_decl', 'op_src_decl', 'op_dest_decl', \
1028 'op_rd', 'op_wb', 'mem_acc_size', 'mem_acc_type']
1029 compositeCode = ''
1030
1031 myDict = templateMap.copy()
1032 myDict.update(d.__dict__)
1033 # The "operands" and "snippets" attributes of the InstObjParams
1034 # objects are for internal use and not substitution.
1035 del myDict['operands']
1036 del myDict['snippets']
1037
1038 for name in labelRE.findall(template):
1039 # Don't try to find a snippet to go with things that will
1040 # match against attributes of d, or that are other templates,
1041 # or that we're going to generate later, or that we've already
1042 # found.
1043 if not hasattr(d, name) and \
1044 not templateMap.has_key(name) and \
1045 not myDict.has_key(name) and \
1046 name not in perFuncNames:
1047 myDict[name] = d.snippets[name]
1048 if isinstance(myDict[name], str):
1049 myDict[name] = substMungedOpNames(substBitOps(myDict[name]))
1050 compositeCode += (" " + myDict[name])
1051 operands = SubOperandList(compositeCode, d.operands)
1052
1053 myDict['op_decl'] = operands.concatAttrStrings('op_decl')
1054
1055 is_src = lambda op: op.is_src
1056 is_dest = lambda op: op.is_dest
1057
1058 myDict['op_src_decl'] = \
1059 operands.concatSomeAttrStrings(is_src, 'op_src_decl')
1060 myDict['op_dest_decl'] = \
1061 operands.concatSomeAttrStrings(is_dest, 'op_dest_decl')
1062
1063 myDict['op_rd'] = operands.concatAttrStrings('op_rd')
1064 myDict['op_wb'] = operands.concatAttrStrings('op_wb')
1065
1066 if d.operands.memOperand:
1067 myDict['mem_acc_size'] = d.operands.memOperand.mem_acc_size
1068 myDict['mem_acc_type'] = d.operands.memOperand.mem_acc_type
1069
1070 else:
1071 # Start with the template namespace. Make a copy since we're
1072 # going to modify it.
1073 myDict = templateMap.copy()
1074 # if the argument is a dictionary, we just use it.
1075 if isinstance(d, dict):
1076 myDict.update(d)
1077 # if the argument is an object, we use its attribute map.
1078 elif hasattr(d, '__dict__'):
1079 myDict.update(d.__dict__)
1080 else:
1081 raise TypeError, "Template.subst() arg must be or have dictionary"
1082 return template % myDict
1083
1084 # Convert to string. This handles the case when a template with a
1085 # CPU-specific term gets interpolated into another template or into
1086 # an output block.
1087 def __str__(self):
1088 return expand_cpu_symbols_to_string(self.template)
1089

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

1230 c += '\n\t_destRegIdx[%d] = %s;' % \
1231 (self.dest_reg_idx, self.reg_spec)
1232 return c
1233
1234 def makeRead(self):
1235 if (self.ctype == 'float' or self.ctype == 'double'):
1236 error(0, 'Attempt to read integer register as FP')
1237 if (self.size == self.dflt_size):
1027 return template % myDict
1028
1029 # Convert to string. This handles the case when a template with a
1030 # CPU-specific term gets interpolated into another template or into
1031 # an output block.
1032 def __str__(self):
1033 return expand_cpu_symbols_to_string(self.template)
1034

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

1175 c += '\n\t_destRegIdx[%d] = %s;' % \
1176 (self.dest_reg_idx, self.reg_spec)
1177 return c
1178
1179 def makeRead(self):
1180 if (self.ctype == 'float' or self.ctype == 'double'):
1181 error(0, 'Attempt to read integer register as FP')
1182 if (self.size == self.dflt_size):
1238 return '%s = xc->readIntRegOperand(this, %d);\n' % \
1183 return '%s = xc->readIntReg(this, %d);\n' % \
1239 (self.base_name, self.src_reg_idx)
1240 elif (self.size > self.dflt_size):
1184 (self.base_name, self.src_reg_idx)
1185 elif (self.size > self.dflt_size):
1241 int_reg_val = 'xc->readIntRegOperand(this, %d)' % \
1242 (self.src_reg_idx)
1186 int_reg_val = 'xc->readIntReg(this, %d)' % (self.src_reg_idx)
1243 if (self.is_signed):
1244 int_reg_val = 'sext<%d>(%s)' % (self.dflt_size, int_reg_val)
1245 return '%s = %s;\n' % (self.base_name, int_reg_val)
1246 else:
1187 if (self.is_signed):
1188 int_reg_val = 'sext<%d>(%s)' % (self.dflt_size, int_reg_val)
1189 return '%s = %s;\n' % (self.base_name, int_reg_val)
1190 else:
1247 return '%s = bits(xc->readIntRegOperand(this, %d), %d, 0);\n' % \
1191 return '%s = bits(xc->readIntReg(this, %d), %d, 0);\n' % \
1248 (self.base_name, self.src_reg_idx, self.size-1)
1249
1250 def makeWrite(self):
1251 if (self.ctype == 'float' or self.ctype == 'double'):
1252 error(0, 'Attempt to write integer register as FP')
1253 if (self.size != self.dflt_size and self.is_signed):
1254 final_val = 'sext<%d>(%s)' % (self.size, self.base_name)
1255 else:
1256 final_val = self.base_name
1257 wb = '''
1258 {
1259 %s final_val = %s;
1192 (self.base_name, self.src_reg_idx, self.size-1)
1193
1194 def makeWrite(self):
1195 if (self.ctype == 'float' or self.ctype == 'double'):
1196 error(0, 'Attempt to write integer register as FP')
1197 if (self.size != self.dflt_size and self.is_signed):
1198 final_val = 'sext<%d>(%s)' % (self.size, self.base_name)
1199 else:
1200 final_val = self.base_name
1201 wb = '''
1202 {
1203 %s final_val = %s;
1260 xc->setIntRegOperand(this, %d, final_val);\n
1204 xc->setIntReg(this, %d, final_val);\n
1261 if (traceData) { traceData->setData(final_val); }
1262 }''' % (self.dflt_ctype, final_val, self.dest_reg_idx)
1263 return wb
1264
1265class FloatRegOperand(Operand):
1266 def isReg(self):
1267 return 1
1268

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

1278 c += '\n\t_destRegIdx[%d] = %s + FP_Base_DepTag;' % \
1279 (self.dest_reg_idx, self.reg_spec)
1280 return c
1281
1282 def makeRead(self):
1283 bit_select = 0
1284 width = 0;
1285 if (self.ctype == 'float'):
1205 if (traceData) { traceData->setData(final_val); }
1206 }''' % (self.dflt_ctype, final_val, self.dest_reg_idx)
1207 return wb
1208
1209class FloatRegOperand(Operand):
1210 def isReg(self):
1211 return 1
1212

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

1222 c += '\n\t_destRegIdx[%d] = %s + FP_Base_DepTag;' % \
1223 (self.dest_reg_idx, self.reg_spec)
1224 return c
1225
1226 def makeRead(self):
1227 bit_select = 0
1228 width = 0;
1229 if (self.ctype == 'float'):
1286 func = 'readFloatRegOperand'
1230 func = 'readFloatReg'
1287 width = 32;
1288 elif (self.ctype == 'double'):
1231 width = 32;
1232 elif (self.ctype == 'double'):
1289 func = 'readFloatRegOperand'
1233 func = 'readFloatReg'
1290 width = 64;
1291 else:
1234 width = 64;
1235 else:
1292 func = 'readFloatRegOperandBits'
1236 func = 'readFloatRegBits'
1293 if (self.ctype == 'uint32_t'):
1294 width = 32;
1295 elif (self.ctype == 'uint64_t'):
1296 width = 64;
1297 if (self.size != self.dflt_size):
1298 bit_select = 1
1299 if width:
1300 base = 'xc->%s(this, %d, %d)' % \

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

1310
1311 def makeWrite(self):
1312 final_val = self.base_name
1313 final_ctype = self.ctype
1314 widthSpecifier = ''
1315 width = 0
1316 if (self.ctype == 'float'):
1317 width = 32
1237 if (self.ctype == 'uint32_t'):
1238 width = 32;
1239 elif (self.ctype == 'uint64_t'):
1240 width = 64;
1241 if (self.size != self.dflt_size):
1242 bit_select = 1
1243 if width:
1244 base = 'xc->%s(this, %d, %d)' % \

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

1254
1255 def makeWrite(self):
1256 final_val = self.base_name
1257 final_ctype = self.ctype
1258 widthSpecifier = ''
1259 width = 0
1260 if (self.ctype == 'float'):
1261 width = 32
1318 func = 'setFloatRegOperand'
1262 func = 'setFloatReg'
1319 elif (self.ctype == 'double'):
1320 width = 64
1263 elif (self.ctype == 'double'):
1264 width = 64
1321 func = 'setFloatRegOperand'
1265 func = 'setFloatReg'
1322 elif (self.ctype == 'uint32_t'):
1266 elif (self.ctype == 'uint32_t'):
1323 func = 'setFloatRegOperandBits'
1267 func = 'setFloatRegBits'
1324 width = 32
1325 elif (self.ctype == 'uint64_t'):
1268 width = 32
1269 elif (self.ctype == 'uint64_t'):
1326 func = 'setFloatRegOperandBits'
1270 func = 'setFloatRegBits'
1327 width = 64
1328 else:
1271 width = 64
1272 else:
1329 func = 'setFloatRegOperandBits'
1273 func = 'setFloatRegBits'
1330 final_ctype = 'uint%d_t' % self.dflt_size
1331 if (self.size != self.dflt_size and self.is_signed):
1332 final_val = 'sext<%d>(%s)' % (self.size, self.base_name)
1333 if width:
1334 widthSpecifier = ', %d' % width
1335 wb = '''
1336 {
1337 %s final_val = %s;

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

1346 return 1
1347
1348 def isControlReg(self):
1349 return 1
1350
1351 def makeConstructor(self):
1352 c = ''
1353 if self.is_src:
1274 final_ctype = 'uint%d_t' % self.dflt_size
1275 if (self.size != self.dflt_size and self.is_signed):
1276 final_val = 'sext<%d>(%s)' % (self.size, self.base_name)
1277 if width:
1278 widthSpecifier = ', %d' % width
1279 wb = '''
1280 {
1281 %s final_val = %s;

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

1290 return 1
1291
1292 def isControlReg(self):
1293 return 1
1294
1295 def makeConstructor(self):
1296 c = ''
1297 if self.is_src:
1354 c += '\n\t_srcRegIdx[%d] = %s + Ctrl_Base_DepTag;' % \
1298 c += '\n\t_srcRegIdx[%d] = %s;' % \
1355 (self.src_reg_idx, self.reg_spec)
1356 if self.is_dest:
1299 (self.src_reg_idx, self.reg_spec)
1300 if self.is_dest:
1357 c += '\n\t_destRegIdx[%d] = %s + Ctrl_Base_DepTag;' % \
1301 c += '\n\t_destRegIdx[%d] = %s;' % \
1358 (self.dest_reg_idx, self.reg_spec)
1359 return c
1360
1361 def makeRead(self):
1362 bit_select = 0
1363 if (self.ctype == 'float' or self.ctype == 'double'):
1364 error(0, 'Attempt to read control register as FP')
1302 (self.dest_reg_idx, self.reg_spec)
1303 return c
1304
1305 def makeRead(self):
1306 bit_select = 0
1307 if (self.ctype == 'float' or self.ctype == 'double'):
1308 error(0, 'Attempt to read control register as FP')
1365 base = 'xc->readMiscRegOperand(this, %s)' % self.src_reg_idx
1309 base = 'xc->readMiscRegWithEffect(%s)' % self.reg_spec
1366 if self.size == self.dflt_size:
1367 return '%s = %s;\n' % (self.base_name, base)
1368 else:
1369 return '%s = bits(%s, %d, 0);\n' % \
1370 (self.base_name, base, self.size-1)
1371
1372 def makeWrite(self):
1373 if (self.ctype == 'float' or self.ctype == 'double'):
1374 error(0, 'Attempt to write control register as FP')
1310 if self.size == self.dflt_size:
1311 return '%s = %s;\n' % (self.base_name, base)
1312 else:
1313 return '%s = bits(%s, %d, 0);\n' % \
1314 (self.base_name, base, self.size-1)
1315
1316 def makeWrite(self):
1317 if (self.ctype == 'float' or self.ctype == 'double'):
1318 error(0, 'Attempt to write control register as FP')
1375 wb = 'xc->setMiscRegOperandWithEffect(this, %s, %s);\n' % \
1376 (self.dest_reg_idx, self.base_name)
1319 wb = 'xc->setMiscRegWithEffect(%s, %s);\n' % (self.reg_spec, self.base_name)
1377 wb += 'if (traceData) { traceData->setData(%s); }' % \
1378 self.base_name
1379 return wb
1380
1381class MemOperand(Operand):
1382 def isMem(self):
1383 return 1
1384

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

1601 # like concatAttrLists, but only include the values for the operands
1602 # for which the provided filter function returns true
1603 def concatSomeAttrLists(self, filter, attr_name):
1604 return self.__internalConcatAttrs(attr_name, filter, [])
1605
1606 def sort(self):
1607 self.items.sort(lambda a, b: a.sort_pri - b.sort_pri)
1608
1320 wb += 'if (traceData) { traceData->setData(%s); }' % \
1321 self.base_name
1322 return wb
1323
1324class MemOperand(Operand):
1325 def isMem(self):
1326 return 1
1327

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

1544 # like concatAttrLists, but only include the values for the operands
1545 # for which the provided filter function returns true
1546 def concatSomeAttrLists(self, filter, attr_name):
1547 return self.__internalConcatAttrs(attr_name, filter, [])
1548
1549 def sort(self):
1550 self.items.sort(lambda a, b: a.sort_pri - b.sort_pri)
1551
1609class SubOperandList(OperandList):
1610
1611 # Find all the operands in the given code block. Returns an operand
1612 # descriptor list (instance of class OperandList).
1613 def __init__(self, code, master_list):
1614 self.items = []
1615 self.bases = {}
1616 # delete comments so we don't match on reg specifiers inside
1617 code = commentRE.sub('', code)
1618 # search for operands
1619 next_pos = 0
1620 while 1:
1621 match = operandsRE.search(code, next_pos)
1622 if not match:
1623 # no more matches: we're done
1624 break
1625 op = match.groups()
1626 # regexp groups are operand full name, base, and extension
1627 (op_full, op_base, op_ext) = op
1628 # find this op in the master list
1629 op_desc = master_list.find_base(op_base)
1630 if not op_desc:
1631 error(0, 'Found operand %s which is not in the master list!' \
1632 ' This is an internal error' % \
1633 op_base)
1634 else:
1635 # See if we've already found this operand
1636 op_desc = self.find_base(op_base)
1637 if not op_desc:
1638 # if not, add a reference to it to this sub list
1639 self.append(master_list.bases[op_base])
1640
1641 # start next search after end of current match
1642 next_pos = match.end()
1643 self.sort()
1644 self.memOperand = None
1645 for op_desc in self.items:
1646 if op_desc.isMem():
1647 if self.memOperand:
1648 error(0, "Code block has more than one memory operand.")
1649 self.memOperand = op_desc
1650
1651# Regular expression object to match C++ comments
1652# (used in findOperands())
1653commentRE = re.compile(r'//.*\n')
1654
1655# Regular expression object to match assignment statements
1656# (used in findOperands())
1657assignRE = re.compile(r'\s*=(?!=)', re.MULTILINE)
1658

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

1676 del flag_list[i]
1677 else:
1678 i += 1
1679 pre = '\n\tflags['
1680 post = '] = true;'
1681 code = pre + string.join(flag_list, post + pre) + post
1682 return code
1683
1552# Regular expression object to match C++ comments
1553# (used in findOperands())
1554commentRE = re.compile(r'//.*\n')
1555
1556# Regular expression object to match assignment statements
1557# (used in findOperands())
1558assignRE = re.compile(r'\s*=(?!=)', re.MULTILINE)
1559

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

1577 del flag_list[i]
1578 else:
1579 i += 1
1580 pre = '\n\tflags['
1581 post = '] = true;'
1582 code = pre + string.join(flag_list, post + pre) + post
1583 return code
1584
1684# Assume all instruction flags are of the form 'IsFoo'
1685instFlagRE = re.compile(r'Is.*')
1686
1687# OpClass constants end in 'Op' except No_OpClass
1688opClassRE = re.compile(r'.*Op|No_OpClass')
1689
1690class InstObjParams:
1691 def __init__(self, mnem, class_name, base_class = '',
1692 snippets = None, opt_args = []):
1693 self.mnemonic = mnem
1694 self.class_name = class_name
1695 self.base_class = base_class
1696 compositeCode = ''
1697 if snippets:
1698 if not isinstance(snippets, dict):
1699 snippets = {'code' : snippets}
1700 for snippet in snippets.values():
1701 if isinstance(snippet, str):
1702 compositeCode += (" " + snippet)
1703 self.snippets = snippets
1704
1705 self.operands = OperandList(compositeCode)
1585class CodeBlock:
1586 def __init__(self, code):
1587 self.orig_code = code
1588 self.operands = OperandList(code)
1589 self.code = substMungedOpNames(substBitOps(code))
1706 self.constructor = self.operands.concatAttrStrings('constructor')
1707 self.constructor += \
1708 '\n\t_numSrcRegs = %d;' % self.operands.numSrcRegs
1709 self.constructor += \
1710 '\n\t_numDestRegs = %d;' % self.operands.numDestRegs
1711 self.constructor += \
1712 '\n\t_numFPDestRegs = %d;' % self.operands.numFPDestRegs
1713 self.constructor += \
1714 '\n\t_numIntDestRegs = %d;' % self.operands.numIntDestRegs
1590 self.constructor = self.operands.concatAttrStrings('constructor')
1591 self.constructor += \
1592 '\n\t_numSrcRegs = %d;' % self.operands.numSrcRegs
1593 self.constructor += \
1594 '\n\t_numDestRegs = %d;' % self.operands.numDestRegs
1595 self.constructor += \
1596 '\n\t_numFPDestRegs = %d;' % self.operands.numFPDestRegs
1597 self.constructor += \
1598 '\n\t_numIntDestRegs = %d;' % self.operands.numIntDestRegs
1599
1600 self.op_decl = self.operands.concatAttrStrings('op_decl')
1601
1602 is_src = lambda op: op.is_src
1603 is_dest = lambda op: op.is_dest
1604
1605 self.op_src_decl = \
1606 self.operands.concatSomeAttrStrings(is_src, 'op_src_decl')
1607 self.op_dest_decl = \
1608 self.operands.concatSomeAttrStrings(is_dest, 'op_dest_decl')
1609
1610 self.op_rd = self.operands.concatAttrStrings('op_rd')
1611 self.op_wb = self.operands.concatAttrStrings('op_wb')
1612
1715 self.flags = self.operands.concatAttrLists('flags')
1716
1613 self.flags = self.operands.concatAttrLists('flags')
1614
1615 if self.operands.memOperand:
1616 self.mem_acc_size = self.operands.memOperand.mem_acc_size
1617 self.mem_acc_type = self.operands.memOperand.mem_acc_type
1618
1717 # Make a basic guess on the operand class (function unit type).
1619 # Make a basic guess on the operand class (function unit type).
1718 # These are good enough for most cases, and can be overridden
1620 # These are good enough for most cases, and will be overridden
1719 # later otherwise.
1720 if 'IsStore' in self.flags:
1721 self.op_class = 'MemWriteOp'
1722 elif 'IsLoad' in self.flags or 'IsPrefetch' in self.flags:
1723 self.op_class = 'MemReadOp'
1724 elif 'IsFloating' in self.flags:
1725 self.op_class = 'FloatAddOp'
1726 else:
1727 self.op_class = 'IntAluOp'
1728
1621 # later otherwise.
1622 if 'IsStore' in self.flags:
1623 self.op_class = 'MemWriteOp'
1624 elif 'IsLoad' in self.flags or 'IsPrefetch' in self.flags:
1625 self.op_class = 'MemReadOp'
1626 elif 'IsFloating' in self.flags:
1627 self.op_class = 'FloatAddOp'
1628 else:
1629 self.op_class = 'IntAluOp'
1630
1631# Assume all instruction flags are of the form 'IsFoo'
1632instFlagRE = re.compile(r'Is.*')
1633
1634# OpClass constants end in 'Op' except No_OpClass
1635opClassRE = re.compile(r'.*Op|No_OpClass')
1636
1637class InstObjParams:
1638 def __init__(self, mnem, class_name, base_class = '',
1639 code = None, opt_args = [], extras = {}):
1640 self.mnemonic = mnem
1641 self.class_name = class_name
1642 self.base_class = base_class
1643 if code:
1644 #If the user already made a CodeBlock, pick the parts from it
1645 if isinstance(code, CodeBlock):
1646 origCode = code.orig_code
1647 codeBlock = code
1648 else:
1649 origCode = code
1650 codeBlock = CodeBlock(code)
1651 stringExtras = {}
1652 otherExtras = {}
1653 for (k, v) in extras.items():
1654 if type(v) == str:
1655 stringExtras[k] = v
1656 else:
1657 otherExtras[k] = v
1658 compositeCode = "\n".join([origCode] + stringExtras.values())
1659 # compositeCode = '\n'.join([origCode] +
1660 # [pair[1] for pair in extras])
1661 compositeBlock = CodeBlock(compositeCode)
1662 for code_attr in compositeBlock.__dict__.keys():
1663 setattr(self, code_attr, getattr(compositeBlock, code_attr))
1664 for (key, snippet) in stringExtras.items():
1665 setattr(self, key, CodeBlock(snippet).code)
1666 for (key, item) in otherExtras.items():
1667 setattr(self, key, item)
1668 self.code = codeBlock.code
1669 self.orig_code = origCode
1670 else:
1671 self.constructor = ''
1672 self.flags = []
1729 # Optional arguments are assumed to be either StaticInst flags
1730 # or an OpClass value. To avoid having to import a complete
1731 # list of these values to match against, we do it ad-hoc
1732 # with regexps.
1733 for oa in opt_args:
1734 if instFlagRE.match(oa):
1735 self.flags.append(oa)
1736 elif opClassRE.match(oa):

--- 148 unchanged lines hidden ---
1673 # Optional arguments are assumed to be either StaticInst flags
1674 # or an OpClass value. To avoid having to import a complete
1675 # list of these values to match against, we do it ad-hoc
1676 # with regexps.
1677 for oa in opt_args:
1678 if instFlagRE.match(oa):
1679 self.flags.append(oa)
1680 elif opClassRE.match(oa):

--- 148 unchanged lines hidden ---