mips: Implement readRegOtherThread and setRegOtherThread directly.
authorGabe Black <gabeblack@google.com>
Sun, 28 Apr 2019 08:22:40 +0000 (08:22 +0000)
committerGabe Black <gabeblack@google.com>
Mon, 29 Apr 2019 22:57:37 +0000 (22:57 +0000)
These accessors can be implemented as helper functions within MIPS
without having to plumb them through a bunch of common interfaces.
There are a few problems with the way they were implemented which are
carried forward to this new implementation as well. That includes
hiding the register accesses from the ISA parser and therefore the
CPU's dependency tracking, potentially panicing or accessing a non
existent thread based on a possible set of input values, and modifying
register values even if an instruction is being executed speculatively.

Fixing these problems would be fairly involved and require changing how
dependencies are tracked in all the CPUs so that they can act across
threads, and also how registers are handled in the ISA description
itself.

The original implementation just punted on making this work in CPUs
other than the minor CPU (and potentially one or more CPU models that
were not and/or are not in the code base). Where as that implementation
might have paniced if these methods were called, this will attempt to
work, but may have incorrect behavior based on the limitations
described above. I'd consider this an acceptable tradeoff, at least for
the time being.

Change-Id: I94adceafb9812a8641c76ea3518c3285c31baf51
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/18435
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Maintainer: Jason Lowe-Power <jason@lowepower.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/arch/mips/isa/decoder.isa
src/arch/mips/isa/formats/mt.isa
src/arch/mips/mt.hh

index 771e6f921ababe589fff3621663acb3a64d06398..3406ed5d2b22e12e5c01f454dec2e377238ece5c 100644 (file)
@@ -383,85 +383,85 @@ decode OPCODE_HI default Unknown::unknown() {
                     // Decode MIPS MT MFTR instruction into sub-instructions
                     0x8: decode MT_U {
                         0x0: mftc0({{
-                            data = xc->readRegOtherThread(RegId(MiscRegClass,
+                            data = readRegOtherThread(xc, RegId(MiscRegClass,
                                                             (RT << 3 | SEL)));
                         }});
                         0x1: decode SEL {
                             0x0: mftgpr({{
-                                data = xc->readRegOtherThread(
+                                data = readRegOtherThread(xc,
                                                     RegId(IntRegClass, RT));
                             }});
                             0x1: decode RT {
                                 0x0: mftlo_dsp0({{
-                                    data = xc->readRegOtherThread(
+                                    data = readRegOtherThread(xc,
                                            RegId(IntRegClass, INTREG_DSP_LO0));
                                 }});
                                 0x1: mfthi_dsp0({{
-                                    data = xc->readRegOtherThread(
+                                    data = readRegOtherThread(xc,
                                            RegId(IntRegClass, INTREG_DSP_HI0));
                                 }});
                                 0x2: mftacx_dsp0({{
-                                    data = xc->readRegOtherThread(
+                                    data = readRegOtherThread(xc,
                                           RegId(IntRegClass, INTREG_DSP_ACX0));
                                 }});
                                 0x4: mftlo_dsp1({{
-                                    data = xc->readRegOtherThread(
+                                    data = readRegOtherThread(xc,
                                            RegId(IntRegClass, INTREG_DSP_LO1));
                                 }});
                                 0x5: mfthi_dsp1({{
-                                    data = xc->readRegOtherThread(
+                                    data = readRegOtherThread(xc,
                                            RegId(IntRegClass, INTREG_DSP_HI1));
                                 }});
                                 0x6: mftacx_dsp1({{
-                                    data = xc->readRegOtherThread(
+                                    data = readRegOtherThread(xc,
                                           RegId(IntRegClass, INTREG_DSP_ACX1));
                                 }});
                                 0x8: mftlo_dsp2({{
-                                    data = xc->readRegOtherThread(
+                                    data = readRegOtherThread(xc,
                                            RegId(IntRegClass, INTREG_DSP_LO2));
                                 }});
                                 0x9: mfthi_dsp2({{
-                                    data = xc->readRegOtherThread(
+                                    data = readRegOtherThread(xc,
                                            RegId(IntRegClass, INTREG_DSP_HI2));
                                 }});
                                 0x10: mftacx_dsp2({{
-                                    data = xc->readRegOtherThread(
+                                    data = readRegOtherThread(xc,
                                           RegId(IntRegClass, INTREG_DSP_ACX2));
                                 }});
                                 0x12: mftlo_dsp3({{
-                                    data = xc->readRegOtherThread(
+                                    data = readRegOtherThread(xc,
                                            RegId(IntRegClass, INTREG_DSP_LO3));
                                 }});
                                 0x13: mfthi_dsp3({{
-                                    data = xc->readRegOtherThread(
+                                    data = readRegOtherThread(xc,
                                            RegId(IntRegClass, INTREG_DSP_HI3));
                                 }});
                                 0x14: mftacx_dsp3({{
-                                    data = xc->readRegOtherThread(
+                                    data = readRegOtherThread(xc,
                                           RegId(IntRegClass, INTREG_DSP_ACX3));
                                 }});
                                 0x16: mftdsp({{
-                                    data = xc->readRegOtherThread(
+                                    data = readRegOtherThread(xc,
                                        RegId(IntRegClass, INTREG_DSP_CONTROL));
                                 }});
                                 default: CP0Unimpl::unknown();
                             }
                             0x2: decode MT_H {
                                 0x0: mftc1({{
-                                    data = xc->readRegOtherThread(
+                                    data = readRegOtherThread(xc,
                                                      RegId(FloatRegClass, RT));
                                 }});
                                 0x1: mfthc1({{
-                                    data = xc->readRegOtherThread(
+                                    data = readRegOtherThread(xc,
                                                      RegId(FloatRegClass, RT));
                                 }});
                             }
                             0x3: cftc1({{
-                                uint32_t fcsr_val = xc->readRegOtherThread(
+                                uint32_t fcsr_val = readRegOtherThread(xc,
                                           RegId(FloatRegClass, FLOATREG_FCSR));
                                 switch (RT) {
                                   case 0:
-                                    data = xc->readRegOtherThread(
+                                    data = readRegOtherThread(xc,
                                             RegId(MiscRegClass, FLOATREG_FIR));
                                     break;
                                   case 25:
@@ -491,62 +491,62 @@ decode OPCODE_HI default Unknown::unknown() {
                 format MT_MTTR {
                     // Decode MIPS MT MTTR instruction into sub-instructions
                     0xC: decode MT_U {
-                        0x0: mttc0({{ xc->setRegOtherThread(
+                        0x0: mttc0({{ setRegOtherThread(xc,
                                      RegId(MiscRegClass, (RD << 3 | SEL)), Rt);
                                    }});
                         0x1: decode SEL {
-                            0x0: mttgpr({{ xc->setRegOtherThread(
+                            0x0: mttgpr({{ setRegOtherThread(xc,
                                                    RegId(IntRegClass, RD), Rt);
                             }});
                             0x1: decode RT {
-                                0x0: mttlo_dsp0({{ xc->setRegOtherThread(
+                                0x0: mttlo_dsp0({{ setRegOtherThread(xc,
                                        RegId(IntRegClass, INTREG_DSP_LO0), Rt);
                                 }});
-                                0x1: mtthi_dsp0({{ xc->setRegOtherThread(
+                                0x1: mtthi_dsp0({{ setRegOtherThread(xc,
                                        RegId(IntRegClass, INTREG_DSP_HI0), Rt);
                                 }});
-                                0x2: mttacx_dsp0({{ xc->setRegOtherThread(
+                                0x2: mttacx_dsp0({{ setRegOtherThread(xc,
                                       RegId(IntRegClass, INTREG_DSP_ACX0), Rt);
                                 }});
-                                0x4: mttlo_dsp1({{ xc->setRegOtherThread(
+                                0x4: mttlo_dsp1({{ setRegOtherThread(xc,
                                        RegId(IntRegClass, INTREG_DSP_LO1), Rt);
                                 }});
-                                0x5: mtthi_dsp1({{ xc->setRegOtherThread(
+                                0x5: mtthi_dsp1({{ setRegOtherThread(xc,
                                        RegId(IntRegClass, INTREG_DSP_HI1), Rt);
                                 }});
-                                0x6: mttacx_dsp1({{ xc->setRegOtherThread(
+                                0x6: mttacx_dsp1({{ setRegOtherThread(xc,
                                       RegId(IntRegClass, INTREG_DSP_ACX1), Rt);
                                 }});
-                                0x8: mttlo_dsp2({{ xc->setRegOtherThread(
+                                0x8: mttlo_dsp2({{ setRegOtherThread(xc,
                                        RegId(IntRegClass, INTREG_DSP_LO2), Rt);
                                 }});
-                                0x9: mtthi_dsp2({{ xc->setRegOtherThread(
+                                0x9: mtthi_dsp2({{ setRegOtherThread(xc,
                                        RegId(IntRegClass, INTREG_DSP_HI2), Rt);
                                 }});
-                                0x10: mttacx_dsp2({{ xc->setRegOtherThread(
+                                0x10: mttacx_dsp2({{ setRegOtherThread(xc,
                                       RegId(IntRegClass, INTREG_DSP_ACX2), Rt);
                                 }});
-                                0x12: mttlo_dsp3({{ xc->setRegOtherThread(
+                                0x12: mttlo_dsp3({{ setRegOtherThread(xc,
                                        RegId(IntRegClass, INTREG_DSP_LO3), Rt);
                                 }});
-                                0x13: mtthi_dsp3({{ xc->setRegOtherThread(
+                                0x13: mtthi_dsp3({{ setRegOtherThread(xc,
                                        RegId(IntRegClass, INTREG_DSP_HI3), Rt);
                                 }});
-                                0x14: mttacx_dsp3({{ xc->setRegOtherThread(
+                                0x14: mttacx_dsp3({{ setRegOtherThread(xc,
                                       RegId(IntRegClass, INTREG_DSP_ACX3), Rt);
                                 }});
-                                0x16: mttdsp({{ xc->setRegOtherThread(
+                                0x16: mttdsp({{ setRegOtherThread(xc,
                                    RegId(IntRegClass, INTREG_DSP_CONTROL), Rt);
                                 }});
                                 default: CP0Unimpl::unknown();
 
                             }
                             0x2: mttc1({{
-                                uint64_t data = xc->readRegOtherThread(
+                                uint64_t data = readRegOtherThread(xc,
                                                      RegId(FloatRegClass, RD));
                                 data = insertBits(data, MT_H ? 63 : 31,
                                                   MT_H ? 32 : 0, Rt);
-                                xc->setRegOtherThread(RegId(FloatRegClass, RD),
+                                setRegOtherThread(xc, RegId(FloatRegClass, RD),
                                                       data);
                             }});
                             0x3: cttc1({{
@@ -583,7 +583,7 @@ decode OPCODE_HI default Unknown::unknown() {
                                             "Access to Floating Control "
                                             "S""tatus Register", FS);
                                 }
-                                xc->setRegOtherThread(
+                                setRegOtherThread(xc,
                                     RegId(FloatRegClass, FLOATREG_FCSR), data);
                             }});
                             default: CP0Unimpl::unknown();
index a68d74ce7438fd0a22a955f5ed7a6e844f6cc8c0..52356ff3290b5a45a64806e692011f5bfeb79656 100644 (file)
@@ -101,7 +101,7 @@ output exec {{
             MVPConf0Reg &mvp_conf0)
     {
         vpe_conf0 = xc->readMiscReg(MISCREG_VPE_CONF0);
-        tc_bind_mt = xc->readRegOtherThread(RegId(MiscRegClass,
+        tc_bind_mt = readRegOtherThread(xc, RegId(MiscRegClass,
                                                   MISCREG_TC_BIND));
         tc_bind = xc->readMiscReg(MISCREG_TC_BIND);
         vpe_control = xc->readMiscReg(MISCREG_VPE_CONTROL);
index 67aeb6477cf245cd921f79d4147fe71af57b894c..378ff591f1ea81e4df8a0e39972ee4ad2cd54fb2 100644 (file)
 #include "base/bitfield.hh"
 #include "base/logging.hh"
 #include "base/trace.hh"
+#include "cpu/exec_context.hh"
 
 namespace MipsISA
 {
 
+static inline RegVal
+readRegOtherThread(ThreadContext *tc, const RegId &reg,
+                   ThreadID tid=InvalidThreadID)
+{
+    ThreadContext *otc = nullptr;
+    if (tid != InvalidThreadID)
+        otc = tc->getCpuPtr()->getContext(tid);
+    else
+        otc = tc;
+
+    switch (reg.classValue()) {
+      case IntRegClass:
+        return otc->readIntReg(reg.index());
+        break;
+      case FloatRegClass:
+        return otc->readFloatReg(reg.index());
+        break;
+      case MiscRegClass:
+        return otc->readMiscReg(reg.index());
+      default:
+        panic("Unexpected reg class! (%s)", reg.className());
+    }
+}
+
+static inline void
+setRegOtherThread(ThreadContext *tc, const RegId& reg, RegVal val,
+                  ThreadID tid=InvalidThreadID)
+{
+    ThreadContext *otc = nullptr;
+    if (tid != InvalidThreadID)
+        otc = tc->getCpuPtr()->getContext(tid);
+    else
+        otc = tc;
+
+    switch (reg.classValue()) {
+      case IntRegClass:
+        return otc->setIntReg(reg.index(), val);
+        break;
+      case FloatRegClass:
+        return otc->setFloatReg(reg.index(), val);
+        break;
+      case MiscRegClass:
+        return otc->setMiscReg(reg.index(), val);
+      default:
+        panic("Unexpected reg class! (%s)", reg.className());
+    }
+}
+
+static inline RegVal
+readRegOtherThread(ExecContext *xc, const RegId &reg,
+                   ThreadID tid=InvalidThreadID)
+{
+    return readRegOtherThread(xc->tcBase(), reg, tid);
+}
+
+static inline void
+setRegOtherThread(ExecContext *xc, const RegId& reg, RegVal val,
+                  ThreadID tid=InvalidThreadID)
+{
+    setRegOtherThread(xc->tcBase(), reg, val, tid);
+}
+
 template <class TC>
 inline unsigned
 getVirtProcNum(TC *tc)
@@ -113,25 +176,25 @@ forkThread(TC *tc, Fault &fault, int Rd_bits, int Rs, int Rt)
     int success = 0;
     for (ThreadID tid = 0; tid < num_threads && success == 0; tid++) {
         TCBindReg tidTCBind =
-            tc->readRegOtherThread(RegId(MiscRegClass, MISCREG_TC_BIND), tid);
+            readRegOtherThread(tc, RegId(MiscRegClass, MISCREG_TC_BIND), tid);
         TCBindReg tcBind = tc->readMiscRegNoEffect(MISCREG_TC_BIND);
 
         if (tidTCBind.curVPE == tcBind.curVPE) {
 
             TCStatusReg tidTCStatus =
-                tc->readRegOtherThread(RegId(MiscRegClass, MISCREG_TC_STATUS),
+                readRegOtherThread(tc, RegId(MiscRegClass, MISCREG_TC_STATUS),
                                        tid);
 
             TCHaltReg tidTCHalt =
-                tc->readRegOtherThread(RegId(MiscRegClass, MISCREG_TC_HALT),
+                readRegOtherThread(tc, RegId(MiscRegClass, MISCREG_TC_HALT),
                                        tid);
 
             if (tidTCStatus.da == 1 && tidTCHalt.h == 0 &&
                 tidTCStatus.a == 0 && success == 0) {
 
-                tc->setRegOtherThread(RegId(MiscRegClass, MISCREG_TC_RESTART),
+                setRegOtherThread(tc, RegId(MiscRegClass, MISCREG_TC_RESTART),
                                       Rs, tid);
-                tc->setRegOtherThread(RegId(IntRegClass, Rd_bits), Rt, tid);
+                setRegOtherThread(tc, RegId(IntRegClass, Rd_bits), Rt, tid);
 
                 StatusReg status = tc->readMiscReg(MISCREG_STATUS);
                 TCStatusReg tcStatus = tc->readMiscReg(MISCREG_TC_STATUS);
@@ -150,7 +213,7 @@ forkThread(TC *tc, Fault &fault, int Rd_bits, int Rs, int Rt)
                 tidTCStatus.asid = tcStatus.asid;
 
                 // Write Status Register
-                tc->setRegOtherThread(RegId(MiscRegClass, MISCREG_TC_STATUS),
+                setRegOtherThread(tc, RegId(MiscRegClass, MISCREG_TC_STATUS),
                                       tidTCStatus, tid);
 
                 // Mark As Successful Fork
@@ -186,13 +249,13 @@ yieldThread(TC *tc, Fault &fault, int src_reg, uint32_t yield_mask)
 
         for (ThreadID tid = 0; tid < num_threads; tid++) {
             TCStatusReg tidTCStatus =
-                tc->readRegOtherThread(RegId(MiscRegClass, MISCREG_TC_STATUS),
+                readRegOtherThread(tc, RegId(MiscRegClass, MISCREG_TC_STATUS),
                                        tid);
             TCHaltReg tidTCHalt =
-                tc->readRegOtherThread(RegId(MiscRegClass, MISCREG_TC_HALT),
+                readRegOtherThread(tc, RegId(MiscRegClass, MISCREG_TC_HALT),
                                        tid);
             TCBindReg tidTCBind =
-                tc->readRegOtherThread(RegId(MiscRegClass, MISCREG_TC_BIND),
+                readRegOtherThread(tc, RegId(MiscRegClass, MISCREG_TC_BIND),
                                        tid);
 
             if (tidTCBind.curVPE == tcBind.curVPE &&