From bc1438414a1e48395797ffbe2e6b5f54d53249a5 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 25 Jul 2021 02:29:45 -0700 Subject: [PATCH] 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 Reviewed-by: Boris Shingarov Maintainer: Gabe Black --- src/arch/sparc/isa/base.isa | 5 ++- src/arch/sparc/isa/decoder.isa | 20 +++++------ src/arch/sparc/isa/formats/basic.isa | 27 ++++++++++++++- src/arch/sparc/isa/formats/mem/basicmem.isa | 38 +++++++++++++++++++++ src/arch/sparc/isa/formats/mem/blockmem.isa | 28 +++++++++++++++ src/arch/sparc/isa/formats/mem/swap.isa | 2 -- src/arch/sparc/isa/formats/mem/util.isa | 4 --- 7 files changed, 104 insertions(+), 20 deletions(-) diff --git a/src/arch/sparc/isa/base.isa b/src/arch/sparc/isa/base.isa index 9adc5ee9de..8b118f4f0c 100644 --- a/src/arch/sparc/isa/base.isa +++ b/src/arch/sparc/isa/base.isa @@ -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(); diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index 9c85cdf9b1..7296c1a61d 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -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();}}); - 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();}}); - 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();}}); - 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();}}); } } - 0x34: Store::stfa({{Mem_uw = Frds_uw;}}); + 0x34: Storef::stfa({{Mem_uw = Frds_uw;}}); 0x36: stqfa({{fault = std::make_shared();}}); - 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(); diff --git a/src/arch/sparc/isa/formats/basic.isa b/src/arch/sparc/isa/formats/basic.isa index e0441b3237..0d2346dfd0 100644 --- a/src/arch/sparc/isa/formats/basic.isa +++ b/src/arch/sparc/isa/formats/basic.isa @@ -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) diff --git a/src/arch/sparc/isa/formats/mem/basicmem.isa b/src/arch/sparc/isa/formats/mem/basicmem.isa index 03544787f4..83377ae8fe 100644 --- a/src/arch/sparc/isa/formats/mem/basicmem.isa +++ b/src/arch/sparc/isa/formats/mem/basicmem.isa @@ -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, diff --git a/src/arch/sparc/isa/formats/mem/blockmem.isa b/src/arch/sparc/isa/formats/mem/blockmem.isa index fb9cfc4704..3ae08204a4 100644 --- a/src/arch/sparc/isa/formats/mem/blockmem.isa +++ b/src/arch/sparc/isa/formats/mem/blockmem.isa @@ -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) +}}; diff --git a/src/arch/sparc/isa/formats/mem/swap.isa b/src/arch/sparc/isa/formats/mem/swap.isa index ef13385bdf..62348b4f67 100644 --- a/src/arch/sparc/isa/formats/mem/swap.isa +++ b/src/arch/sparc/isa/formats/mem/swap.isa @@ -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; diff --git a/src/arch/sparc/isa/formats/mem/util.isa b/src/arch/sparc/isa/formats/mem/util.isa index da2a4f9a85..82387e2eef 100644 --- a/src/arch/sparc/isa/formats/mem/util.isa +++ b/src/arch/sparc/isa/formats/mem/util.isa @@ -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;