cpu-minor: Use PCStateBase in the minor CPU DynInst class.

Change-Id: I43d538568d473e27cdbfe6ea77c317b18cfdf18f
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/52047
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: ZHENGRONG WANG <seanyukigeek@gmail.com>
Maintainer: ZHENGRONG WANG <seanyukigeek@gmail.com>
diff --git a/src/cpu/minor/decode.cc b/src/cpu/minor/decode.cc
index ab908e0..e82811f 100644
--- a/src/cpu/minor/decode.cc
+++ b/src/cpu/minor/decode.cc
@@ -115,7 +115,7 @@
 {
     inst->traceData = cpu.getTracer()->getInstRecord(curTick(),
         cpu.getContext(inst->id.threadId),
-        inst->staticInst, inst->pc, static_inst);
+        inst->staticInst, *inst->pc, static_inst);
 
     /* Use the execSeqNum as the fetch sequence number as this most closely
      *  matches the other processor models' idea of fetch sequence */
@@ -176,7 +176,7 @@
 
                     /* Set up PC for the next micro-op emitted */
                     if (!decode_info.inMacroop) {
-                        decode_info.microopPC = inst->pc;
+                        set(decode_info.microopPC, *inst->pc);
                         decode_info.inMacroop = true;
                     }
 
@@ -188,14 +188,15 @@
 
                     output_inst =
                         new MinorDynInst(static_micro_inst, inst->id);
-                    output_inst->pc = decode_info.microopPC;
+                    set(output_inst->pc, decode_info.microopPC);
                     output_inst->fault = NoFault;
 
                     /* Allow a predicted next address only on the last
                      *  microop */
                     if (static_micro_inst->isLastMicroop()) {
                         output_inst->predictedTaken = inst->predictedTaken;
-                        output_inst->predictedTarget = inst->predictedTarget;
+                        set(output_inst->predictedTarget,
+                                inst->predictedTarget);
                     }
 
                     DPRINTF(Decode, "Microop decomposition inputIndex:"
diff --git a/src/cpu/minor/dyn_inst.cc b/src/cpu/minor/dyn_inst.cc
index 5a4ef37..8a07647 100644
--- a/src/cpu/minor/dyn_inst.cc
+++ b/src/cpu/minor/dyn_inst.cc
@@ -120,7 +120,7 @@
 operator <<(std::ostream &os, const MinorDynInst &inst)
 {
     os << inst.id << " pc: 0x"
-        << std::hex << inst.pc.instAddr() << std::dec << " (";
+        << std::hex << inst.pc->instAddr() << std::dec << " (";
 
     if (inst.isFault())
         os << "fault: \"" << inst.fault->name() << '"';
@@ -180,7 +180,7 @@
 {
     if (isFault()) {
         minorInst(named_object, "id=F;%s addr=0x%x fault=\"%s\"\n",
-            id, pc.instAddr(), fault->name());
+            id, pc->instAddr(), fault->name());
     } else {
         unsigned int num_src_regs = staticInst->numSrcRegs();
         unsigned int num_dest_regs = staticInst->numDestRegs();
@@ -222,7 +222,7 @@
 
         minorInst(named_object, "id=%s addr=0x%x inst=\"%s\" class=%s"
             " flags=\"%s\"%s%s\n",
-            id, pc.instAddr(),
+            id, pc->instAddr(),
             (staticInst->opClass() == No_OpClass ?
                 "(invalid)" : staticInst->disassemble(0,NULL)),
             enums::OpClassStrings[staticInst->opClass()],
diff --git a/src/cpu/minor/dyn_inst.hh b/src/cpu/minor/dyn_inst.hh
index d71ccec..96a1649 100644
--- a/src/cpu/minor/dyn_inst.hh
+++ b/src/cpu/minor/dyn_inst.hh
@@ -173,64 +173,64 @@
     InstId id;
 
     /** Trace information for this instruction's execution */
-    Trace::InstRecord *traceData;
+    Trace::InstRecord *traceData = nullptr;
 
     /** The fetch address of this instruction */
-    TheISA::PCState pc;
+    std::unique_ptr<PCStateBase> pc;
 
     /** This is actually a fault masquerading as an instruction */
     Fault fault;
 
     /** Tried to predict the destination of this inst (if a control
      *  instruction or a sys call) */
-    bool triedToPredict;
+    bool triedToPredict = false;
 
     /** This instruction was predicted to change control flow and
      *  the following instructions will have a newer predictionSeqNum */
-    bool predictedTaken;
+    bool predictedTaken = false;
 
     /** Predicted branch target */
-    TheISA::PCState predictedTarget;
+    std::unique_ptr<PCStateBase> predictedTarget;
 
     /** Fields only set during execution */
 
     /** FU this instruction is issued to */
-    unsigned int fuIndex;
+    unsigned int fuIndex = 0;
 
     /** This instruction is in the LSQ, not a functional unit */
-    bool inLSQ;
+    bool inLSQ = false;
 
     /** Translation fault in case of a mem ref */
     Fault translationFault;
 
     /** The instruction has been sent to the store buffer */
-    bool inStoreBuffer;
+    bool inStoreBuffer = false;
 
     /** Can this instruction be executed out of order.  In this model,
      *  this only happens with mem refs that need to be issued early
      *  to allow other instructions to fill the fetch delay */
-    bool canEarlyIssue;
+    bool canEarlyIssue = false;
 
     /** Flag controlling conditional execution of the instruction */
-    bool predicate;
+    bool predicate = true;
 
     /** Flag controlling conditional execution of the memory access associated
      *  with the instruction (only meaningful for loads/stores) */
-    bool memAccPredicate;
+    bool memAccPredicate = true;
 
     /** execSeqNum of the latest inst on which this inst depends.
      *  This can be used as a sanity check for dependency ordering
      *  where slightly out of order execution is required (notably
      *  initiateAcc for memory ops) */
-    InstSeqNum instToWaitFor;
+    InstSeqNum instToWaitFor = 0;
 
     /** Extra delay at the end of the pipeline */
-    Cycles extraCommitDelay;
-    TimingExpr *extraCommitDelayExpr;
+    Cycles extraCommitDelay{0};
+    TimingExpr *extraCommitDelayExpr = nullptr;
 
     /** Once issued, extraCommitDelay becomes minimumCommitCycle
      *  to account for delay in absolute time */
-    Cycles minimumCommitCycle;
+    Cycles minimumCommitCycle{0};
 
     /** Flat register indices so that, when clearing the scoreboard, we
      *  have the same register indices as when the instruction was marked
@@ -239,13 +239,7 @@
 
   public:
     MinorDynInst(StaticInstPtr si, InstId id_=InstId(), Fault fault_=NoFault) :
-        staticInst(si), id(id_), traceData(NULL),
-        pc(TheISA::PCState(0)), fault(fault_),
-        triedToPredict(false), predictedTaken(false),
-        fuIndex(0), inLSQ(false), translationFault(NoFault),
-        inStoreBuffer(false), canEarlyIssue(false), predicate(true),
-        memAccPredicate(true), instToWaitFor(0), extraCommitDelay(Cycles(0)),
-        extraCommitDelayExpr(NULL), minimumCommitCycle(Cycles(0)),
+        staticInst(si), id(id_), fault(fault_), translationFault(NoFault),
         flatDestRegIdx(si ? si->numDestRegs() : 0)
     { }
 
diff --git a/src/cpu/minor/exec_context.hh b/src/cpu/minor/exec_context.hh
index 6d94e47..ba0be03 100644
--- a/src/cpu/minor/exec_context.hh
+++ b/src/cpu/minor/exec_context.hh
@@ -93,8 +93,8 @@
         execute(execute_),
         inst(inst_)
     {
-        DPRINTF(MinorExecute, "ExecContext setting PC: %s\n", inst->pc);
-        pcState(inst->pc);
+        DPRINTF(MinorExecute, "ExecContext setting PC: %s\n", *inst->pc);
+        pcState(inst->pc->as<TheISA::PCState>());
         setPredicate(inst->readPredicate());
         setMemAccPredicate(inst->readMemAccPredicate());
         thread.setIntReg(zeroReg, 0);
diff --git a/src/cpu/minor/execute.cc b/src/cpu/minor/execute.cc
index 3234de5..39a3ba4 100644
--- a/src/cpu/minor/execute.cc
+++ b/src/cpu/minor/execute.cc
@@ -224,7 +224,7 @@
 Execute::tryToBranch(MinorDynInstPtr inst, Fault fault, BranchData &branch)
 {
     ThreadContext *thread = cpu.getContext(inst->id.threadId);
-    const TheISA::PCState &pc_before = inst->pc;
+    const std::unique_ptr<PCStateBase> pc_before(inst->pc->clone());
     TheISA::PCState target = thread->pcState();
 
     /* Force a branch for SerializeAfter/SquashAfter instructions
@@ -236,10 +236,10 @@
          inst->staticInst->isSquashAfter());
 
     DPRINTF(Branch, "tryToBranch before: %s after: %s%s\n",
-        pc_before, target, (force_branch ? " (forcing)" : ""));
+        *pc_before, target, (force_branch ? " (forcing)" : ""));
 
     /* Will we change the PC to something other than the next instruction? */
-    bool must_branch = pc_before != target ||
+    bool must_branch = *pc_before != target ||
         fault != NoFault ||
         force_branch;
 
@@ -251,7 +251,7 @@
         thread->pcState(target);
 
         DPRINTF(Branch, "Advancing current PC from: %s to: %s\n",
-            pc_before, target);
+            *pc_before, target);
     }
 
     if (inst->predictedTaken && !force_branch) {
@@ -261,24 +261,26 @@
              *  intended PC value */
             DPRINTF(Branch, "Predicted a branch from 0x%x to 0x%x but"
                 " none happened inst: %s\n",
-                inst->pc.instAddr(), inst->predictedTarget.instAddr(), *inst);
+                inst->pc->instAddr(), inst->predictedTarget->instAddr(),
+                *inst);
 
             reason = BranchData::BadlyPredictedBranch;
-        } else if (inst->predictedTarget == target) {
+        } else if (*inst->predictedTarget == target) {
             /* Branch prediction got the right target, kill the branch and
              *  carry on.
              *  Note that this information to the branch predictor might get
              *  overwritten by a "real" branch during this cycle */
             DPRINTF(Branch, "Predicted a branch from 0x%x to 0x%x correctly"
                 " inst: %s\n",
-                inst->pc.instAddr(), inst->predictedTarget.instAddr(), *inst);
+                inst->pc->instAddr(), inst->predictedTarget->instAddr(),
+                *inst);
 
             reason = BranchData::CorrectlyPredictedBranch;
         } else {
             /* Branch prediction got the wrong target */
             DPRINTF(Branch, "Predicted a branch from 0x%x to 0x%x"
                     " but got the wrong target (actual: 0x%x) inst: %s\n",
-                    inst->pc.instAddr(), inst->predictedTarget.instAddr(),
+                    inst->pc->instAddr(), inst->predictedTarget->instAddr(),
                     target.instAddr(), *inst);
 
             reason = BranchData::BadlyPredictedBranchTarget;
@@ -286,7 +288,7 @@
     } else if (must_branch) {
         /* Unpredicted branch */
         DPRINTF(Branch, "Unpredicted branch from 0x%x to 0x%x inst: %s\n",
-            inst->pc.instAddr(), target.instAddr(), *inst);
+            inst->pc->instAddr(), target.instAddr(), *inst);
 
         reason = BranchData::UnpredictedBranch;
     } else {
@@ -890,7 +892,7 @@
     if (inst->traceData)
         inst->traceData->setCPSeq(thread->numOp);
 
-    cpu.probeInstCommit(inst->staticInst, inst->pc.instAddr());
+    cpu.probeInstCommit(inst->staticInst, inst->pc->instAddr());
 }
 
 bool
diff --git a/src/cpu/minor/fetch2.cc b/src/cpu/minor/fetch2.cc
index 68c1371..3988132 100644
--- a/src/cpu/minor/fetch2.cc
+++ b/src/cpu/minor/fetch2.cc
@@ -192,26 +192,24 @@
 Fetch2::predictBranch(MinorDynInstPtr inst, BranchData &branch)
 {
     Fetch2ThreadInfo &thread = fetchInfo[inst->id.threadId];
-    TheISA::PCState inst_pc = inst->pc;
 
     assert(!inst->predictedTaken);
 
     /* Skip non-control/sys call instructions */
-    if (inst->staticInst->isControl() ||
-        inst->staticInst->isSyscall())
-    {
+    if (inst->staticInst->isControl() || inst->staticInst->isSyscall()){
+        std::unique_ptr<PCStateBase> inst_pc(inst->pc->clone());
+
         /* Tried to predict */
         inst->triedToPredict = true;
 
         DPRINTF(Branch, "Trying to predict for inst: %s\n", *inst);
 
         if (branchPredictor.predict(inst->staticInst,
-            inst->id.fetchSeqNum, inst_pc,
-            inst->id.threadId))
-        {
+                    inst->id.fetchSeqNum, inst_pc->as<TheISA::PCState>(),
+                    inst->id.threadId)) {
+            set(branch.target, *inst_pc);
             inst->predictedTaken = true;
-            inst->predictedTarget = inst_pc;
-            branch.target = inst_pc;
+            set(inst->predictedTarget, inst_pc);
         }
     } else {
         DPRINTF(Branch, "Not attempting prediction for inst: %s\n", *inst);
@@ -226,7 +224,7 @@
         BranchData new_branch = BranchData(BranchData::BranchPrediction,
             inst->id.threadId,
             inst->id.streamSeqNum, thread.predictionSeqNum + 1,
-            inst->predictedTarget, inst);
+            inst->predictedTarget->as<TheISA::PCState>(), inst);
 
         /* Mark with a new prediction number by the stream number of the
          *  instruction causing the prediction */
@@ -235,7 +233,7 @@
 
         DPRINTF(Branch, "Branch predicted taken inst: %s target: %s"
             " new predictionSeqNum: %d\n",
-            *inst, inst->predictedTarget, thread.predictionSeqNum);
+            *inst, *inst->predictedTarget, thread.predictionSeqNum);
     }
 }
 
@@ -369,7 +367,7 @@
                  *  not been set */
                 assert(dyn_inst->id.execSeqNum == 0);
 
-                dyn_inst->pc = fetch_info.pc;
+                set(dyn_inst->pc, fetch_info.pc);
 
                 /* Pack a faulting instruction but allow other
                  *  instructions to be generated. (Fetch2 makes no
@@ -412,7 +410,7 @@
                      *  has not been set */
                     assert(dyn_inst->id.execSeqNum == 0);
 
-                    dyn_inst->pc = fetch_info.pc;
+                    set(dyn_inst->pc, fetch_info.pc);
                     DPRINTF(Fetch, "decoder inst %s\n", *dyn_inst);
 
                     // Collect some basic inst class stats
diff --git a/src/cpu/minor/lsq.cc b/src/cpu/minor/lsq.cc
index 6c606a6..e4c97ea 100644
--- a/src/cpu/minor/lsq.cc
+++ b/src/cpu/minor/lsq.cc
@@ -1648,7 +1648,7 @@
     request->request->setVirt(
         addr, size, flags, cpu.dataRequestorId(),
         /* I've no idea why we need the PC, but give it */
-        inst->pc.instAddr(), std::move(amo_op));
+        inst->pc->instAddr(), std::move(amo_op));
     request->request->setByteEnable(byte_enable);
 
     requests.push(request);