diff --git a/src/arch/alpha/isa/branch.isa b/src/arch/alpha/isa/branch.isa index 7438e7e18..974193efd 100644 --- a/src/arch/alpha/isa/branch.isa +++ b/src/arch/alpha/isa/branch.isa @@ -218,7 +218,7 @@ def template JumpOrBranchDecode {{ def format CondBranch(code) {{ code = 'bool cond;\n' + code + '\nif (cond) NPC = NPC + disp;\n'; - iop = InstObjParams(name, Name, 'Branch', CodeBlock(code), + iop = InstObjParams(name, Name, 'Branch', code, ('IsDirectControl', 'IsCondControl')) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) @@ -230,8 +230,7 @@ let {{ def UncondCtrlBase(name, Name, base_class, npc_expr, flags): # Declare basic control transfer w/o link (i.e. link reg is R31) nolink_code = 'NPC = %s;\n' % npc_expr - nolink_iop = InstObjParams(name, Name, base_class, - CodeBlock(nolink_code), flags) + nolink_iop = InstObjParams(name, Name, base_class, nolink_code, flags) header_output = BasicDeclare.subst(nolink_iop) decoder_output = BasicConstructor.subst(nolink_iop) exec_output = BasicExecute.subst(nolink_iop) @@ -239,7 +238,7 @@ def UncondCtrlBase(name, Name, base_class, npc_expr, flags): # Generate declaration of '*AndLink' version, append to decls link_code = 'Ra = NPC & ~3;\n' + nolink_code link_iop = InstObjParams(name, Name + 'AndLink', base_class, - CodeBlock(link_code), flags) + link_code, flags) header_output += BasicDeclare.subst(link_iop) decoder_output += BasicConstructor.subst(link_iop) exec_output += BasicExecute.subst(link_iop) diff --git a/src/arch/alpha/isa/fp.isa b/src/arch/alpha/isa/fp.isa index 3b5575f62..c845ea442 100644 --- a/src/arch/alpha/isa/fp.isa +++ b/src/arch/alpha/isa/fp.isa @@ -293,7 +293,7 @@ def template FloatingPointDecode {{ // currently unimplemented (will fail). // - Generates NOP if FC == 31. def format FloatingPointOperate(code, *opt_args) {{ - iop = InstObjParams(name, Name, 'AlphaFP', CodeBlock(code), opt_args) + iop = InstObjParams(name, Name, 'AlphaFP', code, opt_args) decode_block = FloatingPointDecode.subst(iop) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) @@ -303,7 +303,7 @@ def format FloatingPointOperate(code, *opt_args) {{ // Special format for cvttq where rounding mode is pre-decoded def format FPFixedRounding(code, class_suffix, *opt_args) {{ Name += class_suffix - iop = InstObjParams(name, Name, 'AlphaFP', CodeBlock(code), opt_args) + iop = InstObjParams(name, Name, 'AlphaFP', code, opt_args) decode_block = FloatingPointDecode.subst(iop) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) diff --git a/src/arch/alpha/isa/int.isa b/src/arch/alpha/isa/int.isa index 45e096ebd..bd9c3ccd9 100644 --- a/src/arch/alpha/isa/int.isa +++ b/src/arch/alpha/isa/int.isa @@ -113,16 +113,14 @@ def format IntegerOperate(code, *opt_flags) {{ imm_code = re.sub(r'Rb_or_imm(\.\w+)?', 'imm', orig_code) # generate declaration for register version - cblk = CodeBlock(code) - iop = InstObjParams(name, Name, 'AlphaStaticInst', cblk, opt_flags) + iop = InstObjParams(name, Name, 'AlphaStaticInst', code, opt_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) exec_output = BasicExecute.subst(iop) if uses_imm: # append declaration for imm version - imm_cblk = CodeBlock(imm_code) - imm_iop = InstObjParams(name, Name + 'Imm', 'IntegerImm', imm_cblk, + imm_iop = InstObjParams(name, Name + 'Imm', 'IntegerImm', imm_code, opt_flags) header_output += BasicDeclare.subst(imm_iop) decoder_output += BasicConstructor.subst(imm_iop) diff --git a/src/arch/alpha/isa/main.isa b/src/arch/alpha/isa/main.isa index 6e65cf9d3..d72dfe34a 100644 --- a/src/arch/alpha/isa/main.isa +++ b/src/arch/alpha/isa/main.isa @@ -338,7 +338,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, 'AlphaStaticInst', CodeBlock(code), flags) + iop = InstObjParams(name, Name, 'AlphaStaticInst', code, flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) @@ -424,8 +424,7 @@ def template OperateNopCheckDecode {{ // Like BasicOperate format, but generates NOP if RC/FC == 31 def format BasicOperateWithNopCheck(code, *opt_args) {{ - iop = InstObjParams(name, Name, 'AlphaStaticInst', CodeBlock(code), - opt_args) + iop = InstObjParams(name, Name, 'AlphaStaticInst', code, opt_args) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = OperateNopCheckDecode.subst(iop) diff --git a/src/arch/alpha/isa/mem.isa b/src/arch/alpha/isa/mem.isa index 02291ed6b..c0bdd2c05 100644 --- a/src/arch/alpha/isa/mem.isa +++ b/src/arch/alpha/isa/mem.isa @@ -126,7 +126,7 @@ output decoder {{ }}; def format LoadAddress(code) {{ - iop = InstObjParams(name, Name, 'MemoryDisp32', CodeBlock(code)) + iop = InstObjParams(name, Name, 'MemoryDisp32', code) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) @@ -191,22 +191,28 @@ def template CompleteAccDeclare {{ }}; -def template LoadStoreConstructor {{ +def template EACompConstructor {{ /** TODO: change op_class to AddrGenOp or something (requires * creating new member of OpClass enum in op_class.hh, updating * config files, etc.). */ inline %(class_name)s::EAComp::EAComp(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp) { - %(ea_constructor)s; + %(constructor)s; } +}}; + +def template MemAccConstructor {{ inline %(class_name)s::MemAcc::MemAcc(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s) { - %(memacc_constructor)s; + %(constructor)s; } +}}; + +def template LoadStoreConstructor {{ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, new EAComp(machInst), new MemAcc(machInst)) @@ -227,7 +233,7 @@ def template EACompExecute {{ %(fp_enable_check)s; %(op_decl)s; %(op_rd)s; - %(code)s; + %(ea_code)s; if (fault == NoFault) { %(op_wb)s; @@ -253,7 +259,7 @@ def template LoadMemAccExecute {{ if (fault == NoFault) { fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); - %(code)s; + %(memacc_code)s; } if (fault == NoFault) { @@ -352,7 +358,7 @@ def template StoreMemAccExecute {{ EA = xc->getEA(); if (fault == NoFault) { - %(code)s; + %(memacc_code)s; } if (fault == NoFault) { @@ -497,7 +503,7 @@ def template MiscMemAccExecute {{ EA = xc->getEA(); if (fault == NoFault) { - %(code)s; + %(memacc_code)s; } return NoFault; @@ -582,63 +588,24 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, # add hook to get effective addresses into execution trace output. ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n' - # generate code block objects - ea_cblk = CodeBlock(ea_code) - memacc_cblk = CodeBlock(memacc_code) - postacc_cblk = CodeBlock(postacc_code) - # Some CPU models execute the memory operation as an atomic unit, # while others want to separate them into an effective address # computation and a memory access operation. As a result, we need # to generate three StaticInst objects. Note that the latter two # are nested inside the larger "atomic" one. - # generate InstObjParams for EAComp object - ea_iop = InstObjParams(name, Name, base_class, ea_cblk, inst_flags) - - # generate InstObjParams for MemAcc object - memacc_iop = InstObjParams(name, Name, base_class, memacc_cblk, inst_flags) - # in the split execution model, the MemAcc portion is responsible - # for the post-access code. - memacc_iop.postacc_code = postacc_cblk.code - - # generate InstObjParams for InitiateAcc, CompleteAcc object - # The code used depends on the template being used - if (exec_template_base == 'Load'): - initiateacc_cblk = CodeBlock(ea_code + memacc_code) - completeacc_cblk = CodeBlock(memacc_code + postacc_code) - elif (exec_template_base.startswith('Store')): - initiateacc_cblk = CodeBlock(ea_code + memacc_code) - completeacc_cblk = CodeBlock(postacc_code) - else: - initiateacc_cblk = '' - completeacc_cblk = '' - - initiateacc_iop = InstObjParams(name, Name, base_class, initiateacc_cblk, - inst_flags) - - completeacc_iop = InstObjParams(name, Name, base_class, completeacc_cblk, - inst_flags) - - if (exec_template_base == 'Load'): - initiateacc_iop.ea_code = ea_cblk.code - initiateacc_iop.memacc_code = memacc_cblk.code - completeacc_iop.memacc_code = memacc_cblk.code - completeacc_iop.postacc_code = postacc_cblk.code - elif (exec_template_base.startswith('Store')): - initiateacc_iop.ea_code = ea_cblk.code - initiateacc_iop.memacc_code = memacc_cblk.code - completeacc_iop.postacc_code = postacc_cblk.code - - # generate InstObjParams for unified execution - cblk = CodeBlock(ea_code + memacc_code + postacc_code) - iop = InstObjParams(name, Name, base_class, cblk, inst_flags) - - iop.ea_constructor = ea_cblk.constructor - iop.ea_code = ea_cblk.code - iop.memacc_constructor = memacc_cblk.constructor - iop.memacc_code = memacc_cblk.code - iop.postacc_code = postacc_cblk.code + # Generate InstObjParams for each of the three objects. Note that + # they differ only in the set of code objects contained (which in + # turn affects the object's overall operand list). + iop = InstObjParams(name, Name, base_class, + { 'ea_code':ea_code, 'memacc_code':memacc_code, 'postacc_code':postacc_code }, + inst_flags) + ea_iop = InstObjParams(name, Name, base_class, + { 'ea_code':ea_code }, + inst_flags) + memacc_iop = InstObjParams(name, Name, base_class, + { 'memacc_code':memacc_code, 'postacc_code':postacc_code }, + inst_flags) if mem_flags: s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';' @@ -659,13 +626,16 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, completeAccTemplate = eval(exec_template_base + 'CompleteAcc') # (header_output, decoder_output, decode_block, exec_output) - return (LoadStoreDeclare.subst(iop), LoadStoreConstructor.subst(iop), + return (LoadStoreDeclare.subst(iop), + EACompConstructor.subst(ea_iop) + + MemAccConstructor.subst(memacc_iop) + + LoadStoreConstructor.subst(iop), decode_template.subst(iop), EACompExecute.subst(ea_iop) + memAccExecTemplate.subst(memacc_iop) + fullExecTemplate.subst(iop) - + initiateAccTemplate.subst(initiateacc_iop) - + completeAccTemplate.subst(completeacc_iop)) + + initiateAccTemplate.subst(iop) + + completeAccTemplate.subst(iop)) }}; def format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }}, diff --git a/src/arch/alpha/isa/pal.isa b/src/arch/alpha/isa/pal.isa index f4c10da1d..294b92e2f 100644 --- a/src/arch/alpha/isa/pal.isa +++ b/src/arch/alpha/isa/pal.isa @@ -68,7 +68,7 @@ output decoder {{ }}; def format EmulatedCallPal(code, *flags) {{ - iop = InstObjParams(name, Name, 'EmulatedCallPal', CodeBlock(code), flags) + iop = InstObjParams(name, Name, 'EmulatedCallPal', code, flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) @@ -131,7 +131,7 @@ output decoder {{ }}; def format CallPal(code, *flags) {{ - iop = InstObjParams(name, Name, 'CallPalBase', CodeBlock(code), flags) + iop = InstObjParams(name, Name, 'CallPalBase', code, flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) @@ -269,8 +269,7 @@ output decoder {{ def format HwMoveIPR(code, *flags) {{ all_flags = ['IprAccessOp'] all_flags += flags - iop = InstObjParams(name, Name, 'HwMoveIPR', CodeBlock(code), - all_flags) + iop = InstObjParams(name, Name, 'HwMoveIPR', code, all_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py index 83cdf73bc..07ae72cb8 100755 --- a/src/arch/isa_parser.py +++ b/src/arch/isa_parser.py @@ -1017,37 +1017,38 @@ class 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 + # Build a dict ('myDict') to use for the template substitution. + # Start with the template namespace. Make a copy since we're + # going to modify it. + myDict = templateMap.copy() + 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'] + # If we're dealing with an InstObjParams object, we need + # to be a little more sophisticated. The instruction-wide + # parameters are already formed, but the parameters which + # are only function wide still need to be generated. 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]) + snippetLabels = [l for l in labelRE.findall(template) + if d.snippets.has_key(l)] + + snippets = dict([(s, mungeSnippet(d.snippets[s])) + for s in snippetLabels]) + + myDict.update(snippets) + + compositeCode = ' '.join(map(str, snippets.values())) + + # Add in template itself in case it references any + # operands explicitly (like Mem) + compositeCode += ' ' + template + operands = SubOperandList(compositeCode, d.operands) myDict['op_decl'] = operands.concatAttrStrings('op_decl') @@ -1067,18 +1068,14 @@ class Template: 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() + elif isinstance(d, dict): # if the argument is a dictionary, we just use it. - if isinstance(d, dict): - myDict.update(d) + myDict.update(d) + elif hasattr(d, '__dict__'): # 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.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 @@ -1662,8 +1659,12 @@ assignRE = re.compile(r'\s*=(?!=)', re.MULTILINE) def substMungedOpNames(code): return operandsWithExtRE.sub(r'\1', code) -def joinLists(t): - return map(string.join, t) +# Fix up code snippets for final substitution in templates. +def mungeSnippet(s): + if isinstance(s, str): + return substMungedOpNames(substBitOps(s)) + else: + return s def makeFlagConstructor(flag_list): if len(flag_list) == 0: @@ -1689,17 +1690,13 @@ opClassRE = re.compile(r'.*Op|No_OpClass') class InstObjParams: def __init__(self, mnem, class_name, base_class = '', - snippets = None, opt_args = []): + snippets = {}, 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) + if not isinstance(snippets, dict): + snippets = {'code' : snippets} + compositeCode = ' '.join(map(str, snippets.values())) self.snippets = snippets self.operands = OperandList(compositeCode) diff --git a/src/arch/mips/isa/decoder.isa b/src/arch/mips/isa/decoder.isa index d65e3eb94..12f36c449 100644 --- a/src/arch/mips/isa/decoder.isa +++ b/src/arch/mips/isa/decoder.isa @@ -154,19 +154,20 @@ decode OPCODE_HI default Unknown::unknown() { 0x3: decode FUNCTION_LO { format HiLoOp { - 0x0: mult({{ val = Rs.sd * Rt.sd; }}); - 0x1: multu({{ val = Rs.ud * Rt.ud; }}); - } - - format HiLoMiscOp { - 0x2: div({{ if (Rt.sd != 0) { - HI = Rs.sd % Rt.sd; - LO = Rs.sd / Rt.sd; + 0x0: mult({{ int64_t val = Rs.sd * Rt.sd; }}); + 0x1: multu({{ uint64_t val = Rs.ud * Rt.ud; }}); + 0x2: div({{ int64_t val; + if (Rt.sd != 0) { + int64_t hi = Rs.sd % Rt.sd; + int64_t lo = Rs.sd / Rt.sd; + val = (hi << 32) | lo; } }}); - 0x3: divu({{ if (Rt.ud != 0) { - HI = Rs.ud % Rt.ud; - LO = Rs.ud / Rt.ud; + 0x3: divu({{ uint64_t val; + if (Rt.ud != 0) { + uint64_t hi = Rs.ud % Rt.ud; + uint64_t lo = Rs.ud / Rt.ud; + val = (hi << 32) | lo; } }}); } @@ -950,17 +951,17 @@ decode OPCODE_HI default Unknown::unknown() { }}); format HiLoOp { - 0x0: madd({{ val = ((int64_t) HI << 32 | LO) + - (Rs.sd * Rt.sd); + 0x0: madd({{ int64_t val = ((int64_t) HI << 32 | LO) + + (Rs.sd * Rt.sd); }}); - 0x1: maddu({{ val = ((uint64_t) HI << 32 | LO) + - (Rs.ud * Rt.ud); + 0x1: maddu({{ uint64_t val = ((uint64_t) HI << 32 | LO) + + (Rs.ud * Rt.ud); }}); - 0x4: msub({{ val = ((int64_t) HI << 32 | LO) - - (Rs.sd * Rt.sd); + 0x4: msub({{ int64_t val = ((int64_t) HI << 32 | LO) - + (Rs.sd * Rt.sd); }}); - 0x5: msubu({{ val = ((uint64_t) HI << 32 | LO) - - (Rs.ud * Rt.ud); + 0x5: msubu({{ uint64_t val = ((uint64_t) HI << 32 | LO) - + (Rs.ud * Rt.ud); }}); } } diff --git a/src/arch/mips/isa/formats/int.isa b/src/arch/mips/isa/formats/int.isa index e9b096f56..2f131f6d9 100644 --- a/src/arch/mips/isa/formats/int.isa +++ b/src/arch/mips/isa/formats/int.isa @@ -240,11 +240,6 @@ def format IntImmOp(code, *opt_flags) {{ }}; def format HiLoOp(code, *opt_flags) {{ - if '.sd' in code: - code = 'int64_t ' + code - elif '.ud' in code: - code = 'uint64_t ' + code - code += 'HI = val<63:32>;\n' code += 'LO = val<31:0>;\n' @@ -260,7 +255,7 @@ def format HiLoMiscOp(code, *opt_flags) {{ header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) - exec_output = HiLoExecute.subst(iop) + exec_output = BasicExecute.subst(iop) }}; diff --git a/src/arch/mips/isa/formats/mem.isa b/src/arch/mips/isa/formats/mem.isa index e786cfbe2..fccda2775 100644 --- a/src/arch/mips/isa/formats/mem.isa +++ b/src/arch/mips/isa/formats/mem.isa @@ -166,22 +166,28 @@ def template CompleteAccDeclare {{ }}; -def template LoadStoreConstructor {{ +def template EACompConstructor {{ /** TODO: change op_class to AddrGenOp or something (requires * creating new member of OpClass enum in op_class.hh, updating * config files, etc.). */ inline %(class_name)s::EAComp::EAComp(MachInst machInst) : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp) { - %(ea_constructor)s; + %(constructor)s; } +}}; + +def template MemAccConstructor {{ inline %(class_name)s::MemAcc::MemAcc(MachInst machInst) : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s) { - %(memacc_constructor)s; + %(constructor)s; } +}}; + +def template LoadStoreConstructor {{ inline %(class_name)s::%(class_name)s(MachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, new EAComp(machInst), new MemAcc(machInst)) @@ -202,7 +208,7 @@ def template EACompExecute {{ %(fp_enable_check)s; %(op_decl)s; %(op_rd)s; - %(code)s; + %(ea_code)s; if (fault == NoFault) { %(op_wb)s; @@ -228,7 +234,7 @@ def template LoadMemAccExecute {{ if (fault == NoFault) { fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); - %(code)s; + %(memacc_code)s; } if (fault == NoFault) { @@ -327,7 +333,7 @@ def template StoreMemAccExecute {{ EA = xc->getEA(); if (fault == NoFault) { - %(code)s; + %(memacc_code)s; } if (fault == NoFault) { @@ -471,7 +477,7 @@ def template MiscMemAccExecute {{ EA = xc->getEA(); if (fault == NoFault) { - %(code)s; + %(memacc_code)s; } return NoFault; diff --git a/src/arch/mips/isa/formats/util.isa b/src/arch/mips/isa/formats/util.isa index 73164bc0d..ec524113d 100644 --- a/src/arch/mips/isa/formats/util.isa +++ b/src/arch/mips/isa/formats/util.isa @@ -40,63 +40,24 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, # add hook to get effective addresses into execution trace output. ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n' - # generate code block objects - ea_cblk = CodeBlock(ea_code) - memacc_cblk = CodeBlock(memacc_code) - postacc_cblk = CodeBlock(postacc_code) - # Some CPU models execute the memory operation as an atomic unit, # while others want to separate them into an effective address # computation and a memory access operation. As a result, we need # to generate three StaticInst objects. Note that the latter two # are nested inside the larger "atomic" one. - # generate InstObjParams for EAComp object - ea_iop = InstObjParams(name, Name, base_class, ea_cblk, inst_flags) - - # generate InstObjParams for MemAcc object - memacc_iop = InstObjParams(name, Name, base_class, memacc_cblk, inst_flags) - # in the split execution model, the MemAcc portion is responsible - # for the post-access code. - memacc_iop.postacc_code = postacc_cblk.code - - # generate InstObjParams for InitiateAcc, CompleteAcc object - # The code used depends on the template being used - if (exec_template_base == 'Load'): - initiateacc_cblk = CodeBlock(ea_code + memacc_code) - completeacc_cblk = CodeBlock(memacc_code + postacc_code) - elif (exec_template_base.startswith('Store')): - initiateacc_cblk = CodeBlock(ea_code + memacc_code) - completeacc_cblk = CodeBlock(postacc_code) - else: - initiateacc_cblk = '' - completeacc_cblk = '' - - initiateacc_iop = InstObjParams(name, Name, base_class, initiateacc_cblk, - inst_flags) - - completeacc_iop = InstObjParams(name, Name, base_class, completeacc_cblk, - inst_flags) - - if (exec_template_base == 'Load'): - initiateacc_iop.ea_code = ea_cblk.code - initiateacc_iop.memacc_code = memacc_cblk.code - completeacc_iop.memacc_code = memacc_cblk.code - completeacc_iop.postacc_code = postacc_cblk.code - elif (exec_template_base.startswith('Store')): - initiateacc_iop.ea_code = ea_cblk.code - initiateacc_iop.memacc_code = memacc_cblk.code - completeacc_iop.postacc_code = postacc_cblk.code - - # generate InstObjParams for unified execution - cblk = CodeBlock(ea_code + memacc_code + postacc_code) - iop = InstObjParams(name, Name, base_class, cblk, inst_flags) - - iop.ea_constructor = ea_cblk.constructor - iop.ea_code = ea_cblk.code - iop.memacc_constructor = memacc_cblk.constructor - iop.memacc_code = memacc_cblk.code - iop.postacc_code = postacc_cblk.code + # Generate InstObjParams for each of the three objects. Note that + # they differ only in the set of code objects contained (which in + # turn affects the object's overall operand list). + iop = InstObjParams(name, Name, base_class, + { 'ea_code':ea_code, 'memacc_code':memacc_code, 'postacc_code':postacc_code }, + inst_flags) + ea_iop = InstObjParams(name, Name, base_class, + { 'ea_code':ea_code }, + inst_flags) + memacc_iop = InstObjParams(name, Name, base_class, + { 'memacc_code':memacc_code, 'postacc_code':postacc_code }, + inst_flags) if mem_flags: s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';' @@ -117,14 +78,19 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, completeAccTemplate = eval(exec_template_base + 'CompleteAcc') # (header_output, decoder_output, decode_block, exec_output) - return (LoadStoreDeclare.subst(iop), LoadStoreConstructor.subst(iop), + return (LoadStoreDeclare.subst(iop), + EACompConstructor.subst(ea_iop) + + MemAccConstructor.subst(memacc_iop) + + LoadStoreConstructor.subst(iop), decode_template.subst(iop), EACompExecute.subst(ea_iop) + memAccExecTemplate.subst(memacc_iop) + fullExecTemplate.subst(iop) - + initiateAccTemplate.subst(initiateacc_iop) - + completeAccTemplate.subst(completeacc_iop)) + + initiateAccTemplate.subst(iop) + + completeAccTemplate.subst(iop)) }}; + + output header {{ std::string inst2string(MachInst machInst); }}; diff --git a/src/arch/sparc/isa/formats/mem/util.isa b/src/arch/sparc/isa/formats/mem/util.isa index 87a841270..c56821c4f 100644 --- a/src/arch/sparc/isa/formats/mem/util.isa +++ b/src/arch/sparc/isa/formats/mem/util.isa @@ -170,7 +170,6 @@ def template LoadInitiateAcc {{ { Fault fault = NoFault; Addr EA; - uint%(mem_acc_size)s_t Mem; %(op_decl)s; %(op_rd)s; %(ea_code)s; diff --git a/src/cpu/o3/alpha/dyn_inst.hh b/src/cpu/o3/alpha/dyn_inst.hh index c340a806a..ee895d77c 100644 --- a/src/cpu/o3/alpha/dyn_inst.hh +++ b/src/cpu/o3/alpha/dyn_inst.hh @@ -123,6 +123,44 @@ class AlphaDynInst : 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 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 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();