diff options
Diffstat (limited to 'src/arch')
56 files changed, 713 insertions, 649 deletions
diff --git a/src/arch/alpha/SConscript b/src/arch/alpha/SConscript index 3cc5ec270..addd49884 100644 --- a/src/arch/alpha/SConscript +++ b/src/arch/alpha/SConscript @@ -52,6 +52,7 @@ base_sources = Split(''' intregfile.cc miscregfile.cc regfile.cc + remote_gdb.cc ''') # Full-system sources @@ -66,7 +67,6 @@ full_system_sources = Split(''' osfpal.cc pagetable.cc stacktrace.cc - remote_gdb.cc system.cc tlb.cc tru64/system.cc 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/alpha/isa_traits.hh b/src/arch/alpha/isa_traits.hh index 35d9ce843..a267ac034 100644 --- a/src/arch/alpha/isa_traits.hh +++ b/src/arch/alpha/isa_traits.hh @@ -132,7 +132,7 @@ namespace AlphaISA const int NumPALShadowRegs = 8; const int NumFloatArchRegs = 32; // @todo: Figure out what this number really should be. - const int NumMiscArchRegs = 32; + const int NumMiscArchRegs = 77; const int NumIntRegs = NumIntArchRegs + NumPALShadowRegs; const int NumFloatRegs = NumFloatArchRegs; diff --git a/src/arch/alpha/regfile.hh b/src/arch/alpha/regfile.hh index ff5830822..54372da36 100644 --- a/src/arch/alpha/regfile.hh +++ b/src/arch/alpha/regfile.hh @@ -78,13 +78,11 @@ namespace AlphaISA Addr readNextNPC() { - return nnpc; + return npc + sizeof(MachInst); } void setNextNPC(Addr val) - { - nnpc = val; - } + { } protected: IntRegFile intRegFile; // (signed) integer register file @@ -189,6 +187,11 @@ namespace AlphaISA } }; + static inline int flattenIntIndex(ThreadContext * tc, int reg) + { + return reg; + } + void copyRegs(ThreadContext *src, ThreadContext *dest); void copyMiscRegs(ThreadContext *src, ThreadContext *dest); diff --git a/src/arch/alpha/remote_gdb.cc b/src/arch/alpha/remote_gdb.cc index f23fc3205..4637bd7a6 100644 --- a/src/arch/alpha/remote_gdb.cc +++ b/src/arch/alpha/remote_gdb.cc @@ -121,14 +121,18 @@ #include <string> #include <unistd.h> +#include "config/full_system.hh" +#if FULL_SYSTEM +#include "arch/alpha/vtophys.hh" +#endif + #include "arch/alpha/kgdb.h" +#include "arch/alpha/utility.hh" #include "arch/alpha/remote_gdb.hh" -#include "arch/vtophys.hh" #include "base/intmath.hh" #include "base/remote_gdb.hh" #include "base/socket.hh" #include "base/trace.hh" -#include "config/full_system.hh" #include "cpu/thread_context.hh" #include "cpu/static_inst.hh" #include "mem/physical.hh" @@ -152,6 +156,9 @@ RemoteGDB::RemoteGDB(System *_system, ThreadContext *c) bool RemoteGDB::acc(Addr va, size_t len) { +#if !FULL_SYSTEM + panic("acc function needs to be rewritten for SE mode\n"); +#else Addr last_va; va = TheISA::TruncPage(va); @@ -191,6 +198,7 @@ RemoteGDB::acc(Addr va, size_t len) DPRINTF(GDBAcc, "acc: %#x mapping is valid\n", va); return true; +#endif } /////////////////////////////////////////////////////////// diff --git a/src/arch/alpha/syscallreturn.hh b/src/arch/alpha/syscallreturn.hh index 803c3b7da..47b4ac8c7 100644 --- a/src/arch/alpha/syscallreturn.hh +++ b/src/arch/alpha/syscallreturn.hh @@ -32,54 +32,25 @@ #ifndef __ARCH_ALPHA_SYSCALLRETURN_HH__ #define __ARCH_ALPHA_SYSCALLRETURN_HH__ -class SyscallReturn { - public: - template <class T> - SyscallReturn(T v, bool s) - { - retval = (uint64_t)v; - success = s; - } - - template <class T> - SyscallReturn(T v) - { - success = (v >= 0); - retval = (uint64_t)v; - } - - ~SyscallReturn() {} - - SyscallReturn& operator=(const SyscallReturn& s) { - retval = s.retval; - success = s.success; - return *this; - } - - bool successful() { return success; } - uint64_t value() { return retval; } - - - private: - uint64_t retval; - bool success; -}; +#include "cpu/thread_context.hh" +#include "sim/syscallreturn.hh" namespace AlphaISA { - static inline void setSyscallReturn(SyscallReturn return_value, RegFile *regs) + static inline void setSyscallReturn(SyscallReturn return_value, + ThreadContext * tc) { // check for error condition. Alpha syscall convention is to // indicate success/failure in reg a3 (r19) and put the // return value itself in the standard return value reg (v0). if (return_value.successful()) { // no error - regs->setIntReg(SyscallSuccessReg, 0); - regs->setIntReg(ReturnValueReg, return_value.value()); + tc->setIntReg(SyscallSuccessReg, 0); + tc->setIntReg(ReturnValueReg, return_value.value()); } else { // got an error, return details - regs->setIntReg(SyscallSuccessReg, (IntReg)-1); - regs->setIntReg(ReturnValueReg, -return_value.value()); + tc->setIntReg(SyscallSuccessReg, (IntReg)-1); + tc->setIntReg(ReturnValueReg, -return_value.value()); } } } diff --git a/src/arch/alpha/system.cc b/src/arch/alpha/system.cc index cd923948c..ed0938aeb 100644 --- a/src/arch/alpha/system.cc +++ b/src/arch/alpha/system.cc @@ -195,12 +195,6 @@ AlphaSystem::setAlphaAccess(Addr access) panic("could not find m5AlphaAccess\n"); } -bool -AlphaSystem::breakpoint() -{ - return remoteGDB[0]->trap(SIGTRAP); -} - void AlphaSystem::serialize(std::ostream &os) { diff --git a/src/arch/alpha/system.hh b/src/arch/alpha/system.hh index 0c073a68c..f92b71c9a 100644 --- a/src/arch/alpha/system.hh +++ b/src/arch/alpha/system.hh @@ -56,8 +56,6 @@ class AlphaSystem : public System ~AlphaSystem(); - virtual bool breakpoint(); - /** * Serialization stuff */ diff --git a/src/arch/alpha/utility.hh b/src/arch/alpha/utility.hh index 100736555..9a06cc2a4 100644 --- a/src/arch/alpha/utility.hh +++ b/src/arch/alpha/utility.hh @@ -121,9 +121,9 @@ namespace AlphaISA template <class TC> void zeroRegisters(TC *tc); -#if FULL_SYSTEM // Alpha IPR register accessors - inline bool PcPAL(Addr addr) { return addr & 0x1; } + inline bool PcPAL(Addr addr) { return addr & 0x3; } +#if FULL_SYSTEM //////////////////////////////////////////////////////////////////////// // diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py index 59eb18c9c..07ae72cb8 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,80 @@ 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): + 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) + + # 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 the argument is a dictionary, we just use it. - if isinstance(d, dict): + + if isinstance(d, InstObjParams): + # 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.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'] + + 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') + + 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 + + elif isinstance(d, dict): + # if the argument is a dictionary, we just use it. myDict.update(d) - # if the argument is an object, we use its attribute map. elif hasattr(d, '__dict__'): + # if the argument is an object, we use its attribute map. myDict.update(d.__dict__) else: raise TypeError, "Template.subst() arg must be or have dictionary" - # 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) return template % myDict # Convert to string. This handles the case when a template with a @@ -1296,10 +1348,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 +1359,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->readMiscRegWithEffect(%s)' % self.reg_spec + base = 'xc->readMiscRegOperandWithEffect(this, %s)' % self.src_reg_idx if self.size == self.dflt_size: return '%s = %s;\n' % (self.base_name, base) else: @@ -1317,7 +1369,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 +1603,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') @@ -1564,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: @@ -1583,11 +1682,24 @@ 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 = {}, opt_args = []): + self.mnemonic = mnem + self.class_name = class_name + self.base_class = base_class + if not isinstance(snippets, dict): + snippets = {'code' : snippets} + compositeCode = ' '.join(map(str, snippets.values())) + self.snippets = snippets + + self.operands = OperandList(compositeCode) self.constructor = self.operands.concatAttrStrings('constructor') self.constructor += \ '\n\t_numSrcRegs = %d;' % self.operands.numSrcRegs @@ -1597,28 +1709,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 +1723,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/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/basic.isa b/src/arch/mips/isa/formats/basic.isa index 29a445b2c..ec065b865 100644 --- a/src/arch/mips/isa/formats/basic.isa +++ b/src/arch/mips/isa/formats/basic.isa @@ -88,7 +88,7 @@ def template BasicDecodeWithMnemonic {{ // The most basic instruction format... def format BasicOp(code, *flags) {{ - iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) + iop = InstObjParams(name, Name, 'MipsStaticInst', code, flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) diff --git a/src/arch/mips/isa/formats/branch.isa b/src/arch/mips/isa/formats/branch.isa index 8c89fbfa2..a67f04dca 100644 --- a/src/arch/mips/isa/formats/branch.isa +++ b/src/arch/mips/isa/formats/branch.isa @@ -247,7 +247,7 @@ def format Branch(code,*opt_flags) {{ code += '} else {\n' code += not_taken_code - iop = InstObjParams(name, Name, 'Branch', CodeBlock(code), inst_flags) + iop = InstObjParams(name, Name, 'Branch', code, inst_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) @@ -266,7 +266,7 @@ def format Jump(code, *opt_flags) {{ else: inst_flags += (x, ) - iop = InstObjParams(name, Name, 'Jump', CodeBlock(code), inst_flags) + iop = InstObjParams(name, Name, 'Jump', code, inst_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) diff --git a/src/arch/mips/isa/formats/control.isa b/src/arch/mips/isa/formats/control.isa index 6c7d396f3..1c63a6e22 100644 --- a/src/arch/mips/isa/formats/control.isa +++ b/src/arch/mips/isa/formats/control.isa @@ -130,7 +130,7 @@ output decoder {{ }}; def format System(code, *flags) {{ - iop = InstObjParams(name, Name, 'Control', CodeBlock(code), flags) + iop = InstObjParams(name, Name, 'Control', code, flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) @@ -138,7 +138,7 @@ def format System(code, *flags) {{ }}; def format CP0Control(code, *flags) {{ - iop = InstObjParams(name, Name, 'CP0Control', CodeBlock(code), flags) + iop = InstObjParams(name, Name, 'CP0Control', code, flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) @@ -146,7 +146,7 @@ def format CP0Control(code, *flags) {{ }}; def format CP1Control(code, *flags) {{ - iop = InstObjParams(name, Name, 'CP1Control', CodeBlock(code), flags) + iop = InstObjParams(name, Name, 'CP1Control', code, flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) diff --git a/src/arch/mips/isa/formats/fp.isa b/src/arch/mips/isa/formats/fp.isa index 153f3f949..ac6805cc7 100644 --- a/src/arch/mips/isa/formats/fp.isa +++ b/src/arch/mips/isa/formats/fp.isa @@ -209,7 +209,7 @@ def template FloatingPointExecute {{ // Primary format for float point operate instructions: def format FloatOp(code, *flags) {{ - iop = InstObjParams(name, Name, 'FPOp', CodeBlock(code), flags) + iop = InstObjParams(name, Name, 'FPOp', code, flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) @@ -248,7 +248,7 @@ def format FloatCompareOp(cond_code, *flags) {{ code += cond_code + '}' code += 'FCSR = genCCVector(FCSR, CC, cond);\n' - iop = InstObjParams(name, Name, 'FPCompareOp', CodeBlock(code)) + iop = InstObjParams(name, Name, 'FPCompareOp', code) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) @@ -299,7 +299,7 @@ def format FloatConvertOp(code, *flags) {{ else: code += 'val); ' - iop = InstObjParams(name, Name, 'FPOp', CodeBlock(code)) + iop = InstObjParams(name, Name, 'FPOp', code) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) @@ -307,7 +307,7 @@ def format FloatConvertOp(code, *flags) {{ }}; def format FloatAccOp(code, *flags) {{ - iop = InstObjParams(name, Name, 'FPOp', CodeBlock(code), flags) + iop = InstObjParams(name, Name, 'FPOp', code, flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) @@ -316,7 +316,7 @@ def format FloatAccOp(code, *flags) {{ // Primary format for float64 operate instructions: def format Float64Op(code, *flags) {{ - iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) + iop = InstObjParams(name, Name, 'MipsStaticInst', code, flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) @@ -364,7 +364,7 @@ def format FloatPSCompareOp(cond_code1, cond_code2, *flags) {{ code += cond_code2 code += 'FCSR = genCCVector(FCSR, CC, cond2);}\n}' - iop = InstObjParams(name, Name, 'FPCompareOp', CodeBlock(code)) + iop = InstObjParams(name, Name, 'FPCompareOp', code) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) diff --git a/src/arch/mips/isa/formats/int.isa b/src/arch/mips/isa/formats/int.isa index 654dd8921..2f131f6d9 100644 --- a/src/arch/mips/isa/formats/int.isa +++ b/src/arch/mips/isa/formats/int.isa @@ -224,7 +224,7 @@ output decoder {{ }}; def format IntOp(code, *opt_flags) {{ - iop = InstObjParams(name, Name, 'IntOp', CodeBlock(code), opt_flags) + iop = InstObjParams(name, Name, 'IntOp', code, opt_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = RegNopCheckDecode.subst(iop) @@ -232,7 +232,7 @@ def format IntOp(code, *opt_flags) {{ }}; def format IntImmOp(code, *opt_flags) {{ - iop = InstObjParams(name, Name, 'IntImmOp', CodeBlock(code), opt_flags) + iop = InstObjParams(name, Name, 'IntImmOp', code, opt_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = ImmNopCheckDecode.subst(iop) @@ -240,15 +240,10 @@ 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' - iop = InstObjParams(name, Name, 'HiLoOp', CodeBlock(code), opt_flags) + iop = InstObjParams(name, Name, 'HiLoOp', code, opt_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) @@ -256,11 +251,11 @@ def format HiLoOp(code, *opt_flags) {{ }}; def format HiLoMiscOp(code, *opt_flags) {{ - iop = InstObjParams(name, Name, 'HiLoMiscOp', CodeBlock(code), opt_flags) + iop = InstObjParams(name, Name, '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/mt.isa b/src/arch/mips/isa/formats/mt.isa index 96435f8c9..d7240335e 100644 --- a/src/arch/mips/isa/formats/mt.isa +++ b/src/arch/mips/isa/formats/mt.isa @@ -74,7 +74,7 @@ def template MTExecute {{ // Primary format for integer operate instructions: def format MipsMT() {{ code = 'panic(\"Mips MT Is Currently Unimplemented.\");\n' - iop = InstObjParams(name, Name, 'MT', CodeBlock(code)) + iop = InstObjParams(name, Name, 'MT', code) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) diff --git a/src/arch/mips/isa/formats/noop.isa b/src/arch/mips/isa/formats/noop.isa index 7f3d313ad..a8995d658 100644 --- a/src/arch/mips/isa/formats/noop.isa +++ b/src/arch/mips/isa/formats/noop.isa @@ -125,7 +125,7 @@ def template ImmNopCheckDecode {{ // Like BasicOperate format, but generates NOP if RC/FC == 31 def format BasicOperateWithNopCheck(code, *opt_args) {{ - iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), + iop = InstObjParams(name, Name, 'MipsStaticInst', code, opt_args) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) diff --git a/src/arch/mips/isa/formats/tlbop.isa b/src/arch/mips/isa/formats/tlbop.isa index b974ccbed..dbfbb8ce1 100644 --- a/src/arch/mips/isa/formats/tlbop.isa +++ b/src/arch/mips/isa/formats/tlbop.isa @@ -70,9 +70,7 @@ def template TlbOpExecute {{ // Primary format for integer operate instructions: def format TlbOp(code, *opt_flags) {{ - orig_code = code - cblk = CodeBlock(code) - iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags) + iop = InstObjParams(name, Name, 'MipsStaticInst', code, opt_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecodeWithMnemonic.subst(iop) diff --git a/src/arch/mips/isa/formats/trap.isa b/src/arch/mips/isa/formats/trap.isa index b9066f374..96d1167d2 100644 --- a/src/arch/mips/isa/formats/trap.isa +++ b/src/arch/mips/isa/formats/trap.isa @@ -73,7 +73,7 @@ def format Trap(code, *flags) {{ code = 'warn(\"' code += 'Trap Exception Handler Is Currently Not Implemented.' code += '\");' - iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) + iop = InstObjParams(name, Name, 'MipsStaticInst', code, flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) 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/mips/regfile/regfile.hh b/src/arch/mips/regfile/regfile.hh index dee883c4a..7b57b31f5 100644 --- a/src/arch/mips/regfile/regfile.hh +++ b/src/arch/mips/regfile/regfile.hh @@ -173,6 +173,11 @@ namespace MipsISA } }; + static inline int flattenIntIndex(ThreadContext * tc, int reg) + { + return reg; + } + void copyRegs(ThreadContext *src, ThreadContext *dest); void copyMiscRegs(ThreadContext *src, ThreadContext *dest); diff --git a/src/arch/mips/remote_gdb.hh b/src/arch/mips/remote_gdb.hh new file mode 100644 index 000000000..5886ab849 --- /dev/null +++ b/src/arch/mips/remote_gdb.hh @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2002-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Nathan Binkert + */ + +#ifndef __ARCH_MIPS_REMOTE_GDB_HH__ +#define __ARCH_MIPS_REMOTE_GDB_HH__ + +#include "base/remote_gdb.hh" + +namespace MipsISA +{ + class RemoteGDB : public BaseRemoteGDB + { + public: + //These needs to be written to suit MIPS + + RemoteGDB(System *system, ThreadContext *context) + : BaseRemoteGDB(system, context, 1) + {} + + bool acc(Addr, size_t) + { panic("acc not implemented for MIPS!"); } + + void getregs() + { panic("getregs not implemented for MIPS!"); } + + void setregs() + { panic("setregs not implemented for MIPS!"); } + + void clearSingleStep() + { panic("clearSingleStep not implemented for MIPS!"); } + + void setSingleStep() + { panic("setSingleStep not implemented for MIPS!"); } + }; +} + +#endif /* __ARCH_ALPHA_REMOTE_GDB_H__ */ diff --git a/src/arch/mips/syscallreturn.hh b/src/arch/mips/syscallreturn.hh index ef1093caf..47290b634 100644 --- a/src/arch/mips/syscallreturn.hh +++ b/src/arch/mips/syscallreturn.hh @@ -32,51 +32,22 @@ #ifndef __ARCH_MIPS_SYSCALLRETURN_HH__ #define __ARCH_MIPS_SYSCALLRETURN_HH__ -class SyscallReturn { - public: - template <class T> - SyscallReturn(T v, bool s) - { - retval = (uint32_t)v; - success = s; - } - - template <class T> - SyscallReturn(T v) - { - success = (v >= 0); - retval = (uint32_t)v; - } - - ~SyscallReturn() {} - - SyscallReturn& operator=(const SyscallReturn& s) { - retval = s.retval; - success = s.success; - return *this; - } - - bool successful() { return success; } - uint64_t value() { return retval; } - - - private: - uint64_t retval; - bool success; -}; +#include "sim/syscallreturn.hh" +#include "cpu/thread_context.hh" namespace MipsISA { - static inline void setSyscallReturn(SyscallReturn return_value, RegFile *regs) + static inline void setSyscallReturn(SyscallReturn return_value, + ThreadContext *tc) { if (return_value.successful()) { // no error - regs->setIntReg(SyscallSuccessReg, 0); - regs->setIntReg(ReturnValueReg1, return_value.value()); + tc->setIntReg(SyscallSuccessReg, 0); + tc->setIntReg(ReturnValueReg1, return_value.value()); } else { // got an error, return details - regs->setIntReg(SyscallSuccessReg, (IntReg) -1); - regs->setIntReg(ReturnValueReg1, -return_value.value()); + tc->setIntReg(SyscallSuccessReg, (IntReg) -1); + tc->setIntReg(ReturnValueReg1, -return_value.value()); } } } diff --git a/src/arch/sparc/SConscript b/src/arch/sparc/SConscript index c2ef97bfa..555bfba3d 100644 --- a/src/arch/sparc/SConscript +++ b/src/arch/sparc/SConscript @@ -50,12 +50,12 @@ base_sources = Split(''' intregfile.cc miscregfile.cc regfile.cc + remote_gdb.cc ''') # Full-system sources full_system_sources = Split(''' arguments.cc - remote_gdb.cc pagetable.cc stacktrace.cc system.cc diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index b465e52d2..d94c05a0f 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -302,10 +302,12 @@ void doREDFault(ThreadContext *tc, TrapType tt) MiscReg TSTATE = tc->readMiscReg(MISCREG_TSTATE); MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE); MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE); - MiscReg CCR = tc->readMiscReg(MISCREG_CCR); + //MiscReg CCR = tc->readMiscReg(MISCREG_CCR); + MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2); MiscReg ASI = tc->readMiscReg(MISCREG_ASI); MiscReg CWP = tc->readMiscReg(MISCREG_CWP); - MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE); + //MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE); + MiscReg CANSAVE = tc->readMiscReg(NumIntArchRegs + 3); MiscReg GL = tc->readMiscReg(MISCREG_GL); MiscReg PC = tc->readPC(); MiscReg NPC = tc->readNextPC(); @@ -382,10 +384,12 @@ void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv) MiscReg TSTATE = tc->readMiscReg(MISCREG_TSTATE); MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE); MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE); - MiscReg CCR = tc->readMiscReg(MISCREG_CCR); + //MiscReg CCR = tc->readMiscReg(MISCREG_CCR); + MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2); MiscReg ASI = tc->readMiscReg(MISCREG_ASI); MiscReg CWP = tc->readMiscReg(MISCREG_CWP); - MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE); + //MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE); + MiscReg CANSAVE = tc->readIntReg(NumIntArchRegs + 3); MiscReg GL = tc->readMiscReg(MISCREG_GL); MiscReg PC = tc->readPC(); MiscReg NPC = tc->readNextPC(); @@ -646,19 +650,21 @@ void PageTableFault::invoke(ThreadContext *tc) { Process *p = tc->getProcessPtr(); - // address is higher than the stack region or in the current stack region - if (vaddr > p->stack_base || vaddr > p->stack_min) - FaultBase::invoke(tc); - - // We've accessed the next page - if (vaddr > p->stack_min - PageBytes) { + // We've accessed the next page of the stack, so extend the stack + // to cover it. + if(vaddr < p->stack_min && vaddr >= p->stack_min - PageBytes) + { p->stack_min -= PageBytes; - if (p->stack_base - p->stack_min > 8*1024*1024) + if(p->stack_base - p->stack_min > 8*1024*1024) fatal("Over max stack size for one thread\n"); p->pTable->allocate(p->stack_min, PageBytes); warn("Increasing stack size by one page."); - } else { - FaultBase::invoke(tc); + } + // Otherwise, we have an unexpected page fault. Report that fact, + // and what address was accessed to cause the fault. + else + { + panic("Page table fault when accessing virtual address %#x\n", vaddr); } } diff --git a/src/arch/sparc/intregfile.cc b/src/arch/sparc/intregfile.cc index 60856d3fa..2c9d9b162 100644 --- a/src/arch/sparc/intregfile.cc +++ b/src/arch/sparc/intregfile.cc @@ -66,6 +66,7 @@ void IntRegFile::clear() memset(regGlobals[x], 0, sizeof(IntReg) * RegsPerFrame); for(int x = 0; x < 2 * NWindows; x++) memset(regSegments[x], 0, sizeof(IntReg) * RegsPerFrame); + memset(regs, 0, sizeof(IntReg) * NumIntRegs); } IntRegFile::IntRegFile() @@ -78,6 +79,8 @@ IntRegFile::IntRegFile() IntReg IntRegFile::readReg(int intReg) { + DPRINTF(Sparc, "Read register %d = 0x%x\n", intReg, regs[intReg]); + return regs[intReg]; IntReg val; if(intReg < NumIntArchRegs) val = regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask]; @@ -96,6 +99,12 @@ void IntRegFile::setReg(int intReg, const IntReg &val) if(intReg) { DPRINTF(Sparc, "Wrote register %d = 0x%x\n", intReg, val); + regs[intReg] = val; + } + return; + if(intReg) + { + DPRINTF(Sparc, "Wrote register %d = 0x%x\n", intReg, val); if(intReg < NumIntArchRegs) regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask] = val; else if((intReg -= NumIntArchRegs) < NumMicroIntRegs) diff --git a/src/arch/sparc/intregfile.hh b/src/arch/sparc/intregfile.hh index d66d0fcb7..716d45a65 100644 --- a/src/arch/sparc/intregfile.hh +++ b/src/arch/sparc/intregfile.hh @@ -34,6 +34,7 @@ #include "arch/sparc/isa_traits.hh" #include "arch/sparc/types.hh" +#include "base/bitfield.hh" #include <string> @@ -54,15 +55,19 @@ namespace SparcISA private: friend class RegFile; protected: + //The number of bits needed to index into each 8 register frame static const int FrameOffsetBits = 3; + //The number of bits to choose between the 4 sets of 8 registers static const int FrameNumBits = 2; + //The number of registers per "frame" (8) static const int RegsPerFrame = 1 << FrameOffsetBits; - static const int FrameNumMask = + //A mask to get the frame number + static const uint64_t FrameNumMask = (FrameNumBits == sizeof(int)) ? (unsigned int)(-1) : (1 << FrameNumBits) - 1; - static const int FrameOffsetMask = + static const uint64_t FrameOffsetMask = (FrameOffsetBits == sizeof(int)) ? (unsigned int)(-1) : (1 << FrameOffsetBits) - 1; @@ -70,6 +75,7 @@ namespace SparcISA IntReg regGlobals[MaxGL+1][RegsPerFrame]; IntReg regSegments[2 * NWindows][RegsPerFrame]; IntReg microRegs[NumMicroIntRegs]; + IntReg regs[NumIntRegs]; enum regFrame {Globals, Outputs, Locals, Inputs, NumFrames}; diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index 175866eba..e59ce9d11 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -76,9 +76,15 @@ decode OP default Unknown::unknown() }}); 0x2: bpccx(19, {{ if(passesCondition(Ccr<7:4>, COND2)) + { + //warn("Took branch!\n"); NNPC = xc->readPC() + disp; + } else + { + //warn("Didn't take branch!\n"); handle_annul + } }}); } } @@ -247,16 +253,14 @@ decode OP default Unknown::unknown() ((Rs1 & val2) | (carryin & (Rs1 | val2)))<0:>)<63:>}}, {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} ); - 0x1A: umulcc({{ + 0x1A: IntOpCcRes::umulcc({{ uint64_t resTemp; Rd = resTemp = Rs1.udw<31:0> * Rs2_or_imm13.udw<31:0>; - Y = resTemp<63:32>;}}, - {{0}},{{0}},{{0}},{{0}}); - 0x1B: smulcc({{ + Y = resTemp<63:32>;}}); + 0x1B: IntOpCcRes::smulcc({{ int64_t resTemp; Rd = resTemp = Rs1.sdw<31:0> * Rs2_or_imm13.sdw<31:0>; - Y = resTemp<63:32>;}}, - {{0}},{{0}},{{0}},{{0}}); + Y = resTemp<63:32>;}}); 0x1C: subccc({{ int64_t resTemp, val2 = Rs2_or_imm13; int64_t carryin = Ccr<0:0>; @@ -266,10 +270,9 @@ decode OP default Unknown::unknown() {{(~((Rs1<63:1> + (~(val2 + carryin))<63:1>) + (Rs1<0:> + (~(val2+carryin))<0:> + 1)<63:1>))<63:>}}, {{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}} ); - 0x1D: udivxcc({{ + 0x1D: IntOpCcRes::udivxcc({{ if(Rs2_or_imm13.udw == 0) fault = new DivisionByZero; - else Rd = Rs1.udw / Rs2_or_imm13.udw;}} - ,{{0}},{{0}},{{0}},{{0}}); + else Rd = Rs1.udw / Rs2_or_imm13.udw;}}); 0x1E: udivcc({{ uint32_t resTemp, val2 = Rs2_or_imm13.udw; int32_t overflow = 0; @@ -880,16 +883,11 @@ decode OP default Unknown::unknown() } }}); 0x39: Branch::return({{ - //If both MemAddressNotAligned and - //a fill trap happen, it's not clear - //which one should be returned. Addr target = Rs1 + Rs2_or_imm13; - if(target & 0x3) - fault = new MemAddressNotAligned; - else - NNPC = target; if(fault == NoFault) { + //Check for fills which are higher priority than alignment + //faults. if(Canrestore == 0) { if(Otherwin) @@ -897,18 +895,15 @@ decode OP default Unknown::unknown() else fault = new FillNNormal(4*Wstate<2:0>); } + //Check for alignment faults + else if(target & 0x3) + fault = new MemAddressNotAligned; else { - //CWP should be set directly so that it always happens - //Also, this will allow writing to the new window and - //reading from the old one + NNPC = target; Cwp = (Cwp - 1 + NWindows) % NWindows; Cansave = Cansave + 1; Canrestore = Canrestore - 1; - //This is here to make sure the CWP is written - //no matter what. This ensures that the results - //are written in the new window as well. - xc->setMiscRegWithEffect(MISCREG_CWP, Cwp); } } }}); @@ -926,7 +921,7 @@ decode OP default Unknown::unknown() xc->syscall(R1); #endif } - }}); + }}, IsSerializeAfter, IsNonSpeculative); 0x2: Trap::tccx({{ if(passesCondition(Ccr<7:4>, COND2)) { @@ -939,36 +934,27 @@ decode OP default Unknown::unknown() xc->syscall(R1); #endif } - }}); + }}, IsSerializeAfter, IsNonSpeculative); } 0x3B: Nop::flush({{/*Instruction memory flush*/}}); 0x3C: save({{ - //CWP should be set directly so that it always happens - //Also, this will allow writing to the new window and - //reading from the old one if(Cansave == 0) { if(Otherwin) fault = new SpillNOther(4*Wstate<5:3>); else fault = new SpillNNormal(4*Wstate<2:0>); - //Cwp = (Cwp + 2) % NWindows; } else if(Cleanwin - Canrestore == 0) { - //Cwp = (Cwp + 1) % NWindows; fault = new CleanWindow; } else { Cwp = (Cwp + 1) % NWindows; - Rd = Rs1 + Rs2_or_imm13; + Rd_next = Rs1 + Rs2_or_imm13; Cansave = Cansave - 1; Canrestore = Canrestore + 1; - //This is here to make sure the CWP is written - //no matter what. This ensures that the results - //are written in the new window as well. - xc->setMiscRegWithEffect(MISCREG_CWP, Cwp); } }}); 0x3D: restore({{ @@ -981,17 +967,10 @@ decode OP default Unknown::unknown() } else { - //CWP should be set directly so that it always happens - //Also, this will allow writing to the new window and - //reading from the old one Cwp = (Cwp - 1 + NWindows) % NWindows; - Rd = Rs1 + Rs2_or_imm13; + Rd_prev = Rs1 + Rs2_or_imm13; Cansave = Cansave + 1; Canrestore = Canrestore - 1; - //This is here to make sure the CWP is written - //no matter what. This ensures that the results - //are written in the new window as well. - xc->setMiscRegWithEffect(MISCREG_CWP, Cwp); } }}); 0x3E: decode FCN { 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 5fb7ade2d..2db756320 100644 --- a/src/arch/sparc/isa/formats/branch.isa +++ b/src/arch/sparc/isa/formats/branch.isa @@ -170,7 +170,7 @@ output decoder {{ printMnemonic(response, mnemonic); ccprintf(response, "0x%x", target); - if(symtab->findNearestSymbol(target, symbol, symbolAddr)) + if(symtab && symtab->findNearestSymbol(target, symbol, symbolAddr)) { ccprintf(response, " <%s", symbol); if(symbolAddr != target) @@ -178,6 +178,10 @@ output decoder {{ else ccprintf(response, ">"); } + else + { + ccprintf(response, "<%d>", target); + } return response.str(); } @@ -244,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': @@ -252,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) @@ -262,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 55e9fba45..1d9075a57 100644 --- a/src/arch/sparc/isa/formats/mem/basicmem.isa +++ b/src/arch/sparc/isa/formats/mem/basicmem.isa @@ -55,16 +55,20 @@ let {{ def doMemFormat(code, execute, faultCode, name, Name, asi, 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", - asi, opt_flags) + execute, faultCode, name, name + "Imm", + Name, Name + "Imm", asi, opt_flags) return (header_output, decoder_output, exec_output, decode_block) }}; @@ -72,7 +76,7 @@ def format LoadAlt(code, asi, *opt_flags) {{ (header_output, decoder_output, exec_output, - decode_block) = doMemFormat(code, LoadExecute, + decode_block) = doMemFormat(code, LoadFuncs, AlternateASIPrivFaultCheck, name, Name, asi, opt_flags) }}; @@ -80,7 +84,7 @@ def format StoreAlt(code, asi, *opt_flags) {{ (header_output, decoder_output, exec_output, - decode_block) = doMemFormat(code, StoreExecute, + decode_block) = doMemFormat(code, StoreFuncs, AlternateASIPrivFaultCheck, name, Name, asi, opt_flags) }}; @@ -89,7 +93,7 @@ def format Load(code, *opt_flags) {{ decoder_output, exec_output, decode_block) = doMemFormat(code, - LoadExecute, '', name, Name, 0, opt_flags) + LoadFuncs, '', name, Name, 0, opt_flags) }}; def format Store(code, *opt_flags) {{ @@ -97,5 +101,5 @@ def format Store(code, *opt_flags) {{ decoder_output, exec_output, decode_block) = doMemFormat(code, - StoreExecute, '', name, Name, 0, opt_flags) + StoreFuncs, '', name, Name, 0, opt_flags) }}; diff --git a/src/arch/sparc/isa/formats/mem/blockmem.isa b/src/arch/sparc/isa/formats/mem/blockmem.isa index 32421a75f..352e963b3 100644 --- a/src/arch/sparc/isa/formats/mem/blockmem.isa +++ b/src/arch/sparc/isa/formats/mem/blockmem.isa @@ -456,14 +456,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( @@ -496,18 +496,18 @@ let {{ else: flag_code = "flags[IsDelayedCommit] = true; flags[IsFirstMicroOp] = true;" pcedCode = matcher.sub("RdLow", code) - iop = InstObjParams(name, Name, 'TwinMem', pcedCode, - opt_flags, {"ea_code": addrCalcReg, + iop = InstObjParams(name, Name, 'TwinMem', + {"code": pcedCode, "ea_code": addrCalcReg, "fault_check": faultCode, "micro_pc": microPc, - "set_flags": flag_code}) - iop_imm = InstObjParams(name, Name + 'Imm', 'TwinMemImm', pcedCode, - opt_flags, {"ea_code": addrCalcImm, + "set_flags": flag_code}, opt_flags) + iop_imm = InstObjParams(name, Name + 'Imm', 'TwinMemImm', + {"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( - pcedCode, addrCalcReg, addrCalcImm, LoadExecute, faultCode, + pcedCode, addrCalcReg, addrCalcImm, LoadFuncs, faultCode, makeMicroName(name, microPc), makeMicroName(name + "Imm", microPc), makeMicroName(Name, microPc), @@ -527,7 +527,7 @@ def format BlockLoad(code, asi, *opt_flags) {{ decoder_output, exec_output, decode_block) = doBlockMemFormat(code, faultCode, - LoadExecute, name, Name, asi, opt_flags) + LoadFuncs, name, Name, asi, opt_flags) }}; def format BlockStore(code, asi, *opt_flags) {{ @@ -539,7 +539,7 @@ def format BlockStore(code, asi, *opt_flags) {{ decoder_output, exec_output, decode_block) = doBlockMemFormat(code, faultCode, - StoreExecute, name, Name, asi, opt_flags) + StoreFuncs, name, Name, asi, opt_flags) }}; def format TwinLoad(code, asi, *opt_flags) {{ diff --git a/src/arch/sparc/isa/formats/mem/util.isa b/src/arch/sparc/isa/formats/mem/util.isa index b6e0945b7..5bb4e1fe6 100644 --- a/src/arch/sparc/isa/formats/mem/util.isa +++ b/src/arch/sparc/isa/formats/mem/util.isa @@ -1,4 +1,4 @@ -// Copyright (c) 2006 The Regents of The University of Michigan +// Copyright (c) 2006-2007 The Regents of The University of Michigan // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -144,7 +144,7 @@ def template LoadExecute {{ %(op_decl)s; %(op_rd)s; %(ea_code)s; - DPRINTF(Sparc, "The address is 0x%x\n", EA); + DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA); %(fault_check)s; if(fault == NoFault) { @@ -162,16 +162,18 @@ 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; if(fault == NoFault) { @@ -179,18 +181,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<typeof(Mem)>(); %(code)s; if(fault == NoFault) { - %(code_wb)s; + %(op_wb)s; } return fault; } @@ -209,7 +213,7 @@ def template StoreExecute {{ %(op_decl)s; %(op_rd)s; %(ea_code)s; - DPRINTF(Sparc, "The address is 0x%x\n", EA); + DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA); %(fault_check)s; if(fault == NoFault) { @@ -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 { @@ -238,7 +244,7 @@ def template StoreExecute {{ %(op_decl)s; %(op_rd)s; %(ea_code)s; - DPRINTF(Sparc, "The address is 0x%x\n", EA); + DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA); %(fault_check)s; if(fault == NoFault) { @@ -256,7 +262,9 @@ def template StoreExecute {{ } return fault; } +}}; +def template StoreCompleteAcc {{ Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc, Trace::InstRecord * traceData) const { @@ -276,6 +284,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 = ''' @@ -316,21 +326,11 @@ 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, asi, opt_flags, microParam): + def doSplitExecute(execute, name, Name, asi, opt_flags, microParam): microParam["asi_val"] = asi; - 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) + 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, @@ -339,8 +339,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, asi, 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/arch/sparc/isa/includes.isa b/src/arch/sparc/isa/includes.isa index 624afb693..2e7b16f20 100644 --- a/src/arch/sparc/isa/includes.isa +++ b/src/arch/sparc/isa/includes.isa @@ -37,12 +37,13 @@ output header {{ #include <sstream> #include <iostream> -#include "cpu/static_inst.hh" #include "arch/sparc/faults.hh" -#include "mem/request.hh" // some constructors use MemReq flags -#include "mem/packet.hh" #include "arch/sparc/isa_traits.hh" #include "arch/sparc/regfile.hh" +#include "base/misc.hh" +#include "cpu/static_inst.hh" +#include "mem/packet.hh" +#include "mem/request.hh" // some constructors use MemReq flags }}; output decoder {{ diff --git a/src/arch/sparc/isa/operands.isa b/src/arch/sparc/isa/operands.isa index abb82f88c..2d1c3d3b9 100644 --- a/src/arch/sparc/isa/operands.isa +++ b/src/arch/sparc/isa/operands.isa @@ -56,15 +56,26 @@ def operands {{ # Int regs default to unsigned, but code should not count on this. # For clarity, descriptions that depend on unsigned behavior should # explicitly specify '.uq'. + 'Rd': ('IntReg', 'udw', 'RD', 'IsInteger', 1), + # The Rd from the previous window + 'Rd_prev': ('IntReg', 'udw', 'RD + NumIntArchRegs + NumMicroIntRegs', 'IsInteger', 2), + # The Rd from the next window + 'Rd_next': ('IntReg', 'udw', 'RD + 2 * NumIntArchRegs + NumMicroIntRegs', 'IsInteger', 3), # For microcoded twin load instructions, RdTwin appears in the "code" - # for the instruction and is replaced by RdLow or RdHigh by the format + # for the instruction is replaced by RdLow or RdHigh by the format # before it's processed by the iop. - 'RdLow': ('IntReg', 'udw', 'RD & (~1)', 'IsInteger', 2), - 'RdHigh': ('IntReg', 'udw', 'RD | 1', 'IsInteger', 3), - 'Rs1': ('IntReg', 'udw', 'RS1', 'IsInteger', 4), - 'Rs2': ('IntReg', 'udw', 'RS2', 'IsInteger', 5), - 'uReg0': ('IntReg', 'udw', 'NumIntArchRegs', 'IsInteger', 6), + # The low (even) register of a two register pair + 'RdLow': ('IntReg', 'udw', 'RD & (~1)', 'IsInteger', 4), + # The high (odd) register of a two register pair + 'RdHigh': ('IntReg', 'udw', 'RD | 1', 'IsInteger', 5), + 'Rs1': ('IntReg', 'udw', 'RS1', 'IsInteger', 6), + 'Rs2': ('IntReg', 'udw', 'RS2', 'IsInteger', 7), + # A microcode register. Right now, this is the only one. + 'uReg0': ('IntReg', 'udw', 'NumIntArchRegs', 'IsInteger', 8), + # Because double and quad precision register numbers are decoded + # differently, they get different operands. The single precision versions + # have an s post pended to their name. 'Frds': ('FloatReg', 'sf', 'RD', 'IsFloating', 10), 'Frd': ('FloatReg', 'df', 'dfpr(RD)', 'IsFloating', 10), # Each Frd_N refers to the Nth double precision register from Frd. @@ -83,14 +94,17 @@ def operands {{ 'Frs2': ('FloatReg', 'df', 'dfpr(RS2)', 'IsFloating', 12), 'NPC': ('NPC', 'udw', None, ( None, None, 'IsControl' ), 31), 'NNPC': ('NNPC', 'udw', None, (None, None, 'IsControl' ), 32), + # Registers which are used explicitly in instructions 'R0': ('IntReg', 'udw', '0', None, 6), 'R1': ('IntReg', 'udw', '1', None, 7), 'R15': ('IntReg', 'udw', '15', 'IsInteger', 8), 'R16': ('IntReg', 'udw', '16', None, 9), # Control registers - 'Y': ('ControlReg', 'udw', 'MISCREG_Y', None, 40), - 'Ccr': ('ControlReg', 'udw', 'MISCREG_CCR', None, 41), +# 'Y': ('ControlReg', 'udw', 'MISCREG_Y', None, 40), +# 'Ccr': ('ControlReg', 'udw', 'MISCREG_CCR', None, 41), + 'Y': ('IntReg', 'udw', 'NumIntArchRegs + 1', None, 40), + 'Ccr': ('IntReg', 'udw', 'NumIntArchRegs + 2', None, 41), 'Asi': ('ControlReg', 'udw', 'MISCREG_ASI', None, 42), 'Fprs': ('ControlReg', 'udw', 'MISCREG_FPRS', None, 43), 'Pcr': ('ControlReg', 'udw', 'MISCREG_PCR', None, 44), @@ -112,12 +126,17 @@ def operands {{ 'Pstate': ('ControlReg', 'udw', 'MISCREG_PSTATE', None, 59), 'Tl': ('ControlReg', 'udw', 'MISCREG_TL', None, 60), 'Pil': ('ControlReg', 'udw', 'MISCREG_PIL', None, 61), - 'Cwp': ('ControlReg', 'udw', 'MISCREG_CWP', None, 62), - 'Cansave': ('ControlReg', 'udw', 'MISCREG_CANSAVE', None, 63), - 'Canrestore': ('ControlReg', 'udw', 'MISCREG_CANRESTORE', None, 64), - 'Cleanwin': ('ControlReg', 'udw', 'MISCREG_CLEANWIN', None, 65), - 'Otherwin': ('ControlReg', 'udw', 'MISCREG_OTHERWIN', None, 66), - 'Wstate': ('ControlReg', 'udw', 'MISCREG_WSTATE', None, 67), + 'Cwp': ('ControlReg', 'udw', 'MISCREG_CWP', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 62), +# 'Cansave': ('ControlReg', 'udw', 'MISCREG_CANSAVE', None, 63), +# 'Canrestore': ('ControlReg', 'udw', 'MISCREG_CANRESTORE', None, 64), +# 'Cleanwin': ('ControlReg', 'udw', 'MISCREG_CLEANWIN', None, 65), +# 'Otherwin': ('ControlReg', 'udw', 'MISCREG_OTHERWIN', None, 66), +# 'Wstate': ('ControlReg', 'udw', 'MISCREG_WSTATE', None, 67), + 'Cansave': ('IntReg', 'udw', 'NumIntArchRegs + 3', None, 63), + 'Canrestore': ('IntReg', 'udw', 'NumIntArchRegs + 4', None, 64), + 'Cleanwin': ('IntReg', 'udw', 'NumIntArchRegs + 5', None, 65), + 'Otherwin': ('IntReg', 'udw', 'NumIntArchRegs + 6', None, 66), + 'Wstate': ('IntReg', 'udw', 'NumIntArchRegs + 7', None, 67), 'Gl': ('ControlReg', 'udw', 'MISCREG_GL', None, 68), 'Hpstate': ('ControlReg', 'udw', 'MISCREG_HPSTATE', None, 69), diff --git a/src/arch/sparc/isa_traits.hh b/src/arch/sparc/isa_traits.hh index 8aa8ea7f3..8a26334a7 100644 --- a/src/arch/sparc/isa_traits.hh +++ b/src/arch/sparc/isa_traits.hh @@ -58,8 +58,8 @@ namespace SparcISA // These enumerate all the registers for dependence tracking. enum DependenceTags { - FP_Base_DepTag = 33, - Ctrl_Base_DepTag = 97, + FP_Base_DepTag = 32*3+8, + Ctrl_Base_DepTag = FP_Base_DepTag + 64, }; // semantically meaningful register indices diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc index d9fcb0280..422bc2fbe 100644 --- a/src/arch/sparc/miscregfile.cc +++ b/src/arch/sparc/miscregfile.cc @@ -46,15 +46,16 @@ class Checkpoint; string SparcISA::getMiscRegName(RegIndex index) { static::string miscRegName[NumMiscRegs] = - {"y", "ccr", "asi", "tick", "fprs", "pcr", "pic", - "gsr", "softint_set", "softint_clr", "softint", "tick_cmpr", - "stick", "stick_cmpr", - "tpc", "tnpc", "tstate", "tt", "privtick", "tba", "pstate", "tl", - "pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin", - "wstate", "gl", - "hpstate", "htstate", "hintp", "htba", "hver", "strand_sts_reg", - "hstick_cmpr", - "fsr"}; + {/*"y", "ccr",*/ "asi", "tick", "fprs", "pcr", "pic", + "gsr", "softint_set", "softint_clr", "softint", "tick_cmpr", + "stick", "stick_cmpr", + "tpc", "tnpc", "tstate", "tt", "privtick", "tba", "pstate", "tl", + "pil", "cwp", /*"cansave", "canrestore", "cleanwin", "otherwin", + "wstate",*/ "gl", + "hpstate", "htstate", "hintp", "htba", "hver", "strand_sts_reg", + "hstick_cmpr", + "fsr"}; + return miscRegName[index]; } @@ -65,8 +66,8 @@ enum RegMask void MiscRegFile::clear() { - y = 0; - ccr = 0; + //y = 0; + //ccr = 0; asi = 0; tick = ULL(1) << 63; fprs = 0; @@ -83,11 +84,11 @@ void MiscRegFile::clear() tl = 0; pil = 0; cwp = 0; - cansave = 0; - canrestore = 0; - cleanwin = 0; - otherwin = 0; - wstate = 0; + //cansave = 0; + //canrestore = 0; + //cleanwin = 0; + //otherwin = 0; + //wstate = 0; gl = 0; //In a T1, bit 11 is apparently always 1 hpstate = (1 << 11); @@ -149,10 +150,10 @@ MiscReg MiscRegFile::readReg(int miscReg) (uint64_t)priContext << 32 | (uint64_t)secContext << 48; - case MISCREG_Y: - return y; - case MISCREG_CCR: - return ccr; + //case MISCREG_Y: + // return y; + //case MISCREG_CCR: + // return ccr; case MISCREG_ASI: return asi; case MISCREG_FPRS: @@ -195,16 +196,16 @@ MiscReg MiscRegFile::readReg(int miscReg) return pil; case MISCREG_CWP: return cwp; - case MISCREG_CANSAVE: - return cansave; - case MISCREG_CANRESTORE: - return canrestore; - case MISCREG_CLEANWIN: - return cleanwin; - case MISCREG_OTHERWIN: - return otherwin; - case MISCREG_WSTATE: - return wstate; + //case MISCREG_CANSAVE: + // return cansave; + //case MISCREG_CANRESTORE: + // return canrestore; + //case MISCREG_CLEANWIN: + // return cleanwin; + //case MISCREG_OTHERWIN: + // return otherwin; + //case MISCREG_WSTATE: + // return wstate; case MISCREG_GL: return gl; @@ -375,12 +376,12 @@ MiscReg MiscRegFile::readRegWithEffect(int miscReg, ThreadContext * tc) void MiscRegFile::setReg(int miscReg, const MiscReg &val) { switch (miscReg) { - case MISCREG_Y: - y = val; - break; - case MISCREG_CCR: - ccr = val; - break; +// case MISCREG_Y: +// y = val; +// break; +// case MISCREG_CCR: +// ccr = val; +// break; case MISCREG_ASI: asi = val; break; @@ -441,21 +442,21 @@ void MiscRegFile::setReg(int miscReg, const MiscReg &val) case MISCREG_CWP: cwp = val; break; - case MISCREG_CANSAVE: - cansave = val; - break; - case MISCREG_CANRESTORE: - canrestore = val; - break; - case MISCREG_CLEANWIN: - cleanwin = val; - break; - case MISCREG_OTHERWIN: - otherwin = val; - break; - case MISCREG_WSTATE: - wstate = val; - break; +// case MISCREG_CANSAVE: +// cansave = val; +// break; +// case MISCREG_CANRESTORE: +// canrestore = val; +// break; +// case MISCREG_CLEANWIN: +// cleanwin = val; +// break; +// case MISCREG_OTHERWIN: +// otherwin = val; +// break; +// case MISCREG_WSTATE: +// wstate = val; +// break; case MISCREG_GL: gl = val; break; @@ -676,23 +677,23 @@ void MiscRegFile::serialize(std::ostream & os) { SERIALIZE_SCALAR(pstate); SERIALIZE_SCALAR(tba); - SERIALIZE_SCALAR(y); +// SERIALIZE_SCALAR(y); SERIALIZE_SCALAR(pil); SERIALIZE_SCALAR(gl); SERIALIZE_SCALAR(cwp); SERIALIZE_ARRAY(tt, MaxTL); - SERIALIZE_SCALAR(ccr); +// SERIALIZE_SCALAR(ccr); SERIALIZE_SCALAR(asi); SERIALIZE_SCALAR(tl); SERIALIZE_ARRAY(tpc, MaxTL); SERIALIZE_ARRAY(tnpc, MaxTL); SERIALIZE_ARRAY(tstate, MaxTL); SERIALIZE_SCALAR(tick); - SERIALIZE_SCALAR(cansave); - SERIALIZE_SCALAR(canrestore); - SERIALIZE_SCALAR(otherwin); - SERIALIZE_SCALAR(cleanwin); - SERIALIZE_SCALAR(wstate); +// SERIALIZE_SCALAR(cansave); +// SERIALIZE_SCALAR(canrestore); +// SERIALIZE_SCALAR(otherwin); +// SERIALIZE_SCALAR(cleanwin); +// SERIALIZE_SCALAR(wstate); SERIALIZE_SCALAR(fsr); SERIALIZE_SCALAR(fprs); SERIALIZE_SCALAR(hpstate); @@ -735,23 +736,23 @@ void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section) { UNSERIALIZE_SCALAR(pstate); UNSERIALIZE_SCALAR(tba); - UNSERIALIZE_SCALAR(y); +// UNSERIALIZE_SCALAR(y); UNSERIALIZE_SCALAR(pil); UNSERIALIZE_SCALAR(gl); UNSERIALIZE_SCALAR(cwp); UNSERIALIZE_ARRAY(tt, MaxTL); - UNSERIALIZE_SCALAR(ccr); +// UNSERIALIZE_SCALAR(ccr); UNSERIALIZE_SCALAR(asi); UNSERIALIZE_SCALAR(tl); UNSERIALIZE_ARRAY(tpc, MaxTL); UNSERIALIZE_ARRAY(tnpc, MaxTL); UNSERIALIZE_ARRAY(tstate, MaxTL); UNSERIALIZE_SCALAR(tick); - UNSERIALIZE_SCALAR(cansave); - UNSERIALIZE_SCALAR(canrestore); - UNSERIALIZE_SCALAR(otherwin); - UNSERIALIZE_SCALAR(cleanwin); - UNSERIALIZE_SCALAR(wstate); +// UNSERIALIZE_SCALAR(cansave); +// UNSERIALIZE_SCALAR(canrestore); +// UNSERIALIZE_SCALAR(otherwin); +// UNSERIALIZE_SCALAR(cleanwin); +// UNSERIALIZE_SCALAR(wstate); UNSERIALIZE_SCALAR(fsr); UNSERIALIZE_SCALAR(fprs); UNSERIALIZE_SCALAR(hpstate); diff --git a/src/arch/sparc/miscregfile.hh b/src/arch/sparc/miscregfile.hh index 8a2e8e810..66c9f17df 100644 --- a/src/arch/sparc/miscregfile.hh +++ b/src/arch/sparc/miscregfile.hh @@ -47,8 +47,8 @@ namespace SparcISA enum MiscRegIndex { /** Ancillary State Registers */ - MISCREG_Y, /* 0 */ - MISCREG_CCR, +// MISCREG_Y, +// MISCREG_CCR, MISCREG_ASI, MISCREG_TICK, MISCREG_FPRS, @@ -73,11 +73,11 @@ namespace SparcISA MISCREG_TL, MISCREG_PIL, MISCREG_CWP, - MISCREG_CANSAVE, - MISCREG_CANRESTORE, - MISCREG_CLEANWIN, - MISCREG_OTHERWIN, - MISCREG_WSTATE, +// MISCREG_CANSAVE, +// MISCREG_CANRESTORE, +// MISCREG_CLEANWIN, +// MISCREG_OTHERWIN, +// MISCREG_WSTATE, MISCREG_GL, /** Hyper privileged registers */ @@ -171,8 +171,8 @@ namespace SparcISA private: /* ASR Registers */ - uint64_t y; // Y (used in obsolete multiplication) - uint8_t ccr; // Condition Code Register + //uint64_t y; // Y (used in obsolete multiplication) + //uint8_t ccr; // Condition Code Register uint8_t asi; // Address Space Identifier uint64_t tick; // Hardware clock-tick counter uint8_t fprs; // Floating-Point Register State @@ -197,11 +197,11 @@ namespace SparcISA uint8_t tl; // Trap Level uint8_t pil; // Process Interrupt Register uint8_t cwp; // Current Window Pointer - uint8_t cansave; // Savable windows - uint8_t canrestore; // Restorable windows - uint8_t cleanwin; // Clean windows - uint8_t otherwin; // Other windows - uint8_t wstate; // Window State + //uint8_t cansave; // Savable windows + //uint8_t canrestore; // Restorable windows + //uint8_t cleanwin; // Clean windows + //uint8_t otherwin; // Other windows + //uint8_t wstate; // Window State uint8_t gl; // Global level register /** Hyperprivileged Registers */ diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc index 405e408e5..1e639b9a5 100644 --- a/src/arch/sparc/process.cc +++ b/src/arch/sparc/process.cc @@ -95,17 +95,22 @@ SparcLiveProcess::startup() */ //No windows contain info from other programs - threadContexts[0]->setMiscReg(MISCREG_OTHERWIN, 0); + //threadContexts[0]->setMiscReg(MISCREG_OTHERWIN, 0); + threadContexts[0]->setIntReg(NumIntArchRegs + 6, 0); //There are no windows to pop - threadContexts[0]->setMiscReg(MISCREG_CANRESTORE, 0); + //threadContexts[0]->setMiscReg(MISCREG_CANRESTORE, 0); + threadContexts[0]->setIntReg(NumIntArchRegs + 4, 0); //All windows are available to save into - threadContexts[0]->setMiscReg(MISCREG_CANSAVE, NWindows - 2); + //threadContexts[0]->setMiscReg(MISCREG_CANSAVE, NWindows - 2); + threadContexts[0]->setIntReg(NumIntArchRegs + 3, NWindows - 2); //All windows are "clean" - threadContexts[0]->setMiscReg(MISCREG_CLEANWIN, NWindows); + //threadContexts[0]->setMiscReg(MISCREG_CLEANWIN, NWindows); + threadContexts[0]->setIntReg(NumIntArchRegs + 5, NWindows); //Start with register window 0 threadContexts[0]->setMiscReg(MISCREG_CWP, 0); //Always use spill and fill traps 0 - threadContexts[0]->setMiscReg(MISCREG_WSTATE, 0); + //threadContexts[0]->setMiscReg(MISCREG_WSTATE, 0); + threadContexts[0]->setIntReg(NumIntArchRegs + 7, 0); //Set the trap level to 0 threadContexts[0]->setMiscReg(MISCREG_TL, 0); //Set the ASI register to something fixed @@ -427,5 +432,8 @@ SparcLiveProcess::argsInit(int intSize, int pageSize) threadContexts[0]->setNextPC(prog_entry + sizeof(MachInst)); threadContexts[0]->setNextNPC(prog_entry + (2 * sizeof(MachInst))); + //Align the "stack_min" to a page boundary. + stack_min = roundDown(stack_min, pageSize); + // num_processes++; } diff --git a/src/arch/sparc/regfile.cc b/src/arch/sparc/regfile.cc index b36133544..4be411d17 100644 --- a/src/arch/sparc/regfile.cc +++ b/src/arch/sparc/regfile.cc @@ -151,6 +151,72 @@ void RegFile::setIntReg(int intReg, const IntReg &val) intRegFile.setReg(intReg, val); } +int SparcISA::flattenIntIndex(ThreadContext * tc, int reg) +{ + int gl = tc->readMiscReg(MISCREG_GL); + int cwp = tc->readMiscReg(MISCREG_CWP); + //DPRINTF(Sparc, "Global Level = %d, Current Window Pointer = %d\n", gl, cwp); + int newReg; + if(reg < 8) + { + //Global register + //Put it in the appropriate set of globals + newReg = reg + gl * 8; + } + else if(reg < NumIntArchRegs) + { + //Regular windowed register + //Put it in the window pointed to by cwp + newReg = MaxGL * 8 + + ((reg - 8 - cwp * 16 + NWindows * 16) % (NWindows * 16)); + } + else if(reg < NumIntArchRegs + NumMicroIntRegs) + { + //Microcode register + //Displace from the end of the regular registers + newReg = reg - NumIntArchRegs + MaxGL * 8 + NWindows * 16; + } + else if(reg < 2 * NumIntArchRegs + NumMicroIntRegs) + { + reg -= (NumIntArchRegs + NumMicroIntRegs); + if(reg < 8) + { + //Global register from the next window + //Put it in the appropriate set of globals + newReg = reg + gl * 8; + } + else + { + //Windowed register from the previous window + //Put it in the window before the one pointed to by cwp + newReg = MaxGL * 8 + + ((reg - 8 - (cwp - 1) * 16 + NWindows * 16) % (NWindows * 16)); + } + } + else if(reg < 3 * NumIntArchRegs + NumMicroIntRegs) + { + reg -= (2 * NumIntArchRegs + NumMicroIntRegs); + if(reg < 8) + { + //Global register from the previous window + //Put it in the appropriate set of globals + newReg = reg + gl * 8; + } + else + { + //Windowed register from the next window + //Put it in the window after the one pointed to by cwp + newReg = MaxGL * 8 + + ((reg - 8 - (cwp + 1) * 16 + NWindows * 16) % (NWindows * 16)); + } + } + else + panic("Tried to flatten invalid register index %d!\n", reg); + DPRINTF(Sparc, "Flattened register %d to %d.\n", reg, newReg); + return newReg; + //return intRegFile.flattenIndex(reg); +} + void RegFile::serialize(std::ostream &os) { intRegFile.serialize(os); @@ -220,8 +286,8 @@ void SparcISA::copyMiscRegs(ThreadContext *src, ThreadContext *dest) // ASRs - dest->setMiscReg(MISCREG_Y, src->readMiscReg(MISCREG_Y)); - dest->setMiscReg(MISCREG_CCR, src->readMiscReg(MISCREG_CCR)); +// dest->setMiscReg(MISCREG_Y, src->readMiscReg(MISCREG_Y)); +// dest->setMiscReg(MISCREG_CCR, src->readMiscReg(MISCREG_CCR)); dest->setMiscReg(MISCREG_ASI, src->readMiscReg(MISCREG_ASI)); dest->setMiscReg(MISCREG_TICK, src->readMiscReg(MISCREG_TICK)); dest->setMiscReg(MISCREG_FPRS, src->readMiscReg(MISCREG_FPRS)); @@ -236,11 +302,11 @@ void SparcISA::copyMiscRegs(ThreadContext *src, ThreadContext *dest) dest->setMiscReg(MISCREG_PSTATE, src->readMiscReg(MISCREG_PSTATE)); dest->setMiscReg(MISCREG_PIL, src->readMiscReg(MISCREG_PIL)); dest->setMiscReg(MISCREG_CWP, src->readMiscReg(MISCREG_CWP)); - dest->setMiscReg(MISCREG_CANSAVE, src->readMiscReg(MISCREG_CANSAVE)); - dest->setMiscReg(MISCREG_CANRESTORE, src->readMiscReg(MISCREG_CANRESTORE)); - dest->setMiscReg(MISCREG_OTHERWIN, src->readMiscReg(MISCREG_OTHERWIN)); - dest->setMiscReg(MISCREG_CLEANWIN, src->readMiscReg(MISCREG_CLEANWIN)); - dest->setMiscReg(MISCREG_WSTATE, src->readMiscReg(MISCREG_WSTATE)); +// dest->setMiscReg(MISCREG_CANSAVE, src->readMiscReg(MISCREG_CANSAVE)); +// dest->setMiscReg(MISCREG_CANRESTORE, src->readMiscReg(MISCREG_CANRESTORE)); +// dest->setMiscReg(MISCREG_OTHERWIN, src->readMiscReg(MISCREG_OTHERWIN)); +// dest->setMiscReg(MISCREG_CLEANWIN, src->readMiscReg(MISCREG_CLEANWIN)); +// dest->setMiscReg(MISCREG_WSTATE, src->readMiscReg(MISCREG_WSTATE)); dest->setMiscReg(MISCREG_GL, src->readMiscReg(MISCREG_GL)); // Hyperprivilged registers diff --git a/src/arch/sparc/regfile.hh b/src/arch/sparc/regfile.hh index 0a09d0f66..d9af0757c 100644 --- a/src/arch/sparc/regfile.hh +++ b/src/arch/sparc/regfile.hh @@ -120,6 +120,8 @@ namespace SparcISA void changeContext(RegContextParam param, RegContextVal val); }; + int flattenIntIndex(ThreadContext * tc, int reg); + void copyRegs(ThreadContext *src, ThreadContext *dest); void copyMiscRegs(ThreadContext *src, ThreadContext *dest); diff --git a/src/arch/sparc/sparc_traits.hh b/src/arch/sparc/sparc_traits.hh index a3d29ea8a..d89ec1119 100644 --- a/src/arch/sparc/sparc_traits.hh +++ b/src/arch/sparc/sparc_traits.hh @@ -41,7 +41,8 @@ namespace SparcISA // Number of register windows, can legally be 3 to 32 const int NWindows = 8; - const int NumMicroIntRegs = 1; + //const int NumMicroIntRegs = 1; + const int NumMicroIntRegs = 8; // const int NumRegularIntRegs = MaxGL * 8 + NWindows * 16; // const int NumMicroIntRegs = 1; diff --git a/src/arch/sparc/syscallreturn.hh b/src/arch/sparc/syscallreturn.hh index 75a063da1..d92b12790 100644 --- a/src/arch/sparc/syscallreturn.hh +++ b/src/arch/sparc/syscallreturn.hh @@ -33,58 +33,30 @@ #include <inttypes.h> +#include "sim/syscallreturn.hh" #include "arch/sparc/regfile.hh" - -class SyscallReturn -{ - public: - template <class T> - SyscallReturn(T v, bool s) - { - retval = (uint64_t)v; - success = s; - } - - template <class T> - SyscallReturn(T v) - { - success = (v >= 0); - retval = (uint64_t)v; - } - - ~SyscallReturn() {} - - SyscallReturn& operator=(const SyscallReturn& s) - { - retval = s.retval; - success = s.success; - return *this; - } - - bool successful() { return success; } - uint64_t value() { return retval; } - - private: - uint64_t retval; - bool success; -}; +#include "cpu/thread_context.hh" namespace SparcISA { static inline void setSyscallReturn(SyscallReturn return_value, - RegFile *regs) + ThreadContext * tc) { // check for error condition. SPARC syscall convention is to // indicate success/failure in reg the carry bit of the ccr // and put the return value itself in the standard return value reg (). if (return_value.successful()) { // no error, clear XCC.C - regs->setMiscReg(MISCREG_CCR, regs->readMiscReg(MISCREG_CCR) & 0xEE); - regs->setIntReg(ReturnValueReg, return_value.value()); + tc->setIntReg(NumIntArchRegs + 2, + tc->readIntReg(NumIntArchRegs + 2) & 0xEE); + //tc->setMiscReg(MISCREG_CCR, tc->readMiscReg(MISCREG_CCR) & 0xEE); + tc->setIntReg(ReturnValueReg, return_value.value()); } else { // got an error, set XCC.C - regs->setMiscReg(MISCREG_CCR, regs->readMiscReg(MISCREG_CCR) | 0x11); - regs->setIntReg(ReturnValueReg, return_value.value()); + tc->setIntReg(NumIntArchRegs + 2, + tc->readIntReg(NumIntArchRegs + 2) | 0x11); + //tc->setMiscReg(MISCREG_CCR, tc->readMiscReg(MISCREG_CCR) | 0x11); + tc->setIntReg(ReturnValueReg, -return_value.value()); } } }; diff --git a/src/arch/sparc/system.cc b/src/arch/sparc/system.cc index da83d86fc..2600213fd 100644 --- a/src/arch/sparc/system.cc +++ b/src/arch/sparc/system.cc @@ -191,12 +191,6 @@ SparcSystem::~SparcSystem() delete partition_desc; } -bool -SparcSystem::breakpoint() -{ - panic("Need to implement"); -} - void SparcSystem::serialize(std::ostream &os) { diff --git a/src/arch/sparc/system.hh b/src/arch/sparc/system.hh index c81b093e8..ac4d34279 100644 --- a/src/arch/sparc/system.hh +++ b/src/arch/sparc/system.hh @@ -68,8 +68,6 @@ class SparcSystem : public System ~SparcSystem(); - virtual bool breakpoint(); - /** * Serialization stuff */ |