sparc: Stop using fp_enable_check.
SPARC and MIPS are the only ISAs using this mechanism. This is a step towards making them self sufficient and simplifying the ISA parser, it's interface to the rest of gem5, and it's assumptions about how ISAs are structured. Change-Id: Ied85d5012a806321fd717f654d940171da3450af Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/48717 Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Boris Shingarov <shingarov@labware.com> Maintainer: Gabe Black <gabe.black@gmail.com>
This commit is contained in:
@@ -123,10 +123,9 @@ output exec {{
|
||||
/// @retval Full-system mode: NoFault if FP is enabled, FpDisabled
|
||||
/// if not.
|
||||
static inline Fault
|
||||
checkFpEnableFault(ExecContext *xc)
|
||||
checkFpEnabled(PSTATE pstate, RegVal fprs)
|
||||
{
|
||||
PSTATE pstate = xc->readMiscReg(MISCREG_PSTATE);
|
||||
if (pstate.pef && xc->readMiscReg(MISCREG_FPRS) & 0x4) {
|
||||
if (pstate.pef && fprs & 0x4) {
|
||||
return NoFault;
|
||||
} else {
|
||||
return std::make_shared<FpDisabled>();
|
||||
|
||||
@@ -1258,7 +1258,7 @@ decode OP default Unknown::unknown()
|
||||
}}, MEM_SWAP);
|
||||
|
||||
format Trap {
|
||||
0x20: Load::ldf({{Frds_uw = Mem_uw;}});
|
||||
0x20: Loadf::ldf({{Frds_uw = Mem_uw;}});
|
||||
0x21: decode RD {
|
||||
0x0: Load::ldfsr({{fault = checkFpEnableFault(xc);
|
||||
if (fault)
|
||||
@@ -1271,8 +1271,8 @@ decode OP default Unknown::unknown()
|
||||
default: FailUnimpl::ldfsrOther();
|
||||
}
|
||||
0x22: ldqf({{fault = std::make_shared<FpDisabled>();}});
|
||||
0x23: Load::lddf({{Frd_udw = Mem_udw;}});
|
||||
0x24: Store::stf({{Mem_uw = Frds_uw;}});
|
||||
0x23: Loadf::lddf({{Frd_udw = Mem_udw;}});
|
||||
0x24: Storef::stf({{Mem_uw = Frds_uw;}});
|
||||
0x25: decode RD {
|
||||
0x0: StoreFsr::stfsr({{fault = checkFpEnableFault(xc);
|
||||
if (fault)
|
||||
@@ -1285,11 +1285,11 @@ decode OP default Unknown::unknown()
|
||||
default: FailUnimpl::stfsrOther();
|
||||
}
|
||||
0x26: stqf({{fault = std::make_shared<FpDisabled>();}});
|
||||
0x27: Store::stdf({{Mem_udw = Frd_udw;}});
|
||||
0x27: Storef::stdf({{Mem_udw = Frd_udw;}});
|
||||
0x2D: Nop::prefetch();
|
||||
0x30: LoadAlt::ldfa({{Frds_uw = Mem_uw;}});
|
||||
0x30: LoadfAlt::ldfa({{Frds_uw = Mem_uw;}});
|
||||
0x32: ldqfa({{fault = std::make_shared<FpDisabled>();}});
|
||||
format LoadAlt {
|
||||
format LoadfAlt {
|
||||
0x33: decode EXT_ASI {
|
||||
// ASI_NUCLEUS
|
||||
0x04: FailUnimpl::lddfa_n();
|
||||
@@ -1328,7 +1328,7 @@ decode OP default Unknown::unknown()
|
||||
// ASI_SECONDARY_NO_FAULT_LITTLE
|
||||
0x8B: FailUnimpl::lddfa_snfl();
|
||||
|
||||
format BlockLoad {
|
||||
format BlockLoadf {
|
||||
// LDBLOCKF
|
||||
// ASI_BLOCK_AS_IF_USER_PRIMARY
|
||||
0x16: FailUnimpl::ldblockf_aiup();
|
||||
@@ -1370,9 +1370,9 @@ decode OP default Unknown::unknown()
|
||||
{{fault = std::make_shared<DataAccessException>();}});
|
||||
}
|
||||
}
|
||||
0x34: Store::stfa({{Mem_uw = Frds_uw;}});
|
||||
0x34: Storef::stfa({{Mem_uw = Frds_uw;}});
|
||||
0x36: stqfa({{fault = std::make_shared<FpDisabled>();}});
|
||||
format StoreAlt {
|
||||
format StorefAlt {
|
||||
0x37: decode EXT_ASI {
|
||||
// ASI_NUCLEUS
|
||||
0x04: FailUnimpl::stdfa_n();
|
||||
@@ -1411,7 +1411,7 @@ decode OP default Unknown::unknown()
|
||||
// ASI_SECONDARY_NO_FAULT_LITTLE
|
||||
0x8B: FailUnimpl::stdfa_snfl();
|
||||
|
||||
format BlockStore {
|
||||
format BlockStoref {
|
||||
// STBLOCKF
|
||||
// ASI_BLOCK_AS_IF_USER_PRIMARY
|
||||
0x16: FailUnimpl::stblockf_aiup();
|
||||
|
||||
@@ -104,6 +104,25 @@ Fault
|
||||
{
|
||||
Fault fault = NoFault;
|
||||
|
||||
%(op_decl)s;
|
||||
%(op_rd)s;
|
||||
%(code)s;
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(op_wb)s;
|
||||
}
|
||||
return fault;
|
||||
}
|
||||
}};
|
||||
|
||||
// Basic instruction class execute method template.
|
||||
def template FpExecute {{
|
||||
Fault
|
||||
%(class_name)s::execute(ExecContext *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
Fault fault = NoFault;
|
||||
|
||||
%(fp_enable_check)s;
|
||||
%(op_decl)s;
|
||||
%(op_rd)s;
|
||||
@@ -152,6 +171,10 @@ def format BasicOperate(code, *flags) {{
|
||||
|
||||
}};
|
||||
|
||||
let {{
|
||||
fp_enabled = 'fault = checkFpEnabled(Pstate, Fprs);'
|
||||
}};
|
||||
|
||||
def format FpBasic(code, *flags) {{
|
||||
exec_code = """
|
||||
Fsr |= bits(Fsr, 4, 0) << 5;
|
||||
@@ -181,7 +204,9 @@ def format FpBasic(code, *flags) {{
|
||||
"""
|
||||
fp_code = filterDoubles(code)
|
||||
iop = InstObjParams(name, Name, 'SparcStaticInst',
|
||||
{ "code" : exec_code, "fp_code" : fp_code }, flags)
|
||||
{ "code" : exec_code,
|
||||
"fp_code" : fp_code,
|
||||
"fp_enabled" : fp_enabled }, flags)
|
||||
header_output = FpBasicDeclare.subst(iop)
|
||||
decoder_output = BasicConstructor.subst(iop)
|
||||
decode_block = BasicDecode.subst(iop)
|
||||
|
||||
@@ -83,6 +83,16 @@ def format LoadAlt(code, *opt_flags) {{
|
||||
AlternateASIPrivFaultCheck, name, Name, "EXT_ASI", opt_flags)
|
||||
}};
|
||||
|
||||
def format LoadfAlt(code, *opt_flags) {{
|
||||
code = filterDoubles(code)
|
||||
(header_output,
|
||||
decoder_output,
|
||||
exec_output,
|
||||
decode_block) = doMemFormat(code, LoadFuncs,
|
||||
AlternateASIPrivFaultCheck + fp_enabled, name, Name, "EXT_ASI",
|
||||
opt_flags)
|
||||
}};
|
||||
|
||||
def format StoreAlt(code, *opt_flags) {{
|
||||
code = filterDoubles(code)
|
||||
(header_output,
|
||||
@@ -92,6 +102,16 @@ def format StoreAlt(code, *opt_flags) {{
|
||||
AlternateASIPrivFaultCheck, name, Name, "EXT_ASI", opt_flags)
|
||||
}};
|
||||
|
||||
def format StorefAlt(code, *opt_flags) {{
|
||||
code = filterDoubles(code)
|
||||
(header_output,
|
||||
decoder_output,
|
||||
exec_output,
|
||||
decode_block) = doMemFormat(code, StoreFuncs,
|
||||
AlternateASIPrivFaultCheck + fp_enabled, name, Name, "EXT_ASI",
|
||||
opt_flags)
|
||||
}};
|
||||
|
||||
def format Load(code, *opt_flags) {{
|
||||
code = filterDoubles(code)
|
||||
(header_output,
|
||||
@@ -101,6 +121,15 @@ def format Load(code, *opt_flags) {{
|
||||
LoadFuncs, '', name, Name, 0, opt_flags)
|
||||
}};
|
||||
|
||||
def format Loadf(code, *opt_flags) {{
|
||||
code = filterDoubles(code)
|
||||
(header_output,
|
||||
decoder_output,
|
||||
exec_output,
|
||||
decode_block) = doMemFormat(code,
|
||||
LoadFuncs, fp_enabled, name, Name, 0, opt_flags)
|
||||
}};
|
||||
|
||||
def format Store(code, *opt_flags) {{
|
||||
code = filterDoubles(code)
|
||||
(header_output,
|
||||
@@ -110,6 +139,15 @@ def format Store(code, *opt_flags) {{
|
||||
StoreFuncs, '', name, Name, 0, opt_flags)
|
||||
}};
|
||||
|
||||
def format Storef(code, *opt_flags) {{
|
||||
code = filterDoubles(code)
|
||||
(header_output,
|
||||
decoder_output,
|
||||
exec_output,
|
||||
decode_block) = doMemFormat(code,
|
||||
StoreFuncs, fp_enabled, name, Name, 0, opt_flags)
|
||||
}};
|
||||
|
||||
def format StoreFsr(code, *opt_flags) {{
|
||||
code = filterDoubles(code)
|
||||
(header_output,
|
||||
|
||||
@@ -165,6 +165,20 @@ def format BlockLoad(code, *opt_flags) {{
|
||||
LoadFuncs, name, Name, opt_flags)
|
||||
}};
|
||||
|
||||
def format BlockLoadf(code, *opt_flags) {{
|
||||
code = filterDoubles(code)
|
||||
# We need to make sure to check the highest priority fault last.
|
||||
# That way, if other faults have been detected, they'll be overwritten
|
||||
# rather than the other way around.
|
||||
faultCode = AlternateASIPrivFaultCheck + BlockAlignmentFaultCheck + \
|
||||
fp_enabled
|
||||
(header_output,
|
||||
decoder_output,
|
||||
exec_output,
|
||||
decode_block) = doBlockMemFormat(code, faultCode,
|
||||
LoadFuncs, name, Name, opt_flags)
|
||||
}};
|
||||
|
||||
def format BlockStore(code, *opt_flags) {{
|
||||
code = filterDoubles(code)
|
||||
# We need to make sure to check the highest priority fault last.
|
||||
@@ -177,3 +191,17 @@ def format BlockStore(code, *opt_flags) {{
|
||||
decode_block) = doBlockMemFormat(code, faultCode,
|
||||
StoreFuncs, name, Name, opt_flags)
|
||||
}};
|
||||
|
||||
def format BlockStoref(code, *opt_flags) {{
|
||||
code = filterDoubles(code)
|
||||
# We need to make sure to check the highest priority fault last.
|
||||
# That way, if other faults have been detected, they'll be overwritten
|
||||
# rather than the other way around.
|
||||
faultCode = AlternateASIPrivFaultCheck + BlockAlignmentFaultCheck + \
|
||||
fp_enabled
|
||||
(header_output,
|
||||
decoder_output,
|
||||
exec_output,
|
||||
decode_block) = doBlockMemFormat(code, faultCode,
|
||||
StoreFuncs, name, Name, opt_flags)
|
||||
}};
|
||||
|
||||
@@ -34,7 +34,6 @@ def template SwapExecute {{
|
||||
// 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 = 0;
|
||||
|
||||
@@ -70,7 +69,6 @@ def template SwapInitiateAcc {{
|
||||
{
|
||||
Fault fault = NoFault;
|
||||
Addr EA;
|
||||
%(fp_enable_check)s;
|
||||
uint64_t mem_data = 0;
|
||||
%(op_decl)s;
|
||||
%(op_rd)s;
|
||||
|
||||
@@ -36,7 +36,6 @@ def template LoadExecute {{
|
||||
{
|
||||
Fault fault = NoFault;
|
||||
Addr EA;
|
||||
%(fp_enable_check)s;
|
||||
%(op_decl)s;
|
||||
%(op_rd)s;
|
||||
%(ea_code)s;
|
||||
@@ -64,7 +63,6 @@ def template LoadInitiateAcc {{
|
||||
{
|
||||
Fault fault = NoFault;
|
||||
Addr EA;
|
||||
%(fp_enable_check)s;
|
||||
%(op_decl)s;
|
||||
%(op_rd)s;
|
||||
%(ea_code)s;
|
||||
@@ -104,7 +102,6 @@ def template StoreExecute {{
|
||||
// It should be optomized out in all the others
|
||||
bool storeCond = true;
|
||||
Addr EA;
|
||||
%(fp_enable_check)s;
|
||||
%(op_decl)s;
|
||||
%(op_rd)s;
|
||||
%(ea_code)s;
|
||||
@@ -134,7 +131,6 @@ def template StoreInitiateAcc {{
|
||||
Fault fault = NoFault;
|
||||
bool storeCond = true;
|
||||
Addr EA;
|
||||
%(fp_enable_check)s;
|
||||
%(op_decl)s;
|
||||
|
||||
%(op_rd)s;
|
||||
|
||||
Reference in New Issue
Block a user