diff options
author | Ali Saidi <saidi@eecs.umich.edu> | 2007-02-12 13:06:30 -0500 |
---|---|---|
committer | Ali Saidi <saidi@eecs.umich.edu> | 2007-02-12 13:06:30 -0500 |
commit | b5a4d95811db487d946200bf103e2af376db7690 (patch) | |
tree | 8004993f9ea05c8b78ba34930455fe671dff0e2d /src/arch/sparc/isa/formats | |
parent | 1f834b569c8a39f44882c2f2010a9f0ecffdaab1 (diff) | |
download | gem5-b5a4d95811db487d946200bf103e2af376db7690.tar.xz |
rename store conditional stuff as extra data so it can be used for conditional swaps as well
Add support for a twin 64 bit int load
Add Memory barrier and write barrier flags as appropriate
Make atomic memory ops atomic
src/arch/alpha/isa/mem.isa:
src/arch/alpha/locked_mem.hh:
src/cpu/base_dyn_inst.hh:
src/mem/cache/cache_blk.hh:
src/mem/cache/cache_impl.hh:
rename store conditional stuff as extra data so it can be used for conditional swaps as well
src/arch/alpha/types.hh:
src/arch/mips/types.hh:
src/arch/sparc/types.hh:
add a largest read data type for statically allocating read buffers in atomic simple cpu
src/arch/isa_parser.py:
Add support for a twin 64 bit int load
src/arch/sparc/isa/decoder.isa:
Make atomic memory ops atomic
Add Memory barrier and write barrier flags as appropriate
src/arch/sparc/isa/formats/mem/basicmem.isa:
add post access code block and define a twinload format for twin loads
src/arch/sparc/isa/formats/mem/blockmem.isa:
remove old microcoded twin load coad
src/arch/sparc/isa/formats/mem/mem.isa:
swap.isa replaces the code in loadstore.isa
src/arch/sparc/isa/formats/mem/util.isa:
add a post access code block
src/arch/sparc/isa/includes.isa:
need bigint.hh for Twin64_t
src/arch/sparc/isa/operands.isa:
add a twin 64 int type
src/cpu/simple/atomic.cc:
src/cpu/simple/atomic.hh:
src/cpu/simple/base.hh:
src/cpu/simple/timing.cc:
add support for twinloads
add support for swap and conditional swap instructions
rename store conditional stuff as extra data so it can be used for conditional swaps as well
src/mem/packet.cc:
src/mem/packet.hh:
Add support for atomic swap memory commands
src/mem/packet_access.hh:
Add endian conversion function for Twin64_t type
src/mem/physical.cc:
src/mem/physical.hh:
src/mem/request.hh:
Add support for atomic swap memory commands
Rename sc code to extradata
--HG--
extra : convert_revision : 69d908512fb34a4e28b29a6e58b807fb1a6b1656
Diffstat (limited to 'src/arch/sparc/isa/formats')
-rw-r--r-- | src/arch/sparc/isa/formats/mem/basicmem.isa | 28 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/mem/blockmem.isa | 212 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/mem/mem.isa | 4 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/mem/swap.isa | 183 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/mem/util.isa | 12 |
5 files changed, 211 insertions, 228 deletions
diff --git a/src/arch/sparc/isa/formats/mem/basicmem.isa b/src/arch/sparc/isa/formats/mem/basicmem.isa index 1d9075a57..751262811 100644 --- a/src/arch/sparc/isa/formats/mem/basicmem.isa +++ b/src/arch/sparc/isa/formats/mem/basicmem.isa @@ -1,4 +1,4 @@ -// Copyright (c) 2006 The Regents of The University of Michigan +// Copyright (c) 2006-2007 The Regents of The University of Michigan // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -52,22 +52,20 @@ def template MemDeclare {{ }}; let {{ - def doMemFormat(code, execute, faultCode, name, Name, asi, opt_flags): + def doMemFormat(code, execute, faultCode, name, Name, asi, opt_flags, postacc_code = ''): addrCalcReg = 'EA = Rs1 + Rs2;' addrCalcImm = 'EA = Rs1 + imm;' iop = InstObjParams(name, Name, 'Mem', - {"code": code, "fault_check": faultCode, - "ea_code": addrCalcReg}, - opt_flags) + {"code": code, "postacc_code" : postacc_code, + "fault_check": faultCode, "ea_code": addrCalcReg}, opt_flags) iop_imm = InstObjParams(name, Name + "Imm", 'MemImm', - {"code": code, "fault_check": faultCode, - "ea_code": addrCalcImm}, - opt_flags) + {"code": code, "postacc_code" : postacc_code, + "fault_check": faultCode, "ea_code": addrCalcImm}, opt_flags) 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 = doDualSplitExecute(code, addrCalcReg, addrCalcImm, - execute, faultCode, name, name + "Imm", + exec_output = doDualSplitExecute(code, postacc_code, addrCalcReg, + addrCalcImm, execute, faultCode, name, name + "Imm", Name, Name + "Imm", asi, opt_flags) return (header_output, decoder_output, exec_output, decode_block) }}; @@ -103,3 +101,13 @@ def format Store(code, *opt_flags) {{ decode_block) = doMemFormat(code, StoreFuncs, '', name, Name, 0, opt_flags) }}; + +def format TwinLoad(code, asi, *opt_flags) {{ + (header_output, + decoder_output, + exec_output, + decode_block) = doMemFormat(code, LoadFuncs, + AlternateASIPrivFaultCheck + TwinAlignmentFaultCheck, + name, Name, asi, opt_flags) +}}; + diff --git a/src/arch/sparc/isa/formats/mem/blockmem.isa b/src/arch/sparc/isa/formats/mem/blockmem.isa index 9795d2342..499685a5c 100644 --- a/src/arch/sparc/isa/formats/mem/blockmem.isa +++ b/src/arch/sparc/isa/formats/mem/blockmem.isa @@ -91,65 +91,6 @@ output header {{ }; }}; -output header {{ - - class TwinMem : public SparcMacroInst - { - protected: - - // Constructor - // We make the assumption that all block memory operations - // Will take 8 instructions to execute - TwinMem(const char *mnem, ExtMachInst _machInst) : - SparcMacroInst(mnem, _machInst, No_OpClass, 2) - {} - }; - - class TwinMemImm : public BlockMem - { - protected: - - // Constructor - TwinMemImm(const char *mnem, ExtMachInst _machInst) : - BlockMem(mnem, _machInst) - {} - }; - - class TwinMemMicro : public SparcMicroInst - { - protected: - - // Constructor - TwinMemMicro(const char *mnem, ExtMachInst _machInst, - OpClass __opClass, int8_t _offset) : - SparcMicroInst(mnem, _machInst, __opClass), - offset(_offset) - {} - - std::string generateDisassembly(Addr pc, - const SymbolTable *symtab) const; - - const int8_t offset; - }; - - class TwinMemImmMicro : public BlockMemMicro - { - protected: - - // Constructor - TwinMemImmMicro(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 @@ -208,64 +149,6 @@ output decoder {{ }}; -output decoder {{ - std::string TwinMemMicro::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 TwinMemImmMicro::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 @@ -359,39 +242,6 @@ def template BlockMemDeclare {{ }; }}; -def template TwinMemDeclare {{ - /** - * 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 - %(InitiateAccDeclare)s - %(CompleteAccDeclare)s - }; - - class %(class_name)s_1 : public %(base_class)sMicro - { - public: - //Constructor - %(class_name)s_1(ExtMachInst machInst); - %(BasicExecDeclare)s - %(InitiateAccDeclare)s - %(CompleteAccDeclare)s - }; - }; -}}; - // Basic instruction class constructor template. def template BlockMemConstructor {{ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) @@ -409,17 +259,6 @@ def template BlockMemConstructor {{ } }}; -// Basic instruction class constructor template. -def template TwinMemConstructor {{ - 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); - } -}}; - def template BlockMemMicroConstructor {{ inline %(class_name)s:: %(class_name)s_%(micro_pc)s:: @@ -467,47 +306,7 @@ let {{ decoder_output += BlockMemMicroConstructor.subst(iop) decoder_output += BlockMemMicroConstructor.subst(iop_imm) exec_output += doDualSplitExecute( - pcedCode, addrCalcReg, addrCalcImm, execute, faultCode, - makeMicroName(name, microPc), - makeMicroName(name + "Imm", microPc), - makeMicroName(Name, microPc), - makeMicroName(Name + "Imm", microPc), - asi, opt_flags); - faultCode = '' - return (header_output, decoder_output, exec_output, decode_block) - - def doTwinLoadFormat(code, faultCode, name, Name, asi, opt_flags): - addrCalcReg = 'EA = Rs1 + Rs2 + offset;' - addrCalcImm = 'EA = Rs1 + imm + offset;' - iop = InstObjParams(name, Name, 'TwinMem', code, opt_flags) - iop_imm = InstObjParams(name, Name + 'Imm', 'TwinMemImm', code, opt_flags) - header_output = TwinMemDeclare.subst(iop) + TwinMemDeclare.subst(iop_imm) - decoder_output = TwinMemConstructor.subst(iop) + TwinMemConstructor.subst(iop_imm) - decode_block = ROrImmDecode.subst(iop) - matcher = re.compile(r'RdTwin') - exec_output = '' - for microPc in range(2): - flag_code = '' - pcedCode = '' - if (microPc == 1): - flag_code = "flags[IsLastMicroOp] = true;" - pcedCode = "RdLow = uReg0;\n" - pcedCode += matcher.sub("RdHigh", code) - else: - flag_code = "flags[IsDelayedCommit] = true; flags[IsFirstMicroOp] = true;" - pcedCode = matcher.sub("uReg0", code) - iop = InstObjParams(name, Name, 'TwinMem', - {"code": pcedCode, "ea_code": addrCalcReg, - "fault_check": faultCode, "micro_pc": microPc, - "set_flags": flag_code}, opt_flags) - iop_imm = InstObjParams(name, Name + 'Imm', 'TwinMemImm', - {"code": pcedCode, "ea_code": addrCalcImm, - "fault_check": faultCode, "micro_pc": microPc, - "set_flags": flag_code}, opt_flags) - decoder_output += BlockMemMicroConstructor.subst(iop) - decoder_output += BlockMemMicroConstructor.subst(iop_imm) - exec_output += doDualSplitExecute( - pcedCode, addrCalcReg, addrCalcImm, LoadFuncs, faultCode, + pcedCode, '', addrCalcReg, addrCalcImm, execute, faultCode, makeMicroName(name, microPc), makeMicroName(name + "Imm", microPc), makeMicroName(Name, microPc), @@ -515,7 +314,6 @@ let {{ asi, opt_flags); faultCode = '' return (header_output, decoder_output, exec_output, decode_block) - }}; def format BlockLoad(code, asi, *opt_flags) {{ @@ -541,11 +339,3 @@ def format BlockStore(code, asi, *opt_flags) {{ decode_block) = doBlockMemFormat(code, faultCode, StoreFuncs, name, Name, asi, opt_flags) }}; - -def format TwinLoad(code, asi, *opt_flags) {{ - faultCode = AlternateASIPrivFaultCheck + TwinAlignmentFaultCheck - (header_output, - decoder_output, - exec_output, - decode_block) = doTwinLoadFormat(code, faultCode, name, Name, asi, opt_flags) -}}; diff --git a/src/arch/sparc/isa/formats/mem/mem.isa b/src/arch/sparc/isa/formats/mem/mem.isa index fedece2b8..db45e226d 100644 --- a/src/arch/sparc/isa/formats/mem/mem.isa +++ b/src/arch/sparc/isa/formats/mem/mem.isa @@ -1,4 +1,4 @@ -// Copyright (c) 2006 The Regents of The University of Michigan +// Copyright (c) 2006-2007 The Regents of The University of Michigan // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -42,4 +42,4 @@ ##include "blockmem.isa" //Include the load/store and cas memory format -##include "loadstore.isa" +##include "swap.isa" diff --git a/src/arch/sparc/isa/formats/mem/swap.isa b/src/arch/sparc/isa/formats/mem/swap.isa new file mode 100644 index 000000000..818597a84 --- /dev/null +++ b/src/arch/sparc/isa/formats/mem/swap.isa @@ -0,0 +1,183 @@ +// Copyright (c) 2007 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 +// Ali Saidi + +//This template provides the execute functions for a swap +def template SwapExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Fault fault = NoFault; + //This is to support the conditional store in cas instructions. + //It should be optomized out in all the others + bool storeCond = true; + Addr EA; + %(fp_enable_check)s; + %(op_decl)s; + uint64_t mem_data; + + %(op_rd)s; + %(ea_code)s; + DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA); + %(fault_check)s; + if(fault == NoFault) + { + %(code)s; + } + if(storeCond && fault == NoFault) + { + fault = xc->write((uint%(mem_acc_size)s_t)Mem, + EA, %(asi_val)s, &mem_data); + } + if(fault == NoFault) + { + //Handle the swapping + %(postacc_code)s; + } + if(fault == NoFault) + { + //Write the resulting state to the execution context + %(op_wb)s; + } + + return fault; + } +}}; + + +def template SwapInitiateAcc {{ + Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, + Trace::InstRecord * traceData) const + { + Fault fault = NoFault; + Addr EA; + %(fp_enable_check)s; + uint64_t mem_data = 0; + %(op_decl)s; + %(op_rd)s; + %(ea_code)s; + + DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA); + %(fault_check)s; + + if(fault == NoFault) + { + %(code)s; + } + if(fault == NoFault) + { + fault = xc->write((uint%(mem_acc_size)s_t)Mem, + EA, %(asi_val)s, &mem_data); + } + return fault; + } +}}; + + + +def template SwapCompleteAcc {{ + Fault %(class_name)s::completeAcc(PacketPtr pkt, %(CPU_exec_context)s * xc, + Trace::InstRecord * traceData) const + { + Fault fault = NoFault; + %(op_decl)s; + + uint64_t mem_data = pkt->get<uint%(mem_acc_size)s_t>(); + + if(fault == NoFault) + { + //Handle the swapping + %(postacc_code)s; + } + if(fault == NoFault) + { + //Write the resulting state to the execution context + %(op_wb)s; + } + + return fault; + } +}}; + +let {{ + SwapFuncs = [SwapExecute, SwapInitiateAcc, SwapCompleteAcc] +}}; + + +def format Swap(code, postacc_code, mem_flags, *opt_flags) {{ + mem_flags = makeList(mem_flags) + flags = string.join(mem_flags, '|') + + (header_output, + decoder_output, + exec_output, + decode_block) = doMemFormat(code, SwapFuncs, '', name, Name, flags, + opt_flags, postacc_code) +}}; + +def format SwapAlt(code, postacc_code, asi, mem_flags, *opt_flags) {{ + mem_flags = makeList(mem_flags) + mem_flags.append(asi) + flags = string.join(mem_flags, '|') + (header_output, + decoder_output, + exec_output, + decode_block) = doMemFormat(code, SwapFuncs, AlternateASIPrivFaultCheck, + name, Name, flags, opt_flags, postacc_code) +}}; + + +let {{ + def doCasFormat(code, execute, faultCode, name, Name, asi, opt_flags, postacc_code = ''): + addrCalcReg = 'EA = Rs1;' + iop = InstObjParams(name, Name, 'Mem', + {"code": code, "postacc_code" : postacc_code, + "fault_check": faultCode, "ea_code": addrCalcReg}, opt_flags) + header_output = MemDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + microParams = {"code": code, "postacc_code" : postacc_code, + "ea_code" : addrCalcReg, "fault_check" : faultCode} + exec_output = doSplitExecute(execute, name, Name, asi, opt_flags, + microParams); + return (header_output, decoder_output, exec_output, decode_block) +}}; + + +def format CasAlt(code, postacc_code, asi, mem_flags, *opt_flags) {{ + mem_flags = makeList(mem_flags) + mem_flags.append(asi) + flags = string.join(mem_flags, '|') + (header_output, + decoder_output, + exec_output, + decode_block) = doCasFormat(code, SwapFuncs, AlternateASIPrivFaultCheck, + name, Name, flags, opt_flags, postacc_code) +}}; + + diff --git a/src/arch/sparc/isa/formats/mem/util.isa b/src/arch/sparc/isa/formats/mem/util.isa index dbaabdca4..1d884d6c3 100644 --- a/src/arch/sparc/isa/formats/mem/util.isa +++ b/src/arch/sparc/isa/formats/mem/util.isa @@ -149,7 +149,7 @@ def template LoadExecute {{ %(fault_check)s; if(fault == NoFault) { - fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, %(asi_val)s); + fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, %(asi_val)s); } if(fault == NoFault) { @@ -179,7 +179,7 @@ def template LoadInitiateAcc {{ %(fault_check)s; if(fault == NoFault) { - fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, %(asi_val)s); + fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, %(asi_val)s); } return fault; } @@ -246,6 +246,7 @@ def template StoreInitiateAcc {{ Addr EA; %(fp_enable_check)s; %(op_decl)s; + %(op_rd)s; %(ea_code)s; DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA); @@ -290,6 +291,7 @@ def template CompleteAccDeclare {{ let {{ LoadFuncs = [LoadExecute, LoadInitiateAcc, LoadCompleteAcc] StoreFuncs = [StoreExecute, StoreInitiateAcc, StoreCompleteAcc] + # The LSB can be zero, since it's really the MSB in doubles and quads # and we're dealing with doubles BlockAlignmentFaultCheck = ''' @@ -337,14 +339,14 @@ let {{ return execf.subst(iop) + initf.subst(iop) + compf.subst(iop) - def doDualSplitExecute(code, eaRegCode, eaImmCode, execute, + def doDualSplitExecute(code, postacc_code, eaRegCode, eaImmCode, execute, faultCode, nameReg, nameImm, NameReg, NameImm, asi, opt_flags): executeCode = '' for (eaCode, name, Name) in ( (eaRegCode, nameReg, NameReg), (eaImmCode, nameImm, NameImm)): - microParams = {"code": code, "ea_code": eaCode, - "fault_check": faultCode} + microParams = {"code": code, "postacc_code" : postacc_code, + "ea_code": eaCode, "fault_check": faultCode} executeCode += doSplitExecute(execute, name, Name, asi, opt_flags, microParams) return executeCode |