diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py index a96622d4a..aacdf455f 100755 --- a/src/arch/isa_parser.py +++ b/src/arch/isa_parser.py @@ -808,8 +808,7 @@ class GenCode: # a defineInst() method that generates the code for an instruction # definition. -exportContextSymbols = ('InstObjParams', 'CodeBlock', - 'makeList', 're', 'string') +exportContextSymbols = ('InstObjParams', 'makeList', 're', 'string') exportContext = {} @@ -1003,27 +1002,83 @@ def substBitOps(code): # Template objects are format strings that allow substitution from # the attribute spaces of other objects (e.g. InstObjParams instances). +labelRE = re.compile(r'[^%]%\(([^\)]+)\)[sd]') + class Template: def __init__(self, t): self.template = t def subst(self, d): - # Start with the template namespace. Make a copy since we're - # going to modify it. - myDict = templateMap.copy() - # if the argument is a dictionary, we just use it. - if isinstance(d, dict): - myDict.update(d) - # if the argument is an object, we use its attribute map. - elif hasattr(d, '__dict__'): - myDict.update(d.__dict__) - else: - raise TypeError, "Template.subst() arg must be or have dictionary" + myDict = None + # Protect non-Python-dict substitutions (e.g. if there's a printf # in the templated C++ code) template = protect_non_subst_percents(self.template) # CPU-model-specific substitutions are handled later (in GenCode). template = protect_cpu_symbols(template) + + # if we're dealing with an InstObjParams object, we need to be a + # little more sophisticated. Otherwise, just do what we've always + # done + if isinstance(d, InstObjParams): + # The instruction wide parameters are already formed, but the + # parameters which are only function wide still need to be + # generated. + perFuncNames = ['op_decl', 'op_src_decl', 'op_dest_decl', \ + 'op_rd', 'op_wb', 'mem_acc_size', 'mem_acc_type'] + compositeCode = '' + + myDict = templateMap.copy() + myDict.update(d.__dict__) + # The "operands" and "snippets" attributes of the InstObjParams + # objects are for internal use and not substitution. + del myDict['operands'] + del myDict['snippets'] + + for name in labelRE.findall(template): + # Don't try to find a snippet to go with things that will + # match against attributes of d, or that are other templates, + # or that we're going to generate later, or that we've already + # found. + if not hasattr(d, name) and \ + not templateMap.has_key(name) and \ + not myDict.has_key(name) and \ + name not in perFuncNames: + myDict[name] = d.snippets[name] + if isinstance(myDict[name], str): + myDict[name] = substMungedOpNames(substBitOps(myDict[name])) + compositeCode += (" " + myDict[name]) + operands = SubOperandList(compositeCode, d.operands) + + myDict['op_decl'] = operands.concatAttrStrings('op_decl') + + is_src = lambda op: op.is_src + is_dest = lambda op: op.is_dest + + myDict['op_src_decl'] = \ + operands.concatSomeAttrStrings(is_src, 'op_src_decl') + myDict['op_dest_decl'] = \ + operands.concatSomeAttrStrings(is_dest, 'op_dest_decl') + + myDict['op_rd'] = operands.concatAttrStrings('op_rd') + myDict['op_wb'] = operands.concatAttrStrings('op_wb') + + if d.operands.memOperand: + myDict['mem_acc_size'] = d.operands.memOperand.mem_acc_size + myDict['mem_acc_type'] = d.operands.memOperand.mem_acc_type + + else: + # Start with the template namespace. Make a copy since we're + # going to modify it. + myDict = templateMap.copy() + # if the argument is a dictionary, we just use it. + if isinstance(d, dict): + myDict.update(d) + # if the argument is an object, we use its attribute map. + elif hasattr(d, '__dict__'): + myDict.update(d.__dict__) + else: + raise TypeError, "Template.subst() arg must be or have dictionary" return template % myDict # Convert to string. This handles the case when a template with a @@ -1296,10 +1351,10 @@ class ControlRegOperand(Operand): def makeConstructor(self): c = '' if self.is_src: - c += '\n\t_srcRegIdx[%d] = %s;' % \ + c += '\n\t_srcRegIdx[%d] = %s + Ctrl_Base_DepTag;' % \ (self.src_reg_idx, self.reg_spec) if self.is_dest: - c += '\n\t_destRegIdx[%d] = %s;' % \ + c += '\n\t_destRegIdx[%d] = %s + Ctrl_Base_DepTag;' % \ (self.dest_reg_idx, self.reg_spec) return c @@ -1307,7 +1362,7 @@ class ControlRegOperand(Operand): bit_select = 0 if (self.ctype == 'float' or self.ctype == 'double'): error(0, 'Attempt to read control register as FP') - base = 'xc->readMiscReg(%s)' % self.reg_spec + base = 'xc->readMiscRegOperand(this, %s)' % self.src_reg_idx if self.size == self.dflt_size: return '%s = %s;\n' % (self.base_name, base) else: @@ -1317,7 +1372,8 @@ class ControlRegOperand(Operand): def makeWrite(self): if (self.ctype == 'float' or self.ctype == 'double'): error(0, 'Attempt to write control register as FP') - wb = 'xc->setMiscRegWithEffect(%s, %s);\n' % (self.reg_spec, self.base_name) + wb = 'xc->setMiscRegOperandWithEffect(this, %s, %s);\n' % \ + (self.dest_reg_idx, self.base_name) wb += 'if (traceData) { traceData->setData(%s); }' % \ self.base_name return wb @@ -1550,6 +1606,48 @@ class OperandList: def sort(self): self.items.sort(lambda a, b: a.sort_pri - b.sort_pri) +class SubOperandList(OperandList): + + # Find all the operands in the given code block. Returns an operand + # descriptor list (instance of class OperandList). + def __init__(self, code, master_list): + self.items = [] + self.bases = {} + # delete comments so we don't match on reg specifiers inside + code = commentRE.sub('', code) + # search for operands + next_pos = 0 + while 1: + match = operandsRE.search(code, next_pos) + if not match: + # no more matches: we're done + break + op = match.groups() + # regexp groups are operand full name, base, and extension + (op_full, op_base, op_ext) = op + # find this op in the master list + op_desc = master_list.find_base(op_base) + if not op_desc: + error(0, 'Found operand %s which is not in the master list!' \ + ' This is an internal error' % \ + op_base) + else: + # See if we've already found this operand + op_desc = self.find_base(op_base) + if not op_desc: + # if not, add a reference to it to this sub list + self.append(master_list.bases[op_base]) + + # start next search after end of current match + next_pos = match.end() + self.sort() + self.memOperand = None + for op_desc in self.items: + if op_desc.isMem(): + if self.memOperand: + error(0, "Code block has more than one memory operand.") + self.memOperand = op_desc + # Regular expression object to match C++ comments # (used in findOperands()) commentRE = re.compile(r'//.*\n') @@ -1583,11 +1681,28 @@ def makeFlagConstructor(flag_list): code = pre + string.join(flag_list, post + pre) + post return code -class CodeBlock: - def __init__(self, code): - self.orig_code = code - self.operands = OperandList(code) - self.code = substMungedOpNames(substBitOps(code)) +# Assume all instruction flags are of the form 'IsFoo' +instFlagRE = re.compile(r'Is.*') + +# OpClass constants end in 'Op' except No_OpClass +opClassRE = re.compile(r'.*Op|No_OpClass') + +class InstObjParams: + def __init__(self, mnem, class_name, base_class = '', + snippets = None, opt_args = []): + self.mnemonic = mnem + self.class_name = class_name + self.base_class = base_class + compositeCode = '' + if snippets: + if not isinstance(snippets, dict): + snippets = {'code' : snippets} + for snippet in snippets.values(): + if isinstance(snippet, str): + compositeCode += (" " + snippet) + self.snippets = snippets + + self.operands = OperandList(compositeCode) self.constructor = self.operands.concatAttrStrings('constructor') self.constructor += \ '\n\t_numSrcRegs = %d;' % self.operands.numSrcRegs @@ -1597,28 +1712,10 @@ class CodeBlock: '\n\t_numFPDestRegs = %d;' % self.operands.numFPDestRegs self.constructor += \ '\n\t_numIntDestRegs = %d;' % self.operands.numIntDestRegs - - self.op_decl = self.operands.concatAttrStrings('op_decl') - - is_src = lambda op: op.is_src - is_dest = lambda op: op.is_dest - - self.op_src_decl = \ - self.operands.concatSomeAttrStrings(is_src, 'op_src_decl') - self.op_dest_decl = \ - self.operands.concatSomeAttrStrings(is_dest, 'op_dest_decl') - - self.op_rd = self.operands.concatAttrStrings('op_rd') - self.op_wb = self.operands.concatAttrStrings('op_wb') - self.flags = self.operands.concatAttrLists('flags') - if self.operands.memOperand: - self.mem_acc_size = self.operands.memOperand.mem_acc_size - self.mem_acc_type = self.operands.memOperand.mem_acc_type - # Make a basic guess on the operand class (function unit type). - # These are good enough for most cases, and will be overridden + # These are good enough for most cases, and can be overridden # later otherwise. if 'IsStore' in self.flags: self.op_class = 'MemWriteOp' @@ -1629,48 +1726,6 @@ class CodeBlock: else: self.op_class = 'IntAluOp' -# Assume all instruction flags are of the form 'IsFoo' -instFlagRE = re.compile(r'Is.*') - -# OpClass constants end in 'Op' except No_OpClass -opClassRE = re.compile(r'.*Op|No_OpClass') - -class InstObjParams: - def __init__(self, mnem, class_name, base_class = '', - code = None, opt_args = [], extras = {}): - self.mnemonic = mnem - self.class_name = class_name - self.base_class = base_class - if code: - #If the user already made a CodeBlock, pick the parts from it - if isinstance(code, CodeBlock): - origCode = code.orig_code - codeBlock = code - else: - origCode = code - codeBlock = CodeBlock(code) - stringExtras = {} - otherExtras = {} - for (k, v) in extras.items(): - if type(v) == str: - stringExtras[k] = v - else: - otherExtras[k] = v - compositeCode = "\n".join([origCode] + stringExtras.values()) - # compositeCode = '\n'.join([origCode] + - # [pair[1] for pair in extras]) - compositeBlock = CodeBlock(compositeCode) - for code_attr in compositeBlock.__dict__.keys(): - setattr(self, code_attr, getattr(compositeBlock, code_attr)) - for (key, snippet) in stringExtras.items(): - setattr(self, key, CodeBlock(snippet).code) - for (key, item) in otherExtras.items(): - setattr(self, key, item) - self.code = codeBlock.code - self.orig_code = origCode - else: - self.constructor = '' - self.flags = [] # Optional arguments are assumed to be either StaticInst flags # or an OpClass value. To avoid having to import a complete # list of these values to match against, we do it ad-hoc diff --git a/src/arch/sparc/isa/formats/basic.isa b/src/arch/sparc/isa/formats/basic.isa index a4c05387b..56e933763 100644 --- a/src/arch/sparc/isa/formats/basic.isa +++ b/src/arch/sparc/isa/formats/basic.isa @@ -95,8 +95,7 @@ def template BasicDecodeWithMnemonic {{ // The most basic instruction format... used only for a few misc. insts def format BasicOperate(code, *flags) {{ - iop = InstObjParams(name, Name, 'SparcStaticInst', - CodeBlock(code), flags) + iop = InstObjParams(name, Name, 'SparcStaticInst', code, flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) diff --git a/src/arch/sparc/isa/formats/branch.isa b/src/arch/sparc/isa/formats/branch.isa index 3062f38b2..2db756320 100644 --- a/src/arch/sparc/isa/formats/branch.isa +++ b/src/arch/sparc/isa/formats/branch.isa @@ -248,7 +248,6 @@ def format Branch(code, *opt_flags) {{ // Primary format for branch instructions: def format BranchN(bits, code, *opt_flags) {{ code = re.sub(r'handle_annul', handle_annul, code) - codeBlk = CodeBlock(code) new_opt_flags = [] for flag in opt_flags: if flag == ',a': @@ -256,7 +255,7 @@ def format BranchN(bits, code, *opt_flags) {{ Name += 'Annul' else: new_opt_flags += flag - iop = InstObjParams(name, Name, "BranchNBits<%d>" % bits, codeBlk, new_opt_flags) + iop = InstObjParams(name, Name, "BranchNBits<%d>" % bits, code, new_opt_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) exec_output = BranchExecute.subst(iop) @@ -266,8 +265,7 @@ def format BranchN(bits, code, *opt_flags) {{ // Primary format for branch instructions: def format BranchSplit(code, *opt_flags) {{ code = re.sub(r'handle_annul', handle_annul, code) - codeBlk = CodeBlock(code) - iop = InstObjParams(name, Name, 'BranchSplit', codeBlk, opt_flags) + iop = InstObjParams(name, Name, 'BranchSplit', code, opt_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) exec_output = BranchExecute.subst(iop) diff --git a/src/arch/sparc/isa/formats/integerop.isa b/src/arch/sparc/isa/formats/integerop.isa index 4f8ebebcc..363aca1a1 100644 --- a/src/arch/sparc/isa/formats/integerop.isa +++ b/src/arch/sparc/isa/formats/integerop.isa @@ -263,14 +263,15 @@ let {{ def doIntFormat(code, ccCode, name, Name, opt_flags): (usesImm, code, immCode, rString, iString) = splitOutImm(code) - iop = InstObjParams(name, Name, 'IntOp', code, - opt_flags, {"cc_code": ccCode}) + iop = InstObjParams(name, Name, 'IntOp', + {"code": code, "cc_code": ccCode}, + opt_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) exec_output = IntOpExecute.subst(iop) if usesImm: imm_iop = InstObjParams(name, Name + 'Imm', 'IntOpImm' + iString, - immCode, opt_flags, {"cc_code": ccCode}) + {"code": immCode, "cc_code": ccCode}, opt_flags) header_output += BasicDeclare.subst(imm_iop) decoder_output += BasicConstructor.subst(imm_iop) exec_output += IntOpExecute.subst(imm_iop) @@ -341,7 +342,7 @@ def format IntOpCcRes(code, *opt_flags) {{ def format SetHi(code, *opt_flags) {{ iop = InstObjParams(name, Name, 'SetHi', - code, opt_flags, {"cc_code": ''}) + {"code": code, "cc_code": ''}, opt_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) exec_output = IntOpExecute.subst(iop) diff --git a/src/arch/sparc/isa/formats/mem/basicmem.isa b/src/arch/sparc/isa/formats/mem/basicmem.isa index cb6c2f161..d5b17d720 100644 --- a/src/arch/sparc/isa/formats/mem/basicmem.isa +++ b/src/arch/sparc/isa/formats/mem/basicmem.isa @@ -55,15 +55,20 @@ let {{ def doMemFormat(code, execute, faultCode, name, Name, opt_flags): addrCalcReg = 'EA = Rs1 + Rs2;' addrCalcImm = 'EA = Rs1 + imm;' - iop = InstObjParams(name, Name, 'Mem', code, - opt_flags, {"fault_check": faultCode, "ea_code": addrCalcReg}) - iop_imm = InstObjParams(name, Name + "Imm", 'MemImm', code, - opt_flags, {"fault_check": faultCode, "ea_code": addrCalcImm}) + iop = InstObjParams(name, Name, 'Mem', + {"code": code, "fault_check": faultCode, + "ea_code": addrCalcReg}, + opt_flags) + iop_imm = InstObjParams(name, Name + "Imm", 'MemImm', + {"code": code, "fault_check": faultCode, + "ea_code": addrCalcImm}, + opt_flags) header_output = MemDeclare.subst(iop) + MemDeclare.subst(iop_imm) decoder_output = BasicConstructor.subst(iop) + BasicConstructor.subst(iop_imm) decode_block = ROrImmDecode.subst(iop) - exec_output = doDualSplitExecute(code, addrCalcReg, addrCalcImm, execute, - faultCode, name, name + "Imm", Name, Name + "Imm", opt_flags) + exec_output = doDualSplitExecute(code, addrCalcReg, addrCalcImm, + execute, faultCode, name, name + "Imm", + Name, Name + "Imm", opt_flags) return (header_output, decoder_output, exec_output, decode_block) }}; @@ -71,7 +76,7 @@ def format LoadAlt(code, *opt_flags) {{ (header_output, decoder_output, exec_output, - decode_block) = doMemFormat(code, LoadExecute, + decode_block) = doMemFormat(code, LoadFuncs, AlternateAsiPrivFaultCheck, name, Name, opt_flags) }}; @@ -79,7 +84,7 @@ def format StoreAlt(code, *opt_flags) {{ (header_output, decoder_output, exec_output, - decode_block) = doMemFormat(code, StoreExecute, + decode_block) = doMemFormat(code, StoreFuncs, AlternateAsiPrivFaultCheck, name, Name, opt_flags) }}; @@ -88,7 +93,7 @@ def format Load(code, *opt_flags) {{ decoder_output, exec_output, decode_block) = doMemFormat(code, - LoadExecute, '', name, Name, opt_flags) + LoadFuncs, '', name, Name, opt_flags) }}; def format Store(code, *opt_flags) {{ @@ -96,5 +101,5 @@ def format Store(code, *opt_flags) {{ decoder_output, exec_output, decode_block) = doMemFormat(code, - StoreExecute, '', name, Name, opt_flags) + StoreFuncs, '', name, Name, opt_flags) }}; diff --git a/src/arch/sparc/isa/formats/mem/blockmem.isa b/src/arch/sparc/isa/formats/mem/blockmem.isa index 8b4aca473..c124dc600 100644 --- a/src/arch/sparc/isa/formats/mem/blockmem.isa +++ b/src/arch/sparc/isa/formats/mem/blockmem.isa @@ -293,14 +293,14 @@ let {{ else: flag_code = "flags[IsDelayedCommit] = true;" pcedCode = matcher.sub("Frd_%d" % microPc, code) - iop = InstObjParams(name, Name, 'BlockMem', pcedCode, - opt_flags, {"ea_code": addrCalcReg, + iop = InstObjParams(name, Name, 'BlockMem', + {"code": pcedCode, "ea_code": addrCalcReg, "fault_check": faultCode, "micro_pc": microPc, - "set_flags": flag_code}) - iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm', pcedCode, - opt_flags, {"ea_code": addrCalcImm, + "set_flags": flag_code}, opt_flags) + iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm', + {"code": pcedCode, "ea_code": addrCalcImm, "fault_check": faultCode, "micro_pc": microPc, - "set_flags": flag_code}) + "set_flags": flag_code}, opt_flags) decoder_output += BlockMemMicroConstructor.subst(iop) decoder_output += BlockMemMicroConstructor.subst(iop_imm) exec_output += doDualSplitExecute( @@ -315,25 +315,25 @@ let {{ }}; def format BlockLoad(code, *opt_flags) {{ - # We need to make sure to check the highest priority fault last. - # That way, if other faults have been detected, they'll be overwritten - # rather than the other way around. - faultCode = AlternateASIPrivFaultCheck + BlockAlignmentFaultCheck - (header_output, - decoder_output, - exec_output, - decode_block) = doBlockMemFormat(code, faultCode, - LoadExecute, name, Name, opt_flags) + # We need to make sure to check the highest priority fault last. + # That way, if other faults have been detected, they'll be overwritten + # rather than the other way around. + faultCode = AlternateASIPrivFaultCheck + BlockAlignmentFaultCheck + (header_output, + decoder_output, + exec_output, + decode_block) = doBlockMemFormat(code, faultCode, + LoadFuncs, name, Name, opt_flags) }}; def format BlockStore(code, *opt_flags) {{ - # We need to make sure to check the highest priority fault last. - # That way, if other faults have been detected, they'll be overwritten - # rather than the other way around. - faultCode = AlternateASIPrivFaultCheck + BlockAlignmentFaultCheck - (header_output, - decoder_output, - exec_output, - decode_block) = doBlockMemFormat(code, faultCode, - StoreExecute, name, Name, opt_flags) + # We need to make sure to check the highest priority fault last. + # That way, if other faults have been detected, they'll be overwritten + # rather than the other way around. + faultCode = AlternateASIPrivFaultCheck + BlockAlignmentFaultCheck + (header_output, + decoder_output, + exec_output, + decode_block) = doBlockMemFormat(code, faultCode, + StoreFuncs, name, Name, opt_flags) }}; diff --git a/src/arch/sparc/isa/formats/mem/util.isa b/src/arch/sparc/isa/formats/mem/util.isa index f3adbe19f..e87223000 100644 --- a/src/arch/sparc/isa/formats/mem/util.isa +++ b/src/arch/sparc/isa/formats/mem/util.isa @@ -162,15 +162,17 @@ def template LoadExecute {{ return fault; } +}}; +def template LoadInitiateAcc {{ Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, Trace::InstRecord * traceData) const { Fault fault = NoFault; Addr EA; uint%(mem_acc_size)s_t Mem; - %(ea_decl)s; - %(ea_rd)s; + %(op_decl)s; + %(op_rd)s; %(ea_code)s; DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA); %(fault_check)s; @@ -180,18 +182,20 @@ def template LoadExecute {{ } return fault; } +}}; +def template LoadCompleteAcc {{ Fault %(class_name)s::completeAcc(PacketPtr pkt, %(CPU_exec_context)s * xc, Trace::InstRecord * traceData) const { Fault fault = NoFault; - %(code_decl)s; - %(code_rd)s; + %(op_decl)s; + %(op_rd)s; Mem = pkt->get(); %(code)s; if(fault == NoFault) { - %(code_wb)s; + %(op_wb)s; } return fault; } @@ -228,7 +232,9 @@ def template StoreExecute {{ return fault; } +}}; +def template StoreInitiateAcc {{ Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, Trace::InstRecord * traceData) const { @@ -255,7 +261,9 @@ def template StoreExecute {{ } return fault; } +}}; +def template StoreCompleteAcc {{ Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc, Trace::InstRecord * traceData) const { @@ -275,6 +283,8 @@ def template CompleteAccDeclare {{ //Here are some code snippets which check for various fault conditions let {{ + LoadFuncs = [LoadExecute, LoadInitiateAcc, LoadCompleteAcc] + StoreFuncs = [StoreExecute, StoreInitiateAcc, StoreCompleteAcc] # The LSB can be zero, since it's really the MSB in doubles and quads # and we're dealing with doubles BlockAlignmentFaultCheck = ''' @@ -308,20 +318,10 @@ let {{ //and in the other they're distributed across two. Also note that for //execute functions, the name of the base class doesn't matter. let {{ - def doSplitExecute(code, execute, name, Name, opt_flags, microParam): - codeParam = microParam.copy() - codeParam["ea_code"] = '' - codeIop = InstObjParams(name, Name, '', code, opt_flags, codeParam) - eaIop = InstObjParams(name, Name, '', microParam["ea_code"], - opt_flags, microParam) - iop = InstObjParams(name, Name, '', code, opt_flags, microParam) - (iop.ea_decl, - iop.ea_rd, - iop.ea_wb) = (eaIop.op_decl, eaIop.op_rd, eaIop.op_wb) - (iop.code_decl, - iop.code_rd, - iop.code_wb) = (codeIop.op_decl, codeIop.op_rd, codeIop.op_wb) - return execute.subst(iop) + def doSplitExecute(execute, name, Name, opt_flags, microParam): + iop = InstObjParams(name, Name, '', microParam, opt_flags) + (execf, initf, compf) = execute + return execf.subst(iop) + initf.subst(iop) + compf.subst(iop) def doDualSplitExecute(code, eaRegCode, eaImmCode, execute, @@ -330,8 +330,9 @@ let {{ for (eaCode, name, Name) in ( (eaRegCode, nameReg, NameReg), (eaImmCode, nameImm, NameImm)): - microParams = {"ea_code" : eaCode, "fault_check": faultCode} - executeCode += doSplitExecute(code, execute, name, Name, + microParams = {"code": code, "ea_code": eaCode, + "fault_check": faultCode} + executeCode += doSplitExecute(execute, name, Name, opt_flags, microParams) return executeCode }}; diff --git a/src/arch/sparc/isa/formats/nop.isa b/src/arch/sparc/isa/formats/nop.isa index 37ef2e8d0..de2ba2f54 100644 --- a/src/arch/sparc/isa/formats/nop.isa +++ b/src/arch/sparc/isa/formats/nop.isa @@ -88,9 +88,7 @@ def template NopExecute {{ // Primary format for integer operate instructions: def format Nop(code, *opt_flags) {{ - orig_code = code - cblk = CodeBlock(code) - iop = InstObjParams(name, Name, 'Nop', cblk, opt_flags) + iop = InstObjParams(name, Name, 'Nop', code, opt_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) diff --git a/src/arch/sparc/isa/formats/priv.isa b/src/arch/sparc/isa/formats/priv.isa index 3d47ca02f..36403afb4 100644 --- a/src/arch/sparc/isa/formats/priv.isa +++ b/src/arch/sparc/isa/formats/priv.isa @@ -235,8 +235,9 @@ let {{ name = mnem regBase = 'WrPriv' break - iop = InstObjParams(name, Name, regBase, code, - opt_flags, {"check": checkCode, "reg_name": regName}) + iop = InstObjParams(name, Name, regBase, + {"code": code, "check": checkCode, "reg_name": regName}, + opt_flags) header_output = BasicDeclare.subst(iop) if regName == '': decoder_output = BasicConstructor.subst(iop) @@ -245,7 +246,8 @@ let {{ exec_output = PrivExecute.subst(iop) if usesImm: imm_iop = InstObjParams(name, Name + 'Imm', regBase + 'Imm', - immCode, opt_flags, {"check": checkCode, "reg_name": regName}) + {"code": immCode, "check": checkCode, "reg_name": regName}, + opt_flags) header_output += BasicDeclare.subst(imm_iop) if regName == '': decoder_output += BasicConstructor.subst(imm_iop) diff --git a/src/arch/sparc/isa/formats/trap.isa b/src/arch/sparc/isa/formats/trap.isa index 04d467cfe..9c118b227 100644 --- a/src/arch/sparc/isa/formats/trap.isa +++ b/src/arch/sparc/isa/formats/trap.isa @@ -83,9 +83,7 @@ def template TrapExecute {{ }}; def format Trap(code, *opt_flags) {{ - orig_code = code - cblk = CodeBlock(code) - iop = InstObjParams(name, Name, 'Trap', cblk, opt_flags) + iop = InstObjParams(name, Name, 'Trap', code, opt_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) diff --git a/src/cpu/o3/sparc/dyn_inst.hh b/src/cpu/o3/sparc/dyn_inst.hh index 2d73ca8d1..fda99cb6c 100644 --- a/src/cpu/o3/sparc/dyn_inst.hh +++ b/src/cpu/o3/sparc/dyn_inst.hh @@ -106,6 +106,45 @@ class SparcDynInst : public BaseDynInst this->threadNumber); } + /** Reads a miscellaneous register. */ + TheISA::MiscReg readMiscRegOperand(const StaticInst *si, int idx) + { + return this->cpu->readMiscReg( + si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag, + this->threadNumber); + } + + /** Reads a misc. register, including any side-effects the read + * might have as defined by the architecture. + */ + TheISA::MiscReg readMiscRegOperandWithEffect(const StaticInst *si, int idx) + { + return this->cpu->readMiscRegWithEffect( + si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag, + this->threadNumber); + } + + /** Sets a misc. register. */ + void setMiscRegOperand(const StaticInst * si, + int idx, const TheISA::MiscReg &val) + { + this->instResult.integer = val; + return this->cpu->setMiscReg( + si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag, + val, this->threadNumber); + } + + /** Sets a misc. register, including any side-effects the write + * might have as defined by the architecture. + */ + void setMiscRegOperandWithEffect( + const StaticInst *si, int idx, const TheISA::MiscReg &val) + { + return this->cpu->setMiscRegWithEffect( + si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag, + val, this->threadNumber); + } + #if FULL_SYSTEM /** Calls hardware return from error interrupt. */ Fault hwrei(); @@ -130,30 +169,31 @@ class SparcDynInst : public BaseDynInst // storage (which is pretty hard to imagine they would have reason // to do). - uint64_t readIntReg(const StaticInst *si, int idx) + uint64_t readIntRegOperand(const StaticInst *si, int idx) { uint64_t val = this->cpu->readIntReg(this->_srcRegIdx[idx]); DPRINTF(Sparc, "Reading int reg %d (%d, %d) as %x\n", (int)this->_flatSrcRegIdx[idx], (int)this->_srcRegIdx[idx], idx, val); return this->cpu->readIntReg(this->_srcRegIdx[idx]); } - TheISA::FloatReg readFloatReg(const StaticInst *si, int idx, int width) + TheISA::FloatReg readFloatRegOperand(const StaticInst *si, + int idx, int width) { return this->cpu->readFloatReg(this->_srcRegIdx[idx], width); } - TheISA::FloatReg readFloatReg(const StaticInst *si, int idx) + TheISA::FloatReg readFloatRegOperand(const StaticInst *si, int idx) { return this->cpu->readFloatReg(this->_srcRegIdx[idx]); } - TheISA::FloatRegBits readFloatRegBits(const StaticInst *si, + TheISA::FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx, int width) { return this->cpu->readFloatRegBits(this->_srcRegIdx[idx], width); } - TheISA::FloatRegBits readFloatRegBits(const StaticInst *si, int idx) + TheISA::FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx) { return this->cpu->readFloatRegBits(this->_srcRegIdx[idx]); } @@ -161,38 +201,38 @@ class SparcDynInst : public BaseDynInst /** @todo: Make results into arrays so they can handle multiple dest * registers. */ - void setIntReg(const StaticInst *si, int idx, uint64_t val) + void setIntRegOperand(const StaticInst *si, int idx, uint64_t val) { DPRINTF(Sparc, "Setting int reg %d (%d, %d) to %x\n", (int)this->_flatDestRegIdx[idx], (int)this->_destRegIdx[idx], idx, val); this->cpu->setIntReg(this->_destRegIdx[idx], val); - BaseDynInst::setIntReg(si, idx, val); + BaseDynInst::setIntRegOperand(si, idx, val); } - void setFloatReg(const StaticInst *si, int idx, + void setFloatRegOperand(const StaticInst *si, int idx, TheISA::FloatReg val, int width) { this->cpu->setFloatReg(this->_destRegIdx[idx], val, width); - BaseDynInst::setFloatReg(si, idx, val, width); + BaseDynInst::setFloatRegOperand(si, idx, val, width); } - void setFloatReg(const StaticInst *si, int idx, TheISA::FloatReg val) + void setFloatRegOperand(const StaticInst *si, int idx, TheISA::FloatReg val) { this->cpu->setFloatReg(this->_destRegIdx[idx], val); - BaseDynInst::setFloatReg(si, idx, val); + BaseDynInst::setFloatRegOperand(si, idx, val); } - void setFloatRegBits(const StaticInst *si, int idx, + void setFloatRegOperandBits(const StaticInst *si, int idx, TheISA::FloatRegBits val, int width) { this->cpu->setFloatRegBits(this->_destRegIdx[idx], val, width); - BaseDynInst::setFloatRegBits(si, idx, val); + BaseDynInst::setFloatRegOperandBits(si, idx, val); } - void setFloatRegBits(const StaticInst *si, + void setFloatRegOperandBits(const StaticInst *si, int idx, TheISA::FloatRegBits val) { this->cpu->setFloatRegBits(this->_destRegIdx[idx], val); - BaseDynInst::setFloatRegBits(si, idx, val); + BaseDynInst::setFloatRegOperandBits(si, idx, val); } public: diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh index c39bfa9cd..dd178f64d 100644 --- a/src/cpu/simple/base.hh +++ b/src/cpu/simple/base.hh @@ -303,6 +303,31 @@ class BaseSimpleCPU : public BaseCPU return thread->setMiscRegWithEffect(misc_reg, val); } + MiscReg readMiscRegOperand(const StaticInst *si, int idx) + { + int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag; + return thread->readMiscReg(reg_idx); + } + + MiscReg readMiscRegOperandWithEffect(const StaticInst *si, int idx) + { + int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag; + return thread->readMiscRegWithEffect(reg_idx); + } + + void setMiscRegOperand(const StaticInst *si, int idx, const MiscReg &val) + { + int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag; + return thread->setMiscReg(reg_idx, val); + } + + void setMiscRegOperandWithEffect( + const StaticInst *si, int idx, const MiscReg &val) + { + int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag; + return thread->setMiscRegWithEffect(reg_idx, val); + } + #if FULL_SYSTEM Fault hwrei() { return thread->hwrei(); } void ev5_trap(Fault fault) { fault->invoke(tc); }