diff options
Diffstat (limited to 'src/arch/sparc/isa/formats/mem/blockmem.isa')
-rw-r--r-- | src/arch/sparc/isa/formats/mem/blockmem.isa | 368 |
1 files changed, 368 insertions, 0 deletions
diff --git a/src/arch/sparc/isa/formats/mem/blockmem.isa b/src/arch/sparc/isa/formats/mem/blockmem.isa new file mode 100644 index 000000000..8584662a1 --- /dev/null +++ b/src/arch/sparc/isa/formats/mem/blockmem.isa @@ -0,0 +1,368 @@ +// Copyright (c) 2006 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: Ali Saidi +// Gabe Black + +//////////////////////////////////////////////////////////////////// +// +// Block Memory instructions +// + +output header {{ + + class BlockMem : public SparcMacroInst + { + protected: + + // Constructor + // We make the assumption that all block memory operations + // Will take 8 instructions to execute + BlockMem(const char *mnem, ExtMachInst _machInst) : + SparcMacroInst(mnem, _machInst, No_OpClass, 8) + {} + }; + + class BlockMemImm : public BlockMem + { + protected: + + // Constructor + BlockMemImm(const char *mnem, ExtMachInst _machInst) : + BlockMem(mnem, _machInst) + {} + }; + + class BlockMemMicro : public SparcDelayedMicroInst + { + protected: + + // Constructor + BlockMemMicro(const char *mnem, ExtMachInst _machInst, + OpClass __opClass, int8_t _offset) : + SparcDelayedMicroInst(mnem, _machInst, __opClass), + offset(_offset) + {} + + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; + + const int8_t offset; + }; + + class BlockMemImmMicro : public BlockMemMicro + { + protected: + + // Constructor + BlockMemImmMicro(const char *mnem, ExtMachInst _machInst, + OpClass __opClass, int8_t _offset) : + BlockMemMicro(mnem, _machInst, __opClass, _offset), + imm(sext<13>(SIMM13)) + {} + + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; + + const int32_t imm; + }; +}}; + +output decoder {{ + std::string BlockMemMicro::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + std::stringstream response; + bool load = flags[IsLoad]; + bool save = flags[IsStore]; + + printMnemonic(response, mnemonic); + if(save) + { + printReg(response, _srcRegIdx[0]); + ccprintf(response, ", "); + } + ccprintf(response, "[ "); + printReg(response, _srcRegIdx[!save ? 0 : 1]); + ccprintf(response, " + "); + printReg(response, _srcRegIdx[!save ? 1 : 2]); + ccprintf(response, " ]"); + if(load) + { + ccprintf(response, ", "); + printReg(response, _destRegIdx[0]); + } + + return response.str(); + } + + std::string BlockMemImmMicro::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + std::stringstream response; + bool load = flags[IsLoad]; + bool save = flags[IsStore]; + + printMnemonic(response, mnemonic); + if(save) + { + printReg(response, _srcRegIdx[1]); + ccprintf(response, ", "); + } + ccprintf(response, "[ "); + printReg(response, _srcRegIdx[0]); + if(imm >= 0) + ccprintf(response, " + 0x%x ]", imm); + else + ccprintf(response, " + -0x%x ]", -imm); + if(load) + { + ccprintf(response, ", "); + printReg(response, _destRegIdx[0]); + } + + return response.str(); + } + +}}; + +def template BlockMemDeclare {{ + /** + * Static instruction class for a block memory operation + */ + class %(class_name)s : public %(base_class)s + { + public: + //Constructor + %(class_name)s(ExtMachInst machInst); + + protected: + class %(class_name)s_0 : public %(base_class)sMicro + { + public: + //Constructor + %(class_name)s_0(ExtMachInst machInst); + %(BasicExecDeclare)s + }; + + class %(class_name)s_1 : public %(base_class)sMicro + { + public: + //Constructor + %(class_name)s_1(ExtMachInst machInst); + %(BasicExecDeclare)s + }; + + class %(class_name)s_2 : public %(base_class)sMicro + { + public: + //Constructor + %(class_name)s_2(ExtMachInst machInst); + %(BasicExecDeclare)s + }; + + class %(class_name)s_3 : public %(base_class)sMicro + { + public: + //Constructor + %(class_name)s_3(ExtMachInst machInst); + %(BasicExecDeclare)s + }; + + class %(class_name)s_4 : public %(base_class)sMicro + { + public: + //Constructor + %(class_name)s_4(ExtMachInst machInst); + %(BasicExecDeclare)s + }; + + class %(class_name)s_5 : public %(base_class)sMicro + { + public: + //Constructor + %(class_name)s_5(ExtMachInst machInst); + %(BasicExecDeclare)s + }; + + class %(class_name)s_6 : public %(base_class)sMicro + { + public: + //Constructor + %(class_name)s_6(ExtMachInst machInst); + %(BasicExecDeclare)s + }; + + class %(class_name)s_7 : public %(base_class)sMicro + { + public: + //Constructor + %(class_name)s_7(ExtMachInst machInst); + %(BasicExecDeclare)s + }; + }; +}}; + +// Basic instruction class constructor template. +def template BlockMemConstructor {{ + inline %(class_name)s::%(class_name)s(ExtMachInst machInst) + : %(base_class)s("%(mnemonic)s", machInst) + { + %(constructor)s; + microOps[0] = new %(class_name)s_0(machInst); + microOps[1] = new %(class_name)s_1(machInst); + microOps[2] = new %(class_name)s_2(machInst); + microOps[3] = new %(class_name)s_3(machInst); + microOps[4] = new %(class_name)s_4(machInst); + microOps[5] = new %(class_name)s_5(machInst); + microOps[6] = new %(class_name)s_6(machInst); + microOps[7] = new %(class_name)s_7(machInst); + } +}}; + +def template BlockMemMicroConstructor {{ + inline %(class_name)s:: + %(class_name)s_%(micro_pc)s:: + %(class_name)s_%(micro_pc)s(ExtMachInst machInst) : + %(base_class)sMicro("%(mnemonic)s[%(micro_pc)s]", + machInst, %(op_class)s, %(micro_pc)s * 8) + { + %(constructor)s; + %(set_flags)s; + } +}}; + +def template MicroLoadExecute {{ + Fault %(class_name)s::%(class_name)s_%(micro_pc)s::execute( + %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + { + Fault fault = NoFault; + Addr EA; + %(op_decl)s; + %(op_rd)s; + %(ea_code)s; + %(fault_check)s; + DPRINTF(Sparc, "The address is 0x%x\n", EA); + xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0); + %(code)s; + + if(fault == NoFault) + { + //Write the resulting state to the execution context + %(op_wb)s; + } + + return fault; + } +}}; + +def template MicroStoreExecute {{ + Fault %(class_name)s::%(class_name)s_%(micro_pc)s::execute( + %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + { + Fault fault = NoFault; + uint64_t write_result = 0; + Addr EA; + %(op_decl)s; + %(op_rd)s; + %(ea_code)s; + %(fault_check)s; + DPRINTF(Sparc, "The address is 0x%x\n", EA); + %(code)s; + + if(fault == NoFault) + { + xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result); + //Write the resulting state to the execution context + %(op_wb)s; + } + + return fault; + } +}}; + +let {{ + + def doBlockMemFormat(code, execute, name, Name, opt_flags): + # XXX Need to take care of pstate.hpriv as well. The lower ASIs + # are split into ones that are available in priv and hpriv, and + # those that are only available in hpriv + faultCheck = '''if(bits(Pstate,2,2) == 0 && (EXT_ASI & 0x80) == 0) + return new PrivilegedAction; + if(AsiIsAsIfUser((ASI)EXT_ASI) && !bits(Pstate,2,2)) + return new PrivilegedAction; + //The LSB can be zero, since it's really the MSB in doubles + //and quads + if(RD & 0xe) + return new IllegalInstruction; + if(EA & 0x3f) + return new MemAddressNotAligned; + ''' + addrCalcReg = 'EA = Rs1 + Rs2 + offset;' + addrCalcImm = 'EA = Rs1 + imm + offset;' + iop = InstObjParams(name, Name, 'BlockMem', code, opt_flags) + iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm', code, opt_flags) + header_output = BlockMemDeclare.subst(iop) + BlockMemDeclare.subst(iop_imm) + decoder_output = BlockMemConstructor.subst(iop) + BlockMemConstructor.subst(iop_imm) + decode_block = ROrImmDecode.subst(iop) + matcher = re.compile(r'Frd_N') + exec_output = '' + for microPC in range(8): + flag_code = '' + if (microPC == 7): + flag_code = "flags[IsLastMicroOp] = true;" + pcedCode = matcher.sub("Frd_%d" % microPC, code) + iop = InstObjParams(name, Name, 'BlockMem', pcedCode, + opt_flags, {"ea_code": addrCalcReg, + "fault_check": faultCheck, "micro_pc": microPC, + "set_flags": flag_code}) + iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm', pcedCode, + opt_flags, {"ea_code": addrCalcImm, + "fault_check": faultCheck, "micro_pc": microPC, + "set_flags": flag_code}) + exec_output += execute.subst(iop) + exec_output += execute.subst(iop_imm) + decoder_output += BlockMemMicroConstructor.subst(iop) + decoder_output += BlockMemMicroConstructor.subst(iop_imm) + faultCheck = '' + return (header_output, decoder_output, exec_output, decode_block) +}}; + +def format BlockLoad(code, *opt_flags) {{ + (header_output, + decoder_output, + exec_output, + decode_block) = doBlockMemFormat(code, MicroLoadExecute, + name, Name, opt_flags) +}}; + +def format BlockStore(code, *opt_flags) {{ + (header_output, + decoder_output, + exec_output, + decode_block) = doBlockMemFormat(code, MicroStoreExecute, + name, Name, opt_flags) +}}; |