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:
Gabe Black
2021-07-25 02:29:45 -07:00
parent 645c6b3ceb
commit bc1438414a
7 changed files with 104 additions and 20 deletions

View File

@@ -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>();

View File

@@ -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();

View File

@@ -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)

View File

@@ -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,

View File

@@ -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)
}};

View File

@@ -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;

View File

@@ -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;