format Jump {
0x2: j({{ NNPC = (NPC & 0xF0000000) & (0x00000000 & JMPTARG << 2);}});
- 0x3: jal({{ NNPC = (NPC & 0xF0000000) & (0x00000000 & JMPTARG << 2);}},IsCall,IsLink);
+ 0x3: jal({{ NNPC = (NPC & 0xF0000000) & (0x00000000 & JMPTARG << 2);}},IsCall,IsReturn);
}
format Branch {
//operations are enabled."
0x3: decode FUNCTION_HI {
0x0: decode FUNCTION_LO {
- format Memory {
- 0x0: lwxc1({{ EA = Rs + Rt; }},{{ Ft<31:0> = Mem.uf; }});
+ format LoadMemory2 {
+ 0x0: lwxc1({{ EA = Rs + Rt; }},{{ Ft<31:0> = Mem.sf; }});
0x1: ldxc1({{ EA = Rs + Rt; }},{{ Ft<63:0> = Mem.df; }});
0x5: luxc1({{ //Need to make EA<2:0> = 0
EA = Rs + Rt;
}
0x1: decode FUNCTION_LO {
- format Memory {
- 0x0: swxc1({{ EA = Rs + Rt; }},{{ Mem.uf = Ft<31:0>; }});
- 0x1: sdxc1({{ EA = Rs + Rt; }},{{ Mem.uf = Ft<63:0>}});
+ format StoreMemory2 {
+ 0x0: swxc1({{ EA = Rs + Rt; }},{{ Mem.sf = Ft<31:0>; }});
+ 0x1: sdxc1({{ EA = Rs + Rt; }},{{ Mem.df = Ft<63:0>}});
0x5: suxc1({{ //Need to make EA<2:0> = 0
EA = Rs + Rt;
}},
}
0x4: decode OPCODE_LO default FailUnimpl::reserved() {
- format Memory {
- 0x0: lb({{ EA = Rs + disp; }}, {{ Rb.sw = Mem.sb; }});
- 0x1: lh({{ EA = Rs + disp; }}, {{ Rb.sw = Mem.sh; }});
- 0x2: lwl({{ EA = Rs + disp; }}, {{ Rb.sw = Mem.sw; }});//, WordAlign);
- 0x3: lw({{ EA = Rs + disp; }}, {{ Rb.uq = Mem.sb; }});
- 0x4: lbu({{ EA = Rs + disp; }}, {{ Rb.uw = Mem.ub; }});
- 0x5: lhu({{ EA = Rs + disp; }}, {{ Rb.uw = Mem.uh; }});
- 0x6: lwr({{ EA = Rs + disp; }}, {{ Rb.uw = Mem.uw; }});//, WordAlign);
+ format LoadMemory {
+ 0x0: lb({{ Rb.sw = Mem.sb; }});
+ 0x1: lh({{ Rb.sw = Mem.sh; }});
+ 0x2: lwl({{ Rb.sw = Mem.sw; }});//, WordAlign);
+ 0x3: lw({{ Rb.uq = Mem.sb; }});
+ 0x4: lbu({{ Rb.uw = Mem.ub; }});
+ 0x5: lhu({{ Rb.uw = Mem.uh; }});
+ 0x6: lwr({{ Rb.uw = Mem.uw; }});//, WordAlign);
}
0x7: FailUnimpl::reserved();
}
0x5: decode OPCODE_LO default FailUnimpl::reserved() {
- format Memory {
- 0x0: sb({{ EA = Rs + disp; }}, {{ Mem.ub = Rt<7:0>; }});
- 0x1: sh({{ EA = Rs + disp; }},{{ Mem.uh = Rt<15:0>; }});
- 0x2: swl({{ EA = Rs + disp; }},{{ Mem.ub = Rt<31:0>; }});//,WordAlign);
- 0x3: sw({{ EA = Rs + disp; }},{{ Mem.ub = Rt<31:0>; }});
- 0x6: swr({{ EA = Rs + disp; }},{{ Mem.ub = Rt<31:0>; }});//,WordAlign);
+ format StoreMemory {
+ 0x0: sb({{ Mem.ub = Rt<7:0>; }});
+ 0x1: sh({{ Mem.uh = Rt<15:0>; }});
+ 0x2: swl({{ Mem.ub = Rt<31:0>; }});//,WordAlign);
+ 0x3: sw({{ Mem.ub = Rt<31:0>; }});
+ 0x6: swr({{ Mem.ub = Rt<31:0>; }});//,WordAlign);
}
format WarnUnimpl {
0x6: decode OPCODE_LO default FailUnimpl::reserved() {
0x0: WarnUnimpl::ll();
- format Memory {
- 0x1: lwc1({{ EA = Rs + disp; }},{{ Ft<31:0> = Mem.uf; }});
- 0x5: ldc1({{ EA = Rs + disp; }},{{ Ft<63:0> = Mem.df; }});
+ format LoadMemory {
+ 0x1: lwc1({{ Ft<31:0> = Mem.sf; }});
+ 0x5: ldc1({{ Ft<63:0> = Mem.df; }});
}
}
0x7: decode OPCODE_LO default FailUnimpl::reserved() {
0x0: WarnUnimpl::sc();
- format Memory {
- 0x1: swc1({{ EA = Rs + disp; }},{{ Mem.uf = Ft<31:0>; }});
- 0x5: sdc1({{ EA = Rs + disp; }},{{ Mem.df = Ft<63:0>; }});
+ format StoreMemory {
+ 0x1: swc1({{ Mem.sf = Ft<31:0>; }});
+ 0x5: sdc1({{ Mem.df = Ft<63:0>; }});
}
}
-////////////////////////////////////////////////////////////////////
+// -*- mode:c++ -*-
+
+// Copyright (c) 2003-2005 The Regents of The University of Michigan
+// All rights reserved.
//
-// Mem instructions
+// 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.
output header {{
+ /**
+ * Base class for general Mips memory-format instructions.
+ */
+ class Memory : public MipsStaticInst
+ {
+ protected:
+
+ /// Memory request flags. See mem_req_base.hh.
+ unsigned memAccessFlags;
+ /// Pointer to EAComp object.
+ const StaticInstPtr eaCompPtr;
+ /// Pointer to MemAcc object.
+ const StaticInstPtr memAccPtr;
+ /// Displacement for EA calculation (signed).
+ int32_t disp;
+
+ /// Constructor
+ Memory(const char *mnem, MachInst _machInst, OpClass __opClass,
+ StaticInstPtr _eaCompPtr = nullStaticInstPtr,
+ StaticInstPtr _memAccPtr = nullStaticInstPtr)
+ : MipsStaticInst(mnem, _machInst, __opClass),
+ memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr),
+ disp(OFFSET)
+ {
+ }
+
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+
+ public:
+
+ const StaticInstPtr &eaCompInst() const { return eaCompPtr; }
+ const StaticInstPtr &memAccInst() const { return memAccPtr; }
+ };
+
+}};
+
+
+output decoder {{
+ std::string
+ Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+ {
+ return csprintf("%-10s %c%d,%d(r%d)", mnemonic,
+ flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB);
+ }
+
+}};
+
+def format LoadAddress(code) {{
+ iop = InstObjParams(name, Name, 'MemoryDisp32', CodeBlock(code))
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+}};
+
+
+def template LoadStoreDeclare {{
+ /**
+ * Static instruction class for "%(mnemonic)s".
+ */
+ class %(class_name)s : public %(base_class)s
+ {
+ protected:
+
/**
- * Base class for integer operations.
+ * "Fake" effective address computation class for "%(mnemonic)s".
*/
- class Mem : public MipsStaticInst
+ class EAComp : public %(base_class)s
{
- protected:
+ public:
+ /// Constructor
+ EAComp(MachInst machInst);
- /// Constructor
- Mem(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass)
- {
- }
+ %(BasicExecDeclare)s
+ };
- std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ /**
+ * "Fake" memory access instruction class for "%(mnemonic)s".
+ */
+ class MemAcc : public %(base_class)s
+ {
+ public:
+ /// Constructor
+ MemAcc(MachInst machInst);
+
+ %(BasicExecDeclare)s
};
+
+ public:
+
+ /// Constructor.
+ %(class_name)s(MachInst machInst);
+
+ %(BasicExecDeclare)s
+
+ %(InitiateAccDeclare)s
+
+ %(CompleteAccDeclare)s
+ };
}};
-output decoder {{
- std::string Mem::generateDisassembly(Addr pc, const SymbolTable *symtab) const
- {
- return "Disassembly of integer instruction\n";
+
+def template InitiateAccDeclare {{
+ Fault * initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
+}};
+
+
+def template CompleteAccDeclare {{
+ Fault * completeAcc(uint8_t *, %(CPU_exec_context)s *, Trace::InstRecord *) const;
+}};
+
+
+def template LoadStoreConstructor {{
+ /** 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;
+ }
+
+ inline %(class_name)s::MemAcc::MemAcc(MachInst machInst)
+ : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
+ {
+ %(memacc_constructor)s;
+ }
+
+ inline %(class_name)s::%(class_name)s(MachInst machInst)
+ : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
+ new EAComp(machInst), new MemAcc(machInst))
+ {
+ %(constructor)s;
+ }
+}};
+
+
+def template EACompExecute {{
+ Fault *
+ %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault * fault = NoFault;
+
+ %(fp_enable_check)s;
+ %(op_decl)s;
+ %(op_rd)s;
+ %(code)s;
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ xc->setEA(EA);
}
+
+ return fault;
+ }
}};
-def template MemExecute {{
- Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
- {
- //Attempt to execute the instruction
- try
- {
-
- %(op_decl)s;
- %(op_rd)s;
- ea_code
- %(code)s;
- }
- //If we have an exception for some reason,
- //deal with it
- catch(MipsException except)
- {
- //Deal with exception
- return No_Fault;
- }
-
- //Write the resulting state to the execution context
- %(op_wb)s;
-
- return No_Fault;
- }
-}};
-
-// Primary format for integer operate instructions:
-def format Memory(code, ea_code = {{ EA = Rb + disp; }},*opt_flags) {{
- orig_code = code
- cblk = CodeBlock(code)
- iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags)
- header_output = BasicDeclare.subst(iop)
- decoder_output = BasicConstructor.subst(iop)
- decode_block = BasicDecodeWithMnemonic.subst(iop)
- exec_output = MemExecute.subst(iop)
- exec_output.replace('ea_code', 'EA = I ? (R1 + SIMM13) : R1 + R2;');
-}};
-
-def format Cas(code, *opt_flags) {{
- orig_code = code
- cblk = CodeBlock(code)
- iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags)
- header_output = BasicDeclare.subst(iop)
- decoder_output = BasicConstructor.subst(iop)
- decode_block = BasicDecodeWithMnemonic.subst(iop)
- exec_output = MemExecute.subst(iop)
- exec_output.replace('ea_code', 'EA = R1;');
+def template LoadMemAccExecute {{
+ Fault *
+ %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault * fault = NoFault;
+
+ %(fp_enable_check)s;
+ %(op_decl)s;
+ %(op_rd)s;
+ EA = xc->getEA();
+
+ if (fault == NoFault) {
+ fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
+ %(code)s;
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
}};
+
+
+def template LoadExecute {{
+ Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault * fault = NoFault;
+
+ %(fp_enable_check)s;
+ %(op_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+
+ if (fault == NoFault) {
+ fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
+ %(memacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+
+def template LoadInitiateAcc {{
+ Fault * %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault * fault = NoFault;
+
+ %(fp_enable_check)s;
+ %(op_src_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+
+ if (fault == NoFault) {
+ fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
+ }
+
+ return fault;
+ }
+}};
+
+
+def template LoadCompleteAcc {{
+ Fault * %(class_name)s::completeAcc(uint8_t *data,
+ %(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Fault * fault = NoFault;
+
+ %(fp_enable_check)s;
+ %(op_src_decl)s;
+ %(op_dest_decl)s;
+
+ memcpy(&Mem, data, sizeof(Mem));
+
+ if (fault == NoFault) {
+ %(memacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+
+def template StoreMemAccExecute {{
+ Fault *
+ %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault * fault = NoFault;
+ uint64_t write_result = 0;
+
+ %(fp_enable_check)s;
+ %(op_decl)s;
+ %(op_rd)s;
+ EA = xc->getEA();
+
+ if (fault == NoFault) {
+ %(code)s;
+ }
+
+ if (fault == NoFault) {
+ fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
+ memAccessFlags, &write_result);
+ if (traceData) { traceData->setData(Mem); }
+ }
+
+ if (fault == NoFault) {
+ %(postacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+
+def template StoreExecute {{
+ Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault * fault = NoFault;
+ uint64_t write_result = 0;
+
+ %(fp_enable_check)s;
+ %(op_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+
+ if (fault == NoFault) {
+ %(memacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
+ memAccessFlags, &write_result);
+ if (traceData) { traceData->setData(Mem); }
+ }
+
+ if (fault == NoFault) {
+ %(postacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+def template StoreInitiateAcc {{
+ Fault * %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault * fault = NoFault;
+ uint64_t write_result = 0;
+
+ %(fp_enable_check)s;
+ %(op_src_decl)s;
+ %(op_dest_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+
+ if (fault == NoFault) {
+ %(memacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
+ memAccessFlags, &write_result);
+ if (traceData) { traceData->setData(Mem); }
+ }
+
+ return fault;
+ }
+}};
+
+
+def template StoreCompleteAcc {{
+ Fault * %(class_name)s::completeAcc(uint8_t *data,
+ %(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Fault * fault = NoFault;
+ uint64_t write_result = 0;
+
+ %(fp_enable_check)s;
+ %(op_dest_decl)s;
+
+ memcpy(&write_result, data, sizeof(write_result));
+
+ if (fault == NoFault) {
+ %(postacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+// load instructions use Rt as dest, so check for
+// Rt == 31 to detect nops
+def template LoadNopCheckDecode {{
+ {
+ MipsStaticInst *i = new %(class_name)s(machInst);
+ if (RT == 0) {
+ i = makeNop(i);
+ }
+ return i;
+ }
+}};
+
+def format LoadMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
+ mem_flags = [], inst_flags = []) {{
+ (header_output, decoder_output, decode_block, exec_output) = \
+ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ decode_template = LoadNopCheckDecode,
+ exec_template_base = 'Load')
+}};
+
+
+def format StoreMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
+ mem_flags = [], inst_flags = []) {{
+ (header_output, decoder_output, decode_block, exec_output) = \
+ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ exec_template_base = 'Store')
+}};
+
+//FP loads are offloaded to these formats for now ...
+def format LoadMemory2(ea_code = {{ EA = Rs + disp; }}, memacc_code = {{ }},
+ mem_flags = [], inst_flags = []) {{
+ (header_output, decoder_output, decode_block, exec_output) = \
+ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ decode_template = LoadNopCheckDecode,
+ exec_template_base = 'Load')
+}};
+
+
+//FP stores are offloaded to these formats for now ...
+def format StoreMemory2(ea_code = {{ EA = Rs + disp; }},memacc_code = {{ }},
+ mem_flags = [], inst_flags = []) {{
+ (header_output, decoder_output, decode_block, exec_output) = \
+ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ decode_template = LoadNopCheckDecode,
+ exec_template_base = 'Store')
+}};
+
return (header_output, decoder_output,
JumpOrBranchDecode.subst(nolink_iop), exec_output)
+
+def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ postacc_code = '', base_class = 'Memory',
+ decode_template = BasicDecode, exec_template_base = ''):
+ # Make sure flags are in lists (convert to lists if not).
+ mem_flags = makeList(mem_flags)
+ inst_flags = makeList(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 == '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 == '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
+
+ if mem_flags:
+ s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
+ iop.constructor += s
+ memacc_iop.constructor += s
+
+ # select templates
+ memAccExecTemplate = eval(exec_template_base + 'MemAccExecute')
+ fullExecTemplate = eval(exec_template_base + 'Execute')
+ initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
+ completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
+
+ # (header_output, decoder_output, decode_block, exec_output)
+ return (LoadStoreDeclare.subst(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))
}};
+
output exec {{
/// CLEAR ALL CPU INST/EXE HAZARDS