cpu: Implement a flat register interface in thread contexts
authorAndreas Sandberg <Andreas.Sandberg@ARM.com>
Mon, 7 Jan 2013 18:05:44 +0000 (13:05 -0500)
committerAndreas Sandberg <Andreas.Sandberg@ARM.com>
Mon, 7 Jan 2013 18:05:44 +0000 (13:05 -0500)
Some architectures map registers differently depending on their mode
of operations. There is currently no architecture independent way of
accessing all registers. This patch introduces a flat register
interface to the ThreadContext class. This interface is useful, for
example, when serializing or copying thread contexts.

src/cpu/checker/thread_context.hh
src/cpu/inorder/thread_context.cc
src/cpu/inorder/thread_context.hh
src/cpu/o3/thread_context.hh
src/cpu/o3/thread_context_impl.hh
src/cpu/simple_thread.hh
src/cpu/thread_context.hh

index 967f155728a19939473e2c96b2d36e7664e616ba..80726ff19646241d45811ca870e5ef232a415394 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011 ARM Limited
+ * Copyright (c) 2011-2012 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -302,6 +302,24 @@ class CheckerThreadContext : public ThreadContext
     bool misspeculating() { return actualTC->misspeculating(); }
 
     Counter readFuncExeInst() { return actualTC->readFuncExeInst(); }
+
+    uint64_t readIntRegFlat(int idx)
+    { return actualTC->readIntRegFlat(idx); }
+
+    void setIntRegFlat(int idx, uint64_t val)
+    { actualTC->setIntRegFlat(idx, val); }
+
+    FloatReg readFloatRegFlat(int idx)
+    { return actualTC->readFloatRegFlat(idx); }
+
+    void setFloatRegFlat(int idx, FloatReg val)
+    { actualTC->setFloatRegFlat(idx, val); }
+
+    FloatRegBits readFloatRegBitsFlat(int idx)
+    { return actualTC->readFloatRegBitsFlat(idx); }
+
+    void setFloatRegBitsFlat(int idx, FloatRegBits val)
+    { actualTC->setFloatRegBitsFlat(idx, val); }
 };
 
 #endif // __CPU_CHECKER_EXEC_CONTEXT_HH__
index 6b3375a525436378408d27faed12cfcef3284512..4abfb6ccadda48cf3c9fc2ad5e2fd38aed518bb5 100644 (file)
@@ -1,4 +1,16 @@
 /*
+ * Copyright (c) 2012 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
  * Copyright (c) 2007 MIPS Technologies, Inc.
  * All rights reserved.
  *
@@ -249,3 +261,46 @@ InOrderThreadContext::setMiscReg(int misc_reg, const MiscReg &val)
 {
     cpu->setMiscReg(misc_reg, val, thread->threadId());
 }
+
+
+uint64_t
+InOrderThreadContext::readIntRegFlat(int idx)
+{
+    const ThreadID tid = thread->threadId();
+    return cpu->readIntReg(idx, tid);
+}
+
+void
+InOrderThreadContext::setIntRegFlat(int idx, uint64_t val)
+{
+    const ThreadID tid = thread->threadId();
+    cpu->setIntReg(idx, val, tid);
+}
+
+FloatReg
+InOrderThreadContext::readFloatRegFlat(int idx)
+{
+    const ThreadID tid = thread->threadId();
+    return cpu->readFloatReg(idx, tid);
+}
+
+void
+InOrderThreadContext::setFloatRegFlat(int idx, FloatReg val)
+{
+    const ThreadID tid = thread->threadId();
+    cpu->setFloatReg(idx, val, tid);
+}
+
+FloatRegBits
+InOrderThreadContext::readFloatRegBitsFlat(int idx)
+{
+    const ThreadID tid = thread->threadId();
+    return cpu->readFloatRegBits(idx, tid);
+}
+
+void
+InOrderThreadContext::setFloatRegBitsFlat(int idx, FloatRegBits val)
+{
+    const ThreadID tid = thread->threadId();
+    cpu->setFloatRegBits(idx, val, tid);
+}
index a959d71d6de4853f7bd0a278eefc968e64d10427..2191ac238e5994919d716db741bb1aee93baf2cb 100644 (file)
@@ -1,4 +1,16 @@
 /*
+ * Copyright (c) 2012 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
  * Copyright (c) 2007 MIPS Technologies, Inc.
  * All rights reserved.
  *
@@ -292,6 +304,15 @@ class InOrderThreadContext : public ThreadContext
     void changeRegFileContext(unsigned param,
                                       unsigned val)
     { panic("Not supported!"); }
+
+    uint64_t readIntRegFlat(int idx);
+    void setIntRegFlat(int idx, uint64_t val);
+
+    FloatReg readFloatRegFlat(int idx);
+    void setFloatRegFlat(int idx, FloatReg val);
+
+    FloatRegBits readFloatRegBitsFlat(int idx);
+    void setFloatRegBitsFlat(int idx, FloatRegBits val);
 };
 
 #endif
index c6fa178b5e520512988a439f1fb3352266870585..1efcfff9c4f802c43ed0347732c8c91e217f6377 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011 ARM Limited
+ * Copyright (c) 2011-2012 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -175,18 +175,30 @@ class O3ThreadContext : public ThreadContext
     virtual void clearArchRegs();
 
     /** Reads an integer register. */
-    virtual uint64_t readIntReg(int reg_idx);
+    virtual uint64_t readIntReg(int reg_idx) {
+        return readIntRegFlat(flattenIntIndex(reg_idx));
+    }
 
-    virtual FloatReg readFloatReg(int reg_idx);
+    virtual FloatReg readFloatReg(int reg_idx) {
+        return readFloatRegFlat(flattenFloatIndex(reg_idx));
+    }
 
-    virtual FloatRegBits readFloatRegBits(int reg_idx);
+    virtual FloatRegBits readFloatRegBits(int reg_idx) {
+        return readFloatRegBitsFlat(flattenFloatIndex(reg_idx));
+    }
 
     /** Sets an integer register to a value. */
-    virtual void setIntReg(int reg_idx, uint64_t val);
+    virtual void setIntReg(int reg_idx, uint64_t val) {
+        setIntRegFlat(flattenIntIndex(reg_idx), val);
+    }
 
-    virtual void setFloatReg(int reg_idx, FloatReg val);
+    virtual void setFloatReg(int reg_idx, FloatReg val) {
+        setFloatRegFlat(flattenFloatIndex(reg_idx), val);
+    }
 
-    virtual void setFloatRegBits(int reg_idx, FloatRegBits val);
+    virtual void setFloatRegBits(int reg_idx, FloatRegBits val) {
+        setFloatRegBitsFlat(flattenFloatIndex(reg_idx), val);
+    }
 
     /** Reads this thread's PC state. */
     virtual TheISA::PCState pcState()
@@ -268,6 +280,14 @@ class O3ThreadContext : public ThreadContext
             cpu->squashFromTC(thread->threadId());
     }
 
+    virtual uint64_t readIntRegFlat(int idx);
+    virtual void setIntRegFlat(int idx, uint64_t val);
+
+    virtual FloatReg readFloatRegFlat(int idx);
+    virtual void setFloatRegFlat(int idx, FloatReg val);
+
+    virtual FloatRegBits readFloatRegBitsFlat(int idx);
+    virtual void setFloatRegBitsFlat(int idx, FloatRegBits val);
 };
 
 #endif
index 9d60a97006f345a54d105a6e58c5a3b889b27512..4ab793538933cd55ad011db5d5d580954bd13519 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011 ARM Limited
+ * Copyright (c) 2010-2012 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -224,33 +224,29 @@ O3ThreadContext<Impl>::clearArchRegs()
 
 template <class Impl>
 uint64_t
-O3ThreadContext<Impl>::readIntReg(int reg_idx)
+O3ThreadContext<Impl>::readIntRegFlat(int reg_idx)
 {
-    reg_idx = cpu->isa[thread->threadId()]->flattenIntIndex(reg_idx);
     return cpu->readArchIntReg(reg_idx, thread->threadId());
 }
 
 template <class Impl>
 TheISA::FloatReg
-O3ThreadContext<Impl>::readFloatReg(int reg_idx)
+O3ThreadContext<Impl>::readFloatRegFlat(int reg_idx)
 {
-    reg_idx = cpu->isa[thread->threadId()]->flattenFloatIndex(reg_idx);
     return cpu->readArchFloatReg(reg_idx, thread->threadId());
 }
 
 template <class Impl>
 TheISA::FloatRegBits
-O3ThreadContext<Impl>::readFloatRegBits(int reg_idx)
+O3ThreadContext<Impl>::readFloatRegBitsFlat(int reg_idx)
 {
-    reg_idx = cpu->isa[thread->threadId()]->flattenFloatIndex(reg_idx);
     return cpu->readArchFloatRegInt(reg_idx, thread->threadId());
 }
 
 template <class Impl>
 void
-O3ThreadContext<Impl>::setIntReg(int reg_idx, uint64_t val)
+O3ThreadContext<Impl>::setIntRegFlat(int reg_idx, uint64_t val)
 {
-    reg_idx = cpu->isa[thread->threadId()]->flattenIntIndex(reg_idx);
     cpu->setArchIntReg(reg_idx, val, thread->threadId());
 
     conditionalSquash();
@@ -258,9 +254,8 @@ O3ThreadContext<Impl>::setIntReg(int reg_idx, uint64_t val)
 
 template <class Impl>
 void
-O3ThreadContext<Impl>::setFloatReg(int reg_idx, FloatReg val)
+O3ThreadContext<Impl>::setFloatRegFlat(int reg_idx, FloatReg val)
 {
-    reg_idx = cpu->isa[thread->threadId()]->flattenFloatIndex(reg_idx);
     cpu->setArchFloatReg(reg_idx, val, thread->threadId());
 
     conditionalSquash();
@@ -268,9 +263,8 @@ O3ThreadContext<Impl>::setFloatReg(int reg_idx, FloatReg val)
 
 template <class Impl>
 void
-O3ThreadContext<Impl>::setFloatRegBits(int reg_idx, FloatRegBits val)
+O3ThreadContext<Impl>::setFloatRegBitsFlat(int reg_idx, FloatRegBits val)
 {
-    reg_idx = cpu->isa[thread->threadId()]->flattenFloatIndex(reg_idx);
     cpu->setArchFloatRegInt(reg_idx, val, thread->threadId());
 
     conditionalSquash();
index 8e6df94662eaaef672b656e6bcd6c39707f8627e..33dcdd49df4624f07a4c2991fe3267d4ba50d80a 100644 (file)
@@ -237,7 +237,7 @@ class SimpleThread : public ThreadState
     {
         int flatIndex = isa->flattenIntIndex(reg_idx);
         assert(flatIndex < TheISA::NumIntRegs);
-        uint64_t regVal = intRegs[flatIndex];
+        uint64_t regVal(readIntRegFlat(flatIndex));
         DPRINTF(IntRegs, "Reading int reg %d (%d) as %#x.\n",
                 reg_idx, flatIndex, regVal);
         return regVal;
@@ -247,7 +247,7 @@ class SimpleThread : public ThreadState
     {
         int flatIndex = isa->flattenFloatIndex(reg_idx);
         assert(flatIndex < TheISA::NumFloatRegs);
-        FloatReg regVal = floatRegs.f[flatIndex];
+        FloatReg regVal(readFloatRegFlat(flatIndex));
         DPRINTF(FloatRegs, "Reading float reg %d (%d) as %f, %#x.\n",
                 reg_idx, flatIndex, regVal, floatRegs.i[flatIndex]);
         return regVal;
@@ -257,7 +257,7 @@ class SimpleThread : public ThreadState
     {
         int flatIndex = isa->flattenFloatIndex(reg_idx);
         assert(flatIndex < TheISA::NumFloatRegs);
-        FloatRegBits regVal = floatRegs.i[flatIndex];
+        FloatRegBits regVal(readFloatRegBitsFlat(flatIndex));
         DPRINTF(FloatRegs, "Reading float reg %d (%d) bits as %#x, %f.\n",
                 reg_idx, flatIndex, regVal, floatRegs.f[flatIndex]);
         return regVal;
@@ -269,14 +269,14 @@ class SimpleThread : public ThreadState
         assert(flatIndex < TheISA::NumIntRegs);
         DPRINTF(IntRegs, "Setting int reg %d (%d) to %#x.\n",
                 reg_idx, flatIndex, val);
-        intRegs[flatIndex] = val;
+        setIntRegFlat(flatIndex, val);
     }
 
     void setFloatReg(int reg_idx, FloatReg val)
     {
         int flatIndex = isa->flattenFloatIndex(reg_idx);
         assert(flatIndex < TheISA::NumFloatRegs);
-        floatRegs.f[flatIndex] = val;
+        setFloatRegFlat(flatIndex, val);
         DPRINTF(FloatRegs, "Setting float reg %d (%d) to %f, %#x.\n",
                 reg_idx, flatIndex, val, floatRegs.i[flatIndex]);
     }
@@ -288,7 +288,7 @@ class SimpleThread : public ThreadState
         // XXX: Fix array out of bounds compiler error for gem5.fast
         // when checkercpu enabled
         if (flatIndex < TheISA::NumFloatRegs)
-            floatRegs.i[flatIndex] = val;
+            setFloatRegBitsFlat(flatIndex, val);
         DPRINTF(FloatRegs, "Setting float reg %d (%d) bits to %#x, %#f.\n",
                 reg_idx, flatIndex, val, floatRegs.f[flatIndex]);
     }
@@ -384,6 +384,18 @@ class SimpleThread : public ThreadState
     {
         process->syscall(callnum, tc);
     }
+
+    uint64_t readIntRegFlat(int idx) { return intRegs[idx]; }
+    void setIntRegFlat(int idx, uint64_t val) { intRegs[idx] = val; }
+
+    FloatReg readFloatRegFlat(int idx) { return floatRegs.f[idx]; }
+    void setFloatRegFlat(int idx, FloatReg val) { floatRegs.f[idx] = val; }
+
+    FloatRegBits readFloatRegBitsFlat(int idx) { return floatRegs.i[idx]; }
+    void setFloatRegBitsFlat(int idx, FloatRegBits val) {
+        floatRegs.i[idx] = val;
+    }
+
 };
 
 
index e16bc3b398cd31385a590c41bd8b9c195b549b73..611924371899ea0c1341f650b8ac847fc99c3671 100644 (file)
@@ -264,6 +264,30 @@ class ThreadContext
 
     /** function to compare two thread contexts (for debugging) */
     static void compare(ThreadContext *one, ThreadContext *two);
+
+    /** @{ */
+    /**
+     * Flat register interfaces
+     *
+     * Some architectures have different registers visible in
+     * different modes. Such architectures "flatten" a register (see
+     * flattenIntIndex() and flattenFloatIndex()) to map it into the
+     * gem5 register file. This interface provides a flat interface to
+     * the underlying register file, which allows for example
+     * serialization code to access all registers.
+     */
+
+    virtual uint64_t readIntRegFlat(int idx) = 0;
+    virtual void setIntRegFlat(int idx, uint64_t val) = 0;
+
+    virtual FloatReg readFloatRegFlat(int idx) = 0;
+    virtual void setFloatRegFlat(int idx, FloatReg val) = 0;
+
+    virtual FloatRegBits readFloatRegBitsFlat(int idx) = 0;
+    virtual void setFloatRegBitsFlat(int idx, FloatRegBits val) = 0;
+
+    /** @} */
+
 };
 
 /**
@@ -429,6 +453,24 @@ class ProxyThreadContext : public ThreadContext
     { actualTC->syscall(callnum); }
 
     Counter readFuncExeInst() { return actualTC->readFuncExeInst(); }
+
+    uint64_t readIntRegFlat(int idx)
+    { return actualTC->readIntRegFlat(idx); }
+
+    void setIntRegFlat(int idx, uint64_t val)
+    { actualTC->setIntRegFlat(idx, val); }
+
+    FloatReg readFloatRegFlat(int idx)
+    { return actualTC->readFloatRegFlat(idx); }
+
+    void setFloatRegFlat(int idx, FloatReg val)
+    { actualTC->setFloatRegFlat(idx, val); }
+
+    FloatRegBits readFloatRegBitsFlat(int idx)
+    { return actualTC->readFloatRegBitsFlat(idx); }
+
+    void setFloatRegBitsFlat(int idx, FloatRegBits val)
+    { actualTC->setFloatRegBitsFlat(idx, val); }
 };
 
 #endif