diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index aa3b6de6f..a64ff09bb 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -1072,19 +1072,21 @@ decode OP default Unknown::unknown() {{fault = new DataAccessException;}}); } } - 0x3C: Cas::casa({{ - uint64_t val = Mem.uw; - if(Rs2.uw == val) + 0x3C: Cas::casa( + {{uReg0 = Mem.uw;}}, + {{if(Rs2.uw == uReg0) Mem.uw = Rd.uw; - Rd.uw = val; - }}); + else + storeCond = false; + Rd.uw = uReg0;}}); 0x3D: Nop::prefetcha({{ }}); - 0x3E: Cas::casxa({{ - uint64_t val = Mem.udw; - if(Rs2 == val) + 0x3E: Cas::casxa( + {{uReg0 = Mem.udw;}}, + {{if(Rs2 == uReg0) Mem.udw = Rd; - Rd = val; - }}); + else + storeCond = false; + Rd = uReg0;}}); } } } diff --git a/src/arch/sparc/isa/formats/formats.isa b/src/arch/sparc/isa/formats/formats.isa index 5b81a1ab1..8125e6349 100644 --- a/src/arch/sparc/isa/formats/formats.isa +++ b/src/arch/sparc/isa/formats/formats.isa @@ -42,9 +42,6 @@ //Include the memory formats ##include "mem/mem.isa" -//Include the compare and swap format -##include "cas.isa" - //Include the trap format ##include "trap.isa" diff --git a/src/arch/sparc/isa/formats/mem/basicmem.isa b/src/arch/sparc/isa/formats/mem/basicmem.isa index c13194d0f..147767bbc 100644 --- a/src/arch/sparc/isa/formats/mem/basicmem.isa +++ b/src/arch/sparc/isa/formats/mem/basicmem.isa @@ -156,7 +156,7 @@ let {{ 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, + exec_output = doDualSplitExecute(code, addrCalcReg, addrCalcImm, execute, faultCode, name, name + "Imm", Name, Name + "Imm", opt_flags) return (header_output, decoder_output, exec_output, decode_block) }}; diff --git a/src/arch/sparc/isa/formats/mem/blockmem.isa b/src/arch/sparc/isa/formats/mem/blockmem.isa index 93ad1b2b8..4f2f30236 100644 --- a/src/arch/sparc/isa/formats/mem/blockmem.isa +++ b/src/arch/sparc/isa/formats/mem/blockmem.isa @@ -301,7 +301,7 @@ let {{ "set_flags": flag_code}) decoder_output += BlockMemMicroConstructor.subst(iop) decoder_output += BlockMemMicroConstructor.subst(iop_imm) - exec_output += doSplitExecute( + exec_output += doDualSplitExecute( pcedCode, addrCalcReg, addrCalcImm, execute, faultCode, makeMicroName(name, microPc), makeMicroName(name + "Imm", microPc), diff --git a/src/arch/sparc/isa/formats/mem/mem.isa b/src/arch/sparc/isa/formats/mem/mem.isa index 20a22c45d..fedece2b8 100644 --- a/src/arch/sparc/isa/formats/mem/mem.isa +++ b/src/arch/sparc/isa/formats/mem/mem.isa @@ -41,5 +41,5 @@ //Include the block memory format ##include "blockmem.isa" -//Include the load/store memory format +//Include the load/store and cas 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 index 241a25d17..673aee6be 100644 --- a/src/arch/sparc/isa/formats/mem/util.isa +++ b/src/arch/sparc/isa/formats/mem/util.isa @@ -102,6 +102,9 @@ def template StoreExecute {{ { Fault fault = NoFault; uint64_t write_result = 0; + //This is to support the conditional store in cas instructions. + //It should be optomized out in all the others + bool storeCond = true; Addr EA; %(op_decl)s; %(op_rd)s; @@ -112,7 +115,7 @@ def template StoreExecute {{ { %(code)s; } - if(fault == NoFault) + if(storeCond && fault == NoFault) { fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result); } @@ -130,6 +133,7 @@ def template StoreExecute {{ { Fault fault = NoFault; uint64_t write_result = 0; + bool storeCond = true; Addr EA; %(op_decl)s; %(op_rd)s; @@ -140,7 +144,7 @@ def template StoreExecute {{ { %(code)s; } - if(fault == NoFault) + if(storeCond && fault == NoFault) { fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result); } @@ -204,23 +208,29 @@ let {{ //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, + def doSplitExecute(code, eaCode, execute, + faultCode, name, Name, opt_flags): + codeIop = InstObjParams(name, Name, '', code, opt_flags) + eaIop = InstObjParams(name, Name, '', eaCode, + opt_flags, {"fault_check": faultCode}) + iop = InstObjParams(name, Name, '', code, opt_flags, + {"fault_check": faultCode, "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) + return execute.subst(iop) + + + def doDualSplitExecute(code, eaRegCode, eaImmCode, execute, faultCode, 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, {"fault_check": faultCode}) - iop = InstObjParams(name, Name, '', code, opt_flags, - {"fault_check": faultCode, "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) + executeCode += doSplitExecute(code, eaCode, + execute, faultCode, name, Name, opt_flags) return executeCode }};