From 20208d00e6566a7946e589184a7ed9dffb54fc74 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 23 Oct 2006 07:55:52 -0400 Subject: 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/blockmem.isa | 370 ---------------------------- 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 +++++++++++++++ src/arch/sparc/isa/formats/mem/blockmem.isa | 368 +++++++++++++++++++++++++++ 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 +- 12 files changed, 878 insertions(+), 771 deletions(-) delete mode 100644 src/arch/sparc/isa/formats.isa delete mode 100644 src/arch/sparc/isa/formats/blockmem.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 create mode 100644 src/arch/sparc/isa/formats/mem/blockmem.isa create mode 100644 src/arch/sparc/isa/formats/mem/mem.isa create mode 100644 src/arch/sparc/isa/formats/mem/util.isa (limited to 'src/arch') 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/blockmem.isa b/src/arch/sparc/isa/formats/blockmem.isa deleted file mode 100644 index 4a2a14a15..000000000 --- a/src/arch/sparc/isa/formats/blockmem.isa +++ /dev/null @@ -1,370 +0,0 @@ -//////////////////////////////////////////////////////////////////// -// -// 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, OpClass __opClass) : - SparcMacroInst(mnem, _machInst, __opClass, 8) - {} - }; - - class BlockMemImm : public BlockMem - { - protected: - - // Constructor - BlockMemImm(const char *mnem, - ExtMachInst _machInst, OpClass __opClass) : - BlockMem(mnem, _machInst, __opClass), - imm(sext<13>(SIMM13)) - {} - - const int32_t imm; - }; - - 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 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 - */ - 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, %(op_class)s) - { - %(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) -}}; 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/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) +}}; 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) }}; -- cgit v1.2.3