cpu: clean up architectural register classification
authorSteve Reinhardt <steve.reinhardt@amd.com>
Tue, 15 Oct 2013 18:22:42 +0000 (14:22 -0400)
committerSteve Reinhardt <steve.reinhardt@amd.com>
Tue, 15 Oct 2013 18:22:42 +0000 (14:22 -0400)
Move from a poorly documented scheme where the mapping
of unified architectural register indices to register
classes is hardcoded all over to one where there's an
enum for the register classes and a function that
encapsulates the mapping.

13 files changed:
src/arch/arm/insts/misc.cc
src/arch/arm/insts/static_inst.cc
src/arch/power/insts/static_inst.cc
src/arch/x86/insts/static_inst.cc
src/cpu/SConscript
src/cpu/checker/cpu_impl.hh
src/cpu/inorder/cpu.cc
src/cpu/inorder/cpu.hh
src/cpu/inorder/inorder_dyn_inst.cc
src/cpu/o3/dyn_inst.hh
src/cpu/o3/rename_impl.hh
src/cpu/reg_class.cc [new file with mode: 0644]
src/cpu/reg_class.hh [new file with mode: 0644]

index 7d383a87a4cab75221fd7fd9b98567e07b2cf62e..c40b6711f1a8c475fdf7385faae78ff076b5ea91 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2010 ARM Limited
+ * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -38,6 +39,7 @@
  */
 
 #include "arch/arm/insts/misc.hh"
+#include "cpu/reg_class.hh"
 
 std::string
 MrsOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
@@ -48,17 +50,17 @@ MrsOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
     ss << ", ";
     bool foundPsr = false;
     for (unsigned i = 0; i < numSrcRegs(); i++) {
-        int idx = srcRegIdx(i);
-        if (idx < Ctrl_Base_DepTag) {
+        RegIndex idx = srcRegIdx(i);
+        RegIndex rel_idx;
+        if (regIdxToClass(idx, &rel_idx) != MiscRegClass) {
             continue;
         }
-        idx -= Ctrl_Base_DepTag;
-        if (idx == MISCREG_CPSR) {
+        if (rel_idx == MISCREG_CPSR) {
             ss << "cpsr";
             foundPsr = true;
             break;
         }
-        if (idx == MISCREG_SPSR) {
+        if (rel_idx == MISCREG_SPSR) {
             ss << "spsr";
             foundPsr = true;
             break;
index 8306c620f4a1cebb917cb5d0194cb411f756c33f..3ab7dfb0e9c6470299fdac2ff26bc0175ecf6cb8 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2010 ARM Limited
+ * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -45,6 +46,7 @@
 #include "base/loader/symtab.hh"
 #include "base/condcodes.hh"
 #include "base/cprintf.hh"
+#include "cpu/reg_class.hh"
 
 namespace ArmISA
 {
@@ -208,8 +210,11 @@ ArmStaticInst::shift_carry_rs(uint32_t base, uint32_t shamt,
 void
 ArmStaticInst::printReg(std::ostream &os, int reg) const
 {
-    if (reg < FP_Base_DepTag) {
-        switch (reg) {
+    RegIndex rel_reg;
+
+    switch (regIdxToClass(reg, &rel_reg)) {
+      case IntRegClass:
+        switch (rel_reg) {
           case PCReg:
             ccprintf(os, "pc");
             break;
@@ -226,12 +231,14 @@ ArmStaticInst::printReg(std::ostream &os, int reg) const
             ccprintf(os, "r%d", reg);
             break;
         }
-    } else if (reg < Ctrl_Base_DepTag) {
-        ccprintf(os, "f%d", reg - FP_Base_DepTag);
-    } else {
-        reg -= Ctrl_Base_DepTag;
-        assert(reg < NUM_MISCREGS);
-        ccprintf(os, "%s", ArmISA::miscRegName[reg]);
+        break;
+      case FloatRegClass:
+        ccprintf(os, "f%d", rel_reg);
+        break;
+      case MiscRegClass:
+        assert(rel_reg < NUM_MISCREGS);
+        ccprintf(os, "%s", ArmISA::miscRegName[rel_reg]);
+        break;
     }
 }
 
index 1982744bf6f40090fd62340e3c92b9dc88f50b48..09b662453750bbc80d73298a7cf65b487a42524f 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2009 The University of Edinburgh
+ * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  */
 
 #include "arch/power/insts/static_inst.hh"
+#include "cpu/reg_class.hh"
 
 using namespace PowerISA;
 
 void
 PowerStaticInst::printReg(std::ostream &os, int reg) const
 {
-    if (reg < FP_Base_DepTag) {
-        ccprintf(os, "r%d", reg);
-    } else if (reg < Ctrl_Base_DepTag) {
-        ccprintf(os, "f%d", reg - FP_Base_DepTag);
-    } else {
-        switch (reg - Ctrl_Base_DepTag) {
-        case 0: ccprintf(os, "cr"); break;
-        case 1: ccprintf(os, "xer"); break;
-        case 2: ccprintf(os, "lr"); break;
-        case 3: ccprintf(os, "ctr"); break;
-        default: ccprintf(os, "unknown_reg");
+    RegIndex rel_reg;
+
+    switch (regIdxToClass(reg, &rel_reg)) {
+      case IntRegClass:
+        ccprintf(os, "r%d", rel_reg);
+        break;
+      case FloatRegClass:
+        ccprintf(os, "f%d", rel_reg);
+        break;
+      case MiscRegClass:
+        switch (rel_reg) {
+          case 0: ccprintf(os, "cr"); break;
+          case 1: ccprintf(os, "xer"); break;
+          case 2: ccprintf(os, "lr"); break;
+          case 3: ccprintf(os, "ctr"); break;
+          default: ccprintf(os, "unknown_reg");
+            break;
         }
     }
 }
index 29957e121ee18a832315f97324d1c6b06f069139..046a11fb62b086dda3c92034060f5d0158a212b0 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved.
  *
  * The license below extends only to copyright in the software and shall
@@ -39,6 +40,7 @@
 
 #include "arch/x86/insts/static_inst.hh"
 #include "arch/x86/regs/segment.hh"
+#include "cpu/reg_class.hh"
 
 namespace X86ISA
 {
@@ -129,17 +131,20 @@ namespace X86ISA
         static const char * microFormats[9] =
             {"", "t%db", "t%dw", "", "t%dd", "", "", "", "t%d"};
 
-        if (reg < FP_Base_DepTag) {
+        RegIndex rel_reg;
+
+        switch (regIdxToClass(reg, &rel_reg)) {
+          case IntRegClass: {
             const char * suffix = "";
-            bool fold = reg & IntFoldBit;
-            reg &= ~IntFoldBit;
+            bool fold = rel_reg & IntFoldBit;
+            rel_reg &= ~IntFoldBit;
 
             if(fold)
                 suffix = "h";
-            else if(reg < 8 && size == 1)
+            else if(rel_reg < 8 && size == 1)
                 suffix = "l";
 
-            switch (reg) {
+            switch (rel_reg) {
               case INTREG_RAX:
                 ccprintf(os, abcdFormats[size], "a");
                 break;
@@ -189,33 +194,39 @@ namespace X86ISA
                 ccprintf(os, longFormats[size], "15");
                 break;
               default:
-                ccprintf(os, microFormats[size], reg - NUM_INTREGS);
+                ccprintf(os, microFormats[size], rel_reg - NUM_INTREGS);
             }
             ccprintf(os, suffix);
-        } else if (reg < Ctrl_Base_DepTag) {
-            int fpindex = reg - FP_Base_DepTag;
-            if(fpindex < NumMMXRegs) {
-                ccprintf(os, "%%mmx%d", reg - FP_Base_DepTag);
+            break;
+          }
+
+          case FloatRegClass: {
+            if (rel_reg < NumMMXRegs) {
+                ccprintf(os, "%%mmx%d", rel_reg);
                 return;
             }
-            fpindex -= NumMMXRegs;
-            if(fpindex < NumXMMRegs * 2) {
-                ccprintf(os, "%%xmm%d_%s", fpindex / 2,
-                        (fpindex % 2) ? "high": "low");
+            rel_reg -= NumMMXRegs;
+            if (rel_reg < NumXMMRegs * 2) {
+                ccprintf(os, "%%xmm%d_%s", rel_reg / 2,
+                        (rel_reg % 2) ? "high": "low");
                 return;
             }
-            fpindex -= NumXMMRegs * 2;
-            if(fpindex < NumMicroFpRegs) {
-                ccprintf(os, "%%ufp%d", fpindex);
+            rel_reg -= NumXMMRegs * 2;
+            if (rel_reg < NumMicroFpRegs) {
+                ccprintf(os, "%%ufp%d", rel_reg);
                 return;
             }
-            fpindex -= NumMicroFpRegs;
-            ccprintf(os, "%%st(%d)", fpindex);
-        } else {
-            switch (reg - Ctrl_Base_DepTag) {
+            rel_reg -= NumMicroFpRegs;
+            ccprintf(os, "%%st(%d)", rel_reg);
+            break;
+          }
+
+          case MiscRegClass:
+            switch (rel_reg) {
               default:
-                ccprintf(os, "%%ctrl%d", reg - Ctrl_Base_DepTag);
+                ccprintf(os, "%%ctrl%d", rel_reg);
             }
+            break;
         }
     }
 
index 999de1e4998ba12e5470dad4dfbf8f9dc64bc751..f25758c6743b2df2a3e29f08ccc51584ea6257d0 100644 (file)
@@ -118,6 +118,7 @@ Source('nativetrace.cc')
 Source('pc_event.cc')
 Source('profile.cc')
 Source('quiesce_event.cc')
+Source('reg_class.cc')
 Source('static_inst.cc')
 Source('simple_thread.cc')
 Source('thread_context.cc')
index 49ff8eaa178e393faad3bac93626dc6c66a940a2..1967e02f369c18d5cfdd794fe11dc4270228dc7c 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
@@ -50,6 +51,7 @@
 #include "config/the_isa.hh"
 #include "cpu/base_dyn_inst.hh"
 #include "cpu/exetrace.hh"
+#include "cpu/reg_class.hh"
 #include "cpu/simple_thread.hh"
 #include "cpu/static_inst.hh"
 #include "cpu/thread_context.hh"
@@ -597,13 +599,17 @@ Checker<Impl>::copyResult(DynInstPtr &inst, uint64_t mismatch_val,
     // so do the fix-up then start with the next dest reg;
     if (start_idx >= 0) {
         RegIndex idx = inst->destRegIdx(start_idx);
-        if (idx < TheISA::FP_Base_DepTag) {
+        switch (regIdxToClass(idx)) {
+          case IntRegClass:
             thread->setIntReg(idx, mismatch_val);
-        } else if (idx < TheISA::Ctrl_Base_DepTag) {
+            break;
+          case FloatRegClass:
             thread->setFloatRegBits(idx, mismatch_val);
-        } else if (idx < TheISA::Max_DepTag) {
+            break;
+          case MiscRegClass:
             thread->setMiscReg(idx - TheISA::Ctrl_Base_DepTag,
                                mismatch_val);
+            break;
         }
     }
     start_idx++;
@@ -611,14 +617,19 @@ Checker<Impl>::copyResult(DynInstPtr &inst, uint64_t mismatch_val,
     for (int i = start_idx; i < inst->numDestRegs(); i++) {
         RegIndex idx = inst->destRegIdx(i);
         inst->template popResult<uint64_t>(res);
-        if (idx < TheISA::FP_Base_DepTag) {
+        switch (regIdxToClass(idx)) {
+          case IntRegClass:
             thread->setIntReg(idx, res);
-        } else if (idx < TheISA::Ctrl_Base_DepTag) {
+            break;
+          case FloatRegClass:
             thread->setFloatRegBits(idx, res);
-        } else if (idx < TheISA::Max_DepTag) {
+            break;
+          case MiscRegClass:
             // Try to get the proper misc register index for ARM here...
             thread->setMiscReg(idx - TheISA::Ctrl_Base_DepTag, res);
-        } // else Register is out of range...
+            break;
+            // else Register is out of range...
+        }
     }
 }
 
index 2c6b49d82a284c73f96c84462f19f9d4c93cc318..233d532ddbaccd532d841bb31887546dd5b25e1a 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
@@ -59,6 +60,7 @@
 #include "cpu/base.hh"
 #include "cpu/exetrace.hh"
 #include "cpu/quiesce_event.hh"
+#include "cpu/reg_class.hh"
 #include "cpu/simple_thread.hh"
 #include "cpu/thread_context.hh"
 #include "debug/Activity.hh"
@@ -1257,16 +1259,23 @@ InOrderCPU::getPipeStage(int stage_num)
 RegIndex
 InOrderCPU::flattenRegIdx(RegIndex reg_idx, RegType &reg_type, ThreadID tid)
 {
-    if (reg_idx < FP_Base_DepTag) {
+    RegIndex rel_idx;
+
+    switch (regIdxToClass(reg_idx, &rel_idx)) {
+      case IntRegClass:
         reg_type = IntType;
-        return isa[tid]->flattenIntIndex(reg_idx);
-    } else if (reg_idx < Ctrl_Base_DepTag) {
+        return isa[tid]->flattenIntIndex(rel_idx);
+
+      case FloatRegClass:
         reg_type = FloatType;
-        reg_idx -= FP_Base_DepTag;
-        return isa[tid]->flattenFloatIndex(reg_idx);
-    } else {
+        return isa[tid]->flattenFloatIndex(rel_idx);
+
+      case MiscRegClass:
         reg_type = MiscType;
-        return reg_idx - TheISA::Ctrl_Base_DepTag;
+        return rel_idx;
+
+      default:
+        panic("register %d out of range\n", reg_idx);
     }
 }
 
@@ -1344,18 +1353,25 @@ InOrderCPU::readRegOtherThread(unsigned reg_idx, ThreadID tid)
         tid = TheISA::getTargetThread(tcBase(tid));
     }
 
-    if (reg_idx < FP_Base_DepTag) {                   
+    RegIndex rel_idx;
+
+    switch (regIdxToClass(reg_idx, &rel_idx)) {
+      case IntRegClass:
         // Integer Register File
-        return readIntReg(reg_idx, tid);
-    } else if (reg_idx < Ctrl_Base_DepTag) {          
+        return readIntReg(rel_idx, tid);
+
+      case FloatRegClass:
         // Float Register File
-        reg_idx -= FP_Base_DepTag;
-        return readFloatRegBits(reg_idx, tid);
-    } else {
-        reg_idx -= Ctrl_Base_DepTag;
-        return readMiscReg(reg_idx, tid);  // Misc. Register File
+        return readFloatRegBits(rel_idx, tid);
+
+      case MiscRegClass:
+        return readMiscReg(rel_idx, tid);  // Misc. Register File
+
+      default:
+        panic("register %d out of range\n", reg_idx);
     }
 }
+
 void
 InOrderCPU::setRegOtherThread(unsigned reg_idx, const MiscReg &val,
                               ThreadID tid)
@@ -1365,14 +1381,20 @@ InOrderCPU::setRegOtherThread(unsigned reg_idx, const MiscReg &val,
         tid = TheISA::getTargetThread(tcBase(tid));
     }
 
-    if (reg_idx < FP_Base_DepTag) {            // Integer Register File
-        setIntReg(reg_idx, val, tid);
-    } else if (reg_idx < Ctrl_Base_DepTag) {   // Float Register File
-        reg_idx -= FP_Base_DepTag;
-        setFloatRegBits(reg_idx, val, tid);
-    } else {
-        reg_idx -= Ctrl_Base_DepTag;
-        setMiscReg(reg_idx, val, tid); // Misc. Register File
+    RegIndex rel_idx;
+
+    switch (regIdxToClass(reg_idx, &rel_idx)) {
+      case IntRegClass:
+        setIntReg(rel_idx, val, tid);
+        break;
+
+      case FloatRegClass:
+        setFloatRegBits(rel_idx, val, tid);
+        break;
+
+      case MiscRegClass:
+        setMiscReg(rel_idx, val, tid); // Misc. Register File
+        break;
     }
 }
 
index e69c9d47b0f508a0da909692d9bd7351ddb44f6c..6f189f8c97396a686773e3ab68d94622ea652d53 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2012-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
@@ -65,6 +66,7 @@
 #include "cpu/o3/rename_map.hh"
 #include "cpu/activity.hh"
 #include "cpu/base.hh"
+#include "cpu/reg_class.hh"
 #include "cpu/simple_thread.hh"
 #include "cpu/timebuf.hh"
 #include "mem/packet.hh"
@@ -599,12 +601,19 @@ class InOrderCPU : public BaseCPU
 
     RegType inline getRegType(RegIndex reg_idx)
     {
-        if (reg_idx < TheISA::FP_Base_DepTag)
+        switch (regIdxToClass(reg_idx)) {
+          case IntRegClass:
             return IntType;
-        else if (reg_idx < TheISA::Ctrl_Base_DepTag)
+
+          case FloatRegClass:
             return FloatType;
-        else
+
+          case MiscRegClass:
             return MiscType;
+
+          default:
+            panic("register %d out of range\n", reg_idx);
+        }
     }
 
     RegIndex flattenRegIdx(RegIndex reg_idx, RegType &reg_type, ThreadID tid);
index dcf0ce6ae9beea2eec3577b40c246521926a03d4..c2765a3ba25958861174ff0017a3fab15a0e7dd8 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2007 MIPS Technologies, Inc.
+ * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -42,6 +43,7 @@
 #include "cpu/inorder/cpu.hh"
 #include "cpu/inorder/inorder_dyn_inst.hh"
 #include "cpu/exetrace.hh"
+#include "cpu/reg_class.hh"
 #include "debug/InOrderDynInst.hh"
 #include "mem/request.hh"
 #include "sim/fault_fwd.hh"
@@ -473,14 +475,21 @@ InOrderDynInst::readRegOtherThread(unsigned reg_idx, ThreadID tid)
         tid = TheISA::getTargetThread(this->cpu->tcBase(threadNumber));
     }
 
-    if (reg_idx < FP_Base_DepTag) {                   // Integer Register File
-        return this->cpu->readIntReg(reg_idx, tid);
-    } else if (reg_idx < Ctrl_Base_DepTag) {          // Float Register File
-        reg_idx -= FP_Base_DepTag;
-        return this->cpu->readFloatRegBits(reg_idx, tid);
-    } else {
-        reg_idx -= Ctrl_Base_DepTag;
-        return this->cpu->readMiscReg(reg_idx, tid);  // Misc. Register File
+    RegIndex rel_idx;
+
+    switch (regIdxToClass(reg_idx, &rel_idx)) {
+      case IntRegClass:
+        return this->cpu->readIntReg(rel_idx, tid);
+
+      case FloatRegClass:
+        return this->cpu->readFloatRegBits(rel_idx, tid);
+
+      case MiscRegClass:
+        return this->cpu->readMiscReg(rel_idx, tid);  // Misc. Register File
+
+      default:
+        panic("register %d out of range\n", reg_idx);
+
     }
 }
 
@@ -542,14 +551,20 @@ InOrderDynInst::setRegOtherThread(unsigned reg_idx, const MiscReg &val,
         tid = TheISA::getTargetThread(this->cpu->tcBase(threadNumber));
     }
 
-    if (reg_idx < FP_Base_DepTag) {            // Integer Register File
-        this->cpu->setIntReg(reg_idx, val, tid);
-    } else if (reg_idx < Ctrl_Base_DepTag) {   // Float Register File
-        reg_idx -= FP_Base_DepTag;
-        this->cpu->setFloatRegBits(reg_idx, val, tid);
-    } else {
-        reg_idx -= Ctrl_Base_DepTag;
-        this->cpu->setMiscReg(reg_idx, val, tid); // Misc. Register File
+    RegIndex rel_idx;
+
+    switch (regIdxToClass(reg_idx, &rel_idx)) {
+      case IntRegClass:
+        this->cpu->setIntReg(rel_idx, val, tid);
+        break;
+
+      case FloatRegClass:
+        this->cpu->setFloatRegBits(rel_idx, val, tid);
+        break;
+
+      case MiscRegClass:
+        this->cpu->setMiscReg(rel_idx, val, tid); // Misc. Register File
+        break;
     }
 }
 
index 082c1f5d4f4f888b99d25f6f16a5fd7d39ae4e13..ece42b81a2cdb3fea3cebb7a1ee6601fd2192be6 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2010 ARM Limited
+ * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -49,6 +50,7 @@
 #include "cpu/o3/isa_specific.hh"
 #include "cpu/base_dyn_inst.hh"
 #include "cpu/inst_seq.hh"
+#include "cpu/reg_class.hh"
 
 class Packet;
 
@@ -209,11 +211,21 @@ class BaseO3DynInst : public BaseDynInst<Impl>
 
         for (int idx = 0; idx < this->numDestRegs(); idx++) {
             PhysRegIndex prev_phys_reg = this->prevDestRegIdx(idx);
-            TheISA::RegIndex original_dest_reg = this->staticInst->destRegIdx(idx);
-            if (original_dest_reg <  TheISA::FP_Base_DepTag)
-                this->setIntRegOperand(this->staticInst.get(), idx, this->cpu->readIntReg(prev_phys_reg));
-            else if (original_dest_reg < TheISA::Ctrl_Base_DepTag)
-                this->setFloatRegOperandBits(this->staticInst.get(), idx, this->cpu->readFloatRegBits(prev_phys_reg));
+            TheISA::RegIndex original_dest_reg =
+                this->staticInst->destRegIdx(idx);
+            switch (regIdxToClass(original_dest_reg)) {
+              case IntRegClass:
+                this->setIntRegOperand(this->staticInst.get(), idx,
+                                       this->cpu->readIntReg(prev_phys_reg));
+                break;
+              case FloatRegClass:
+                this->setFloatRegOperandBits(this->staticInst.get(), idx,
+                                             this->cpu->readFloatRegBits(prev_phys_reg));
+                break;
+              case MiscRegClass:
+                // no need to forward misc reg values
+                break;
+            }
         }
     }
     /** Calls hardware return from error interrupt. */
index 341ba8804946f80aa22fa7c8700a06f625f074c4..6e564ababaf675865304af6c4ae27980009fa5d0 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
@@ -47,6 +48,7 @@
 #include "arch/registers.hh"
 #include "config/the_isa.hh"
 #include "cpu/o3/rename.hh"
+#include "cpu/reg_class.hh"
 #include "debug/Activity.hh"
 #include "debug/Rename.hh"
 #include "debug/O3PipeView.hh"
@@ -948,22 +950,29 @@ DefaultRename<Impl>::renameSrcRegs(DynInstPtr &inst, ThreadID tid)
     for (int src_idx = 0; src_idx < num_src_regs; src_idx++) {
         RegIndex src_reg = inst->srcRegIdx(src_idx);
         RegIndex flat_src_reg = src_reg;
-        if (src_reg < TheISA::FP_Base_DepTag) {
+        switch (regIdxToClass(src_reg)) {
+          case IntRegClass:
             flat_src_reg = inst->tcBase()->flattenIntIndex(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) {
+            break;
+
+          case FloatRegClass:
             src_reg = src_reg - TheISA::FP_Base_DepTag;
             flat_src_reg = inst->tcBase()->flattenFloatIndex(src_reg);
             DPRINTF(Rename, "Flattening index %d to %d.\n",
                     (int)src_reg, (int)flat_src_reg);
             flat_src_reg += TheISA::NumIntRegs;
-        } else if (src_reg < TheISA::Max_DepTag) {
+            break;
+
+          case MiscRegClass:
             flat_src_reg = src_reg - TheISA::Ctrl_Base_DepTag +
                            TheISA::NumFloatRegs + TheISA::NumIntRegs;
             DPRINTF(Rename, "Adjusting reg index from %d to %d.\n",
                     src_reg, flat_src_reg);
-        } else {
+            break;
+
+          default:
             panic("Reg index is out of bound: %d.", src_reg);
         }
 
@@ -1005,25 +1014,32 @@ DefaultRename<Impl>::renameDestRegs(DynInstPtr &inst, ThreadID tid)
     for (int dest_idx = 0; dest_idx < num_dest_regs; dest_idx++) {
         RegIndex dest_reg = inst->destRegIdx(dest_idx);
         RegIndex flat_dest_reg = dest_reg;
-        if (dest_reg < TheISA::FP_Base_DepTag) {
+        switch (regIdxToClass(dest_reg)) {
+          case IntRegClass:
             // Integer registers are flattened.
             flat_dest_reg = inst->tcBase()->flattenIntIndex(dest_reg);
             DPRINTF(Rename, "Flattening index %d to %d.\n",
                     (int)dest_reg, (int)flat_dest_reg);
-        } else if (dest_reg < TheISA::Ctrl_Base_DepTag) {
+            break;
+
+          case FloatRegClass:
             dest_reg = dest_reg - TheISA::FP_Base_DepTag;
             flat_dest_reg = inst->tcBase()->flattenFloatIndex(dest_reg);
             DPRINTF(Rename, "Flattening index %d to %d.\n",
                     (int)dest_reg, (int)flat_dest_reg);
             flat_dest_reg += TheISA::NumIntRegs;
-        } else if (dest_reg < TheISA::Max_DepTag) {
+            break;
+
+          case MiscRegClass:
             // Floating point and Miscellaneous registers need their indexes
             // adjusted to account for the expanded number of flattened int regs.
             flat_dest_reg = dest_reg - TheISA::Ctrl_Base_DepTag +
                             TheISA::NumIntRegs + TheISA::NumFloatRegs;
             DPRINTF(Rename, "Adjusting reg index from %d to %d.\n",
                     dest_reg, flat_dest_reg);
-        } else {
+            break;
+
+          default:
             panic("Reg index is out of bound: %d.", dest_reg);
         }
 
@@ -1034,7 +1050,7 @@ DefaultRename<Impl>::renameDestRegs(DynInstPtr &inst, ThreadID tid)
         rename_result = renameMap[tid]->rename(flat_dest_reg);
 
         //Mark Scoreboard entry as not ready
-        if (dest_reg < TheISA::Ctrl_Base_DepTag)
+        if (regIdxToClass(dest_reg) != MiscRegClass)
             scoreboard->unsetReg(rename_result.first);
 
         DPRINTF(Rename, "[tid:%u]: Renaming arch reg %i to physical "
diff --git a/src/cpu/reg_class.cc b/src/cpu/reg_class.cc
new file mode 100644 (file)
index 0000000..a3de17b
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2013 Advanced Micro Devices, Inc.
+ * All rights reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Steve Reinhardt
+ */
+
+#include "cpu/reg_class.hh"
+
+const char *RegClassStrings[] = {
+    "IntRegClass",
+    "FloatRegClass",
+    "MiscRegClass"
+};
diff --git a/src/cpu/reg_class.hh b/src/cpu/reg_class.hh
new file mode 100644 (file)
index 0000000..e96c94c
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2013 Advanced Micro Devices, Inc.
+ * All rights reserved
+ *.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Steve Reinhardt
+ */
+
+#ifndef __CPU__REG_CLASS_HH__
+#define __CPU__REG_CLASS_HH__
+
+#include <cassert>
+#include <cstddef>
+
+#include "arch/registers.hh"
+#include "config/the_isa.hh"
+
+/// Enumerate the classes of registers.
+enum RegClass {
+    IntRegClass,        ///< Integer register
+    FloatRegClass,      ///< Floating-point register
+    MiscRegClass        ///< Control (misc) register
+};
+
+/// Number of register classes.  This value is not part of the enum,
+/// because putting it there makes the compiler complain about
+/// unhandled cases in some switch statements.
+const int NumRegClasses = MiscRegClass + 1;
+
+/**
+ * Map a 'unified' architectural register index to its register class.
+ * The unified architectural register index space is used to represent
+ * all architectural register identifiers in a single contiguous
+ * index space.  See http://gem5.org/Register_Indexing.
+ *
+ * @param reg_idx Unified-space register index
+ * @param rel_reg_idx Optional output param pointer; if non-NULL, location
+ *        will be written with the relative register index for reg_idx
+ *
+ * @return Register class of reg_idx
+ */
+inline
+RegClass regIdxToClass(TheISA::RegIndex reg_idx,
+                       TheISA::RegIndex *rel_reg_idx = NULL)
+{
+    assert(reg_idx < TheISA::Max_DepTag);
+    RegClass cl;
+    int offset;
+
+    if (reg_idx < TheISA::FP_Base_DepTag) {
+        cl = IntRegClass;
+        offset = 0;
+    } else if (reg_idx < TheISA::Ctrl_Base_DepTag) {
+        cl = FloatRegClass;
+        offset = TheISA::FP_Base_DepTag;
+    } else {
+        cl = MiscRegClass;
+        offset = TheISA::Ctrl_Base_DepTag;
+    }
+
+    if (rel_reg_idx)
+        *rel_reg_idx = reg_idx - offset;
+    return cl;
+}
+
+/// Map enum values to strings for debugging
+extern const char *RegClassStrings[];
+
+
+#endif // __CPU__REG_CLASS_HH__