From 20208d00e6566a7946e589184a7ed9dffb54fc74 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 23 Oct 2006 07:55:52 -0400 Subject: [PATCH] Broke Load/Store instructions into microcode, and partially refactored memory operations in the SPARC ISA description. --HG-- rename : src/arch/sparc/isa/formats.isa => src/arch/sparc/isa/formats/formats.isa rename : src/arch/sparc/isa/formats/mem.isa => src/arch/sparc/isa/formats/mem/basicmem.isa rename : src/arch/sparc/isa/formats/blockmem.isa => src/arch/sparc/isa/formats/mem/blockmem.isa rename : src/arch/sparc/isa/formats/mem.isa => src/arch/sparc/isa/formats/mem/mem.isa extra : convert_revision : dbbb00f997a102871b084b209b9fa08c5e1853ee --- src/arch/sparc/isa/decoder.isa | 25 +- src/arch/sparc/isa/formats.isa | 37 -- src/arch/sparc/isa/formats/formats.isa | 62 ++++ src/arch/sparc/isa/formats/mem.isa | 347 ------------------ src/arch/sparc/isa/formats/mem/basicmem.isa | 202 ++++++++++ .../sparc/isa/formats/{ => mem}/blockmem.isa | 72 ++-- src/arch/sparc/isa/formats/mem/mem.isa | 45 +++ src/arch/sparc/isa/formats/mem/util.isa | 183 +++++++++ src/arch/sparc/isa/includes.isa | 3 + src/arch/sparc/isa/main.isa | 2 +- src/arch/sparc/isa/operands.isa | 5 +- 11 files changed, 545 insertions(+), 438 deletions(-) delete mode 100644 src/arch/sparc/isa/formats.isa create mode 100644 src/arch/sparc/isa/formats/formats.isa delete mode 100644 src/arch/sparc/isa/formats/mem.isa create mode 100644 src/arch/sparc/isa/formats/mem/basicmem.isa rename src/arch/sparc/isa/formats/{ => mem}/blockmem.isa (84%) create mode 100644 src/arch/sparc/isa/formats/mem/mem.isa create mode 100644 src/arch/sparc/isa/formats/mem/util.isa diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index 9da6bdd33..45d3616d9 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -846,11 +846,10 @@ decode OP default Unknown::unknown() }}); } 0x0E: Store::stx({{Mem.udw = Rd}}); - 0x0F: LoadStore::swap({{ - uint32_t temp = Rd; - Rd = Mem.uw; - Mem.uw = temp; - }}); + 0x0F: LoadStore::swap( + {{*temp = Rd.uw; + Rd.uw = Mem.uw;}}, + {{Mem.uw = *temp;}}); format Load { 0x10: lduwa({{Rd = Mem.uw;}}); 0x11: lduba({{Rd = Mem.ub;}}); @@ -873,16 +872,14 @@ decode OP default Unknown::unknown() 0x1A: ldsha({{Rd = (int16_t)Mem.shw;}}); 0x1B: ldxa({{Rd = (int64_t)Mem.sdw;}}); } - 0x1D: LoadStore::ldstuba({{ - Rd = Mem.ub; - Mem.ub = 0xFF; - }}); + 0x1D: LoadStore::ldstuba( + {{Rd = Mem.ub;}}, + {{Mem.ub = 0xFF}}); 0x1E: Store::stxa({{Mem.udw = Rd}}); - 0x1F: LoadStore::swapa({{ - uint32_t temp = Rd; - Rd = Mem.uw; - Mem.uw = temp; - }}); + 0x1F: LoadStore::swapa( + {{*temp = Rd.uw; + Rd.uw = Mem.uw;}}, + {{Mem.uw = *temp;}}); format Trap { 0x20: Load::ldf({{Frd.uw = Mem.uw;}}); 0x21: decode X { diff --git a/src/arch/sparc/isa/formats.isa b/src/arch/sparc/isa/formats.isa deleted file mode 100644 index e044aee1f..000000000 --- a/src/arch/sparc/isa/formats.isa +++ /dev/null @@ -1,37 +0,0 @@ -//Include the basic format -//Templates from this format are used later -##include "formats/basic.isa" - -//Include base classes for microcoding instructions -##include "formats/micro.isa" - -//Include the noop format -##include "formats/nop.isa" - -//Include the integerOp and integerOpCc format -##include "formats/integerop.isa" - -//Include the memory format -##include "formats/mem.isa" - -//Include the block memory format -##include "formats/blockmem.isa" - -//Include the compare and swap format -##include "formats/cas.isa" - -//Include the trap format -##include "formats/trap.isa" - -//Include the unimplemented format -##include "formats/unimp.isa" - -//Include the "unknown" format -##include "formats/unknown.isa" - -//Include the priveleged mode format -##include "formats/priv.isa" - -//Include the branch format -##include "formats/branch.isa" - diff --git a/src/arch/sparc/isa/formats/formats.isa b/src/arch/sparc/isa/formats/formats.isa new file mode 100644 index 000000000..5b81a1ab1 --- /dev/null +++ b/src/arch/sparc/isa/formats/formats.isa @@ -0,0 +1,62 @@ +// 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: Gabe Black + +//Include the basic format +//Templates from this format are used later +##include "basic.isa" + +//Include base classes for microcoding instructions +##include "micro.isa" + +//Include the noop format +##include "nop.isa" + +//Include the integerOp and integerOpCc format +##include "integerop.isa" + +//Include the memory formats +##include "mem/mem.isa" + +//Include the compare and swap format +##include "cas.isa" + +//Include the trap format +##include "trap.isa" + +//Include the unimplemented format +##include "unimp.isa" + +//Include the "unknown" format +##include "unknown.isa" + +//Include the priveleged mode format +##include "priv.isa" + +//Include the branch format +##include "branch.isa" + diff --git a/src/arch/sparc/isa/formats/mem.isa b/src/arch/sparc/isa/formats/mem.isa deleted file mode 100644 index 2d3dd3d9a..000000000 --- a/src/arch/sparc/isa/formats/mem.isa +++ /dev/null @@ -1,347 +0,0 @@ -//////////////////////////////////////////////////////////////////// -// -// Mem instructions -// - -output header {{ - /** - * Base class for memory operations. - */ - class Mem : public SparcStaticInst - { - protected: - - // Constructor - Mem(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : - SparcStaticInst(mnem, _machInst, __opClass) - { - } - - std::string generateDisassembly(Addr pc, - const SymbolTable *symtab) const; - }; - - /** - * Class for memory operations which use an immediate offset. - */ - class MemImm : public Mem - { - protected: - - // Constructor - MemImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : - Mem(mnem, _machInst, __opClass) - { - imm = sext<13>(SIMM13); - } - - std::string generateDisassembly(Addr pc, - const SymbolTable *symtab) const; - - int32_t imm; - }; -}}; - -output decoder {{ - std::string Mem::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 MemImm::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]); - 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 LoadExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, - Trace::InstRecord *traceData) const - { - Fault fault = NoFault; - Addr EA; - %(op_decl)s; - %(op_rd)s; - %(priv_check)s; - %(ea_code)s; - DPRINTF(Sparc, "The address is 0x%x\n", EA); - fault = 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; - } - - 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; - %(priv_check)s; - %(ea_code)s; - fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0); - return fault; - } - - 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; - Mem = pkt->get(); - %(code)s; - if(fault == NoFault) - { - %(code_wb)s; - } - return fault; - } -}}; - -def template StoreExecute {{ - Fault %(class_name)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; - %(priv_check)s; - %(ea_code)s; - DPRINTF(Sparc, "The address is 0x%x\n", EA); - %(code)s; - - if(fault == NoFault) - { - fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result); - } - if(fault == NoFault) - { - //Write the resulting state to the execution context - %(op_wb)s; - } - - return fault; - } - - Fault %(class_name)s::initiateAcc(%(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; - %(priv_check)s; - %(ea_code)s; - DPRINTF(Sparc, "The address is 0x%x\n", EA); - %(code)s; - if(fault == NoFault) - { - fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result); - } - if(fault == NoFault) - { - //Write the resulting state to the execution context - %(op_wb)s; - } - return fault; - } - - Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc, - Trace::InstRecord * traceData) const - { - return NoFault; - } -}}; - -def template LoadStoreExecute {{ - Fault %(class_name)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; - %(priv_check)s; - %(ea_code)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) - { - 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; - } -}}; - -def template MemDeclare {{ - /** - * Static instruction class for "%(mnemonic)s". - */ - class %(class_name)s : public %(base_class)s - { - public: - - /// Constructor. - %(class_name)s(ExtMachInst machInst); - - %(BasicExecDeclare)s - - %(InitiateAccDeclare)s - - %(CompleteAccDeclare)s - }; -}}; - -def template InitiateAccDeclare {{ - Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; -}}; - -def template CompleteAccDeclare {{ - Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const; -}}; - - -let {{ - # 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 - privilegedString = '''if(bits(Pstate,2,2) == 0 && (EXT_ASI & 0x80) == 0) - return new PrivilegedAction; - if(AsiIsAsIfUser(EXT_ASI) && !bits(Pstate,2,2)) - return new PrivilegedAction;''' - - def doMemFormat(code, execute, priv, name, Name, opt_flags): - addrCalcReg = 'EA = Rs1 + Rs2;' - addrCalcImm = 'EA = Rs1 + imm;' - ea_iop = InstObjParams(name, Name, 'Mem', - addrCalcReg, opt_flags, {"priv_check": priv}) - ea_iop_imm = InstObjParams(name, Name, 'MemImm', - addrCalcImm, opt_flags, {"priv_check": priv}) - code_iop = InstObjParams(name, Name, 'Mem', code, opt_flags) - iop = InstObjParams(name, Name, 'Mem', code, - opt_flags, {"ea_code": addrCalcReg, - "priv_check": priv}) - (iop.ea_decl, - iop.ea_rd, - iop.ea_wb) = (ea_iop.op_decl, ea_iop.op_rd, ea_iop.op_wb) - (iop.code_decl, - iop.code_rd, - iop.code_wb) = (code_iop.op_decl, code_iop.op_rd, code_iop.op_wb) - iop_imm = InstObjParams(name, Name + 'Imm', 'MemImm', code, - opt_flags, {"ea_code": addrCalcImm, - "priv_check": priv}) - (iop_imm.ea_decl, - iop_imm.ea_rd, - iop_imm.ea_wb) = (ea_iop_imm.op_decl, ea_iop_imm.op_rd, ea_iop_imm.op_wb) - (iop_imm.code_decl, - iop_imm.code_rd, - iop_imm.code_wb) = (code_iop.op_decl, code_iop.op_rd, code_iop.op_wb) - 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 = execute.subst(iop) + execute.subst(iop_imm) - return (header_output, decoder_output, exec_output, decode_block) -}}; - -def format LoadAlt(code, *opt_flags) {{ - (header_output, - decoder_output, - exec_output, - decode_block) = doMemFormat(code, LoadExecute, - privelegedString, name, Name, opt_flags) -}}; - -def format StoreAlt(code, *opt_flags) {{ - (header_output, - decoder_output, - exec_output, - decode_block) = doMemFormat(code, StoreExecute, - privilegedString, name, Name, opt_flags) -}}; - -def format Load(code, *opt_flags) {{ - (header_output, - decoder_output, - exec_output, - decode_block) = doMemFormat(code, - LoadExecute, '', name, Name, opt_flags) -}}; - -def format Store(code, *opt_flags) {{ - (header_output, - decoder_output, - exec_output, - decode_block) = doMemFormat(code, - StoreExecute, '', name, Name, opt_flags) -}}; - -def format LoadStore(code, *opt_flags) {{ - (header_output, - decoder_output, - exec_output, - decode_block) = doMemFormat(code, - LoadStoreExecute, '', name, Name, opt_flags) -}}; diff --git a/src/arch/sparc/isa/formats/mem/basicmem.isa b/src/arch/sparc/isa/formats/mem/basicmem.isa new file mode 100644 index 000000000..b524f309a --- /dev/null +++ b/src/arch/sparc/isa/formats/mem/basicmem.isa @@ -0,0 +1,202 @@ +// 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 + +//////////////////////////////////////////////////////////////////// +// +// Mem instructions +// + +output header {{ + /** + * Base class for memory operations. + */ + class Mem : public SparcStaticInst + { + protected: + + // Constructor + Mem(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : + SparcStaticInst(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; + }; + + /** + * Class for memory operations which use an immediate offset. + */ + class MemImm : public Mem + { + protected: + + // Constructor + MemImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : + Mem(mnem, _machInst, __opClass), imm(sext<13>(SIMM13)) + {} + + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; + + const int32_t imm; + }; +}}; + +output decoder {{ + std::string Mem::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 MemImm::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]); + 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 MemDeclare {{ + /** + * Static instruction class for "%(mnemonic)s". + */ + class %(class_name)s : public %(base_class)s + { + public: + + /// Constructor. + %(class_name)s(ExtMachInst machInst); + + %(BasicExecDeclare)s + + %(InitiateAccDeclare)s + + %(CompleteAccDeclare)s + }; +}}; + +let {{ + # 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 + privilegedString = '''if(bits(Pstate,2,2) == 0 && (EXT_ASI & 0x80) == 0) + return new PrivilegedAction; + if(AsiIsAsIfUser(EXT_ASI) && !bits(Pstate,2,2)) + return new PrivilegedAction;''' + + def doMemFormat(code, execute, priv, name, Name, opt_flags): + addrCalcReg = 'EA = Rs1 + Rs2;' + addrCalcImm = 'EA = Rs1 + imm;' + iop = InstObjParams(name, Name, 'Mem', code, + opt_flags, {"priv_check": priv, "ea_code": addrCalcReg}) + iop_imm = InstObjParams(name, Name + "Imm", 'MemImm', code, + opt_flags, {"priv_check": priv, "ea_code": addrCalcImm}) + 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 = doSplitExecute(code, addrCalcReg, addrCalcImm, execute, + priv, name, name + "Imm", Name, Name + "Imm", opt_flags) + return (header_output, decoder_output, exec_output, decode_block) +}}; + +def format LoadAlt(code, *opt_flags) {{ + (header_output, + decoder_output, + exec_output, + decode_block) = doMemFormat(code, LoadExecute, + privelegedString, name, Name, opt_flags) +}}; + +def format StoreAlt(code, *opt_flags) {{ + (header_output, + decoder_output, + exec_output, + decode_block) = doMemFormat(code, StoreExecute, + privilegedString, name, Name, opt_flags) +}}; + +def format Load(code, *opt_flags) {{ + (header_output, + decoder_output, + exec_output, + decode_block) = doMemFormat(code, + LoadExecute, '', name, Name, opt_flags) +}}; + +def format Store(code, *opt_flags) {{ + (header_output, + decoder_output, + exec_output, + decode_block) = doMemFormat(code, + StoreExecute, '', name, Name, opt_flags) +}}; diff --git a/src/arch/sparc/isa/formats/blockmem.isa b/src/arch/sparc/isa/formats/mem/blockmem.isa similarity index 84% rename from src/arch/sparc/isa/formats/blockmem.isa rename to src/arch/sparc/isa/formats/mem/blockmem.isa index 4a2a14a15..8584662a1 100644 --- a/src/arch/sparc/isa/formats/blockmem.isa +++ b/src/arch/sparc/isa/formats/mem/blockmem.isa @@ -1,3 +1,32 @@ +// 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 @@ -12,9 +41,8 @@ output header {{ // Constructor // We make the assumption that all block memory operations // Will take 8 instructions to execute - BlockMem(const char *mnem, - ExtMachInst _machInst, OpClass __opClass) : - SparcMacroInst(mnem, _machInst, __opClass, 8) + BlockMem(const char *mnem, ExtMachInst _machInst) : + SparcMacroInst(mnem, _machInst, No_OpClass, 8) {} }; @@ -23,13 +51,9 @@ output header {{ protected: // Constructor - BlockMemImm(const char *mnem, - ExtMachInst _machInst, OpClass __opClass) : - BlockMem(mnem, _machInst, __opClass), - imm(sext<13>(SIMM13)) + BlockMemImm(const char *mnem, ExtMachInst _machInst) : + BlockMem(mnem, _machInst) {} - - const int32_t imm; }; class BlockMemMicro : public SparcDelayedMicroInst @@ -125,32 +149,6 @@ output decoder {{ }}; -def template LoadStoreExecute {{ - Fault %(class_name)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; - %(priv_check)s; - %(ea_code)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) - { - 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; - } -}}; - def template BlockMemDeclare {{ /** * Static instruction class for a block memory operation @@ -231,7 +229,7 @@ def template BlockMemDeclare {{ // Basic instruction class constructor template. def template BlockMemConstructor {{ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) - : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) + : %(base_class)s("%(mnemonic)s", machInst) { %(constructor)s; microOps[0] = new %(class_name)s_0(machInst); @@ -335,7 +333,7 @@ let {{ for microPC in range(8): flag_code = '' if (microPC == 7): - flag_code = "flags[IsLastMicroOp] = true" + flag_code = "flags[IsLastMicroOp] = true;" pcedCode = matcher.sub("Frd_%d" % microPC, code) iop = InstObjParams(name, Name, 'BlockMem', pcedCode, opt_flags, {"ea_code": addrCalcReg, diff --git a/src/arch/sparc/isa/formats/mem/mem.isa b/src/arch/sparc/isa/formats/mem/mem.isa new file mode 100644 index 000000000..20a22c45d --- /dev/null +++ b/src/arch/sparc/isa/formats/mem/mem.isa @@ -0,0 +1,45 @@ +// 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 + +//////////////////////////////////////////////////////////////////// +// +// Mem formats +// + +//Include mem utility templates and functions +##include "util.isa" + +//Include the basic memory format +##include "basicmem.isa" + +//Include the block memory format +##include "blockmem.isa" + +//Include the load/store memory format +##include "loadstore.isa" diff --git a/src/arch/sparc/isa/formats/mem/util.isa b/src/arch/sparc/isa/formats/mem/util.isa new file mode 100644 index 000000000..296ae1888 --- /dev/null +++ b/src/arch/sparc/isa/formats/mem/util.isa @@ -0,0 +1,183 @@ +// 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 +// Steve Reinhardt + +//////////////////////////////////////////////////////////////////// +// +// Mem utility templates and functions +// + +//This template provides the execute functions for a load +def template LoadExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Fault fault = NoFault; + Addr EA; + %(op_decl)s; + %(op_rd)s; + %(priv_check)s; + %(ea_code)s; + DPRINTF(Sparc, "The address is 0x%x\n", EA); + fault = 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; + } + + 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; + %(priv_check)s; + %(ea_code)s; + fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0); + return fault; + } + + 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; + Mem = pkt->get(); + %(code)s; + if(fault == NoFault) + { + %(code_wb)s; + } + return fault; + } +}}; + +//This template provides the execute functions for a store +def template StoreExecute {{ + Fault %(class_name)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; + %(priv_check)s; + %(ea_code)s; + DPRINTF(Sparc, "The address is 0x%x\n", EA); + %(code)s; + + if(fault == NoFault) + { + fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result); + } + if(fault == NoFault) + { + //Write the resulting state to the execution context + %(op_wb)s; + } + + return fault; + } + + Fault %(class_name)s::initiateAcc(%(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; + %(priv_check)s; + %(ea_code)s; + DPRINTF(Sparc, "The address is 0x%x\n", EA); + %(code)s; + if(fault == NoFault) + { + fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result); + } + if(fault == NoFault) + { + //Write the resulting state to the execution context + %(op_wb)s; + } + return fault; + } + + Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc, + Trace::InstRecord * traceData) const + { + return NoFault; + } +}}; + +//This delcares the initiateAcc function in memory operations +def template InitiateAccDeclare {{ + Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; +}}; + +//This declares the completeAcc function in memory operations +def template CompleteAccDeclare {{ + Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const; +}}; + +//This function properly generates the execute functions for one of the +//templates above. This is needed because in one case, ea computation, +//privelege checks and the actual code all occur in the same function, +//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, eaRegCode, eaImmCode, execute, + priv, nameReg, nameImm, NameReg, NameImm, opt_flags): + codeIop = InstObjParams(nameReg, NameReg, '', code, opt_flags) + executeCode = '' + for (eaCode, name, Name) in ( + (eaRegCode, nameReg, NameReg), + (eaImmCode, nameImm, NameImm)): + eaIop = InstObjParams(name, Name, '', eaCode, + opt_flags, {"priv_check": priv}) + iop = InstObjParams(name, Name, '', code, opt_flags, + {"priv_check": priv, "ea_code" : eaCode}) + (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) + executeCode += execute.subst(iop) + return executeCode +}}; diff --git a/src/arch/sparc/isa/includes.isa b/src/arch/sparc/isa/includes.isa index 9fed36b03..a324756ec 100644 --- a/src/arch/sparc/isa/includes.isa +++ b/src/arch/sparc/isa/includes.isa @@ -49,6 +49,7 @@ output decoder {{ #include "base/cprintf.hh" #include "base/loader/symtab.hh" #include "cpu/thread_context.hh" // for Jump::branchTarget() +#include "mem/packet.hh" #if defined(linux) #include @@ -66,6 +67,8 @@ output exec {{ #include "cpu/base.hh" #include "cpu/exetrace.hh" #include "sim/sim_exit.hh" +#include "mem/packet.hh" +#include "mem/packet_access.hh" using namespace SparcISA; }}; diff --git a/src/arch/sparc/isa/main.isa b/src/arch/sparc/isa/main.isa index 765c98ed1..df5ad0c99 100644 --- a/src/arch/sparc/isa/main.isa +++ b/src/arch/sparc/isa/main.isa @@ -55,7 +55,7 @@ namespace SparcISA; ##include "base.isa" //Include the definitions for the instruction formats -##include "formats.isa" +##include "formats/formats.isa" //Include the decoder definition ##include "decoder.isa" diff --git a/src/arch/sparc/isa/operands.isa b/src/arch/sparc/isa/operands.isa index 40926a5fb..b8b75170b 100644 --- a/src/arch/sparc/isa/operands.isa +++ b/src/arch/sparc/isa/operands.isa @@ -77,7 +77,6 @@ def operands {{ 'Frs1': ('FloatReg', 'df', 'dfpr(RS1)', 'IsFloating', 11), 'Frs2s': ('FloatReg', 'df', 'RS2', 'IsFloating', 12), 'Frs2': ('FloatReg', 'df', 'dfpr(RS2)', 'IsFloating', 12), - 'Mem': ('Mem', 'udw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 20), 'NPC': ('NPC', 'udw', None, ( None, None, 'IsControl' ), 31), 'NNPC': ('NNPC', 'udw', None, (None, None, 'IsControl' ), 32), #'Runiq': ('ControlReg', 'uq', 'Uniq', None, 1), @@ -107,6 +106,8 @@ def operands {{ 'Gl': ('ControlReg', 'udw', 'MISCREG_GL', None, 54), 'Fsr': ('ControlReg', 'udw', 'MISCREG_FSR', None, 55), - 'Gsr': ('ControlReg', 'udw', 'MISCREG_GSR', None, 56) + 'Gsr': ('ControlReg', 'udw', 'MISCREG_GSR', None, 56), + # Mem gets a large number so it's always last + 'Mem': ('Mem', 'udw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 100) }};