495a496,501
> def isVecReg(self):
> return 0
>
> def isVecElem(self):
> return 0
>
660a667,860
> class VecRegOperand(Operand):
> reg_class = 'VecRegClass'
>
> def __init__(self, parser, full_name, ext, is_src, is_dest):
> Operand.__init__(self, parser, full_name, ext, is_src, is_dest)
> self.elemExt = None
> self.parser = parser
>
> def isReg(self):
> return 1
>
> def isVecReg(self):
> return 1
>
> def makeDeclElem(self, elem_op):
> (elem_name, elem_ext) = elem_op
> (elem_spec, dflt_elem_ext, zeroing) = self.elems[elem_name]
> if elem_ext:
> ext = elem_ext
> else:
> ext = dflt_elem_ext
> ctype = self.parser.operandTypeMap[ext]
> return '\n\t%s %s = 0;' % (ctype, elem_name)
>
> def makeDecl(self):
> if not self.is_dest and self.is_src:
> c_decl = '\t/* Vars for %s*/' % (self.base_name)
> if hasattr(self, 'active_elems'):
> if self.active_elems:
> for elem in self.active_elems:
> c_decl += self.makeDeclElem(elem)
> return c_decl + '\t/* End vars for %s */\n' % (self.base_name)
> else:
> return ''
>
> def makeConstructor(self, predRead, predWrite):
> c_src = ''
> c_dest = ''
>
> numAccessNeeded = 1
>
> if self.is_src:
> c_src = src_reg_constructor % (self.reg_class, self.reg_spec)
>
> if self.is_dest:
> c_dest = dst_reg_constructor % (self.reg_class, self.reg_spec)
> c_dest += '\n\t_numVecDestRegs++;'
>
> return c_src + c_dest
>
> # Read destination register to write
> def makeReadWElem(self, elem_op):
> (elem_name, elem_ext) = elem_op
> (elem_spec, dflt_elem_ext, zeroing) = self.elems[elem_name]
> if elem_ext:
> ext = elem_ext
> else:
> ext = dflt_elem_ext
> ctype = self.parser.operandTypeMap[ext]
> c_read = '\t\t%s& %s = %s[%s];\n' % \
> (ctype, elem_name, self.base_name, elem_spec)
> return c_read
>
> def makeReadW(self, predWrite):
> func = 'getWritableVecRegOperand'
> if self.read_code != None:
> return self.buildReadCode(func)
>
> if predWrite:
> rindex = '_destIndex++'
> else:
> rindex = '%d' % self.dest_reg_idx
>
> c_readw = '\t\t%s& tmp_d%s = xc->%s(this, %s);\n'\
> % ('TheISA::VecRegContainer', rindex, func, rindex)
> if self.elemExt:
> c_readw += '\t\tauto %s = tmp_d%s.as<%s>();\n' % (self.base_name,
> rindex, self.parser.operandTypeMap[self.elemExt])
> if self.ext:
> c_readw += '\t\tauto %s = tmp_d%s.as<%s>();\n' % (self.base_name,
> rindex, self.parser.operandTypeMap[self.ext])
> if hasattr(self, 'active_elems'):
> if self.active_elems:
> for elem in self.active_elems:
> c_readw += self.makeReadWElem(elem)
> return c_readw
>
> # Normal source operand read
> def makeReadElem(self, elem_op, name):
> (elem_name, elem_ext) = elem_op
> (elem_spec, dflt_elem_ext, zeroing) = self.elems[elem_name]
>
> if elem_ext:
> ext = elem_ext
> else:
> ext = dflt_elem_ext
> ctype = self.parser.operandTypeMap[ext]
> c_read = '\t\t%s = %s[%s];\n' % \
> (elem_name, name, elem_spec)
> return c_read
>
> def makeRead(self, predRead):
> func = 'readVecRegOperand'
> if self.read_code != None:
> return self.buildReadCode(func)
>
> if predRead:
> rindex = '_sourceIndex++'
> else:
> rindex = '%d' % self.src_reg_idx
>
> name = self.base_name
> if self.is_dest and self.is_src:
> name += '_merger'
>
> c_read = '\t\t%s& tmp_s%s = xc->%s(this, %s);\n' \
> % ('const TheISA::VecRegContainer', rindex, func, rindex)
> # If the parser has detected that elements are being access, create
> # the appropriate view
> if self.elemExt:
> c_read += '\t\tauto %s = tmp_s%s.as<%s>();\n' % \
> (name, rindex, self.parser.operandTypeMap[self.elemExt])
> if self.ext:
> c_read += '\t\tauto %s = tmp_s%s.as<%s>();\n' % \
> (name, rindex, self.parser.operandTypeMap[self.ext])
> if hasattr(self, 'active_elems'):
> if self.active_elems:
> for elem in self.active_elems:
> c_read += self.makeReadElem(elem, name)
> return c_read
>
> def makeWrite(self, predWrite):
> func = 'setVecRegOperand'
> if self.write_code != None:
> return self.buildWriteCode(func)
>
> wb = '''
> if (traceData) {
> panic("Vectors not supported yet in tracedata");
> /*traceData->setData(final_val);*/
> }
> '''
> return wb
>
> def finalize(self, predRead, predWrite):
> super(VecRegOperand, self).finalize(predRead, predWrite)
> if self.is_dest:
> self.op_rd = self.makeReadW(predWrite) + self.op_rd
>
> class VecElemOperand(Operand):
> reg_class = 'VectorElemClass'
>
> def isReg(self):
> return 1
>
> def isVecElem(self):
> return 1
>
> def makeDecl(self):
> if self.is_dest and not self.is_src:
> return '\n\t%s %s;' % (self.ctype, self.base_name)
> else:
> return ''
>
> def makeConstructor(self, predRead, predWrite):
> c_src = ''
> c_dest = ''
>
> numAccessNeeded = 1
> regId = 'RegId(%s, %s * numVecElemPerVecReg + elemIdx, %s)' % \
> (self.reg_class, self.reg_spec)
>
> if self.is_src:
> c_src = ('\n\t_srcRegIdx[_numSrcRegs++] = RegId(%s, %s, %s);' %
> (self.reg_class, self.reg_spec, self.elem_spec))
>
> if self.is_dest:
> c_dest = ('\n\t_destRegIdx[_numDestRegs++] = RegId(%s, %s, %s);' %
> (self.reg_class, self.reg_spec, self.elem_spec))
> c_dest += '\n\t_numVecElemDestRegs++;'
> return c_src + c_dest
>
> def makeRead(self, predRead):
> c_read = ('\n/* Elem is kept inside the operand description */' +
> '\n\tVecElem %s = xc->readVecElemOperand(this, %d);' %
> (self.base_name, self.src_reg_idx))
> return c_read
>
> def makeWrite(self, predWrite):
> c_write = ('\n/* Elem is kept inside the operand description */' +
> '\n\txc->setVecElemOperand(this, %d, %s);' %
> (self.dest_reg_idx, self.base_name))
> return c_write
>
859a1060,1067
> # If is a elem operand, define or update the corresponding
> # vector operand
> isElem = False
> if op_base in parser.elemToVector:
> isElem = True
> elem_op = (op_base, op_ext)
> op_base = parser.elemToVector[op_base]
> op_ext = '' # use the default one
863a1072
>
867,869c1076,1078
< if op_desc.ext != op_ext:
< error ('Inconsistent extensions for operand %s' % \
< op_base)
---
> if op_ext and op_ext != '' and op_desc.ext != op_ext:
> error ('Inconsistent extensions for operand %s: %s - %s' \
> % (op_base, op_desc.ext, op_ext))
871a1081,1093
> if isElem:
> (elem_base, elem_ext) = elem_op
> found = False
> for ae in op_desc.active_elems:
> (ae_base, ae_ext) = ae
> if ae_base == elem_base:
> if ae_ext != elem_ext:
> error('Inconsistent extensions for elem'
> ' operand %s' % elem_base)
> else:
> found = True
> if not found:
> op_desc.active_elems.append(elem_op)
875a1098,1102
> # if operand is a vector elem, add the corresponding vector
> # operand if not already done
> if isElem:
> op_desc.elemExt = elem_op[1]
> op_desc.active_elems = [elem_op]
885a1113
> self.numVecDestRegs = 0
906a1135,1136
> elif op_desc.isVecReg():
> self.numVecDestRegs += 1
996a1227,1231
> # If is a elem operand, define or update the corresponding
> # vector operand
> if op_base in parser.elemToVector:
> elem_op = op_base
> op_base = parser.elemToVector[elem_op]
1107a1343,1344
> header += '\n\t_numVecDestRegs = 0;'
> header += '\n\t_numVecElemDestRegs = 0;'
1151a1389,1390
> elif 'IsVector' in self.flags:
> self.op_class = 'SimdAddOp'
1160a1400,1401
> # if 'IsVector' is set, add call to the Vector enable check
> # function (which should be provided by isa_desc via a declare)
1162a1404,1405
> elif 'IsVector' in self.flags:
> self.fp_enable_check = 'fault = checkVecEnableFault(xc);'
2302a2546,2555
> # reg_spec is either just a string or a dictionary
> # (for elems of vector)
> if isinstance(reg_spec, tuple):
> (reg_spec, elem_spec) = reg_spec
> if isinstance(elem_spec, str):
> attrList.append('elem_spec')
> else:
> assert(isinstance(elem_spec, dict))
> elems = elem_spec
> attrList.append('elems')
2325a2579,2587
> # Add the elems defined in the vector operands and
> # build a map elem -> vector (used in OperandList)
> elem_to_vec = {}
> for op in user_dict.keys():
> if hasattr(self.operandNameMap[op], 'elems'):
> for elem in self.operandNameMap[op].elems.keys():
> operands.append(elem)
> elem_to_vec[elem] = op
> self.elemToVector = elem_to_vec