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
6 changed files with 40 additions and 31 deletions
|
@ -1072,19 +1072,21 @@ decode OP default Unknown::unknown()
|
||||||
{{fault = new DataAccessException;}});
|
{{fault = new DataAccessException;}});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
0x3C: Cas::casa({{
|
0x3C: Cas::casa(
|
||||||
uint64_t val = Mem.uw;
|
{{uReg0 = Mem.uw;}},
|
||||||
if(Rs2.uw == val)
|
{{if(Rs2.uw == uReg0)
|
||||||
Mem.uw = Rd.uw;
|
Mem.uw = Rd.uw;
|
||||||
Rd.uw = val;
|
else
|
||||||
}});
|
storeCond = false;
|
||||||
|
Rd.uw = uReg0;}});
|
||||||
0x3D: Nop::prefetcha({{ }});
|
0x3D: Nop::prefetcha({{ }});
|
||||||
0x3E: Cas::casxa({{
|
0x3E: Cas::casxa(
|
||||||
uint64_t val = Mem.udw;
|
{{uReg0 = Mem.udw;}},
|
||||||
if(Rs2 == val)
|
{{if(Rs2 == uReg0)
|
||||||
Mem.udw = Rd;
|
Mem.udw = Rd;
|
||||||
Rd = val;
|
else
|
||||||
}});
|
storeCond = false;
|
||||||
|
Rd = uReg0;}});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,9 +42,6 @@
|
||||||
//Include the memory formats
|
//Include the memory formats
|
||||||
##include "mem/mem.isa"
|
##include "mem/mem.isa"
|
||||||
|
|
||||||
//Include the compare and swap format
|
|
||||||
##include "cas.isa"
|
|
||||||
|
|
||||||
//Include the trap format
|
//Include the trap format
|
||||||
##include "trap.isa"
|
##include "trap.isa"
|
||||||
|
|
||||||
|
|
|
@ -156,7 +156,7 @@ let {{
|
||||||
header_output = MemDeclare.subst(iop) + MemDeclare.subst(iop_imm)
|
header_output = MemDeclare.subst(iop) + MemDeclare.subst(iop_imm)
|
||||||
decoder_output = BasicConstructor.subst(iop) + BasicConstructor.subst(iop_imm)
|
decoder_output = BasicConstructor.subst(iop) + BasicConstructor.subst(iop_imm)
|
||||||
decode_block = ROrImmDecode.subst(iop)
|
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)
|
faultCode, name, name + "Imm", Name, Name + "Imm", opt_flags)
|
||||||
return (header_output, decoder_output, exec_output, decode_block)
|
return (header_output, decoder_output, exec_output, decode_block)
|
||||||
}};
|
}};
|
||||||
|
|
|
@ -301,7 +301,7 @@ let {{
|
||||||
"set_flags": flag_code})
|
"set_flags": flag_code})
|
||||||
decoder_output += BlockMemMicroConstructor.subst(iop)
|
decoder_output += BlockMemMicroConstructor.subst(iop)
|
||||||
decoder_output += BlockMemMicroConstructor.subst(iop_imm)
|
decoder_output += BlockMemMicroConstructor.subst(iop_imm)
|
||||||
exec_output += doSplitExecute(
|
exec_output += doDualSplitExecute(
|
||||||
pcedCode, addrCalcReg, addrCalcImm, execute, faultCode,
|
pcedCode, addrCalcReg, addrCalcImm, execute, faultCode,
|
||||||
makeMicroName(name, microPc),
|
makeMicroName(name, microPc),
|
||||||
makeMicroName(name + "Imm", microPc),
|
makeMicroName(name + "Imm", microPc),
|
||||||
|
|
|
@ -41,5 +41,5 @@
|
||||||
//Include the block memory format
|
//Include the block memory format
|
||||||
##include "blockmem.isa"
|
##include "blockmem.isa"
|
||||||
|
|
||||||
//Include the load/store memory format
|
//Include the load/store and cas memory format
|
||||||
##include "loadstore.isa"
|
##include "loadstore.isa"
|
||||||
|
|
|
@ -102,6 +102,9 @@ def template StoreExecute {{
|
||||||
{
|
{
|
||||||
Fault fault = NoFault;
|
Fault fault = NoFault;
|
||||||
uint64_t write_result = 0;
|
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;
|
Addr EA;
|
||||||
%(op_decl)s;
|
%(op_decl)s;
|
||||||
%(op_rd)s;
|
%(op_rd)s;
|
||||||
|
@ -112,7 +115,7 @@ def template StoreExecute {{
|
||||||
{
|
{
|
||||||
%(code)s;
|
%(code)s;
|
||||||
}
|
}
|
||||||
if(fault == NoFault)
|
if(storeCond && fault == NoFault)
|
||||||
{
|
{
|
||||||
fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result);
|
fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result);
|
||||||
}
|
}
|
||||||
|
@ -130,6 +133,7 @@ def template StoreExecute {{
|
||||||
{
|
{
|
||||||
Fault fault = NoFault;
|
Fault fault = NoFault;
|
||||||
uint64_t write_result = 0;
|
uint64_t write_result = 0;
|
||||||
|
bool storeCond = true;
|
||||||
Addr EA;
|
Addr EA;
|
||||||
%(op_decl)s;
|
%(op_decl)s;
|
||||||
%(op_rd)s;
|
%(op_rd)s;
|
||||||
|
@ -140,7 +144,7 @@ def template StoreExecute {{
|
||||||
{
|
{
|
||||||
%(code)s;
|
%(code)s;
|
||||||
}
|
}
|
||||||
if(fault == NoFault)
|
if(storeCond && fault == NoFault)
|
||||||
{
|
{
|
||||||
fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result);
|
fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result);
|
||||||
}
|
}
|
||||||
|
@ -204,13 +208,9 @@ let {{
|
||||||
//and in the other they're distributed across two. Also note that for
|
//and in the other they're distributed across two. Also note that for
|
||||||
//execute functions, the name of the base class doesn't matter.
|
//execute functions, the name of the base class doesn't matter.
|
||||||
let {{
|
let {{
|
||||||
def doSplitExecute(code, eaRegCode, eaImmCode, execute,
|
def doSplitExecute(code, eaCode, execute,
|
||||||
faultCode, nameReg, nameImm, NameReg, NameImm, opt_flags):
|
faultCode, name, Name, opt_flags):
|
||||||
codeIop = InstObjParams(nameReg, NameReg, '', code, opt_flags)
|
codeIop = InstObjParams(name, Name, '', code, opt_flags)
|
||||||
executeCode = ''
|
|
||||||
for (eaCode, name, Name) in (
|
|
||||||
(eaRegCode, nameReg, NameReg),
|
|
||||||
(eaImmCode, nameImm, NameImm)):
|
|
||||||
eaIop = InstObjParams(name, Name, '', eaCode,
|
eaIop = InstObjParams(name, Name, '', eaCode,
|
||||||
opt_flags, {"fault_check": faultCode})
|
opt_flags, {"fault_check": faultCode})
|
||||||
iop = InstObjParams(name, Name, '', code, opt_flags,
|
iop = InstObjParams(name, Name, '', code, opt_flags,
|
||||||
|
@ -221,6 +221,16 @@ let {{
|
||||||
(iop.code_decl,
|
(iop.code_decl,
|
||||||
iop.code_rd,
|
iop.code_rd,
|
||||||
iop.code_wb) = (codeIop.op_decl, codeIop.op_rd, codeIop.op_wb)
|
iop.code_wb) = (codeIop.op_decl, codeIop.op_rd, codeIop.op_wb)
|
||||||
executeCode += execute.subst(iop)
|
return execute.subst(iop)
|
||||||
|
|
||||||
|
|
||||||
|
def doDualSplitExecute(code, eaRegCode, eaImmCode, execute,
|
||||||
|
faultCode, nameReg, nameImm, NameReg, NameImm, opt_flags):
|
||||||
|
executeCode = ''
|
||||||
|
for (eaCode, name, Name) in (
|
||||||
|
(eaRegCode, nameReg, NameReg),
|
||||||
|
(eaImmCode, nameImm, NameImm)):
|
||||||
|
executeCode += doSplitExecute(code, eaCode,
|
||||||
|
execute, faultCode, name, Name, opt_flags)
|
||||||
return executeCode
|
return executeCode
|
||||||
}};
|
}};
|
||||||
|
|
Loading…
Reference in a new issue