diff options
Diffstat (limited to 'src/arch/mips/isa/formats/mem.isa')
-rw-r--r-- | src/arch/mips/isa/formats/mem.isa | 183 |
1 files changed, 147 insertions, 36 deletions
diff --git a/src/arch/mips/isa/formats/mem.isa b/src/arch/mips/isa/formats/mem.isa index e2afc7252..f03f7becd 100644 --- a/src/arch/mips/isa/formats/mem.isa +++ b/src/arch/mips/isa/formats/mem.isa @@ -1,6 +1,6 @@ // -*- mode:c++ -*- -// Copyright (c) 2003-2005 The Regents of The University of Michigan +// Copyright (c) 2006 The Regents of The University of Michigan // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -25,6 +25,14 @@ // 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: Gabe Black +// Korey Sewell + +//////////////////////////////////////////////////////////////////// +// +// Memory-format instructions +// output header {{ /** @@ -50,14 +58,8 @@ output header {{ StaticInstPtr _memAccPtr = nullStaticInstPtr) : MipsStaticInst(mnem, _machInst, __opClass), memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr), - disp(OFFSET) + disp(sext<16>(OFFSET)) { - //If Bit 15 is 1 then Sign Extend - int32_t temp = disp & 0x00008000; - - if (temp > 0) { - disp |= 0xFFFF0000; - } } std::string @@ -69,6 +71,24 @@ output header {{ const StaticInstPtr &memAccInst() const { return memAccPtr; } }; + /** + * Base class for a few miscellaneous memory-format insts + * that don't interpret the disp field + */ + class MemoryNoDisp : public Memory + { + protected: + /// Constructor + MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, + StaticInstPtr _eaCompPtr = nullStaticInstPtr, + StaticInstPtr _memAccPtr = nullStaticInstPtr) + : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr) + { + } + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; }}; @@ -76,21 +96,20 @@ output decoder {{ std::string Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const { - return csprintf("%-10s %c%d,%d(r%d)", mnemonic, + return csprintf("%-10s %c%d, %d(r%d)", mnemonic, flags[IsFloating] ? 'f' : 'r', RT, disp, RS); } + std::string + MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + return csprintf("%-10s %c%d, r%d(r%d)", mnemonic, + flags[IsFloating] ? 'f' : 'r', + flags[IsFloating] ? FD : RD, + RS, RT); + } }}; -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". @@ -418,27 +437,76 @@ def template StoreCompleteAcc {{ } }}; -// 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 template MiscMemAccExecute {{ + 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) { + %(code)s; + } + + return NoFault; + } +}}; + +def template MiscExecute {{ + 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) { + %(memacc_code)s; + } + + return NoFault; + } +}}; + +def template MiscInitiateAcc {{ + Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + panic("Misc instruction does not support split access method!"); + return NoFault; + } +}}; + + +def template MiscCompleteAcc {{ + Fault %(class_name)s::completeAcc(uint8_t *data, + %(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + panic("Misc instruction does not support split access method!"); + + return NoFault; + } }}; 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, + decode_template = ImmNopCheckDecode, 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) = \ @@ -446,26 +514,69 @@ def format StoreMemory(memacc_code, ea_code = {{ EA = Rs + disp; }}, exec_template_base = 'Store') }}; -//FP loads are offloaded to these formats for now ... -def format LoadFloatMemory(memacc_code, ea_code = {{ EA = Rs + disp; }}, +def format LoadIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }}, 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 = BasicDecode, + decode_template = ImmNopCheckDecode, exec_template_base = 'Load') }}; +def format StoreIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }}, + 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') +}}; + +def format LoadUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }}, + mem_flags = [], inst_flags = []) {{ + decl_code = 'uint32_t mem_word = Mem.uw;\n' + decl_code += 'uint32_t unalign_addr = Rs + disp;\n' + decl_code += 'uint32_t byte_offset = unalign_addr & 3;\n' + decl_code += '#if BYTE_ORDER == BIG_ENDIAN\n' + decl_code += '\tbyte_offset ^= 3;\n' + decl_code += '#endif\n' + + memacc_code = decl_code + memacc_code + + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, + decode_template = ImmNopCheckDecode, + exec_template_base = 'Load') +}}; -def format StoreFloatMemory(memacc_code, ea_code = {{ EA = Rs + disp; }}, +def format StoreUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }}, mem_flags = [], inst_flags = []) {{ + decl_code = 'uint32_t mem_word = 0;\n' + decl_code += 'uint32_t unaligned_addr = Rs + disp;\n' + decl_code += 'uint32_t byte_offset = unaligned_addr & 3;\n' + decl_code += '#if BYTE_ORDER == BIG_ENDIAN\n' + decl_code += '\tbyte_offset ^= 3;\n' + decl_code += '#endif\n' + decl_code += 'fault = xc->read(EA, (uint32_t&)mem_word, memAccessFlags);\n' + memacc_code = decl_code + memacc_code + '\nMem = mem_word;\n' + (header_output, decoder_output, decode_block, exec_output) = \ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, exec_template_base = 'Store') }}; +def format Prefetch(ea_code = {{ EA = Rs + disp; }}, + mem_flags = [], pf_flags = [], inst_flags = []) {{ + pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT'] + pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad', + 'IsDataPrefetch', 'MemReadOp'] + + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, + 'xc->prefetch(EA, memAccessFlags);', + pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc') + +}}; -def format UnalignedStore(memacc_code, postacc_code, - ea_code = {{ EA = Rb + disp; }}, +def format StoreCond(memacc_code, postacc_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, |