summaryrefslogtreecommitdiff
path: root/src/arch/sparc/isa
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/sparc/isa')
-rw-r--r--src/arch/sparc/isa/decoder.isa22
-rw-r--r--src/arch/sparc/isa/formats/formats.isa3
-rw-r--r--src/arch/sparc/isa/formats/mem/basicmem.isa2
-rw-r--r--src/arch/sparc/isa/formats/mem/blockmem.isa2
-rw-r--r--src/arch/sparc/isa/formats/mem/mem.isa2
-rw-r--r--src/arch/sparc/isa/formats/mem/util.isa40
6 files changed, 40 insertions, 31 deletions
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
}};