kern,arch: Refactor SkipFuncEvent to not use skipFunction.
authorGabe Black <gabeblack@google.com>
Fri, 27 Dec 2019 00:49:11 +0000 (16:49 -0800)
committerGabe Black <gabeblack@google.com>
Tue, 17 Mar 2020 06:53:00 +0000 (06:53 +0000)
Replace it with a new virtual function.

Change-Id: I9d516d21ab3b1d1d70ea1297f984f868d3e7c3fb
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/24111
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
27 files changed:
src/arch/arm/freebsd/fs_workload.cc
src/arch/arm/freebsd/fs_workload.hh
src/arch/arm/fs_workload.cc
src/arch/arm/fs_workload.hh
src/arch/arm/linux/fs_workload.cc
src/arch/arm/linux/fs_workload.hh
src/arch/arm/utility.cc
src/arch/arm/utility.hh
src/arch/mips/linux/system.cc
src/arch/mips/linux/system.hh
src/arch/mips/system.cc
src/arch/mips/system.hh
src/arch/mips/utility.cc
src/arch/mips/utility.hh
src/arch/power/utility.cc
src/arch/power/utility.hh
src/arch/riscv/utility.hh
src/arch/sparc/utility.cc
src/arch/sparc/utility.hh
src/arch/x86/utility.cc
src/arch/x86/utility.hh
src/kern/freebsd/events.cc
src/kern/freebsd/events.hh
src/kern/linux/events.cc
src/kern/linux/events.hh
src/kern/system_events.cc
src/kern/system_events.hh

index c248ff617394370038f3bab6c13b6228d0d317a3..1792273d0064f46c4101f3c5a293c2ef2511e5ea 100644 (file)
@@ -69,7 +69,7 @@ FsFreebsd::FsFreebsd(Params *p) : ArmISA::FsWorkload(p),
             "oops_exit", "Kernel oops in guest");
     }
 
-    uDelaySkipEvent = addKernelFuncEvent<UDelayEvent>(
+    uDelaySkipEvent = addKernelFuncEvent<UDelayEvent<ArmISA::SkipFunc>>(
         "DELAY", "DELAY", 1000, 0);
 }
 
index 7f0ac083f2352bbffcb4a314fb129bdb0098b5b5..0e767a50cf6b1eeb9af5c2ac9b06dc75453e93cb 100644 (file)
@@ -88,7 +88,7 @@ class FsFreebsd : public ArmISA::FsWorkload
      * processor for the appropriate amount of time. This is not functionally
      * required but does speed up simulation.
      */
-    FreeBSD::UDelayEvent *uDelaySkipEvent = nullptr;
+    FreeBSD::UDelayEvent<SkipFunc> *uDelaySkipEvent = nullptr;
 
     /** These variables store addresses of important data structures
      * that are normaly kept coherent at boot with cache mainetence operations.
index ce9c464fed45bc3e38c3623ae5f74203d0ea85a6..b3dd6b5b815a789f6405d8174a2010a1b7a599a3 100644 (file)
 namespace ArmISA
 {
 
+void
+SkipFunc::returnFromFuncIn(ThreadContext *tc)
+{
+    PCState newPC = tc->pcState();
+    if (inAArch64(tc)) {
+        newPC.set(tc->readIntReg(INTREG_X30));
+    } else {
+        newPC.set(tc->readIntReg(ReturnAddressReg) & ~ULL(1));
+    }
+
+    CheckerCPU *checker = tc->getCheckerCpuPtr();
+    if (checker) {
+        tc->pcStateNoRecord(newPC);
+    } else {
+        tc->pcState(newPC);
+    }
+}
+
 FsWorkload::FsWorkload(Params *p) : OsKernel(*p)
 {
     bootLoaders.reserve(p->boot_loader.size());
index 936ddd7a4099b47db9b825e729653bf76a41931a..5e97bba7a9918cf70626990df8c39b2c23e397fa 100644 (file)
 namespace ArmISA
 {
 
+class SkipFunc : public SkipFuncBase
+{
+  public:
+    using SkipFuncBase::SkipFuncBase;
+    void returnFromFuncIn(ThreadContext *tc) override;
+};
+
 class FsWorkload : public OsKernel
 {
   protected:
index 3f5744b1dcc590e6e3c4dba9f762e1b9cbb153c1..e6058baf895c9d5df5b476d893bd70d2cd3cb56b 100644 (file)
@@ -224,21 +224,23 @@ FsLinux::startup()
 
     // With ARM udelay() is #defined to __udelay
     // newer kernels use __loop_udelay and __loop_const_udelay symbols
-    uDelaySkipEvent = addKernelFuncEvent<UDelayEvent>(
+    uDelaySkipEvent = addKernelFuncEvent<UDelayEvent<SkipFunc>>(
         "__loop_udelay", "__udelay", 1000, 0);
     if (!uDelaySkipEvent)
-        uDelaySkipEvent = addKernelFuncEventOrPanic<UDelayEvent>(
+        uDelaySkipEvent = addKernelFuncEventOrPanic<UDelayEvent<SkipFunc>>(
          "__udelay", "__udelay", 1000, 0);
 
     // constant arguments to udelay() have some precomputation done ahead of
     // time. Constant comes from code.
-    constUDelaySkipEvent = addKernelFuncEvent<UDelayEvent>(
+    constUDelaySkipEvent = addKernelFuncEvent<UDelayEvent<SkipFunc>>(
         "__loop_const_udelay", "__const_udelay", 1000, 107374);
     if (!constUDelaySkipEvent)
-        constUDelaySkipEvent = addKernelFuncEventOrPanic<UDelayEvent>(
+        constUDelaySkipEvent =
+            addKernelFuncEventOrPanic<UDelayEvent<SkipFunc>>(
          "__const_udelay", "__const_udelay", 1000, 107374);
 
-    debugPrintkEvent = addKernelFuncEvent<DebugPrintkEvent>("dprintk");
+    debugPrintkEvent =
+        addKernelFuncEvent<DebugPrintkEvent<SkipFunc>>("dprintk");
 }
 
 void
index aa771c8d91533a9a7edbfb892cac06b033f90579..5a798a84d8f56c00ba92f8ecf6a0db87453cec91 100644 (file)
@@ -63,7 +63,7 @@ class FsLinux : public ArmISA::FsWorkload
      * PC based event to skip the dprink() call and emulate its
      * functionality
      */
-    Linux::DebugPrintkEvent *debugPrintkEvent = nullptr;
+    Linux::DebugPrintkEvent<SkipFunc> *debugPrintkEvent = nullptr;
 
     DumpStatsPCEvent *dumpStatsPCEvent = nullptr;
 
@@ -119,14 +119,14 @@ class FsLinux : public ArmISA::FsWorkload
      * processor for the appropriate amount of time. This is not functionally
      * required but does speed up simulation.
      */
-    Linux::UDelayEvent *uDelaySkipEvent;
+    Linux::UDelayEvent<SkipFunc> *uDelaySkipEvent = nullptr;
 
     /** Another PC based skip event for const_udelay(). Similar to the udelay
      * skip, but this function precomputes the first multiply that is done
      * in the generic case since the parameter is known at compile time.
      * Thus we need to do some division to get back to us.
      */
-    Linux::UDelayEvent *constUDelaySkipEvent;
+    Linux::UDelayEvent<SkipFunc> *constUDelaySkipEvent = nullptr;
 
 };
 
index 8f81a3486a646643681c98c745e2f4fcc323caeb..72b03be992e25dd55610cccd5bdd7aaaadae7a94 100644 (file)
@@ -115,24 +115,6 @@ getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
     panic("getArgument() should always return\n");
 }
 
-void
-skipFunction(ThreadContext *tc)
-{
-    PCState newPC = tc->pcState();
-    if (inAArch64(tc)) {
-        newPC.set(tc->readIntReg(INTREG_X30));
-    } else {
-        newPC.set(tc->readIntReg(ReturnAddressReg) & ~ULL(1));
-    }
-
-    CheckerCPU *checker = tc->getCheckerCpuPtr();
-    if (checker) {
-        tc->pcStateNoRecord(newPC);
-    } else {
-        tc->pcState(newPC);
-    }
-}
-
 static void
 copyVecRegs(ThreadContext *src, ThreadContext *dest)
 {
index 3d64bdd133aa9cb9966a71438efb4b56bc0a19f8..231b8b957d7388d4e26119493ed6120dedc333db 100644 (file)
@@ -389,8 +389,6 @@ bool SPAlignmentCheckEnabled(ThreadContext* tc);
 
 uint64_t getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp);
 
-void skipFunction(ThreadContext *tc);
-
 inline void
 advancePC(PCState &pc, const StaticInstPtr &inst)
 {
index 4afb065c19f639bd555e629eaeca04232d82c55e..e9ba8699f8cd2ebe91087911c59f70234612e79b 100644 (file)
@@ -77,7 +77,7 @@ LinuxMipsSystem::setDelayLoop(ThreadContext *tc)
 void
 LinuxMipsSystem::SkipDelayLoopEvent::process(ThreadContext *tc)
 {
-    SkipFuncEvent::process(tc);
+    MipsISA::SkipFunc::process(tc);
     // calculate and set loops_per_jiffy
     ((LinuxMipsSystem *)tc->getSystemPtr())->setDelayLoop(tc);
 }
index 4d11833919e3a3fbff1bab10c3888bd6d6403627..8aa8ea5c1f8a715f840cedf1e123968620da0f68 100644 (file)
@@ -47,11 +47,13 @@ class IdleStartEvent;
 class LinuxMipsSystem : public MipsSystem
 {
   private:
-    class SkipDelayLoopEvent : public SkipFuncEvent
+    using SkipFunc = MipsISA::SkipFunc;
+
+    class SkipDelayLoopEvent : public SkipFunc
     {
       public:
         SkipDelayLoopEvent(PCEventScope *s, const std::string &desc, Addr addr)
-            : SkipFuncEvent(s, desc, addr) {}
+            : SkipFunc(s, desc, addr) {}
         virtual void process(ThreadContext *tc);
     };
 
index f925cb437f21ee7068acf297ca5c5400e4c429a4..028d570a31b3f3ae0e8753ecb0a692c7a3863a74 100644 (file)
@@ -29,7 +29,8 @@
 
 #include "arch/mips/system.hh"
 
-#include "arch/vtophys.hh"
+#include "arch/mips/registers.hh"
+#include "arch/mips/vtophys.hh"
 #include "base/loader/object_file.hh"
 #include "base/loader/symtab.hh"
 #include "base/trace.hh"
 #include "params/MipsSystem.hh"
 #include "sim/byteswap.hh"
 
+void
+MipsISA::SkipFunc::returnFromFuncIn(ThreadContext *tc)
+{
+    MipsISA::PCState newPC = tc->pcState();
+    newPC.set(tc->readIntReg(MipsISA::ReturnAddressReg));
+    tc->pcState(newPC);
+}
+
 MipsSystem::MipsSystem(Params *p) : System(p)
 {
 }
index f05bd1b525a2514c053aa413c3335c82180272c8..87bf205b61cd45342aed54c1c8581169e6496832 100644 (file)
 #include "sim/sim_object.hh"
 #include "sim/system.hh"
 
+
+namespace MipsISA
+{
+
+class SkipFunc : public SkipFuncBase
+{
+  public:
+    using SkipFuncBase::SkipFuncBase;
+
+    void returnFromFuncIn(ThreadContext *tc) override;
+};
+
+} // namespace MipsaISA
+
 class MipsSystem : public System
 {
   public:
index c65a099b38f025565bf360d0ec9fd4541a8a4fde..d2c964847eb4d02d3f183979e775563fcac94df3 100644 (file)
@@ -242,13 +242,5 @@ copyMiscRegs(ThreadContext *src, ThreadContext *dest)
 {
     panic("Copy Misc. Regs Not Implemented Yet\n");
 }
-void
-skipFunction(ThreadContext *tc)
-{
-    PCState newPC = tc->pcState();
-    newPC.set(tc->readIntReg(ReturnAddressReg));
-    tc->pcState(newPC);
-}
-
 
 } // namespace MipsISA
index b0b1169af5dc139e65b7687f110c3d8d551ceb37..c156c82cc8743793e2583536e01fea8b21787d98 100644 (file)
@@ -102,8 +102,6 @@ RoundPage(Addr addr)
 void copyRegs(ThreadContext *src, ThreadContext *dest);
 void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
 
-void skipFunction(ThreadContext *tc);
-
 inline void
 advancePC(PCState &pc, const StaticInstPtr &inst)
 {
index 991a2720e84b989b775c87fbe09126d2f8af45a4..da4748ddbf8ff0dcc3541ec69fb169e748507d24 100644 (file)
@@ -62,10 +62,4 @@ getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
     return 0;
 }
 
-void
-skipFunction(ThreadContext *tc)
-{
-    panic("Not Implemented for POWER");
-}
-
 } // namespace PowerISA
index b2907aef15039ad7165674ac7078a7fa2ec9e9bc..ba28f07200aea00c6377442e3c6a7c57f93a6746 100644 (file)
@@ -52,8 +52,6 @@ copyMiscRegs(ThreadContext *src, ThreadContext *dest)
 {
 }
 
-void skipFunction(ThreadContext *tc);
-
 inline void
 advancePC(PCState &pc, const StaticInstPtr &inst)
 {
index deec64ec30d47ee6c000e88e260add3d7874dcb6..7dcd5e2fd4ea9440aa44c974dcc0b258ad26feed 100644 (file)
@@ -152,12 +152,6 @@ registerName(RegId reg)
     }
 }
 
-inline void
-skipFunction(ThreadContext *tc)
-{
-    panic("Not Implemented for Riscv");
-}
-
 inline void
 advancePC(PCState &pc, const StaticInstPtr &inst)
 {
index 5f3dae1a59de5e79f69786587e4ca4227eaaaab3..04fa7ad807b7b6d608066718a07c4b5c101a8e46 100644 (file)
@@ -242,12 +242,4 @@ copyRegs(ThreadContext *src, ThreadContext *dest)
     dest->pcState(src->pcState());
 }
 
-void
-skipFunction(ThreadContext *tc)
-{
-    PCState newPC = tc->pcState();
-    newPC.set(tc->readIntReg(ReturnAddressReg));
-    tc->pcState(newPC);
-}
-
 } // namespace SPARC_ISA
index 0a29c6bfcf60b3e313afddca5a63639f21172bf5..4738eb438df0983827f61ccf749d0fc2611d525f 100644 (file)
@@ -64,8 +64,6 @@ void copyRegs(ThreadContext *src, ThreadContext *dest);
 
 void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
 
-void skipFunction(ThreadContext *tc);
-
 inline void
 advancePC(PCState &pc, const StaticInstPtr &inst)
 {
index e88cc7f74e5c6e7322871fb87bd52231ad3b0dfa..33b9371b5636f603796585eb07e6f5a68da5e00c 100644 (file)
@@ -106,12 +106,6 @@ copyRegs(ThreadContext *src, ThreadContext *dest)
     dest->pcState(src->pcState());
 }
 
-void
-skipFunction(ThreadContext *tc)
-{
-    panic("Not implemented for x86\n");
-}
-
 uint64_t
 getRFlags(ThreadContext *tc)
 {
index 02613232767fc6cfd93ab0ca2624316a1177f969..b311eefcdcd167c99efb6f3dc73e114f4da7949e 100644 (file)
@@ -71,8 +71,6 @@ namespace X86ISA
 
     void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
 
-    void skipFunction(ThreadContext *tc);
-
     inline void
     advancePC(PCState &pc, const StaticInstPtr &inst)
     {
index a9e2854db94458e9de1d39b302bdf119f7a15d36..b100860e5614c505725b0f45c760349a137c7554 100644 (file)
@@ -45,7 +45,7 @@
 namespace FreeBSD {
 
 void
-UDelayEvent::process(ThreadContext *tc)
+onUDelay(ThreadContext *tc, uint64_t div, uint64_t mul)
 {
     int arg_num;
 
@@ -57,12 +57,10 @@ UDelayEvent::process(ThreadContext *tc)
     //DPRINTFN("DELAY(%d)\n", time);
 
     // convert parameter to ns
-    if (argDivToNs)
-        time /= argDivToNs;
+    if (div)
+        time /= div;
 
-    time *= argMultToNs;
-
-    SkipFuncEvent::process(tc);
+    time *= mul;
 
     // Currently, only ARM full-system simulation uses UDelayEvents to skip
     // __delay and __loop_delay functions. One form involves setting quiesce
index ebee3e08460586c58d928e098a71bdf1b73753bc..2c548b52daf71d10337c1ac25bf3683b26ea4067 100644 (file)
 
 namespace FreeBSD {
 
+void onUDelay(ThreadContext *tc, uint64_t div, uint64_t mul);
+
 /** A class to skip udelay() and related calls in the kernel.
  * This class has two additional parameters that take the argument to udelay and
  * manipulated it to come up with ns and eventually ticks to quiesce for.
  * See descriptions of argDivToNs and argMultToNs below.
  */
-class UDelayEvent : public SkipFuncEvent
+template <typename Base>
+class UDelayEvent : public Base
 {
   private:
     /** value to divide arg by to create ns. This is present beacues the linux
@@ -59,8 +62,14 @@ class UDelayEvent : public SkipFuncEvent
   public:
     UDelayEvent(PCEventScope *s, const std::string &desc, Addr addr,
             uint64_t mult, uint64_t div)
-        : SkipFuncEvent(s, desc, addr), argDivToNs(div), argMultToNs(mult) {}
-    virtual void process(ThreadContext *xc);
+        : Base(s, desc, addr), argDivToNs(div), argMultToNs(mult) {}
+
+    void
+    process(ThreadContext *tc) override
+    {
+        onUDelay(tc, argDivToNs, argMultToNs);
+        Base::process(tc);
+    }
 };
 
 }
index 3c0cbbf88f42851f36418d37be2a95a92d8e35d7..d548b7279b14c5c0ba85310369e80d13ba90e6ae 100644 (file)
@@ -58,7 +58,7 @@
 namespace Linux {
 
 void
-DebugPrintkEvent::process(ThreadContext *tc)
+onDebugPrintk(ThreadContext *tc)
 {
     if (DTRACE(DebugPrintf)) {
         std::stringstream ss;
@@ -67,38 +67,11 @@ DebugPrintkEvent::process(ThreadContext *tc)
         StringWrap name(tc->getSystemPtr()->name() + ".dprintk");
         DPRINTFN("%s", ss.str());
     }
-    SkipFuncEvent::process(tc);
-}
-
-void
-UDelayEvent::process(ThreadContext *tc)
-{
-    int arg_num  = 0;
-
-    // Get the time in native size
-    uint64_t time = TheISA::getArgument(tc, arg_num,  (uint16_t)-1, false);
-
-    // convert parameter to ns
-    if (argDivToNs)
-        time /= argDivToNs;
-
-    time *= argMultToNs;
-
-    SkipFuncEvent::process(tc);
-
-    // Currently, only ARM full-system simulation uses UDelayEvents to skip
-    // __delay and __loop_delay functions. One form involves setting quiesce
-    // time to 0 with the assumption that quiesce will not happen. To avoid
-    // the quiesce handling in this case, only execute the quiesce if time > 0.
-    if (time > 0)
-        tc->quiesceTick(curTick() + SimClock::Int::ns * time);
 }
 
 void
 DmesgDumpEvent::process(ThreadContext *tc)
 {
-    StringWrap name(tc->getCpuPtr()->name() + ".dmesg_dump_event");
-
     inform("Dumping kernel dmesg buffer to %s...\n", fname);
     OutputStream *os = simout.create(fname);
     dumpDmesg(tc, *os->stream());
@@ -110,8 +83,6 @@ DmesgDumpEvent::process(ThreadContext *tc)
 void
 KernelPanicEvent::process(ThreadContext *tc)
 {
-    StringWrap name(tc->getCpuPtr()->name() + ".dmesg_dump_event");
-
     inform("Dumping kernel dmesg buffer to %s...\n", fname);
     OutputStream *os = simout.create(fname);
     dumpDmesg(tc, *os->stream());
@@ -120,4 +91,26 @@ KernelPanicEvent::process(ThreadContext *tc)
     panic(descr());
 }
 
+void
+onUDelay(ThreadContext *tc, uint64_t div, uint64_t mul)
+{
+    int arg_num = 0;
+
+    // Get the time in native size
+    uint64_t time = TheISA::getArgument(tc, arg_num, (uint16_t)-1, false);
+
+    // convert parameter to ns
+    if (div)
+        time /= div;
+
+    time *= mul;
+
+    // Currently, only ARM full-system simulation uses UDelayEvents to skip
+    // __delay and __loop_delay functions. One form involves setting quiesce
+    // time to 0 with the assumption that quiesce will not happen. To avoid
+    // the quiesce handling in this case, only execute the quiesce if time > 0.
+    if (time > 0)
+        tc->quiesceTick(curTick() + SimClock::Int::ns * time);
+}
+
 } // namespace linux
index ed2df2374d47af7a19744eb7e2491ef9aa9039ce..b16e6ead14d542c32fcd4f6daa8d64e1d966339e 100644 (file)
 
 namespace Linux {
 
-class DebugPrintkEvent : public SkipFuncEvent
+void onDebugPrintk(ThreadContext *tc);
+
+template <typename Base>
+class DebugPrintkEvent : public Base
 {
   public:
     DebugPrintkEvent(PCEventScope *s, const std::string &desc, Addr addr)
-        : SkipFuncEvent(s, desc, addr) {}
-    virtual void process(ThreadContext *xc);
+        : Base(s, desc, addr) {}
+    virtual void
+    process(ThreadContext *tc)
+    {
+        onDebugPrintk(tc);
+        Base::process(tc);
+    }
 };
 
 /**
@@ -70,7 +78,7 @@ class DmesgDumpEvent : public PCEvent
     DmesgDumpEvent(PCEventScope *s, const std::string &desc, Addr addr,
                    const std::string &_fname)
         : PCEvent(s, desc, addr), fname(_fname) {}
-    virtual void process(ThreadContext *xc);
+    virtual void process(ThreadContext *tc);
 };
 
 /**
@@ -90,15 +98,19 @@ class KernelPanicEvent : public PCEvent
     KernelPanicEvent(PCEventScope *s, const std::string &desc, Addr addr,
                const std::string &_fname)
         : PCEvent(s, desc, addr), fname(_fname) {}
-    virtual void process(ThreadContext *xc);
+    virtual void process(ThreadContext *tc);
 };
 
-/** A class to skip udelay() and related calls in the kernel.
- * This class has two additional parameters that take the argument to udelay and
- * manipulated it to come up with ns and eventually ticks to quiesce for.
+void onUDelay(ThreadContext *tc, uint64_t div, uint64_t mul);
+
+/**
+ * A class to skip udelay() and related calls in the kernel.
+ * This class has two additional parameters that take the argument to udelay
+ * and manipulated it to come up with ns and eventually ticks to quiesce for.
  * See descriptions of argDivToNs and argMultToNs below.
  */
-class UDelayEvent : public SkipFuncEvent
+template <typename Base>
+class UDelayEvent : public Base
 {
   private:
     /** value to divide arg by to create ns. This is present beacues the linux
@@ -115,10 +127,15 @@ class UDelayEvent : public SkipFuncEvent
   public:
     UDelayEvent(PCEventScope *s, const std::string &desc, Addr addr,
             uint64_t mult, uint64_t div)
-        : SkipFuncEvent(s, desc, addr), argDivToNs(div), argMultToNs(mult) {}
-    virtual void process(ThreadContext *xc);
-};
+        : Base(s, desc, addr), argDivToNs(div), argMultToNs(mult) {}
 
+    virtual void
+    process(ThreadContext *tc)
+    {
+        onUDelay(tc, argDivToNs, argMultToNs);
+        Base::process(tc);
+    }
+};
 
 }
 
index e865be56c72556a3f281c0ff48660e14e8d7ff68..d97b766bd88c83ffc25e3a05097fa660a91a14ca 100644 (file)
 
 #include "kern/system_events.hh"
 
-#include "arch/utility.hh"
 #include "base/trace.hh"
-#include "config/the_isa.hh"
 #include "cpu/thread_context.hh"
 #include "debug/PCEvent.hh"
 
 void
-SkipFuncEvent::process(ThreadContext *tc)
+SkipFuncBase::process(ThreadContext *tc)
 {
     TheISA::PCState oldPC M5_VAR_USED = tc->pcState();
 
-    // Call ISA specific code to do the skipping
-    TheISA::skipFunction(tc);
+    returnFromFuncIn(tc);
+
     DPRINTF(PCEvent, "skipping %s: pc = %s, newpc = %s\n", description,
             oldPC, tc->pcState());
 }
index 83ed37fb6859cc29314de3df6b85b09738bdfa7c..ecae03c6fe7458789576d8bd41929e2bcea3a4e7 100644 (file)
 
 #include "cpu/pc_event.hh"
 
-class SkipFuncEvent : public PCEvent
+class SkipFuncBase : public PCEvent
 {
+  protected:
+    virtual void returnFromFuncIn(ThreadContext *tc) = 0;
+
   public:
-    SkipFuncEvent(PCEventScope *s, const std::string &desc, Addr addr)
+    SkipFuncBase(PCEventScope *s, const std::string &desc, Addr addr)
         : PCEvent(s, desc, addr)
     {}
+
     void process(ThreadContext *tc) override;
 };