X86: Put in the foundation for x87 stack based fp registers.
authorGabe Black <gblack@eecs.umich.edu>
Thu, 20 Sep 2007 01:26:42 +0000 (18:26 -0700)
committerGabe Black <gblack@eecs.umich.edu>
Thu, 20 Sep 2007 01:26:42 +0000 (18:26 -0700)
--HG--
extra : convert_revision : 940f92efd4a9dc59106e991cc6d9836861ab69de

14 files changed:
src/arch/alpha/regfile.hh
src/arch/mips/regfile/regfile.hh
src/arch/sparc/regfile.hh
src/arch/x86/floatregfile.hh
src/arch/x86/floatregs.hh
src/arch/x86/isa/microasm.isa
src/arch/x86/isa/operands.isa
src/arch/x86/isa_traits.hh
src/arch/x86/miscregs.hh
src/arch/x86/regfile.cc
src/arch/x86/regfile.hh
src/cpu/o3/rename_impl.hh
src/cpu/o3/thread_context_impl.hh
src/cpu/simple_thread.hh

index b9370718154eab7752112df3f721d85a0945e547..792a518fb822db0421a961467bd9cd5fbccbc66b 100644 (file)
@@ -192,6 +192,11 @@ namespace AlphaISA
         return reg;
     }
 
+    static inline int flattenFloatIndex(ThreadContext * tc, int reg)
+    {
+        return reg;
+    }
+
     void copyRegs(ThreadContext *src, ThreadContext *dest);
 
     void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
index b83bb576ba67566bcdc71db1197a43910fec6c44..4be8d399c09da5f0d10489700fe745c7d5ae5b00 100644 (file)
@@ -187,6 +187,11 @@ namespace MipsISA
         return reg;
     }
 
+    static inline int flattenFloatIndex(ThreadContext * tc, int reg)
+    {
+        return reg;
+    }
+
     void
     copyRegs(ThreadContext *src, ThreadContext *dest);
 
index f3e253f7ee89bb865195cd60854a00d8ed2c020c..7972d6982e89de0e818f80ef8818c699d1fcd72a 100644 (file)
@@ -122,6 +122,11 @@ namespace SparcISA
 
     int flattenIntIndex(ThreadContext * tc, int reg);
 
+    int flattenFloatIndex(ThreadContext * tc, int reg)
+    {
+        return reg;
+    }
+
     void copyRegs(ThreadContext *src, ThreadContext *dest);
 
     void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
index 14dda443f5489bb74732567bd4fe93e1e1584460..b77ddb0eb3c32e858ffdcd5c365720f978ae086d 100644 (file)
@@ -101,8 +101,9 @@ namespace X86ISA
     std::string getFloatRegName(RegIndex);
 
     //Each 128 bit xmm register is broken into two effective 64 bit registers.
-    const int NumFloatArchRegs = NumMMXRegs + 2 * NumXMMRegs + NumMicroFpRegs;
-    const int NumFloatRegs = NumFloatArchRegs;
+    const int NumFloatRegs =
+        NumMMXRegs + 2 * NumXMMRegs + NumMicroFpRegs;
+    const int NumFloatArchRegs = NumFloatRegs + 8;
 
     class FloatRegFile
     {
index b9d6a5c4351081ca634db92a2b26515573e1027b..30846ec0067297a357e5288df56153b2eb577fd8 100644 (file)
@@ -162,6 +162,12 @@ namespace X86ISA
     {
         return (FloatRegIndex)(FLOATREG_MICROFP_BASE + index);
     }
+
+    static inline FloatRegIndex
+    FLOATREG_STACK(int index, int top)
+    {
+        return (FloatRegIndex)(NUM_FLOATREGS + ((top - index + 8) % 8));
+    }
 };
 
 #endif // __ARCH_X86_FLOATREGS_HH__
index 57990950647d141da273e17abe8f9b96c80c3675..e961cc63cd8a7e6968ae9a250aa5bde16b0cf1c0 100644 (file)
@@ -136,5 +136,10 @@ let {{
 
     assembler.symbols["label"] = labeler
 
+    def stack_index(index):
+        return "(NUM_FLOATREGS + (%s))" % index
+
+    assembler.symbols["st"] = stack_index
+
     macroopDict = assembler.assemble(microcode)
 }};
index 7b0427b4477a6e8fb53b1232be7038a32dc5e719..05a9f4418dc6b75a993a412626e7804bdb356424 100644 (file)
@@ -115,6 +115,9 @@ def operands {{
         'uIP':           ('UPC', 'uqw', None, (None, None, 'IsControl'), 51),
         'nuIP':          ('NUPC', 'uqw', None, (None, None, 'IsControl'), 52),
         'ccFlagBits':    ('IntReg', 'uqw', 'INTREG_PSEUDO(0)', None, 60),
+        # The TOP register should needs to be more protected so that later
+        # instructions don't map their indexes with an old value.
+        'TOP':           ('ControlReg', 'ub', 'MISCREG_X87_TOP', None, 61),
         'SegBase':       ('ControlReg', 'uqw', 'MISCREG_SEG_BASE(segment)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 70),
         'Mem':           ('Mem', 'uqw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 100)
 }};
index 602c99390a68f821026ffcd9a3927cf262328cf5..f3478d7f630c262e26263a37b6d0538544506ff6 100644 (file)
@@ -89,7 +89,9 @@ namespace X86ISA
             //mmx/x87 registers
             8 +
             //xmm registers
-            16
+            16 +
+            //The indices that are mapped over the fp stack
+            8
     };
 
     // semantically meaningful register indices
index 01499e7ad2f31595823157c592b0d42c22b878d8..bab813719ff1ae44024abe0b48b297b807d2003d 100644 (file)
@@ -171,9 +171,12 @@ namespace X86ISA
         MISCREG_LDTR_ATTR = MISCREG_SYSSEG_ATTR_BASE,
         MISCREG_TR_ATTR,
 
+        // Floating point control registers
+        MISCREG_X87_TOP = MISCREG_SYSSEG_ATTR_BASE + NumSysSegments,
+
         //XXX Add "Model-Specific Registers"
 
-        NUM_MISCREGS = MISCREG_SYSSEG_ATTR_BASE + NumSysSegments
+        NUM_MISCREGS
     };
 
     static inline MiscRegIndex
index 96283cada9134ba9d89b3be7c0b56364145de884..889f2f5cd3cb53d18c7f62f57475e9b85af7c57c 100644 (file)
@@ -85,6 +85,7 @@
  * Authors: Gabe Black
  */
 
+#include "arch/x86/floatregs.hh"
 #include "arch/x86/regfile.hh"
 #include "base/trace.hh"
 #include "sim/serialize.hh"
@@ -218,6 +219,15 @@ int X86ISA::flattenIntIndex(ThreadContext * tc, int reg)
         return (reg & ~(1 << 6));
 }
 
+int X86ISA::flattenFloatIndex(ThreadContext * tc, int reg)
+{
+    if (reg > NUM_FLOATREGS) {
+        int top = tc->readMiscRegNoEffect(MISCREG_X87_TOP);
+        reg = FLOATREG_STACK(reg - NUM_FLOATREGS, top);
+    }
+    return reg;
+}
+
 void RegFile::serialize(std::ostream &os)
 {
     intRegFile.serialize(os);
index d4425b04c00d393c45b2e0ac7449b178c983d8b5..650181acae02af1b1d0718a771249318d30ea314 100644 (file)
@@ -149,6 +149,8 @@ namespace X86ISA
 
     int flattenIntIndex(ThreadContext * tc, int reg);
 
+    int flattenFloatIndex(ThreadContext * tc, int reg);
+
     void copyRegs(ThreadContext *src, ThreadContext *dest);
 
     void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
index d78de2c877ed8f184a40fffb369813355c747794..49c8857530902132423a0ce7805d342046a4ccb0 100644 (file)
@@ -959,9 +959,11 @@ DefaultRename<Impl>::renameSrcRegs(DynInstPtr &inst,unsigned tid)
         if (src_reg < TheISA::FP_Base_DepTag) {
             flat_src_reg = TheISA::flattenIntIndex(inst->tcBase(), src_reg);
             DPRINTF(Rename, "Flattening index %d to %d.\n", (int)src_reg, (int)flat_src_reg);
+        } else if (src_reg < TheISA::Ctrl_Base_DepTag) {
+            src_reg = src_reg - TheISA::FP_Base_DepTag;
+            flat_src_reg = TheISA::flattenFloatIndex(inst->tcBase(), src_reg);
+            flat_src_reg += TheISA::NumIntRegs;
         } else {
-            // Floating point and Miscellaneous registers need their indexes
-            // adjusted to account for the expanded number of flattened int regs.
             flat_src_reg = src_reg - TheISA::FP_Base_DepTag + TheISA::NumIntRegs;
             DPRINTF(Rename, "Adjusting reg index from %d to %d.\n", src_reg, flat_src_reg);
         }
index a145e046e1036adc96885b661c8aea281bc3a48a..efbbc232960119377f0488a10a10935c82c6fe17 100755 (executable)
@@ -314,6 +314,7 @@ template <class Impl>
 TheISA::FloatReg
 O3ThreadContext<Impl>::readFloatReg(int reg_idx, int width)
 {
+    reg_idx = TheISA::flattenFloatIndex(this, reg_idx);
     switch(width) {
       case 32:
         return cpu->readArchFloatRegSingle(reg_idx, thread->readTid());
@@ -329,6 +330,7 @@ template <class Impl>
 TheISA::FloatReg
 O3ThreadContext<Impl>::readFloatReg(int reg_idx)
 {
+    reg_idx = TheISA::flattenFloatIndex(this, reg_idx);
     return cpu->readArchFloatRegSingle(reg_idx, thread->readTid());
 }
 
@@ -337,6 +339,7 @@ TheISA::FloatRegBits
 O3ThreadContext<Impl>::readFloatRegBits(int reg_idx, int width)
 {
     DPRINTF(Fault, "Reading floatint register through the TC!\n");
+    reg_idx = TheISA::flattenFloatIndex(this, reg_idx);
     return cpu->readArchFloatRegInt(reg_idx, thread->readTid());
 }
 
@@ -344,6 +347,7 @@ template <class Impl>
 TheISA::FloatRegBits
 O3ThreadContext<Impl>::readFloatRegBits(int reg_idx)
 {
+    reg_idx = TheISA::flattenFloatIndex(this, reg_idx);
     return cpu->readArchFloatRegInt(reg_idx, thread->readTid());
 }
 
@@ -364,6 +368,7 @@ template <class Impl>
 void
 O3ThreadContext<Impl>::setFloatReg(int reg_idx, FloatReg val, int width)
 {
+    reg_idx = TheISA::flattenFloatIndex(this, reg_idx);
     switch(width) {
       case 32:
         cpu->setArchFloatRegSingle(reg_idx, val, thread->readTid());
@@ -383,6 +388,7 @@ template <class Impl>
 void
 O3ThreadContext<Impl>::setFloatReg(int reg_idx, FloatReg val)
 {
+    reg_idx = TheISA::flattenFloatIndex(this, reg_idx);
     cpu->setArchFloatRegSingle(reg_idx, val, thread->readTid());
 
     if (!thread->trapPending && !thread->inSyscall) {
@@ -396,6 +402,7 @@ O3ThreadContext<Impl>::setFloatRegBits(int reg_idx, FloatRegBits val,
                                              int width)
 {
     DPRINTF(Fault, "Setting floatint register through the TC!\n");
+    reg_idx = TheISA::flattenFloatIndex(this, reg_idx);
     cpu->setArchFloatRegInt(reg_idx, val, thread->readTid());
 
     // Squash if we're not already in a state update mode.
@@ -408,6 +415,7 @@ template <class Impl>
 void
 O3ThreadContext<Impl>::setFloatRegBits(int reg_idx, FloatRegBits val)
 {
+    reg_idx = TheISA::flattenFloatIndex(this, reg_idx);
     cpu->setArchFloatRegInt(reg_idx, val, thread->readTid());
 
     // Squash if we're not already in a state update mode.
index 1e87b0bb714588c0ca22457f0ea34e89453e91b9..c018e3e49184b12760ba575bc7f309b011816a59 100644 (file)
@@ -235,52 +235,62 @@ class SimpleThread : public ThreadState
     //
     uint64_t readIntReg(int reg_idx)
     {
-        return regs.readIntReg(TheISA::flattenIntIndex(getTC(), reg_idx));
+        int flatIndex = TheISA::flattenIntIndex(getTC(), reg_idx);
+        return regs.readIntReg(flatIndex);
     }
 
     FloatReg readFloatReg(int reg_idx, int width)
     {
-        return regs.readFloatReg(reg_idx, width);
+        int flatIndex = TheISA::flattenIntIndex(getTC(), reg_idx);
+        return regs.readFloatReg(flatIndex, width);
     }
 
     FloatReg readFloatReg(int reg_idx)
     {
-        return regs.readFloatReg(reg_idx);
+        int flatIndex = TheISA::flattenIntIndex(getTC(), reg_idx);
+        return regs.readFloatReg(flatIndex);
     }
 
     FloatRegBits readFloatRegBits(int reg_idx, int width)
     {
-        return regs.readFloatRegBits(reg_idx, width);
+        int flatIndex = TheISA::flattenIntIndex(getTC(), reg_idx);
+        return regs.readFloatRegBits(flatIndex, width);
     }
 
     FloatRegBits readFloatRegBits(int reg_idx)
     {
-        return regs.readFloatRegBits(reg_idx);
+        int flatIndex = TheISA::flattenIntIndex(getTC(), reg_idx);
+        return regs.readFloatRegBits(flatIndex);
     }
 
     void setIntReg(int reg_idx, uint64_t val)
     {
-        regs.setIntReg(TheISA::flattenIntIndex(getTC(), reg_idx), val);
+        int flatIndex = TheISA::flattenIntIndex(getTC(), reg_idx);
+        regs.setIntReg(flatIndex, val);
     }
 
     void setFloatReg(int reg_idx, FloatReg val, int width)
     {
-        regs.setFloatReg(reg_idx, val, width);
+        int flatIndex = TheISA::flattenIntIndex(getTC(), reg_idx);
+        regs.setFloatReg(flatIndex, val, width);
     }
 
     void setFloatReg(int reg_idx, FloatReg val)
     {
-        regs.setFloatReg(reg_idx, val);
+        int flatIndex = TheISA::flattenIntIndex(getTC(), reg_idx);
+        regs.setFloatReg(flatIndex, val);
     }
 
     void setFloatRegBits(int reg_idx, FloatRegBits val, int width)
     {
-        regs.setFloatRegBits(reg_idx, val, width);
+        int flatIndex = TheISA::flattenIntIndex(getTC(), reg_idx);
+        regs.setFloatRegBits(flatIndex, val, width);
     }
 
     void setFloatRegBits(int reg_idx, FloatRegBits val)
     {
-        regs.setFloatRegBits(reg_idx, val);
+        int flatIndex = TheISA::flattenIntIndex(getTC(), reg_idx);
+        regs.setFloatRegBits(flatIndex, val);
     }
 
     uint64_t readPC()