From 7aa423acad07f05ee547117406a72a5c1b4f6015 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Tue, 15 Oct 2013 14:22:42 -0400 Subject: [PATCH] cpu: clean up architectural register classification 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. --- src/arch/arm/insts/misc.cc | 12 ++-- src/arch/arm/insts/static_inst.cc | 23 +++++--- src/arch/power/insts/static_inst.cc | 30 ++++++---- src/arch/x86/insts/static_inst.cc | 55 ++++++++++------- src/cpu/SConscript | 1 + src/cpu/checker/cpu_impl.hh | 25 +++++--- src/cpu/inorder/cpu.cc | 68 +++++++++++++-------- src/cpu/inorder/cpu.hh | 15 ++++- src/cpu/inorder/inorder_dyn_inst.cc | 47 ++++++++++----- src/cpu/o3/dyn_inst.hh | 22 +++++-- src/cpu/o3/rename_impl.hh | 34 ++++++++--- src/cpu/reg_class.cc | 37 ++++++++++++ src/cpu/reg_class.hh | 92 +++++++++++++++++++++++++++++ 13 files changed, 352 insertions(+), 109 deletions(-) create mode 100644 src/cpu/reg_class.cc create mode 100644 src/cpu/reg_class.hh diff --git a/src/arch/arm/insts/misc.cc b/src/arch/arm/insts/misc.cc index 7d383a87a..c40b6711f 100644 --- a/src/arch/arm/insts/misc.cc +++ b/src/arch/arm/insts/misc.cc @@ -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; diff --git a/src/arch/arm/insts/static_inst.cc b/src/arch/arm/insts/static_inst.cc index 8306c620f..3ab7dfb0e 100644 --- a/src/arch/arm/insts/static_inst.cc +++ b/src/arch/arm/insts/static_inst.cc @@ -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; } } diff --git a/src/arch/power/insts/static_inst.cc b/src/arch/power/insts/static_inst.cc index 1982744bf..09b662453 100644 --- a/src/arch/power/insts/static_inst.cc +++ b/src/arch/power/insts/static_inst.cc @@ -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 @@ -29,23 +30,30 @@ */ #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; } } } diff --git a/src/arch/x86/insts/static_inst.cc b/src/arch/x86/insts/static_inst.cc index 29957e121..046a11fb6 100644 --- a/src/arch/x86/insts/static_inst.cc +++ b/src/arch/x86/insts/static_inst.cc @@ -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; } } diff --git a/src/cpu/SConscript b/src/cpu/SConscript index 999de1e49..f25758c67 100644 --- a/src/cpu/SConscript +++ b/src/cpu/SConscript @@ -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') diff --git a/src/cpu/checker/cpu_impl.hh b/src/cpu/checker/cpu_impl.hh index 49ff8eaa1..1967e02f3 100644 --- a/src/cpu/checker/cpu_impl.hh +++ b/src/cpu/checker/cpu_impl.hh @@ -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::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::copyResult(DynInstPtr &inst, uint64_t mismatch_val, for (int i = start_idx; i < inst->numDestRegs(); i++) { RegIndex idx = inst->destRegIdx(i); inst->template popResult(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... + } } } diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index 2c6b49d82..233d532dd 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -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 ®_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; } } diff --git a/src/cpu/inorder/cpu.hh b/src/cpu/inorder/cpu.hh index e69c9d47b..6f189f8c9 100644 --- a/src/cpu/inorder/cpu.hh +++ b/src/cpu/inorder/cpu.hh @@ -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 ®_type, ThreadID tid); diff --git a/src/cpu/inorder/inorder_dyn_inst.cc b/src/cpu/inorder/inorder_dyn_inst.cc index dcf0ce6ae..c2765a3ba 100644 --- a/src/cpu/inorder/inorder_dyn_inst.cc +++ b/src/cpu/inorder/inorder_dyn_inst.cc @@ -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; } } diff --git a/src/cpu/o3/dyn_inst.hh b/src/cpu/o3/dyn_inst.hh index 082c1f5d4..ece42b81a 100644 --- a/src/cpu/o3/dyn_inst.hh +++ b/src/cpu/o3/dyn_inst.hh @@ -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 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. */ diff --git a/src/cpu/o3/rename_impl.hh b/src/cpu/o3/rename_impl.hh index 341ba8804..6e564abab 100644 --- a/src/cpu/o3/rename_impl.hh +++ b/src/cpu/o3/rename_impl.hh @@ -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::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::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::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 index 000000000..a3de17b8b --- /dev/null +++ b/src/cpu/reg_class.cc @@ -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 index 000000000..e96c94cbb --- /dev/null +++ b/src/cpu/reg_class.hh @@ -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 +#include + +#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__