cpu: add a condition-code register class
authorYasuko Eckert <yasuko.eckert@amd.com>
Tue, 15 Oct 2013 18:22:44 +0000 (14:22 -0400)
committerYasuko Eckert <yasuko.eckert@amd.com>
Tue, 15 Oct 2013 18:22:44 +0000 (14:22 -0400)
Add a third register class for condition codes,
in parallel with the integer and FP classes.
No ISAs use the CC class at this point though.

57 files changed:
src/arch/SConscript
src/arch/alpha/isa.hh
src/arch/alpha/registers.hh
src/arch/alpha/utility.cc
src/arch/arm/insts/static_inst.cc
src/arch/arm/isa.hh
src/arch/arm/registers.hh
src/arch/arm/utility.cc
src/arch/isa_parser.py
src/arch/mips/isa.hh
src/arch/mips/registers.hh
src/arch/null/registers.hh
src/arch/power/insts/static_inst.cc
src/arch/power/isa.hh
src/arch/power/registers.hh
src/arch/power/utility.cc
src/arch/sparc/isa.hh
src/arch/sparc/registers.hh
src/arch/sparc/utility.cc
src/arch/x86/insts/static_inst.cc
src/arch/x86/isa.hh
src/arch/x86/registers.hh
src/arch/x86/utility.cc
src/cpu/base_dyn_inst.hh
src/cpu/checker/cpu.hh
src/cpu/checker/cpu_impl.hh
src/cpu/checker/thread_context.hh
src/cpu/inorder/cpu.cc
src/cpu/inorder/cpu.hh
src/cpu/inorder/inorder_dyn_inst.cc
src/cpu/inorder/inorder_dyn_inst.hh
src/cpu/inorder/thread_context.cc
src/cpu/inorder/thread_context.hh
src/cpu/o3/O3CPU.py
src/cpu/o3/cpu.cc
src/cpu/o3/cpu.hh
src/cpu/o3/dyn_inst.hh
src/cpu/o3/free_list.cc
src/cpu/o3/free_list.hh
src/cpu/o3/inst_queue.hh
src/cpu/o3/inst_queue_impl.hh
src/cpu/o3/regfile.cc
src/cpu/o3/regfile.hh
src/cpu/o3/rename_impl.hh
src/cpu/o3/rename_map.cc
src/cpu/o3/rename_map.hh
src/cpu/o3/thread_context.hh
src/cpu/o3/thread_context_impl.hh
src/cpu/ozone/cpu_impl.hh
src/cpu/reg_class.cc
src/cpu/reg_class.hh
src/cpu/simple/base.cc
src/cpu/simple/base.hh
src/cpu/simple_thread.hh
src/cpu/static_inst.hh
src/cpu/thread_context.cc
src/cpu/thread_context.hh

index b4f94a65f36ee896cd88bf9fa57e2e87ad717c89..e7d74ce516f53f5905f5e25f4ac1dc7a91428fce 100644 (file)
@@ -135,5 +135,6 @@ env.Append(BUILDERS = { 'ISADesc' : isa_desc_builder })
 
 DebugFlag('IntRegs')
 DebugFlag('FloatRegs')
+DebugFlag('CCRegs')
 DebugFlag('MiscRegs')
-CompoundFlag('Registers', [ 'IntRegs', 'FloatRegs', 'MiscRegs' ])
+CompoundFlag('Registers', [ 'IntRegs', 'FloatRegs', 'CCRegs', 'MiscRegs' ])
index e2e2daba8999033d3c3d90c36f6a746e6f301a5e..d3049906634e3b3c724266e1123fcb3ea5d77eb7 100644 (file)
@@ -103,6 +103,13 @@ namespace AlphaISA
             return reg;
         }
 
+        // dummy
+        int
+        flattenCCIndex(int reg)
+        {
+            return reg;
+        }
+
         const Params *params() const;
 
         ISA(Params *p);
index 92ba22ee8c109dc980b16bb1a2ef80aa9a2b728c..3fd774cf7ff195baf670030bdeab57d6776cd715 100644 (file)
@@ -53,6 +53,9 @@ typedef uint64_t FloatRegBits;
 // control register file contents
 typedef uint64_t MiscReg;
 
+// dummy typedef since we don't have CC regs
+typedef uint8_t CCReg;
+
 union AnyReg
 {
     IntReg  intreg;
@@ -91,6 +94,7 @@ const int NumFloatArchRegs = 32;
 
 const int NumIntRegs = NumIntArchRegs + NumPALShadowRegs;
 const int NumFloatRegs = NumFloatArchRegs;
+const int NumCCRegs = 0;
 const int NumMiscRegs = NUM_MISCREGS;
 
 const int TotalNumRegs =
@@ -101,7 +105,8 @@ enum DependenceTags {
     // 0..31 are the integer regs 0..31
     // 32..63 are the FP regs 0..31, i.e. use (reg + FP_Reg_Base)
     FP_Reg_Base = NumIntRegs,
-    Misc_Reg_Base = FP_Reg_Base + NumFloatRegs,
+    CC_Reg_Base = FP_Reg_Base + NumFloatRegs,
+    Misc_Reg_Base = CC_Reg_Base + NumCCRegs, // NumCCRegs == 0
     Max_Reg_Index = Misc_Reg_Base + NumMiscRegs + NumInternalProcRegs
 };
 
index 32fc0b1417feb04470b19e961a1856c172258115..2dfe00f967fdcaecb1ff639d7648ec449178ed65 100644 (file)
@@ -71,6 +71,9 @@ copyRegs(ThreadContext *src, ThreadContext *dest)
     for (int i = 0; i < NumFloatRegs; ++i)
         dest->setFloatRegBits(i, src->readFloatRegBits(i));
 
+    // Would need to add condition-code regs if implemented
+    assert(NumCCRegs == 0);
+
     // Copy misc. registers
     copyMiscRegs(src, dest);
 
index 3ab7dfb0e9c6470299fdac2ff26bc0175ecf6cb8..2a8dee16208b9ec83da3dbcb82a0c6c6a5ed1db5 100644 (file)
@@ -239,6 +239,8 @@ ArmStaticInst::printReg(std::ostream &os, int reg) const
         assert(rel_reg < NUM_MISCREGS);
         ccprintf(os, "%s", ArmISA::miscRegName[rel_reg]);
         break;
+      case CCRegClass:
+        panic("printReg: CCRegClass but ARM has no CC regs\n");
     }
 }
 
index e7abb26b27ab6360ef4f872aa185d3b05dcc6179..6fd57549ad96b22e149b40c076b99400bc648093 100644 (file)
@@ -140,6 +140,13 @@ namespace ArmISA
             return reg;
         }
 
+        // dummy
+        int
+        flattenCCIndex(int reg)
+        {
+            return reg;
+        }
+
         int
         flattenMiscIndex(int reg)
         {
index cc4fac824535b381b2428f1aeda152cda1d06d2b..b9033fd5b06a3c37ff41efa7f806dc8b27bf9800 100644 (file)
@@ -68,6 +68,9 @@ typedef float FloatReg;
 // cop-0/cop-1 system control register
 typedef uint64_t MiscReg;
 
+// dummy typedef since we don't have CC regs
+typedef uint8_t CCReg;
+
 // Constants Related to the number of registers
 const int NumIntArchRegs = NUM_ARCH_INTREGS;
 // The number of single precision floating point registers
@@ -76,6 +79,7 @@ const int NumFloatSpecialRegs = 8;
 
 const int NumIntRegs = NUM_INTREGS;
 const int NumFloatRegs = NumFloatArchRegs + NumFloatSpecialRegs;
+const int NumCCRegs = 0;
 const int NumMiscRegs = NUM_MISCREGS;
 
 const int TotalNumRegs = NumIntRegs + NumFloatRegs + NumMiscRegs;
@@ -102,7 +106,8 @@ const int SyscallSuccessReg = ReturnValueReg;
 
 // These help enumerate all the registers for dependence tracking.
 const int FP_Reg_Base = NumIntRegs * (MODE_MAXMODE + 1);
-const int Misc_Reg_Base = FP_Reg_Base + NumFloatRegs;
+const int CC_Reg_Base = FP_Reg_Base + NumFloatRegs;
+const int Misc_Reg_Base = CC_Reg_Base + NumCCRegs; // NumCCRegs == 0
 const int Max_Reg_Index = Misc_Reg_Base + NumMiscRegs;
 
 typedef union {
index 776c1ae8215de037c1d71ebdec653bd25d46986f..cddc2c5c4849a3a37295ed82eecdb3b1fe2116b9 100644 (file)
@@ -113,7 +113,7 @@ getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
 void
 skipFunction(ThreadContext *tc)
 {
-    TheISA::PCState newPC = tc->pcState();
+    PCState newPC = tc->pcState();
     newPC.set(tc->readIntReg(ReturnAddressReg) & ~ULL(1));
 
     CheckerCPU *checker = tc->getCheckerCpuPtr();
@@ -127,13 +127,16 @@ skipFunction(ThreadContext *tc)
 void
 copyRegs(ThreadContext *src, ThreadContext *dest)
 {
-    for (int i = 0; i < TheISA::NumIntRegs; i++)
+    for (int i = 0; i < NumIntRegs; i++)
         dest->setIntRegFlat(i, src->readIntRegFlat(i));
 
-    for (int i = 0; i < TheISA::NumFloatRegs; i++)
+    for (int i = 0; i < NumFloatRegs; i++)
         dest->setFloatRegFlat(i, src->readFloatRegFlat(i));
 
-    for (int i = 0; i < TheISA::NumMiscRegs; i++)
+    // Would need to add condition-code regs if implemented
+    assert(NumCCRegs == 0);
+
+    for (int i = 0; i < NumMiscRegs; i++)
         dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i));
 
     // setMiscReg "with effect" will set the misc register mapping correctly.
index e4f81c1735df53ae5ddb4244a240fb585a4efbc7..dd9f2e8732b2e46bd6a3a77425d067b48c2814f3 100755 (executable)
@@ -1,4 +1,5 @@
 # Copyright (c) 2003-2005 The Regents of The University of Michigan
+# Copyright (c) 2013 Advanced Micro Devices, Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -497,6 +498,9 @@ class Operand(object):
     def isIntReg(self):
         return 0
 
+    def isCCReg(self):
+        return 0
+
     def isControlReg(self):
         return 0
 
@@ -660,6 +664,79 @@ class FloatRegOperand(Operand):
         }''' % (self.ctype, self.base_name, wp)
         return wb
 
+class CCRegOperand(Operand):
+    def isReg(self):
+        return 1
+
+    def isCCReg(self):
+        return 1
+
+    def makeConstructor(self, predRead, predWrite):
+        c_src = ''
+        c_dest = ''
+
+        if self.is_src:
+            c_src = '\n\t_srcRegIdx[_numSrcRegs++] = %s + CC_Reg_Base;' % \
+                     (self.reg_spec)
+            if self.hasReadPred():
+                c_src = '\n\tif (%s) {%s\n\t}' % \
+                        (self.read_predicate, c_src)
+
+        if self.is_dest:
+            c_dest = \
+              '\n\t_destRegIdx[_numDestRegs++] = %s + CC_Reg_Base;' % \
+              (self.reg_spec)
+            c_dest += '\n\t_numCCDestRegs++;'
+            if self.hasWritePred():
+                c_dest = '\n\tif (%s) {%s\n\t}' % \
+                         (self.write_predicate, c_dest)
+
+        return c_src + c_dest
+
+    def makeRead(self, predRead):
+        if (self.ctype == 'float' or self.ctype == 'double'):
+            error('Attempt to read condition-code register as FP')
+        if self.read_code != None:
+            return self.buildReadCode('readCCRegOperand')
+
+        int_reg_val = ''
+        if predRead:
+            int_reg_val = 'xc->readCCRegOperand(this, _sourceIndex++)'
+            if self.hasReadPred():
+                int_reg_val = '(%s) ? %s : 0' % \
+                              (self.read_predicate, int_reg_val)
+        else:
+            int_reg_val = 'xc->readCCRegOperand(this, %d)' % self.src_reg_idx
+
+        return '%s = %s;\n' % (self.base_name, int_reg_val)
+
+    def makeWrite(self, predWrite):
+        if (self.ctype == 'float' or self.ctype == 'double'):
+            error('Attempt to write condition-code register as FP')
+        if self.write_code != None:
+            return self.buildWriteCode('setCCRegOperand')
+
+        if predWrite:
+            wp = 'true'
+            if self.hasWritePred():
+                wp = self.write_predicate
+
+            wcond = 'if (%s)' % (wp)
+            windex = '_destIndex++'
+        else:
+            wcond = ''
+            windex = '%d' % self.dest_reg_idx
+
+        wb = '''
+        %s
+        {
+            %s final_val = %s;
+            xc->setCCRegOperand(this, %s, final_val);\n
+            if (traceData) { traceData->setData(final_val); }
+        }''' % (wcond, self.ctype, self.base_name, windex)
+
+        return wb
+
 class ControlRegOperand(Operand):
     def isReg(self):
         return 1
@@ -815,6 +892,7 @@ class OperandList(object):
         self.numDestRegs = 0
         self.numFPDestRegs = 0
         self.numIntDestRegs = 0
+        self.numCCDestRegs = 0
         self.numMiscDestRegs = 0
         self.memOperand = None
 
@@ -835,6 +913,8 @@ class OperandList(object):
                         self.numFPDestRegs += 1
                     elif op_desc.isIntReg():
                         self.numIntDestRegs += 1
+                    elif op_desc.isCCReg():
+                        self.numCCDestRegs += 1
                     elif op_desc.isControlReg():
                         self.numMiscDestRegs += 1
             elif op_desc.isMem():
@@ -1030,6 +1110,7 @@ class InstObjParams(object):
         header += '\n\t_numDestRegs = 0;'
         header += '\n\t_numFPDestRegs = 0;'
         header += '\n\t_numIntDestRegs = 0;'
+        header += '\n\t_numCCDestRegs = 0;'
 
         self.constructor = header + \
                            self.operands.concatAttrStrings('constructor')
index 04d4a1dfaaca55852a5c3e118d595142c095bcc9..c601cfc1eda74c442e963780acb5594316af777c 100644 (file)
@@ -177,6 +177,13 @@ namespace MipsISA
         {
             return reg;
         }
+
+        // dummy
+        int
+        flattenCCIndex(int reg)
+        {
+            return reg;
+        }
     };
 }
 
index d9d94e47bac77fc4f9c1d62a27f6fb5688047262..0ac84cc7fec056bb3094a9b7cc645e200e9541ac 100644 (file)
@@ -54,6 +54,7 @@ const int NumFloatSpecialRegs = 5;
 const int MaxShadowRegSets = 16; // Maximum number of shadow register sets
 const int NumIntRegs = NumIntArchRegs + NumIntSpecialRegs;        //HI & LO Regs
 const int NumFloatRegs = NumFloatArchRegs + NumFloatSpecialRegs;//
+const int NumCCRegs = 0;
 
 const uint32_t MIPS32_QNAN = 0x7fbfffff;
 const uint64_t MIPS64_QNAN = ULL(0x7ff7ffffffffffff);
@@ -276,7 +277,8 @@ const int NumMiscRegs = MISCREG_NUMREGS;
 
 // These help enumerate all the registers for dependence tracking.
 const int FP_Reg_Base = NumIntRegs;
-const int Misc_Reg_Base = FP_Reg_Base + NumFloatRegs;
+const int CC_Reg_Base = FP_Reg_Base + NumFloatRegs;
+const int Misc_Reg_Base = CC_Reg_Base + NumCCRegs; // NumCCRegs == 0
 const int Max_Reg_Index = Misc_Reg_Base + NumMiscRegs;
 
 const int TotalNumRegs = NumIntRegs + NumFloatRegs + NumMiscRegs;
@@ -292,6 +294,9 @@ typedef float FloatReg;
 // cop-0/cop-1 system control register
 typedef uint64_t MiscReg;
 
+// dummy typedef since we don't have CC regs
+typedef uint8_t CCReg;
+
 typedef union {
     IntReg   intreg;
     FloatReg fpreg;
index f33b7e5bd35171b0b048f57347c4c6f00b3bfe39..1e52fc5a6eced0f829d84d321e3eaf1651086162 100644 (file)
@@ -47,6 +47,7 @@ namespace NullISA {
 typedef uint64_t IntReg;
 typedef uint32_t FloatRegBits;
 typedef float FloatReg;
+typedef uint8_t CCReg;
 typedef uint64_t MiscReg;
 
 }
index 09b662453750bbc80d73298a7cf65b487a42524f..087e1f740c13754804a916dfc5bc220d66d7cf2b 100644 (file)
@@ -55,6 +55,8 @@ PowerStaticInst::printReg(std::ostream &os, int reg) const
           default: ccprintf(os, "unknown_reg");
             break;
         }
+      case CCRegClass:
+        panic("printReg: POWER does not implement CCRegClass\n");
     }
 }
 
index 33439c48cd2fecf6e5bdb12082470b305c533371..7b59b2ad1179f6d297b87aaebd4aac3f00a8ddbb 100644 (file)
@@ -98,6 +98,13 @@ class ISA : public SimObject
         return reg;
     }
 
+    // dummy
+    int
+    flattenCCIndex(int reg)
+    {
+        return reg;
+    }
+
     void startup(ThreadContext *tc) {}
 
     /// Explicitly import the otherwise hidden startup
index 89de3719cb8b8d62f5413660d57d2b4f1be04d8d..abee516fcda0018eccce4ee225e46512b3089da3 100644 (file)
@@ -52,6 +52,9 @@ typedef uint64_t FloatRegBits;
 typedef double FloatReg;
 typedef uint64_t MiscReg;
 
+// dummy typedef since we don't have CC regs
+typedef uint8_t CCReg;
+
 // Constants Related to the number of registers
 const int NumIntArchRegs = 32;
 
@@ -64,6 +67,7 @@ const int NumInternalProcRegs = 0;
 
 const int NumIntRegs = NumIntArchRegs + NumIntSpecialRegs;
 const int NumFloatRegs = NumFloatArchRegs + NumFloatSpecialRegs;
+const int NumCCRegs = 0;
 const int NumMiscRegs = NUM_MISCREGS;
 
 // Semantically meaningful register indices
@@ -85,7 +89,8 @@ const int SyscallSuccessReg = 3;
 
 // These help enumerate all the registers for dependence tracking.
 const int FP_Reg_Base = NumIntRegs;
-const int Misc_Reg_Base = FP_Reg_Base + NumFloatRegs;
+const int CC_Reg_Base = FP_Reg_Base + NumFloatRegs;
+const int Misc_Reg_Base = CC_Reg_Base + NumCCRegs; // NumCCRegs == 0
 const int Max_Reg_Index = Misc_Reg_Base + NumMiscRegs;
 
 typedef union {
index e3fa246fc3e39cfff34bf889e74844a27746ac40..7be195b8defec7671767d1b324b37f09375563ad 100644 (file)
@@ -48,6 +48,9 @@ copyRegs(ThreadContext *src, ThreadContext *dest)
     for (int i = 0; i < NumFloatRegs; ++i)
         dest->setFloatRegBits(i, src->readFloatRegBits(i));
 
+    // Would need to add condition-code regs if implemented
+    assert(NumCCRegs == 0);
+
     // Copy misc. registers
     copyMiscRegs(src, dest);
 
index 86092f3b579c5286b620cb767a16f1ceeca00e0e..e6f023bc0685c92c46dc8392d5d2c0e149eb6562 100644 (file)
@@ -206,6 +206,13 @@ class ISA : public SimObject
         return reg;
     }
 
+    // dummy
+    int
+    flattenCCIndex(int reg)
+    {
+        return reg;
+    }
+
     typedef SparcISAParams Params;
     const Params *params() const;
 
index 0e774b69eca5648ead08cee1a263b4e040855c58..b25f34584339b17fe53aeab6617d5fd9901c8683 100644 (file)
@@ -48,6 +48,10 @@ typedef uint64_t IntReg;
 typedef uint64_t MiscReg;
 typedef float FloatReg;
 typedef uint32_t FloatRegBits;
+
+// dummy typedef since we don't have CC regs
+typedef uint8_t CCReg;
+
 typedef union
 {
     IntReg intReg;
@@ -70,14 +74,16 @@ const int SyscallPseudoReturnReg = 9;
 
 const int NumIntArchRegs = 32;
 const int NumIntRegs = (MaxGL + 1) * 8 + NWindows * 16 + NumMicroIntRegs;
+const int NumCCRegs = 0;
 
 const int TotalNumRegs = NumIntRegs + NumFloatRegs + NumMiscRegs;
 
 // These enumerate all the registers for dependence tracking.
 enum DependenceTags {
     FP_Reg_Base = NumIntRegs,
-    Misc_Reg_Base = FP_Reg_Base + NumFloatRegs,
-    Max_Reg_Index = Misc_Reg_Base + NumMiscRegs
+    CC_Reg_Base = FP_Reg_Base + NumFloatRegs,
+    Misc_Reg_Base = CC_Reg_Base + NumCCRegs, // NumCCRegs == 0
+    Max_Reg_Index = Misc_Reg_Base + NumMiscRegs,
 };
 
 } // namespace SparcISA
index d99ef4aa018b7474fadc49261ee2357922857f6f..9fa102c6a69a76ee24ecdacb4ae118f344f6ab48 100644 (file)
@@ -234,6 +234,9 @@ copyRegs(ThreadContext *src, ThreadContext *dest)
         dest->setFloatRegBits(i, src->readFloatRegBits(i));
     }
 
+    // Would need to add condition-code regs if implemented
+    assert(NumCCRegs == 0);
+
     // Copy misc. registers
     copyMiscRegs(src, dest);
 
index 046a11fb62b086dda3c92034060f5d0158a212b0..39091289fc199e2d66df2eca7d7e7b208f89450e 100644 (file)
@@ -221,6 +221,10 @@ namespace X86ISA
             break;
           }
 
+          case CCRegClass:
+            ccprintf(os, "%%cc%d", rel_reg);
+            break;
+
           case MiscRegClass:
             switch (rel_reg) {
               default:
index 3ccc2f0ad147ce6ba71a215a3b02a78b2209418a..5f36fd7adf87e9b437adc7f15f79ffd9183595ef 100644 (file)
@@ -85,6 +85,12 @@ namespace X86ISA
             return reg;
         }
 
+        int
+        flattenCCIndex(int reg)
+        {
+            return reg;
+        }
+
         void serialize(std::ostream &os);
         void unserialize(Checkpoint *cp, const std::string &section);
         void startup(ThreadContext *tc);
index bb9f5f7b18ddf16104b97d1c7ad4570118793e3a..d62992dcd18427a3772df561fb66e935fb789798 100644 (file)
@@ -57,6 +57,7 @@ const int NumIntArchRegs = NUM_INTREGS;
 const int NumIntRegs =
     NumIntArchRegs + NumMicroIntRegs +
     NumPseudoIntRegs + NumImplicitIntRegs;
+const int NumCCRegs = 0;
 
 // Each 128 bit xmm register is broken into two effective 64 bit registers.
 // Add 8 for the indices that are mapped over the fp stack
@@ -69,7 +70,8 @@ enum DependenceTags {
     // register index which has the IntFoldBit (1 << 6) set.  To be safe
     // we just start at (1 << 7) == 128.
     FP_Reg_Base = 128,
-    Misc_Reg_Base = FP_Reg_Base + NumFloatRegs,
+    CC_Reg_Base = FP_Reg_Base + NumFloatRegs,
+    Misc_Reg_Base = CC_Reg_Base + NumCCRegs, // NumCCRegs == 0
     Max_Reg_Index = Misc_Reg_Base + NumMiscRegs
 };
 
@@ -87,6 +89,7 @@ const int FramePointerReg = INTREG_RBP;
 const int SyscallPseudoReturnReg = INTREG_RDX;
 
 typedef uint64_t IntReg;
+typedef uint64_t CCReg;
 //XXX Should this be a 128 bit structure for XMM memory ops?
 typedef uint64_t LargestRead;
 typedef uint64_t MiscReg;
index b50b99dfa1ee84854ed082c7f2ab66ea669a94bd..df7d3935d0b737c68560f162d425533ec6d48976 100644 (file)
@@ -244,6 +244,8 @@ copyRegs(ThreadContext *src, ThreadContext *dest)
     //copy float regs
     for (int i = 0; i < NumFloatRegs; ++i)
          dest->setFloatRegBits(i, src->readFloatRegBits(i));
+    // Will need to add condition-code regs when implemented
+    assert(NumCCRegs == 0);
     copyMiscRegs(src, dest);
     dest->pcState(src->pcState());
 }
index 8989a438a1db04768c756945b0a20caf24f3521e..6aecd32dc7d36d06fec1647bfabc82ae0a6b36aa 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2011,2013 ARM Limited
+ * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved.
  *
  * The license below extends only to copyright in the software and shall
@@ -633,6 +634,12 @@ class BaseDynInst : public RefCounted
         setResult<uint64_t>(val);
     }
 
+    /** Records a CC register being set to a value. */
+    void setCCRegOperand(const StaticInst *si, int idx, uint64_t val)
+    {
+        setResult<uint64_t>(val);
+    }
+
     /** Records an fp register being set to a value. */
     void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val,
                             int width)
index 637481706dc7f79d37a8d9815bd49581b35581b1..c49f264f9ffb5099063e96d46ab768f3aa0a8904 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2011 ARM Limited
+ * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -223,6 +224,12 @@ class CheckerCPU : public BaseCPU
         return thread->readFloatRegBits(reg_idx);
     }
 
+    uint64_t readCCRegOperand(const StaticInst *si, int idx)
+    {
+        int reg_idx = si->srcRegIdx(idx) - TheISA::CC_Reg_Base;
+        return thread->readCCReg(reg_idx);
+    }
+
     template <class T>
     void setResult(T t)
     {
@@ -252,6 +259,13 @@ class CheckerCPU : public BaseCPU
         setResult<uint64_t>(val);
     }
 
+    void setCCRegOperand(const StaticInst *si, int idx, uint64_t val)
+    {
+        int reg_idx = si->destRegIdx(idx) - TheISA::CC_Reg_Base;
+        thread->setCCReg(reg_idx, val);
+        setResult<uint64_t>(val);
+    }
+
     bool readPredicate() { return thread->readPredicate(); }
     void setPredicate(bool val)
     {
index 185fed88e8d9165b9853745369817d07a7f92cd7..e18644e0edd6c7071d01ad815bae5c4a0f971a99 100644 (file)
@@ -606,6 +606,9 @@ Checker<Impl>::copyResult(DynInstPtr &inst, uint64_t mismatch_val,
           case FloatRegClass:
             thread->setFloatRegBits(idx, mismatch_val);
             break;
+          case CCRegClass:
+            thread->setCCReg(idx, mismatch_val);
+            break;
           case MiscRegClass:
             thread->setMiscReg(idx - TheISA::Misc_Reg_Base,
                                mismatch_val);
@@ -624,6 +627,9 @@ Checker<Impl>::copyResult(DynInstPtr &inst, uint64_t mismatch_val,
           case FloatRegClass:
             thread->setFloatRegBits(idx, res);
             break;
+          case CCRegClass:
+            thread->setCCReg(idx, res);
+            break;
           case MiscRegClass:
             // Try to get the proper misc register index for ARM here...
             thread->setMiscReg(idx - TheISA::Misc_Reg_Base, res);
index 80726ff19646241d45811ca870e5ef232a415394..c06e03fc6f26d04dcc60cdf521ead8976471697b 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2011-2012 ARM Limited
+ * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -216,6 +217,9 @@ class CheckerThreadContext : public ThreadContext
     FloatRegBits readFloatRegBits(int reg_idx)
     { return actualTC->readFloatRegBits(reg_idx); }
 
+    CCReg readCCReg(int reg_idx)
+    { return actualTC->readCCReg(reg_idx); }
+
     void setIntReg(int reg_idx, uint64_t val)
     {
         actualTC->setIntReg(reg_idx, val);
@@ -234,6 +238,12 @@ class CheckerThreadContext : public ThreadContext
         checkerTC->setFloatRegBits(reg_idx, val);
     }
 
+    void setCCReg(int reg_idx, CCReg val)
+    {
+        actualTC->setCCReg(reg_idx, val);
+        checkerTC->setCCReg(reg_idx, val);
+    }
+
     /** Reads this thread's PC state. */
     TheISA::PCState pcState()
     { return actualTC->pcState(); }
@@ -289,6 +299,7 @@ class CheckerThreadContext : public ThreadContext
 
     int flattenIntIndex(int reg) { return actualTC->flattenIntIndex(reg); }
     int flattenFloatIndex(int reg) { return actualTC->flattenFloatIndex(reg); }
+    int flattenCCIndex(int reg) { return actualTC->flattenCCIndex(reg); }
 
     unsigned readStCondFailures()
     { return actualTC->readStCondFailures(); }
@@ -320,6 +331,12 @@ class CheckerThreadContext : public ThreadContext
 
     void setFloatRegBitsFlat(int idx, FloatRegBits val)
     { actualTC->setFloatRegBitsFlat(idx, val); }
+
+    CCReg readCCRegFlat(int idx)
+    { return actualTC->readCCRegFlat(idx); }
+
+    void setCCRegFlat(int idx, CCReg val)
+    { actualTC->setCCRegFlat(idx, val); }
 };
 
 #endif // __CPU_CHECKER_EXEC_CONTEXT_HH__
index 32ca2caaf6c1435f60867d985c019a1d8bd59e96..5a02f94d9bcc969b8ca0fcf80ab666860596aea8 100644 (file)
@@ -361,6 +361,9 @@ InOrderCPU::InOrderCPU(Params *params)
 
         memset(intRegs[tid], 0, sizeof(intRegs[tid]));
         memset(floatRegs.i[tid], 0, sizeof(floatRegs.i[tid]));
+#ifdef ISA_HAS_CC_REGS
+        memset(ccRegs[tid], 0, sizeof(ccRegs[tid]));
+#endif
         isa[tid]->clear();
 
         // Define dummy instructions and resource requests to be used.
@@ -1305,6 +1308,19 @@ InOrderCPU::readFloatRegBits(RegIndex reg_idx, ThreadID tid)
     return floatRegs.i[tid][reg_idx];
 }
 
+CCReg
+InOrderCPU::readCCReg(RegIndex reg_idx, ThreadID tid)
+{
+#ifdef ISA_HAS_CC_REGS
+    DPRINTF(CCRegs, "[tid:%i]: Reading CC. Reg %i as %x\n",
+            tid, reg_idx, ccRegs[tid][reg_idx]);
+
+    return ccRegs[tid][reg_idx];
+#else
+    panic("readCCReg: ISA does not have CC regs\n");
+#endif
+}
+
 void
 InOrderCPU::setIntReg(RegIndex reg_idx, uint64_t val, ThreadID tid)
 {
@@ -1344,6 +1360,18 @@ InOrderCPU::setFloatRegBits(RegIndex reg_idx, FloatRegBits val, ThreadID tid)
             floatRegs.f[tid][reg_idx]);
 }
 
+void
+InOrderCPU::setCCReg(RegIndex reg_idx, CCReg val, ThreadID tid)
+{
+#ifdef ISA_HAS_CC_REGS
+    DPRINTF(CCRegs, "[tid:%i]: Setting CC. Reg %i to %x\n",
+            tid, reg_idx, val);
+    ccRegs[tid][reg_idx] = val;
+#else
+    panic("readCCReg: ISA does not have CC regs\n");
+#endif
+}
+
 uint64_t
 InOrderCPU::readRegOtherThread(unsigned reg_idx, ThreadID tid)
 {
@@ -1391,6 +1419,10 @@ InOrderCPU::setRegOtherThread(unsigned reg_idx, const MiscReg &val,
         setFloatRegBits(rel_idx, val, tid);
         break;
 
+      case CCRegClass:
+        setCCReg(rel_idx, val, tid);
+        break;
+
       case MiscRegClass:
         setMiscReg(rel_idx, val, tid); // Misc. Register File
         break;
index d5a31cca8dabdb34cc572593a0e52d594bb58272..1183f6fc9ab29876b2b80fd653a132c6978d5504 100644 (file)
@@ -93,6 +93,7 @@ class InOrderCPU : public BaseCPU
     typedef TheISA::IntReg IntReg;
     typedef TheISA::FloatReg FloatReg;
     typedef TheISA::FloatRegBits FloatRegBits;
+    typedef TheISA::CCReg CCReg;
     typedef TheISA::MiscReg MiscReg;
     typedef TheISA::RegIndex RegIndex;
 
@@ -327,6 +328,9 @@ class InOrderCPU : public BaseCPU
         FloatRegBits i[ThePipeline::MaxThreads][TheISA::NumFloatRegs];
     } floatRegs;
     TheISA::IntReg intRegs[ThePipeline::MaxThreads][TheISA::NumIntRegs];
+#ifdef ISA_HAS_CC_REGS
+    TheISA::CCReg ccRegs[ThePipeline::MaxThreads][TheISA::NumCCRegs];
+#endif
 
     /** ISA state */
     std::vector<TheISA::ISA *> isa;
@@ -590,12 +594,16 @@ class InOrderCPU : public BaseCPU
 
     FloatRegBits readFloatRegBits(RegIndex reg_idx, ThreadID tid);
 
+    CCReg readCCReg(RegIndex reg_idx, ThreadID tid);
+
     void setIntReg(RegIndex reg_idx, uint64_t val, ThreadID tid);
 
     void setFloatReg(RegIndex reg_idx, FloatReg val, ThreadID tid);
 
     void setFloatRegBits(RegIndex reg_idx, FloatRegBits val,  ThreadID tid);
 
+    void setCCReg(RegIndex reg_idx, CCReg val, ThreadID tid);
+
     RegIndex flattenRegIdx(RegIndex reg_idx, RegClass &reg_type, ThreadID tid);
 
     /** Reads a miscellaneous register. */
index c2765a3ba25958861174ff0017a3fab15a0e7dd8..aedc630f50595bf0106a859faa8ee08b37d4ff32 100644 (file)
@@ -562,6 +562,10 @@ InOrderDynInst::setRegOtherThread(unsigned reg_idx, const MiscReg &val,
         this->cpu->setFloatRegBits(rel_idx, val, tid);
         break;
 
+      case CCRegClass:
+        this->cpu->setCCReg(rel_idx, val, tid);
+        break;
+
       case MiscRegClass:
         this->cpu->setMiscReg(rel_idx, val, tid); // Misc. Register File
         break;
index afd137a2ec5881f6d9da202cb6385a0294a22907..48c15e292eecd2953e58ed5d79547be190e55f0e 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2007 MIPS Technologies, Inc.
  * Copyright (c) 2004-2006 The Regents of The University of Michigan
+ * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -87,6 +88,8 @@ class InOrderDynInst : public RefCounted
     typedef TheISA::FloatReg FloatReg;
     // Floating point register type.
     typedef TheISA::FloatRegBits FloatRegBits;
+    // Condition code register type.
+    typedef TheISA::CCReg CCReg;
     // Floating point register type.
     typedef TheISA::MiscReg MiscReg;
 
@@ -880,6 +883,11 @@ class InOrderDynInst : public RefCounted
        return instResult[idx].res.fpVal.i;
     }
 
+    CCReg readCCResult(int idx)
+    {
+       return instResult[idx].res.intVal;
+    }
+
     Tick readResultTime(int idx) { return instResult[idx].tick; }
 
     IntReg* getIntResultPtr(int idx) { return &instResult[idx].res.intVal; }
@@ -891,6 +899,7 @@ class InOrderDynInst : public RefCounted
     void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val);
     void setFloatRegOperandBits(const StaticInst *si, int idx,
             TheISA::FloatRegBits val);
+    void setCCRegOperand(const StaticInst *si, int idx, CCReg val);
     void setMiscReg(int misc_reg, const MiscReg &val);
     void setMiscRegNoEffect(int misc_reg, const MiscReg &val);
     void setMiscRegOperand(const StaticInst *si, int idx, const MiscReg &val);
index aab8c226ae9aa166a625afd5114691a3c240639c..763cc6df2b21733128381e57eaed7dbb71f04713 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2012 ARM Limited
+ * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -190,6 +191,14 @@ InOrderThreadContext::readFloatRegBits(int reg_idx)
     return cpu->readFloatRegBits(reg_idx, tid);
 }
 
+CCReg
+InOrderThreadContext::readCCReg(int reg_idx)
+{
+    ThreadID tid = thread->threadId();
+    reg_idx = cpu->isa[tid]->flattenCCIndex(reg_idx);
+    return cpu->readCCReg(reg_idx, tid);
+}
+
 uint64_t
 InOrderThreadContext::readRegOtherThread(int reg_idx, ThreadID tid)
 {
@@ -220,6 +229,14 @@ InOrderThreadContext::setFloatRegBits(int reg_idx, FloatRegBits val)
     cpu->setFloatRegBits(reg_idx, val, tid);
 }
 
+void
+InOrderThreadContext::setCCReg(int reg_idx, CCReg val)
+{
+    ThreadID tid = thread->threadId();
+    reg_idx = cpu->isa[tid]->flattenCCIndex(reg_idx);
+    cpu->setCCReg(reg_idx, val, tid);
+}
+
 void
 InOrderThreadContext::setRegOtherThread(int misc_reg, const MiscReg &val,
                                         ThreadID tid)
@@ -281,3 +298,17 @@ InOrderThreadContext::setFloatRegBitsFlat(int idx, FloatRegBits val)
     const ThreadID tid = thread->threadId();
     cpu->setFloatRegBits(idx, val, tid);
 }
+
+CCReg
+InOrderThreadContext::readCCRegFlat(int idx)
+{
+    const ThreadID tid = thread->threadId();
+    return cpu->readCCReg(idx, tid);
+}
+
+void
+InOrderThreadContext::setCCRegFlat(int idx, CCReg val)
+{
+    const ThreadID tid = thread->threadId();
+    cpu->setCCReg(idx, val, tid);
+}
index f4847d0b43e52ccf2b311ccd8c0a4dae1b39b803..5e1c65f8fc7fd4b36baf2c7bfb9e6ae90036f3a2 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2012 ARM Limited
+ * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -207,6 +208,8 @@ class InOrderThreadContext : public ThreadContext
 
     FloatRegBits readFloatRegBits(int reg_idx);
 
+    CCReg readCCReg(int reg_idx);
+
     uint64_t readRegOtherThread(int misc_reg, ThreadID tid);
 
     /** Sets an integer register to a value. */
@@ -216,6 +219,8 @@ class InOrderThreadContext : public ThreadContext
 
     void setFloatRegBits(int reg_idx, FloatRegBits val);
 
+    void setCCReg(int reg_idx, CCReg val);
+
     void setRegOtherThread(int misc_reg,
                                    const MiscReg &val,
                                    ThreadID tid);
@@ -265,6 +270,9 @@ class InOrderThreadContext : public ThreadContext
     int flattenFloatIndex(int reg)
     { return cpu->isa[thread->threadId()]->flattenFloatIndex(reg); }
 
+    int flattenCCIndex(int reg)
+    { return cpu->isa[thread->threadId()]->flattenCCIndex(reg); }
+
     void activateContext(Cycles delay)
     { cpu->activateContext(thread->threadId(), delay); }
 
@@ -307,6 +315,9 @@ class InOrderThreadContext : public ThreadContext
 
     FloatRegBits readFloatRegBitsFlat(int idx);
     void setFloatRegBitsFlat(int idx, FloatRegBits val);
+
+    CCReg readCCRegFlat(int idx);
+    void setCCRegFlat(int idx, CCReg val);
 };
 
 #endif
index e1988124813cc1b8aaae0c26504a9f1d7a628118..4b94f35818ec5853f1d5c7754919c880982c7903 100644 (file)
@@ -112,6 +112,7 @@ class DerivO3CPU(BaseCPU):
     numPhysIntRegs = Param.Unsigned(256, "Number of physical integer registers")
     numPhysFloatRegs = Param.Unsigned(256, "Number of physical floating point "
                                       "registers")
+    numPhysCCRegs = Param.Unsigned(0, "Number of physical cc registers")
     numIQEntries = Param.Unsigned(64, "Number of instruction queue entries")
     numROBEntries = Param.Unsigned(192, "Number of reorder buffer entries")
 
index 3e33e139a7b109b7b2fd9cfb939606c70662c190..f379b106856e7b7130fb922103e434ab027141c9 100644 (file)
@@ -225,7 +225,8 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
       commit(this, params),
 
       regFile(params->numPhysIntRegs,
-              params->numPhysFloatRegs),
+              params->numPhysFloatRegs,
+              params->numPhysCCRegs),
 
       freeList(name() + ".freelist", &regFile),
 
@@ -327,6 +328,7 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
     //Make Sure That this a Valid Architeture
     assert(params->numPhysIntRegs   >= numThreads * TheISA::NumIntRegs);
     assert(params->numPhysFloatRegs >= numThreads * TheISA::NumFloatRegs);
+    assert(params->numPhysCCRegs >= numThreads * TheISA::NumCCRegs);
 
     rename.setScoreboard(&scoreboard);
     iew.setScoreboard(&scoreboard);
@@ -368,6 +370,12 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
             renameMap[tid].setFloatEntry(ridx, phys_reg);
             commitRenameMap[tid].setFloatEntry(ridx, phys_reg);
         }
+
+        for (RegIndex ridx = 0; ridx < TheISA::NumCCRegs; ++ridx) {
+            PhysRegIndex phys_reg = freeList.getCCReg();
+            renameMap[tid].setCCEntry(ridx, phys_reg);
+            commitRenameMap[tid].setCCEntry(ridx, phys_reg);
+        }
     }
 
     rename.setRenameMap(renameMap);
@@ -555,6 +563,16 @@ FullO3CPU<Impl>::regStats()
         .desc("number of floating regfile writes")
         .prereq(fpRegfileWrites);
 
+    ccRegfileReads
+        .name(name() + ".cc_regfile_reads")
+        .desc("number of cc regfile reads")
+        .prereq(ccRegfileReads);
+
+    ccRegfileWrites
+        .name(name() + ".cc_regfile_writes")
+        .desc("number of cc regfile writes")
+        .prereq(ccRegfileWrites);
+
     miscRegfileReads
         .name(name() + ".misc_regfile_reads")
         .desc("number of misc regfile reads")
@@ -842,13 +860,24 @@ FullO3CPU<Impl>::insertThread(ThreadID tid)
     }
 
     //Bind Float Regs to Rename Map
-    for (int freg = 0; freg < TheISA::NumFloatRegs; freg++) {
+    int max_reg = TheISA::NumIntRegs + TheISA::NumFloatRegs;
+    for (int freg = TheISA::NumIntRegs; freg < max_reg; freg++) {
         PhysRegIndex phys_reg = freeList.getFloatReg();
 
         renameMap[tid].setEntry(freg,phys_reg);
         scoreboard.setReg(phys_reg);
     }
 
+    //Bind condition-code Regs to Rename Map
+    max_reg = TheISA::NumIntRegs + TheISA::NumFloatRegs + TheISA::NumCCRegs;
+    for (int creg = TheISA::NumIntRegs + TheISA::NumFloatRegs;
+         creg < max_reg; creg++) {
+        PhysRegIndex phys_reg = freeList.getCCReg();
+
+        renameMap[tid].setEntry(creg,phys_reg);
+        scoreboard.setReg(phys_reg);
+    }
+
     //Copy Thread Data Into RegFile
     //this->copyFromTC(tid);
 
@@ -888,13 +917,24 @@ FullO3CPU<Impl>::removeThread(ThreadID tid)
     }
 
     // Unbind Float Regs from Rename Map
-    for (int freg = TheISA::NumIntRegs; freg < TheISA::NumFloatRegs; freg++) {
+    int max_reg = TheISA::NumIntRegs + TheISA::NumFloatRegs;
+    for (int freg = TheISA::NumIntRegs; freg < max_reg; freg++) {
         PhysRegIndex phys_reg = renameMap[tid].lookup(freg);
 
         scoreboard.unsetReg(phys_reg);
         freeList.addReg(phys_reg);
     }
 
+    // Unbind condition-code Regs from Rename Map
+    max_reg = TheISA::NumIntRegs + TheISA::NumFloatRegs + TheISA::NumCCRegs;
+    for (int creg = TheISA::NumIntRegs + TheISA::NumFloatRegs;
+         creg < max_reg; creg++) {
+        PhysRegIndex phys_reg = renameMap[tid].lookup(creg);
+
+        scoreboard.unsetReg(phys_reg);
+        freeList.addReg(phys_reg);
+    }
+
     // Squash Throughout Pipeline
     DynInstPtr inst = commit.rob->readHeadInst(tid);
     InstSeqNum squash_seq_num = inst->seqNum;
@@ -934,6 +974,7 @@ FullO3CPU<Impl>::activateWhenReady(ThreadID tid)
 
     bool ready = true;
 
+    // Should these all be '<' not '>='?  This seems backwards...
     if (freeList.numFreeIntRegs() >= TheISA::NumIntRegs) {
         DPRINTF(O3CPU,"[tid:%i] Suspending thread due to not enough "
                 "Phys. Int. Regs.\n",
@@ -944,6 +985,11 @@ FullO3CPU<Impl>::activateWhenReady(ThreadID tid)
                 "Phys. Float. Regs.\n",
                 tid);
         ready = false;
+    } else if (freeList.numFreeCCRegs() >= TheISA::NumCCRegs) {
+        DPRINTF(O3CPU,"[tid:%i] Suspending thread due to not enough "
+                "Phys. CC. Regs.\n",
+                tid);
+        ready = false;
     } else if (commit.rob->numFreeEntries() >=
                commit.rob->entryAmount(activeThreads.size() + 1)) {
         DPRINTF(O3CPU,"[tid:%i] Suspending thread due to not enough "
@@ -1365,6 +1411,14 @@ FullO3CPU<Impl>::readFloatRegBits(int reg_idx)
     return regFile.readFloatRegBits(reg_idx);
 }
 
+template <class Impl>
+CCReg
+FullO3CPU<Impl>::readCCReg(int reg_idx)
+{
+    ccRegfileReads++;
+    return regFile.readCCReg(reg_idx);
+}
+
 template <class Impl>
 void
 FullO3CPU<Impl>::setIntReg(int reg_idx, uint64_t val)
@@ -1389,6 +1443,14 @@ FullO3CPU<Impl>::setFloatRegBits(int reg_idx, FloatRegBits val)
     regFile.setFloatRegBits(reg_idx, val);
 }
 
+template <class Impl>
+void
+FullO3CPU<Impl>::setCCReg(int reg_idx, CCReg val)
+{
+    ccRegfileWrites++;
+    regFile.setCCReg(reg_idx, val);
+}
+
 template <class Impl>
 uint64_t
 FullO3CPU<Impl>::readArchIntReg(int reg_idx, ThreadID tid)
@@ -1419,6 +1481,16 @@ FullO3CPU<Impl>::readArchFloatRegInt(int reg_idx, ThreadID tid)
     return regFile.readFloatRegBits(phys_reg);
 }
 
+template <class Impl>
+CCReg
+FullO3CPU<Impl>::readArchCCReg(int reg_idx, ThreadID tid)
+{
+    ccRegfileReads++;
+    PhysRegIndex phys_reg = commitRenameMap[tid].lookupCC(reg_idx);
+
+    return regFile.readCCReg(phys_reg);
+}
+
 template <class Impl>
 void
 FullO3CPU<Impl>::setArchIntReg(int reg_idx, uint64_t val, ThreadID tid)
@@ -1449,6 +1521,16 @@ FullO3CPU<Impl>::setArchFloatRegInt(int reg_idx, uint64_t val, ThreadID tid)
     regFile.setFloatRegBits(phys_reg, val);
 }
 
+template <class Impl>
+void
+FullO3CPU<Impl>::setArchCCReg(int reg_idx, CCReg val, ThreadID tid)
+{
+    ccRegfileWrites++;
+    PhysRegIndex phys_reg = commitRenameMap[tid].lookupCC(reg_idx);
+
+    regFile.setCCReg(phys_reg, val);
+}
+
 template <class Impl>
 TheISA::PCState
 FullO3CPU<Impl>::pcState(ThreadID tid)
index 1a1f8f8a388cd51fbfbf244806fd01e7fb3d3010..18b75948f7613fc11937703d23e2d798057dda87 100644 (file)
@@ -540,18 +540,24 @@ class FullO3CPU : public BaseO3CPU
 
     TheISA::FloatRegBits readFloatRegBits(int reg_idx);
 
+    TheISA::CCReg readCCReg(int reg_idx);
+
     void setIntReg(int reg_idx, uint64_t val);
 
     void setFloatReg(int reg_idx, TheISA::FloatReg val);
 
     void setFloatRegBits(int reg_idx, TheISA::FloatRegBits val);
 
+    void setCCReg(int reg_idx, TheISA::CCReg val);
+
     uint64_t readArchIntReg(int reg_idx, ThreadID tid);
 
     float readArchFloatReg(int reg_idx, ThreadID tid);
 
     uint64_t readArchFloatRegInt(int reg_idx, ThreadID tid);
 
+    TheISA::CCReg readArchCCReg(int reg_idx, ThreadID tid);
+
     /** Architectural register accessors.  Looks up in the commit
      * rename table to obtain the true physical index of the
      * architected register first, then accesses that physical
@@ -563,6 +569,8 @@ class FullO3CPU : public BaseO3CPU
 
     void setArchFloatRegInt(int reg_idx, uint64_t val, ThreadID tid);
 
+    void setArchCCReg(int reg_idx, TheISA::CCReg val, ThreadID tid);
+
     /** Sets the commit PC state of a specific thread. */
     void pcState(const TheISA::PCState &newPCState, ThreadID tid);
 
@@ -846,6 +854,9 @@ class FullO3CPU : public BaseO3CPU
     //number of float register file accesses
     Stats::Scalar fpRegfileReads;
     Stats::Scalar fpRegfileWrites;
+    //number of CC register file accesses
+    Stats::Scalar ccRegfileReads;
+    Stats::Scalar ccRegfileWrites;
     //number of misc
     Stats::Scalar miscRegfileReads;
     Stats::Scalar miscRegfileWrites;
index 15a82851bd4e1776fde0370b263e0690b81e8293..5477f46d68e1060ce2d93527c989f0d266c37ff4 100644 (file)
@@ -78,6 +78,9 @@ class BaseO3DynInst : public BaseDynInst<Impl>
     typedef TheISA::IntReg   IntReg;
     typedef TheISA::FloatReg FloatReg;
     typedef TheISA::FloatRegBits FloatRegBits;
+#ifdef ISA_HAS_CC_REGS
+    typedef TheISA::CCReg   CCReg;
+#endif
     /** Misc register index type. */
     typedef TheISA::MiscReg  MiscReg;
 
@@ -222,6 +225,10 @@ class BaseO3DynInst : public BaseDynInst<Impl>
                 this->setFloatRegOperandBits(this->staticInst.get(), idx,
                                              this->cpu->readFloatRegBits(prev_phys_reg));
                 break;
+              case CCRegClass:
+                this->setCCRegOperand(this->staticInst.get(), idx,
+                                      this->cpu->readCCReg(prev_phys_reg));
+                break;
               case MiscRegClass:
                 // no need to forward misc reg values
                 break;
@@ -265,6 +272,11 @@ class BaseO3DynInst : public BaseDynInst<Impl>
         return this->cpu->readFloatRegBits(this->_srcRegIdx[idx]);
     }
 
+    uint64_t readCCRegOperand(const StaticInst *si, int idx)
+    {
+        return this->cpu->readCCReg(this->_srcRegIdx[idx]);
+    }
+
     /** @todo: Make results into arrays so they can handle multiple dest
      *  registers.
      */
@@ -287,6 +299,12 @@ class BaseO3DynInst : public BaseDynInst<Impl>
         BaseDynInst<Impl>::setFloatRegOperandBits(si, idx, val);
     }
 
+    void setCCRegOperand(const StaticInst *si, int idx, uint64_t val)
+    {
+        this->cpu->setCCReg(this->_destRegIdx[idx], val);
+        BaseDynInst<Impl>::setCCRegOperand(si, idx, val);
+    }
+
 #if THE_ISA == MIPS_ISA
     uint64_t readRegOtherThread(int misc_reg)
     {
index 0c8a16d0dde599daccb2264bb26938a93967de89..a9544587efaaded4e992dc3ce1dcf2bcdf3a20d0 100644 (file)
@@ -29,7 +29,9 @@
  * Authors: Kevin Lim
  */
 
+#include "arch/registers.hh"
 #include "base/trace.hh"
+#include "config/the_isa.hh"
 #include "cpu/o3/free_list.hh"
 #include "debug/FreeList.hh"
 
index 3919d0afb3bf4739c573e26a556328290f3ded54..aa805e26e0d93fa8744a06ece1657f0b32b12987 100644 (file)
@@ -106,6 +106,9 @@ class UnifiedFreeList
     /** The list of free floating point registers. */
     SimpleFreeList floatList;
 
+    /** The list of free condition-code registers. */
+    SimpleFreeList ccList;
+
     /**
      * The register file object is used only to distinguish integer
      * from floating-point physical register indices.
@@ -133,12 +136,18 @@ class UnifiedFreeList
     /** Gives the name of the freelist. */
     std::string name() const { return _name; };
 
+    /** Returns a pointer to the condition-code free list */
+    SimpleFreeList *getCCList() { return &ccList; }
+
     /** Gets a free integer register. */
     PhysRegIndex getIntReg() { return intList.getReg(); }
 
     /** Gets a free fp register. */
     PhysRegIndex getFloatReg() { return floatList.getReg(); }
 
+    /** Gets a free cc register. */
+    PhysRegIndex getCCReg() { return ccList.getReg(); }
+
     /** Adds a register back to the free list. */
     void addReg(PhysRegIndex freed_reg);
 
@@ -148,17 +157,26 @@ class UnifiedFreeList
     /** Adds a fp register back to the free list. */
     void addFloatReg(PhysRegIndex freed_reg) { floatList.addReg(freed_reg); }
 
+    /** Adds a cc register back to the free list. */
+    void addCCReg(PhysRegIndex freed_reg) { ccList.addReg(freed_reg); }
+
     /** Checks if there are any free integer registers. */
     bool hasFreeIntRegs() const { return intList.hasFreeRegs(); }
 
     /** Checks if there are any free fp registers. */
     bool hasFreeFloatRegs() const { return floatList.hasFreeRegs(); }
 
+    /** Checks if there are any free cc registers. */
+    bool hasFreeCCRegs() const { return ccList.hasFreeRegs(); }
+
     /** Returns the number of free integer registers. */
     unsigned numFreeIntRegs() const { return intList.numFreeRegs(); }
 
     /** Returns the number of free fp registers. */
     unsigned numFreeFloatRegs() const { return floatList.numFreeRegs(); }
+
+    /** Returns the number of free cc registers. */
+    unsigned numFreeCCRegs() const { return ccList.numFreeRegs(); }
 };
 
 inline void
@@ -169,9 +187,11 @@ UnifiedFreeList::addReg(PhysRegIndex freed_reg)
     //already in there.  A bit vector or something similar would be useful.
     if (regFile->isIntPhysReg(freed_reg)) {
         intList.addReg(freed_reg);
-    } else {
-        assert(regFile->isFloatPhysReg(freed_reg));
+    } else if (regFile->isFloatPhysReg(freed_reg)) {
         floatList.addReg(freed_reg);
+    } else {
+        assert(regFile->isCCPhysReg(freed_reg));
+        ccList.addReg(freed_reg);
     }
 
     // These assert conditions ensure that the number of free
index 15190970dad214500969bf76ea6985e14a47433e..212829ec18be4a2fa492145e2c4e81e4826dcc62 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2011-2012 ARM Limited
+ * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved.
  *
  * The license below extends only to copyright in the software and shall
@@ -414,12 +415,6 @@ class InstructionQueue
     /** The number of physical registers in the CPU. */
     unsigned numPhysRegs;
 
-    /** The number of physical integer registers in the CPU. */
-    unsigned numPhysIntRegs;
-
-    /** The number of floating point registers in the CPU. */
-    unsigned numPhysFloatRegs;
-
     /** Delay between commit stage and the IQ.
      *  @todo: Make there be a distinction between the delays within IEW.
      */
index 3e3325beb529aa4ed154c35ab684efe6ab3ec1b6..1c86b7c89ee88993732d5aa3a85f50079204ed37 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2011-2012 ARM Limited
+ * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved.
  *
  * The license below extends only to copyright in the software and shall
@@ -87,16 +88,15 @@ InstructionQueue<Impl>::InstructionQueue(O3CPU *cpu_ptr, IEW *iew_ptr,
       fuPool(params->fuPool),
       numEntries(params->numIQEntries),
       totalWidth(params->issueWidth),
-      numPhysIntRegs(params->numPhysIntRegs),
-      numPhysFloatRegs(params->numPhysFloatRegs),
       commitToIEWDelay(params->commitToIEWDelay)
 {
     assert(fuPool);
 
     numThreads = params->numThreads;
 
-    // Set the number of physical registers as the number of int + float
-    numPhysRegs = numPhysIntRegs + numPhysFloatRegs;
+    // Set the number of total physical registers
+    numPhysRegs = params->numPhysIntRegs + params->numPhysFloatRegs +
+        params->numPhysCCRegs;
 
     //Create an entry for each physical register within the
     //dependency graph.
index 5ba0caefc28eafb68be3f31bf974c70abdb5fe5a..96ce44bddb1e3ea4265315bf56724cfc13b7d8e1 100644 (file)
 
 
 PhysRegFile::PhysRegFile(unsigned _numPhysicalIntRegs,
-                         unsigned _numPhysicalFloatRegs)
+                         unsigned _numPhysicalFloatRegs,
+                         unsigned _numPhysicalCCRegs)
     : intRegFile(_numPhysicalIntRegs),
       floatRegFile(_numPhysicalFloatRegs),
+      ccRegFile(_numPhysicalCCRegs),
       baseFloatRegIndex(_numPhysicalIntRegs),
-      totalNumRegs(_numPhysicalIntRegs + _numPhysicalFloatRegs)
+      baseCCRegIndex(_numPhysicalIntRegs + _numPhysicalFloatRegs),
+      totalNumRegs(_numPhysicalIntRegs
+                   + _numPhysicalFloatRegs
+                   + _numPhysicalCCRegs)
 {
+    if (TheISA::NumCCRegs == 0 && _numPhysicalCCRegs != 0) {
+        // Just make this a warning and go ahead and allocate them
+        // anyway, to keep from having to add checks everywhere
+        warn("Non-zero number of physical CC regs specified, even though\n"
+             "    ISA does not use them.\n");
+    }
 }
 
 
@@ -56,9 +67,15 @@ PhysRegFile::initFreeList(UnifiedFreeList *freeList)
         freeList->addIntReg(reg_idx++);
     }
 
-    // The rest of the registers are the floating-point physical
+    // The next batch of the registers are the floating-point physical
     // registers; put them onto the floating-point free list.
-    while (reg_idx < totalNumRegs) {
+    while (reg_idx < baseCCRegIndex) {
         freeList->addFloatReg(reg_idx++);
     }
+
+    // The rest of the registers are the condition-code physical
+    // registers; put them onto the condition-code free list.
+    while (reg_idx < totalNumRegs) {
+        freeList->addCCReg(reg_idx++);
+    }
 }
index bd3a4f7308abd7804da99b8b6afa959574191b6f..8b87725caa2f33b58d916b6dd0aad40d8ff2665a 100644 (file)
@@ -55,6 +55,7 @@ class PhysRegFile
     typedef TheISA::IntReg IntReg;
     typedef TheISA::FloatReg FloatReg;
     typedef TheISA::FloatRegBits FloatRegBits;
+    typedef TheISA::CCReg CCReg;
 
     typedef union {
         FloatReg d;
@@ -67,6 +68,9 @@ class PhysRegFile
     /** Floating point register file. */
     std::vector<PhysFloatReg> floatRegFile;
 
+    /** Condition-code register file. */
+    std::vector<CCReg> ccRegFile;
+
     /**
      * The first floating-point physical register index.  The physical
      * register file has a single continuous index space, with the
@@ -83,6 +87,12 @@ class PhysRegFile
      */
     unsigned baseFloatRegIndex;
 
+    /**
+     * The first condition-code physical register index.  The
+     * condition-code registers follow the floating-point registers.
+     */
+    unsigned baseCCRegIndex;
+
     /** Total number of physical registers. */
     unsigned totalNumRegs;
 
@@ -92,7 +102,8 @@ class PhysRegFile
      * integer and floating point registers.
      */
     PhysRegFile(unsigned _numPhysicalIntRegs,
-                unsigned _numPhysicalFloatRegs);
+                unsigned _numPhysicalFloatRegs,
+                unsigned _numPhysicalCCRegs);
 
     /**
      * Destructor to free resources
@@ -107,7 +118,11 @@ class PhysRegFile
 
     /** @return the number of floating-point physical registers. */
     unsigned numFloatPhysRegs() const
-    { return totalNumRegs - baseFloatRegIndex; }
+    { return baseCCRegIndex - baseFloatRegIndex; }
+
+    /** @return the number of condition-code physical registers. */
+    unsigned numCCPhysRegs() const
+    { return totalNumRegs - baseCCRegIndex; }
 
     /** @return the total number of physical registers. */
     unsigned totalNumPhysRegs() const { return totalNumRegs; }
@@ -127,7 +142,16 @@ class PhysRegFile
      */
     bool isFloatPhysReg(PhysRegIndex reg_idx) const
     {
-        return (baseFloatRegIndex <= reg_idx && reg_idx < totalNumRegs);
+        return (baseFloatRegIndex <= reg_idx && reg_idx < baseCCRegIndex);
+    }
+
+    /**
+     * Return true if the specified physical register index
+     * corresponds to a condition-code physical register.
+     */
+    bool isCCPhysReg(PhysRegIndex reg_idx)
+    {
+        return (baseCCRegIndex <= reg_idx && reg_idx < totalNumRegs);
     }
 
     /** Reads an integer register. */
@@ -169,6 +193,20 @@ class PhysRegFile
         return floatRegBits;
     }
 
+    /** Reads a condition-code register. */
+    CCReg readCCReg(PhysRegIndex reg_idx)
+    {
+        assert(isCCPhysReg(reg_idx));
+
+        // Remove the base CC reg dependency.
+        PhysRegIndex reg_offset = reg_idx - baseCCRegIndex;
+
+        DPRINTF(IEW, "RegFile: Access to cc register %i, has "
+                "data %#x\n", int(reg_idx), ccRegFile[reg_offset]);
+
+        return ccRegFile[reg_offset];
+    }
+
     /** Sets an integer register to the given value. */
     void setIntReg(PhysRegIndex reg_idx, uint64_t val)
     {
@@ -211,6 +249,19 @@ class PhysRegFile
         floatRegFile[reg_offset].q = val;
     }
 
+    /** Sets a condition-code register to the given value. */
+    void setCCReg(PhysRegIndex reg_idx, CCReg val)
+    {
+        assert(isCCPhysReg(reg_idx));
+
+        // Remove the base CC reg dependency.
+        PhysRegIndex reg_offset = reg_idx - baseCCRegIndex;
+
+        DPRINTF(IEW, "RegFile: Setting cc register %i to %#x\n",
+                int(reg_idx), (uint64_t)val);
+
+        ccRegFile[reg_offset] = val;
+    }
 };
 
 
index 6bfc7d952c2543092e1298849b40d875a80ff205..38191ce36aab8b31ed498f1821067390aa5d1d11 100644 (file)
@@ -65,7 +65,8 @@ DefaultRename<Impl>::DefaultRename(O3CPU *_cpu, DerivO3CPUParams *params)
       renameWidth(params->renameWidth),
       commitWidth(params->commitWidth),
       numThreads(params->numThreads),
-      maxPhysicalRegs(params->numPhysIntRegs + params->numPhysFloatRegs)
+      maxPhysicalRegs(params->numPhysIntRegs + params->numPhysFloatRegs
+                      + params->numPhysCCRegs)
 {
     // @todo: Make into a parameter.
     skidBufferMax = (2 * (decodeToRenameDelay * params->decodeWidth)) + renameWidth;
@@ -974,6 +975,11 @@ DefaultRename<Impl>::renameSrcRegs(DynInstPtr &inst, ThreadID tid)
             fpRenameLookups++;
             break;
 
+          case CCRegClass:
+            flat_rel_src_reg = tc->flattenCCIndex(rel_src_reg);
+            renamed_reg = map->lookupCC(flat_rel_src_reg);
+            break;
+
           case MiscRegClass:
             // misc regs don't get flattened
             flat_rel_src_reg = rel_src_reg;
@@ -1034,6 +1040,12 @@ DefaultRename<Impl>::renameDestRegs(DynInstPtr &inst, ThreadID tid)
             flat_uni_dest_reg = flat_rel_dest_reg + TheISA::FP_Reg_Base;
             break;
 
+          case CCRegClass:
+            flat_rel_dest_reg = tc->flattenCCIndex(rel_dest_reg);
+            rename_result = map->renameCC(flat_rel_dest_reg);
+            flat_uni_dest_reg = flat_rel_dest_reg + TheISA::CC_Reg_Base;
+            break;
+
           case MiscRegClass:
             // misc regs don't get flattened
             flat_rel_dest_reg = rel_dest_reg;
index ecee4c721c699fe5c5e9e0674594a8f8183b1e15..d816bf1fdd33ed7fd34b5c9b34205d7a10167711 100644 (file)
@@ -97,6 +97,8 @@ UnifiedRenameMap::init(PhysRegFile *_regFile,
     intMap.init(TheISA::NumIntRegs, &(freeList->intList), _intZeroReg);
 
     floatMap.init(TheISA::NumFloatRegs, &(freeList->floatList), _floatZeroReg);
+
+    ccMap.init(TheISA::NumFloatRegs, &(freeList->ccList), (RegIndex)-1);
 }
 
 
@@ -112,6 +114,9 @@ UnifiedRenameMap::rename(RegIndex arch_reg)
       case FloatRegClass:
         return renameFloat(rel_arch_reg);
 
+      case CCRegClass:
+        return renameCC(rel_arch_reg);
+
       case MiscRegClass:
         return renameMisc(rel_arch_reg);
 
@@ -134,6 +139,9 @@ UnifiedRenameMap::lookup(RegIndex arch_reg) const
       case FloatRegClass:
         return lookupFloat(rel_arch_reg);
 
+      case CCRegClass:
+        return lookupCC(rel_arch_reg);
+
       case MiscRegClass:
         return lookupMisc(rel_arch_reg);
 
@@ -155,6 +163,9 @@ UnifiedRenameMap::setEntry(RegIndex arch_reg, PhysRegIndex phys_reg)
       case FloatRegClass:
         return setFloatEntry(rel_arch_reg, phys_reg);
 
+      case CCRegClass:
+        return setCCEntry(rel_arch_reg, phys_reg);
+
       case MiscRegClass:
         // Misc registers do not actually rename, so don't change
         // their mappings.  We end up here when a commit or squash
index c989fb88f10c6616141600f264443a7dde518603..751c39f52e1f9d0ee2257d00bf8a61df280c8897 100644 (file)
@@ -163,6 +163,9 @@ class UnifiedRenameMap
      */
     PhysRegFile *regFile;
 
+    /** The condition-code register rename map */
+    SimpleRenameMap ccMap;
+
   public:
     typedef TheISA::RegIndex RegIndex;
 
@@ -213,6 +216,17 @@ class UnifiedRenameMap
         return info;
     }
 
+    /**
+     * Perform rename() on a condition-code register, given a relative
+     * condition-code register index.
+     */
+    RenameInfo renameCC(RegIndex rel_arch_reg)
+    {
+        RenameInfo info = ccMap.rename(rel_arch_reg);
+        assert(regFile->isCCPhysReg(info.first));
+        return info;
+    }
+
     /**
      * Perform rename() on a misc register, given a relative
      * misc register index.
@@ -259,6 +273,17 @@ class UnifiedRenameMap
         return phys_reg;
     }
 
+    /**
+     * Perform lookup() on a condition-code register, given a relative
+     * condition-code register index.
+     */
+    PhysRegIndex lookupCC(RegIndex rel_arch_reg) const
+    {
+        PhysRegIndex phys_reg = ccMap.lookup(rel_arch_reg);
+        assert(regFile->isCCPhysReg(phys_reg));
+        return phys_reg;
+    }
+
     /**
      * Perform lookup() on a misc register, given a relative
      * misc register index.
@@ -301,6 +326,16 @@ class UnifiedRenameMap
         floatMap.setEntry(arch_reg, phys_reg);
     }
 
+    /**
+     * Perform setEntry() on a condition-code register, given a relative
+     * condition-code register index.
+     */
+    void setCCEntry(RegIndex arch_reg, PhysRegIndex phys_reg)
+    {
+        assert(regFile->isCCPhysReg(phys_reg));
+        ccMap.setEntry(arch_reg, phys_reg);
+    }
+
     /**
      * Return the minimum number of free entries across all of the
      * register classes.  The minimum is used so we guarantee that
index 4201878afaecd721981beb30487fba1391eb7f1a..88cf75f4f474bac081a7bc6d8e3d8dd08c793077 100755 (executable)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2011-2012 ARM Limited
+ * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -182,6 +183,10 @@ class O3ThreadContext : public ThreadContext
         return readFloatRegBitsFlat(flattenFloatIndex(reg_idx));
     }
 
+    virtual CCReg readCCReg(int reg_idx) {
+        return readCCRegFlat(flattenCCIndex(reg_idx));
+    }
+
     /** Sets an integer register to a value. */
     virtual void setIntReg(int reg_idx, uint64_t val) {
         setIntRegFlat(flattenIntIndex(reg_idx), val);
@@ -195,6 +200,10 @@ class O3ThreadContext : public ThreadContext
         setFloatRegBitsFlat(flattenFloatIndex(reg_idx), val);
     }
 
+    virtual void setCCReg(int reg_idx, CCReg val) {
+        setCCRegFlat(flattenCCIndex(reg_idx), val);
+    }
+
     /** Reads this thread's PC state. */
     virtual TheISA::PCState pcState()
     { return cpu->pcState(thread->threadId()); }
@@ -234,6 +243,7 @@ class O3ThreadContext : public ThreadContext
 
     virtual int flattenIntIndex(int reg);
     virtual int flattenFloatIndex(int reg);
+    virtual int flattenCCIndex(int reg);
 
     /** Returns the number of consecutive store conditional failures. */
     // @todo: Figure out where these store cond failures should go.
@@ -283,6 +293,9 @@ class O3ThreadContext : public ThreadContext
 
     virtual FloatRegBits readFloatRegBitsFlat(int idx);
     virtual void setFloatRegBitsFlat(int idx, FloatRegBits val);
+
+    virtual CCReg readCCRegFlat(int idx);
+    virtual void setCCRegFlat(int idx, CCReg val);
 };
 
 #endif
index f818cc3dc79c85c326d1ef5c47629bb9c231f973..006d325fc2ee235135f7d505fd51d0ecbe6c8571 100755 (executable)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2010-2012 ARM Limited
+ * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -205,6 +206,13 @@ O3ThreadContext<Impl>::readFloatRegBitsFlat(int reg_idx)
     return cpu->readArchFloatRegInt(reg_idx, thread->threadId());
 }
 
+template <class Impl>
+TheISA::CCReg
+O3ThreadContext<Impl>::readCCRegFlat(int reg_idx)
+{
+    return cpu->readArchCCReg(reg_idx, thread->threadId());
+}
+
 template <class Impl>
 void
 O3ThreadContext<Impl>::setIntRegFlat(int reg_idx, uint64_t val)
@@ -232,6 +240,15 @@ O3ThreadContext<Impl>::setFloatRegBitsFlat(int reg_idx, FloatRegBits val)
     conditionalSquash();
 }
 
+template <class Impl>
+void
+O3ThreadContext<Impl>::setCCRegFlat(int reg_idx, TheISA::CCReg val)
+{
+    cpu->setArchCCReg(reg_idx, val, thread->threadId());
+
+    conditionalSquash();
+}
+
 template <class Impl>
 void
 O3ThreadContext<Impl>::pcState(const TheISA::PCState &val)
@@ -264,6 +281,13 @@ O3ThreadContext<Impl>::flattenFloatIndex(int reg)
     return cpu->isa[thread->threadId()]->flattenFloatIndex(reg);
 }
 
+template <class Impl>
+int
+O3ThreadContext<Impl>::flattenCCIndex(int reg)
+{
+    return cpu->isa[thread->threadId()]->flattenCCIndex(reg);
+}
+
 template <class Impl>
 void
 O3ThreadContext<Impl>::setMiscRegNoEffect(int misc_reg, const MiscReg &val)
index fcab901cf836d8d2a627e187af50c9519a1fc1be..b4b49a55b28ae6d000c1ed762497e144c0a1a1de 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2006 The Regents of The University of Michigan
+ * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -768,6 +769,13 @@ OzoneCPU<Impl>::OzoneTC::readFloatRegBits(int reg_idx)
     return thread->renameTable[idx]->readIntResult();
 }
 
+template <class Impl>
+CCReg
+OzoneCPU<Impl>::OzoneTC::readCCReg(int reg_idx)
+{
+    return thread->renameTable[reg_idx]->readCCResult();
+}
+
 template <class Impl>
 void
 OzoneCPU<Impl>::OzoneTC::setIntReg(int reg_idx, uint64_t val)
@@ -799,6 +807,17 @@ OzoneCPU<Impl>::OzoneTC::setFloatRegBits(int reg_idx, FloatRegBits val)
     panic("Unimplemented!");
 }
 
+template <class Impl>
+void
+OzoneCPU<Impl>::OzoneTC::setCCReg(int reg_idx, CCReg val)
+{
+    thread->renameTable[reg_idx]->setCCResult(val);
+
+    if (!thread->noSquashFromTC) {
+        cpu->squashFromTC();
+    }
+}
+
 template <class Impl>
 void
 OzoneCPU<Impl>::OzoneTC::setPC(Addr val)
index a3de17b8b834c8a9eff197517752965a88741c83..1805eae133a42b693e804d5508957b0c9f624a71 100644 (file)
@@ -33,5 +33,6 @@
 const char *RegClassStrings[] = {
     "IntRegClass",
     "FloatRegClass",
+    "CCRegClass",
     "MiscRegClass"
 };
index c9d4b1c4fec26dfebe58dbe4c762c9dd930fceca..549ebab2627d2619f50f977f27194ea7ed50bf07 100644 (file)
@@ -41,6 +41,7 @@
 enum RegClass {
     IntRegClass,        ///< Integer register
     FloatRegClass,      ///< Floating-point register
+    CCRegClass,         ///< Condition-code register
     MiscRegClass        ///< Control (misc) register
 };
 
@@ -72,9 +73,15 @@ RegClass regIdxToClass(TheISA::RegIndex reg_idx,
     if (reg_idx < TheISA::FP_Reg_Base) {
         cl = IntRegClass;
         offset = 0;
-    } else if (reg_idx < TheISA::Misc_Reg_Base) {
+    } else if (reg_idx < TheISA::CC_Reg_Base) {
         cl = FloatRegClass;
         offset = TheISA::FP_Reg_Base;
+    } else if (reg_idx < TheISA::Misc_Reg_Base) {
+        // if there are no CC regs, the ISA should set
+        // CC_Reg_Base == Misc_Reg_Base so the if above
+        // never succeeds
+        cl = CCRegClass;
+        offset = TheISA::CC_Reg_Base;
     } else {
         cl = MiscRegClass;
         offset = TheISA::Misc_Reg_Base;
index 012a49253dc221dc736810dc9363a622ab6e222a..078f490e8d54fb31d70ac264fd7a14d0238f94a3 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2010-2012 ARM Limited
+ * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -211,6 +212,18 @@ BaseSimpleCPU::regStats()
         .desc("number of times the floating registers were written")
         ;
 
+    numCCRegReads
+        .name(name() + ".num_cc_register_reads")
+        .desc("number of times the CC registers were read")
+        .flags(nozero)
+        ;
+
+    numCCRegWrites
+        .name(name() + ".num_cc_register_writes")
+        .desc("number of times the CC registers were written")
+        .flags(nozero)
+        ;
+
     numMemRefs
         .name(name()+".num_mem_refs")
         .desc("number of memory refs")
index f2e1b278a316e8f3979b7f121c2218a20df68294..8134465af10ff48903d2631271d8f87aedb22510 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2011-2012 ARM Limited
+ * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -84,6 +85,7 @@ class BaseSimpleCPU : public BaseCPU
     typedef TheISA::MiscReg MiscReg;
     typedef TheISA::FloatReg FloatReg;
     typedef TheISA::FloatRegBits FloatRegBits;
+    typedef TheISA::CCReg CCReg;
 
   protected:
     Trace::InstRecord *traceData;
@@ -231,6 +233,10 @@ class BaseSimpleCPU : public BaseCPU
     Stats::Scalar numFpRegReads;
     Stats::Scalar numFpRegWrites;
 
+    //number of condition code register file accesses
+    Stats::Scalar numCCRegReads;
+    Stats::Scalar numCCRegWrites;
+
     // number of simulated memory references
     Stats::Scalar numMemRefs;
     Stats::Scalar numLoadInsts;
@@ -307,6 +313,13 @@ class BaseSimpleCPU : public BaseCPU
         return thread->readFloatRegBits(reg_idx);
     }
 
+    CCReg readCCRegOperand(const StaticInst *si, int idx)
+    {
+        numCCRegReads++;
+        int reg_idx = si->srcRegIdx(idx) - TheISA::CC_Reg_Base;
+        return thread->readCCReg(reg_idx);
+    }
+
     void setIntRegOperand(const StaticInst *si, int idx, uint64_t val)
     {
         numIntRegWrites++;
@@ -328,6 +341,13 @@ class BaseSimpleCPU : public BaseCPU
         thread->setFloatRegBits(reg_idx, val);
     }
 
+    void setCCRegOperand(const StaticInst *si, int idx, CCReg val)
+    {
+        numCCRegWrites++;
+        int reg_idx = si->destRegIdx(idx) - TheISA::CC_Reg_Base;
+        thread->setCCReg(reg_idx, val);
+    }
+
     bool readPredicate() { return thread->readPredicate(); }
     void setPredicate(bool val)
     {
index d752ed105daae1af4f689baad465b9a0cd122c35..fa0d20b0a2c6ac8891ea95e8f87648eddf6186b1 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2011 ARM Limited
+ * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -54,6 +55,7 @@
 #include "config/the_isa.hh"
 #include "cpu/thread_context.hh"
 #include "cpu/thread_state.hh"
+#include "debug/CCRegs.hh"
 #include "debug/FloatRegs.hh"
 #include "debug/IntRegs.hh"
 #include "mem/page_table.hh"
@@ -99,6 +101,7 @@ class SimpleThread : public ThreadState
     typedef TheISA::MiscReg MiscReg;
     typedef TheISA::FloatReg FloatReg;
     typedef TheISA::FloatRegBits FloatRegBits;
+    typedef TheISA::CCReg CCReg;
   public:
     typedef ThreadContext::Status Status;
 
@@ -108,6 +111,9 @@ class SimpleThread : public ThreadState
         FloatRegBits i[TheISA::NumFloatRegs];
     } floatRegs;
     TheISA::IntReg intRegs[TheISA::NumIntRegs];
+#ifdef ISA_HAS_CC_REGS
+    TheISA::CCReg ccRegs[TheISA::NumCCRegs];
+#endif
     TheISA::ISA *const isa;    // one "instance" of the current ISA.
 
     TheISA::PCState _pcState;
@@ -224,6 +230,9 @@ class SimpleThread : public ThreadState
         _pcState = 0;
         memset(intRegs, 0, sizeof(intRegs));
         memset(floatRegs.i, 0, sizeof(floatRegs.i));
+#ifdef ISA_HAS_CC_REGS
+        memset(ccRegs, 0, sizeof(ccRegs));
+#endif
         isa->clear();
     }
 
@@ -260,6 +269,21 @@ class SimpleThread : public ThreadState
         return regVal;
     }
 
+    CCReg readCCReg(int reg_idx)
+    {
+#ifdef ISA_HAS_CC_REGS
+        int flatIndex = isa->flattenCCIndex(reg_idx);
+        assert(flatIndex < TheISA::NumCCRegs);
+        uint64_t regVal(readCCRegFlat(flatIndex));
+        DPRINTF(CCRegs, "Reading CC reg %d (%d) as %#x.\n",
+                reg_idx, flatIndex, regVal);
+        return regVal;
+#else
+        panic("Tried to read a CC register.");
+        return 0;
+#endif
+    }
+
     void setIntReg(int reg_idx, uint64_t val)
     {
         int flatIndex = isa->flattenIntIndex(reg_idx);
@@ -290,6 +314,19 @@ class SimpleThread : public ThreadState
                 reg_idx, flatIndex, val, floatRegs.f[flatIndex]);
     }
 
+    void setCCReg(int reg_idx, CCReg val)
+    {
+#ifdef ISA_HAS_CC_REGS
+        int flatIndex = isa->flattenCCIndex(reg_idx);
+        assert(flatIndex < TheISA::NumCCRegs);
+        DPRINTF(CCRegs, "Setting CC reg %d (%d) to %#x.\n",
+                reg_idx, flatIndex, val);
+        setCCRegFlat(flatIndex, val);
+#else
+        panic("Tried to set a CC register.");
+#endif
+    }
+
     TheISA::PCState
     pcState()
     {
@@ -372,6 +409,12 @@ class SimpleThread : public ThreadState
         return isa->flattenFloatIndex(reg);
     }
 
+    int
+    flattenCCIndex(int reg)
+    {
+        return isa->flattenCCIndex(reg);
+    }
+
     unsigned readStCondFailures() { return storeCondFailures; }
 
     void setStCondFailures(unsigned sc_failures)
@@ -393,6 +436,16 @@ class SimpleThread : public ThreadState
         floatRegs.i[idx] = val;
     }
 
+#ifdef ISA_HAS_CC_REGS
+    CCReg readCCRegFlat(int idx) { return ccRegs[idx]; }
+    void setCCRegFlat(int idx, CCReg val) { ccRegs[idx] = val; }
+#else
+    CCReg readCCRegFlat(int idx)
+    { panic("readCCRegFlat w/no CC regs!\n"); }
+
+    void setCCRegFlat(int idx, CCReg val)
+    { panic("setCCRegFlat w/no CC regs!\n"); }
+#endif
 };
 
 
index 0464eda145b54ff1cce8f8a5c99826b1471d7263..66f254e34ca31232208c1b7e25bbdaecb1e33d24 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -110,6 +111,7 @@ class StaticInst : public RefCounted
 
         IsInteger,      ///< References integer regs.
         IsFloating,     ///< References FP regs.
+        IsCC,           ///< References CC regs.
 
         IsMemRef,       ///< References memory (load, store, or prefetch).
         IsLoad,         ///< Reads from memory (load or prefetch).
@@ -181,6 +183,7 @@ class StaticInst : public RefCounted
     //@{
     int8_t _numFPDestRegs;
     int8_t _numIntDestRegs;
+    int8_t _numCCDestRegs;
     //@}
 
   public:
@@ -220,6 +223,7 @@ class StaticInst : public RefCounted
 
     bool isInteger()      const { return flags[IsInteger]; }
     bool isFloating()     const { return flags[IsFloating]; }
+    bool isCC()           const { return flags[IsCC]; }
 
     bool isControl()      const { return flags[IsControl]; }
     bool isCall()         const { return flags[IsCall]; }
index a5a05a2648501dd6efb61a6e8d1cb5d5d23dc0e9..09f91746af042d19845adafd4f5b9c754dfb14c5 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2012 ARM Limited
+ * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -79,6 +80,14 @@ ThreadContext::compare(ThreadContext *one, ThreadContext *two)
                   i, t1, t2);
     }
 
+    // loop through the Condition Code registers.
+    for (int i = 0; i < TheISA::NumCCRegs; ++i) {
+        TheISA::CCReg t1 = one->readCCReg(i);
+        TheISA::CCReg t2 = two->readCCReg(i);
+        if (t1 != t2)
+            panic("CC reg idx %d doesn't match, one: %#x, two: %#x",
+                  i, t1, t2);
+    }
     if (!(one->pcState() == two->pcState()))
         panic("PC state doesn't match.");
     int id1 = one->cpuId();
@@ -111,6 +120,13 @@ serialize(ThreadContext &tc, std::ostream &os)
         intRegs[i] = tc.readIntRegFlat(i);
     SERIALIZE_ARRAY(intRegs, NumIntRegs);
 
+#ifdef ISA_HAS_CC_REGS
+    CCReg ccRegs[NumCCRegs];
+    for (int i = 0; i < NumCCRegs; ++i)
+        ccRegs[i] = tc.readCCRegFlat(i);
+    SERIALIZE_ARRAY(ccRegs, NumCCRegs);
+#endif
+
     tc.pcState().serialize(os);
 
     // thread_num and cpu_id are deterministic from the config
@@ -133,6 +149,13 @@ unserialize(ThreadContext &tc, Checkpoint *cp, const std::string &section)
     for (int i = 0; i < NumIntRegs; ++i)
         tc.setIntRegFlat(i, intRegs[i]);
 
+#ifdef ISA_HAS_CC_REGS
+    CCReg ccRegs[NumCCRegs];
+    UNSERIALIZE_ARRAY(ccRegs, NumCCRegs);
+    for (int i = 0; i < NumCCRegs; ++i)
+        tc.setCCRegFlat(i, ccRegs[i]);
+#endif
+
     PCState pcState;
     pcState.unserialize(cp, section);
     tc.pcState(pcState);
index dbe3c0ce83e2bb3f9449b257d789e79f5bf0179c..be18f680ff32ee718d48890ff537e1df90508c1e 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2011-2012 ARM Limited
+ * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -96,6 +97,7 @@ class ThreadContext
     typedef TheISA::IntReg IntReg;
     typedef TheISA::FloatReg FloatReg;
     typedef TheISA::FloatRegBits FloatRegBits;
+    typedef TheISA::CCReg CCReg;
     typedef TheISA::MiscReg MiscReg;
   public:
 
@@ -200,12 +202,16 @@ class ThreadContext
 
     virtual FloatRegBits readFloatRegBits(int reg_idx) = 0;
 
+    virtual CCReg readCCReg(int reg_idx) = 0;
+
     virtual void setIntReg(int reg_idx, uint64_t val) = 0;
 
     virtual void setFloatReg(int reg_idx, FloatReg val) = 0;
 
     virtual void setFloatRegBits(int reg_idx, FloatRegBits val) = 0;
 
+    virtual void setCCReg(int reg_idx, CCReg val) = 0;
+
     virtual TheISA::PCState pcState() = 0;
 
     virtual void pcState(const TheISA::PCState &val) = 0;
@@ -228,6 +234,7 @@ class ThreadContext
 
     virtual int flattenIntIndex(int reg) = 0;
     virtual int flattenFloatIndex(int reg) = 0;
+    virtual int flattenCCIndex(int reg) = 0;
 
     virtual uint64_t
     readRegOtherThread(int misc_reg, ThreadID tid)
@@ -283,6 +290,8 @@ class ThreadContext
     virtual FloatRegBits readFloatRegBitsFlat(int idx) = 0;
     virtual void setFloatRegBitsFlat(int idx, FloatRegBits val) = 0;
 
+    virtual CCReg readCCRegFlat(int idx) = 0;
+    virtual void setCCRegFlat(int idx, CCReg val) = 0;
     /** @} */
 
 };
@@ -391,6 +400,9 @@ class ProxyThreadContext : public ThreadContext
     FloatRegBits readFloatRegBits(int reg_idx)
     { return actualTC->readFloatRegBits(reg_idx); }
 
+    CCReg readCCReg(int reg_idx)
+    { return actualTC->readCCReg(reg_idx); }
+
     void setIntReg(int reg_idx, uint64_t val)
     { actualTC->setIntReg(reg_idx, val); }
 
@@ -400,6 +412,9 @@ class ProxyThreadContext : public ThreadContext
     void setFloatRegBits(int reg_idx, FloatRegBits val)
     { actualTC->setFloatRegBits(reg_idx, val); }
 
+    void setCCReg(int reg_idx, CCReg val)
+    { actualTC->setCCReg(reg_idx, val); }
+
     TheISA::PCState pcState() { return actualTC->pcState(); }
 
     void pcState(const TheISA::PCState &val) { actualTC->pcState(val); }
@@ -433,6 +448,9 @@ class ProxyThreadContext : public ThreadContext
     int flattenFloatIndex(int reg)
     { return actualTC->flattenFloatIndex(reg); }
 
+    int flattenCCIndex(int reg)
+    { return actualTC->flattenCCIndex(reg); }
+
     unsigned readStCondFailures()
     { return actualTC->readStCondFailures(); }
 
@@ -464,6 +482,12 @@ class ProxyThreadContext : public ThreadContext
 
     void setFloatRegBitsFlat(int idx, FloatRegBits val)
     { actualTC->setFloatRegBitsFlat(idx, val); }
+
+    CCReg readCCRegFlat(int idx)
+    { return actualTC->readCCRegFlat(idx); }
+
+    void setCCRegFlat(int idx, CCReg val)
+    { actualTC->setCCRegFlat(idx, val); }
 };
 
 /** @{ */