From b5a4d95811db487d946200bf103e2af376db7690 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Mon, 12 Feb 2007 13:06:30 -0500 Subject: 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 --- src/arch/sparc/isa/decoder.isa | 119 ++++++++++------ src/arch/sparc/isa/formats/mem/basicmem.isa | 28 ++-- src/arch/sparc/isa/formats/mem/blockmem.isa | 212 +--------------------------- src/arch/sparc/isa/formats/mem/mem.isa | 4 +- src/arch/sparc/isa/formats/mem/swap.isa | 183 ++++++++++++++++++++++++ src/arch/sparc/isa/formats/mem/util.isa | 12 +- src/arch/sparc/isa/includes.isa | 1 + src/arch/sparc/isa/operands.isa | 1 + 8 files changed, 286 insertions(+), 274 deletions(-) create mode 100644 src/arch/sparc/isa/formats/mem/swap.isa (limited to 'src/arch/sparc/isa') diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index fb606c7cc..0be7defba 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -472,8 +472,8 @@ decode OP default Unknown::unknown() }}); //7-14 should cause an illegal instruction exception 0x0F: decode I { - 0x0: Nop::stbar({{/*stuff*/}}); - 0x1: Nop::membar({{/*stuff*/}}); + 0x0: Nop::stbar({{/*stuff*/}}, IsWriteBarrier, MemWriteOp); + 0x1: Nop::membar({{/*stuff*/}}, IsMemBarrier, MemReadOp); } 0x10: Priv::rdpcr({{Rd = Pcr;}}); 0x11: PrivCheck::rdpic({{Rd = Pic;}}, {{Pcr<0:>}}); @@ -1168,15 +1168,17 @@ decode OP default Unknown::unknown() 0x0A: ldsh({{Rd = (int16_t)Mem.shw;}}); 0x0B: ldx({{Rd = (int64_t)Mem.sdw;}}); } - 0x0D: LoadStore::ldstub( - {{uReg0 = Mem.ub;}}, - {{Rd.ub = uReg0; - Mem.ub = 0xFF;}}); + 0x0D: Swap::ldstub({{Mem.ub = 0xFF;}}, + {{ + uint8_t tmp = mem_data; + Rd.ub = tmp; + }}, MEM_SWAP); 0x0E: Store::stx({{Mem.udw = Rd}}); - 0x0F: LoadStore::swap( - {{ uReg0 = Mem.uw}}, - {{ Mem.uw = Rd.uw; - Rd.uw = uReg0;}}); + 0x0F: Swap::swap({{Mem.uw = Rd.uw}}, + {{ + uint32_t tmp = mem_data; + Rd.uw = tmp; + }}, MEM_SWAP); format LoadAlt { 0x10: lduwa({{Rd = Mem.uw;}}, {{EXT_ASI}}); 0x11: lduba({{Rd = Mem.ub;}}, {{EXT_ASI}}); @@ -1184,34 +1186,60 @@ decode OP default Unknown::unknown() 0x13: decode EXT_ASI { //ASI_LDTD_AIUP 0x22: TwinLoad::ldtx_aiup( - {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}}); + {{RdLow.udw = (Mem.tudw).a; + RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); //ASI_LDTD_AIUS 0x23: TwinLoad::ldtx_aius( - {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}}); + {{RdLow.udw = (Mem.tudw).a; + RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); //ASI_QUAD_LDD 0x24: TwinLoad::ldtx_quad_ldd( - {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}}); + {{RdLow.udw = (Mem.tudw).a; + RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); //ASI_LDTX_REAL 0x26: TwinLoad::ldtx_real( - {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}}); - //ASI_LDTX_N - 0x27: TwinLoad::ldtx_n( - {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}}); - //ASI_LDTX_L - 0x2C: TwinLoad::ldtx_l( - {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}}); + {{RdLow.udw = (Mem.tudw).a; + RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); + //ASI_LDTX_N + 0x27: TwinLoad::ldtx_n( + {{RdLow.udw = (Mem.tudw).a; + RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); + //ASI_LDTX_AIUP_L + 0x2A: TwinLoad::ldtx_aiup_l( + {{RdLow.udw = (Mem.tudw).a; + RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); + //ASI_LDTX_AIUS_L + 0x2B: TwinLoad::ldtx_aius_l( + {{RdLow.udw = (Mem.tudw).a; + RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); + //ASI_LDTX_L + 0x2C: TwinLoad::ldtx_l( + {{RdLow.udw = (Mem.tudw).a; + RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); //ASI_LDTX_REAL_L 0x2E: TwinLoad::ldtx_real_l( - {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}}); + {{RdLow.udw = (Mem.tudw).a; + RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); //ASI_LDTX_N_L 0x2F: TwinLoad::ldtx_n_l( - {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}}); + {{RdLow.udw = (Mem.tudw).a; + RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); //ASI_LDTX_P 0xE2: TwinLoad::ldtx_p( - {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}}); + {{RdLow.udw = (Mem.tudw).a; + RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); //ASI_LDTX_S 0xE3: TwinLoad::ldtx_s( - {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}}); + {{RdLow.udw = (Mem.tudw).a; + RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); + //ASI_LDTX_PL + 0xEA: TwinLoad::ldtx_pl( + {{RdLow.udw = (Mem.tudw).a; + RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); + //ASI_LDTX_SL + 0xEB: TwinLoad::ldtx_sl( + {{RdLow.udw = (Mem.tudw).a; + RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); default: ldtwa({{ uint64_t val = Mem.udw; RdLow = val<31:0>; @@ -1231,15 +1259,18 @@ decode OP default Unknown::unknown() 0x1A: ldsha({{Rd = (int16_t)Mem.shw;}}, {{EXT_ASI}}); 0x1B: ldxa({{Rd = (int64_t)Mem.sdw;}}, {{EXT_ASI}}); } - 0x1D: LoadStoreAlt::ldstuba( - {{uReg0 = Mem.ub;}}, - {{Rd.ub = uReg0; - Mem.ub = 0xFF;}}, {{EXT_ASI}}); + 0x1D: SwapAlt::ldstuba({{Mem.ub = 0xFF;}}, + {{ + uint8_t tmp = mem_data; + Rd.ub = tmp; + }}, {{EXT_ASI}}, MEM_SWAP); 0x1E: StoreAlt::stxa({{Mem.udw = Rd}}, {{EXT_ASI}}); - 0x1F: LoadStoreAlt::swapa( - {{ uReg0 = Mem.uw}}, - {{ Mem.uw = Rd.uw; - Rd.uw = uReg0;}}, {{EXT_ASI}}); + 0x1F: SwapAlt::swapa({{Mem.uw = Rd.uw}}, + {{ + uint32_t tmp = mem_data; + Rd.uw = tmp; + }}, {{EXT_ASI}}, MEM_SWAP); + format Trap { 0x20: Load::ldf({{Frds.uw = Mem.uw;}}); 0x21: decode RD { @@ -1438,21 +1469,17 @@ decode OP default Unknown::unknown() {{fault = new DataAccessException;}}); } } - 0x3C: Cas::casa( - {{uReg0 = Mem.uw;}}, - {{if(Rs2.uw == uReg0) - Mem.uw = Rd.uw; - else - storeCond = false; - Rd.uw = uReg0;}}, {{EXT_ASI}}); + 0x3C: CasAlt::casa({{ + mem_data = htog(Rs2.uw); + Mem.uw = Rd.uw;}}, + {{ + uint32_t tmp = mem_data; + Rd.uw = tmp; + }}, {{EXT_ASI}}, MEM_SWAP_COND); 0x3D: Nop::prefetcha({{ }}); - 0x3E: Cas::casxa( - {{uReg0 = Mem.udw;}}, - {{if(Rs2 == uReg0) - Mem.udw = Rd; - else - storeCond = false; - Rd = uReg0;}}, {{EXT_ASI}}); + 0x3E: CasAlt::casxa({{mem_data = gtoh(Rs2); + Mem.udw = Rd.udw; }}, + {{ Rd.udw = mem_data; }}, {{EXT_ASI}}, MEM_SWAP_COND); } } } 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(); + + 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 diff --git a/src/arch/sparc/isa/includes.isa b/src/arch/sparc/isa/includes.isa index d2ef67154..b46ef011e 100644 --- a/src/arch/sparc/isa/includes.isa +++ b/src/arch/sparc/isa/includes.isa @@ -74,6 +74,7 @@ output exec {{ #include #include "arch/sparc/asi.hh" +#include "base/bigint.hh" #include "cpu/base.hh" #include "cpu/exetrace.hh" #include "sim/sim_exit.hh" diff --git a/src/arch/sparc/isa/operands.isa b/src/arch/sparc/isa/operands.isa index 140055010..f624c3e2b 100644 --- a/src/arch/sparc/isa/operands.isa +++ b/src/arch/sparc/isa/operands.isa @@ -37,6 +37,7 @@ def operand_types {{ 'uw' : ('unsigned int', 32), 'sdw' : ('signed int', 64), 'udw' : ('unsigned int', 64), + 'tudw' : ('twin int', 64), 'sf' : ('float', 32), 'df' : ('float', 64), 'qf' : ('float', 128) -- cgit v1.2.3