arch: Make the decoder takeOverFrom method virtual.

This is only implemented for x86. It's called very rarely, and so
virtual function overhead is practically irrelevant.

Change-Id: Ib6e05a903df95b801164e44d1662e130419fdbd8
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/52076
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br>
Reviewed-by: Earl Ou <shunhsingou@google.com>
Maintainer: Gabe Black <gabe.black@gmail.com>
diff --git a/src/arch/arm/decoder.hh b/src/arch/arm/decoder.hh
index d2e0c68..ba2cb70 100644
--- a/src/arch/arm/decoder.hh
+++ b/src/arch/arm/decoder.hh
@@ -176,14 +176,6 @@
      */
     StaticInstPtr decode(PCStateBase &pc);
 
-    /**
-     * Take over the state from an old decoder when switching CPUs.
-     *
-     * @param old Decoder used in old CPU
-     */
-    void takeOverFrom(Decoder *old) {}
-
-
   public: // ARM-specific decoder state manipulation
     void
     setContext(FPSCR fpscr)
diff --git a/src/arch/generic/decoder.hh b/src/arch/generic/decoder.hh
index e9ebba8..5033554 100644
--- a/src/arch/generic/decoder.hh
+++ b/src/arch/generic/decoder.hh
@@ -62,6 +62,18 @@
         outOfBytes = true;
     }
 
+    /**
+     * Take over the state from an old decoder when switching CPUs.
+     *
+     * @param old Decoder used in old CPU
+     */
+    virtual void
+    takeOverFrom(InstDecoder *old)
+    {
+        instDone = old->instDone;
+        outOfBytes = old->outOfBytes;
+    }
+
     void *moreBytesPtr() const { return _moreBytesPtr; }
     size_t moreBytesSize() const { return _moreBytesSize; }
     Addr pcMask() const { return _pcMask; }
diff --git a/src/arch/mips/decoder.hh b/src/arch/mips/decoder.hh
index d738767..72b9c69 100644
--- a/src/arch/mips/decoder.hh
+++ b/src/arch/mips/decoder.hh
@@ -64,8 +64,6 @@
         instDone = true;
     }
 
-    void takeOverFrom(Decoder *old) {}
-
   protected:
     /// A cache of decoded instruction objects.
     static GenericISA::BasicDecodeCache<Decoder, ExtMachInst> defaultCache;
diff --git a/src/arch/power/decoder.hh b/src/arch/power/decoder.hh
index dcd1e53..f275ecf 100644
--- a/src/arch/power/decoder.hh
+++ b/src/arch/power/decoder.hh
@@ -61,8 +61,6 @@
         instDone = true;
     }
 
-    void takeOverFrom(Decoder *old) {}
-
   protected:
     /// A cache of decoded instruction objects.
     static GenericISA::BasicDecodeCache<Decoder, ExtMachInst> defaultCache;
diff --git a/src/arch/riscv/decoder.hh b/src/arch/riscv/decoder.hh
index 718e698..a1a893a 100644
--- a/src/arch/riscv/decoder.hh
+++ b/src/arch/riscv/decoder.hh
@@ -75,8 +75,6 @@
     //when there is control flow.
     void moreBytes(const PCStateBase &pc, Addr fetchPC);
 
-    void takeOverFrom(Decoder *old) {}
-
     StaticInstPtr decode(PCStateBase &nextPC);
 };
 
diff --git a/src/arch/sparc/decoder.hh b/src/arch/sparc/decoder.hh
index 31b3014..e6bd817 100644
--- a/src/arch/sparc/decoder.hh
+++ b/src/arch/sparc/decoder.hh
@@ -80,8 +80,6 @@
         asi = _asi;
     }
 
-    void takeOverFrom(Decoder *old) {}
-
   protected:
     /// A cache of decoded instruction objects.
     static GenericISA::BasicDecodeCache<Decoder, ExtMachInst> defaultCache;
diff --git a/src/arch/x86/decoder.hh b/src/arch/x86/decoder.hh
index a965fab..ff136af 100644
--- a/src/arch/x86/decoder.hh
+++ b/src/arch/x86/decoder.hh
@@ -291,17 +291,22 @@
     }
 
     void
-    takeOverFrom(Decoder *old)
+    takeOverFrom(InstDecoder *old) override
     {
-        mode = old->mode;
-        submode = old->submode;
+        InstDecoder::takeOverFrom(old);
+
+        Decoder *dec = dynamic_cast<Decoder *>(old);
+        assert(dec);
+
+        mode = dec->mode;
+        submode = dec->submode;
         emi.mode.mode = mode;
         emi.mode.submode = submode;
-        altOp = old->altOp;
-        defOp = old->defOp;
-        altAddr = old->altAddr;
-        defAddr = old->defAddr;
-        stack = old->stack;
+        altOp = dec->altOp;
+        defOp = dec->defOp;
+        altAddr = dec->altAddr;
+        defAddr = dec->defAddr;
+        stack = dec->stack;
     }
 
     void