Bring casa and casxa up to date
src/arch/sparc/isa/decoder.isa: Fix up the casa and casxa instructions. src/arch/sparc/isa/formats/formats.isa: This is handled in loadstore.isa now src/arch/sparc/isa/formats/mem/basicmem.isa: src/arch/sparc/isa/formats/mem/blockmem.isa: Renamed doSplitExecute to doDualSplitExecute. This differentiates between the version that does both a register and immediate version, and one that just does a register version. src/arch/sparc/isa/formats/mem/mem.isa: The cas format is handled in loadstore.isa as well now. src/arch/sparc/isa/formats/mem/util.isa: Reorganized things a bit to better support cas --HG-- extra : convert_revision : 12411e89e763287e52f9825bf7a417b263c1037f
This commit is contained in:
parent
ce313a15d5
commit
9adba8d98e
|
@ -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;}});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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)
|
||||
}};
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
}};
|
||||
|
|
Loading…
Reference in a new issue