summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYasuko Eckert <yasuko.eckert@amd.com>2013-10-15 14:22:44 -0400
committerYasuko Eckert <yasuko.eckert@amd.com>2013-10-15 14:22:44 -0400
commit2c293823aa7cb6d2cac4c0ff35e2023ff132a8f2 (patch)
tree040fdd5bad814d7cb7ee40934974d2b38b28d67a
parent552622184752dc798bc81f9b0b395db68aee9511 (diff)
downloadgem5-2c293823aa7cb6d2cac4c0ff35e2023ff132a8f2.tar.xz
cpu: add a condition-code register class
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.
-rw-r--r--src/arch/SConscript3
-rw-r--r--src/arch/alpha/isa.hh7
-rw-r--r--src/arch/alpha/registers.hh7
-rw-r--r--src/arch/alpha/utility.cc3
-rw-r--r--src/arch/arm/insts/static_inst.cc2
-rw-r--r--src/arch/arm/isa.hh7
-rw-r--r--src/arch/arm/registers.hh7
-rw-r--r--src/arch/arm/utility.cc11
-rwxr-xr-xsrc/arch/isa_parser.py81
-rw-r--r--src/arch/mips/isa.hh7
-rw-r--r--src/arch/mips/registers.hh7
-rw-r--r--src/arch/null/registers.hh1
-rw-r--r--src/arch/power/insts/static_inst.cc2
-rw-r--r--src/arch/power/isa.hh7
-rw-r--r--src/arch/power/registers.hh7
-rw-r--r--src/arch/power/utility.cc3
-rw-r--r--src/arch/sparc/isa.hh7
-rw-r--r--src/arch/sparc/registers.hh10
-rw-r--r--src/arch/sparc/utility.cc3
-rw-r--r--src/arch/x86/insts/static_inst.cc4
-rw-r--r--src/arch/x86/isa.hh6
-rw-r--r--src/arch/x86/registers.hh5
-rw-r--r--src/arch/x86/utility.cc2
-rw-r--r--src/cpu/base_dyn_inst.hh7
-rw-r--r--src/cpu/checker/cpu.hh14
-rw-r--r--src/cpu/checker/cpu_impl.hh6
-rw-r--r--src/cpu/checker/thread_context.hh17
-rw-r--r--src/cpu/inorder/cpu.cc32
-rw-r--r--src/cpu/inorder/cpu.hh8
-rw-r--r--src/cpu/inorder/inorder_dyn_inst.cc4
-rw-r--r--src/cpu/inorder/inorder_dyn_inst.hh9
-rw-r--r--src/cpu/inorder/thread_context.cc31
-rw-r--r--src/cpu/inorder/thread_context.hh11
-rw-r--r--src/cpu/o3/O3CPU.py1
-rw-r--r--src/cpu/o3/cpu.cc88
-rw-r--r--src/cpu/o3/cpu.hh11
-rw-r--r--src/cpu/o3/dyn_inst.hh18
-rw-r--r--src/cpu/o3/free_list.cc2
-rw-r--r--src/cpu/o3/free_list.hh24
-rw-r--r--src/cpu/o3/inst_queue.hh7
-rw-r--r--src/cpu/o3/inst_queue_impl.hh8
-rw-r--r--src/cpu/o3/regfile.cc25
-rw-r--r--src/cpu/o3/regfile.hh57
-rw-r--r--src/cpu/o3/rename_impl.hh14
-rw-r--r--src/cpu/o3/rename_map.cc11
-rw-r--r--src/cpu/o3/rename_map.hh35
-rwxr-xr-xsrc/cpu/o3/thread_context.hh13
-rwxr-xr-xsrc/cpu/o3/thread_context_impl.hh24
-rw-r--r--src/cpu/ozone/cpu_impl.hh19
-rw-r--r--src/cpu/reg_class.cc1
-rw-r--r--src/cpu/reg_class.hh9
-rw-r--r--src/cpu/simple/base.cc13
-rw-r--r--src/cpu/simple/base.hh20
-rw-r--r--src/cpu/simple_thread.hh53
-rw-r--r--src/cpu/static_inst.hh4
-rw-r--r--src/cpu/thread_context.cc23
-rw-r--r--src/cpu/thread_context.hh24
57 files changed, 806 insertions, 36 deletions
diff --git a/src/arch/SConscript b/src/arch/SConscript
index b4f94a65f..e7d74ce51 100644
--- a/src/arch/SConscript
+++ b/src/arch/SConscript
@@ -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' ])
diff --git a/src/arch/alpha/isa.hh b/src/arch/alpha/isa.hh
index e2e2daba8..d30499066 100644
--- a/src/arch/alpha/isa.hh
+++ b/src/arch/alpha/isa.hh
@@ -103,6 +103,13 @@ namespace AlphaISA
return reg;
}
+ // dummy
+ int
+ flattenCCIndex(int reg)
+ {
+ return reg;
+ }
+
const Params *params() const;
ISA(Params *p);
diff --git a/src/arch/alpha/registers.hh b/src/arch/alpha/registers.hh
index 92ba22ee8..3fd774cf7 100644
--- a/src/arch/alpha/registers.hh
+++ b/src/arch/alpha/registers.hh
@@ -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
};
diff --git a/src/arch/alpha/utility.cc b/src/arch/alpha/utility.cc
index 32fc0b141..2dfe00f96 100644
--- a/src/arch/alpha/utility.cc
+++ b/src/arch/alpha/utility.cc
@@ -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);
diff --git a/src/arch/arm/insts/static_inst.cc b/src/arch/arm/insts/static_inst.cc
index 3ab7dfb0e..2a8dee162 100644
--- a/src/arch/arm/insts/static_inst.cc
+++ b/src/arch/arm/insts/static_inst.cc
@@ -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");
}
}
diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh
index e7abb26b2..6fd57549a 100644
--- a/src/arch/arm/isa.hh
+++ b/src/arch/arm/isa.hh
@@ -140,6 +140,13 @@ namespace ArmISA
return reg;
}
+ // dummy
+ int
+ flattenCCIndex(int reg)
+ {
+ return reg;
+ }
+
int
flattenMiscIndex(int reg)
{
diff --git a/src/arch/arm/registers.hh b/src/arch/arm/registers.hh
index cc4fac824..b9033fd5b 100644
--- a/src/arch/arm/registers.hh
+++ b/src/arch/arm/registers.hh
@@ -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 {
diff --git a/src/arch/arm/utility.cc b/src/arch/arm/utility.cc
index 776c1ae82..cddc2c5c4 100644
--- a/src/arch/arm/utility.cc
+++ b/src/arch/arm/utility.cc
@@ -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.
diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py
index e4f81c173..dd9f2e873 100755
--- a/src/arch/isa_parser.py
+++ b/src/arch/isa_parser.py
@@ -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')
diff --git a/src/arch/mips/isa.hh b/src/arch/mips/isa.hh
index 04d4a1dfa..c601cfc1e 100644
--- a/src/arch/mips/isa.hh
+++ b/src/arch/mips/isa.hh
@@ -177,6 +177,13 @@ namespace MipsISA
{
return reg;
}
+
+ // dummy
+ int
+ flattenCCIndex(int reg)
+ {
+ return reg;
+ }
};
}
diff --git a/src/arch/mips/registers.hh b/src/arch/mips/registers.hh
index d9d94e47b..0ac84cc7f 100644
--- a/src/arch/mips/registers.hh
+++ b/src/arch/mips/registers.hh
@@ -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;
diff --git a/src/arch/null/registers.hh b/src/arch/null/registers.hh
index f33b7e5bd..1e52fc5a6 100644
--- a/src/arch/null/registers.hh
+++ b/src/arch/null/registers.hh
@@ -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;
}
diff --git a/src/arch/power/insts/static_inst.cc b/src/arch/power/insts/static_inst.cc
index 09b662453..087e1f740 100644
--- a/src/arch/power/insts/static_inst.cc
+++ b/src/arch/power/insts/static_inst.cc
@@ -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");
}
}
diff --git a/src/arch/power/isa.hh b/src/arch/power/isa.hh
index 33439c48c..7b59b2ad1 100644
--- a/src/arch/power/isa.hh
+++ b/src/arch/power/isa.hh
@@ -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
diff --git a/src/arch/power/registers.hh b/src/arch/power/registers.hh
index 89de3719c..abee516fc 100644
--- a/src/arch/power/registers.hh
+++ b/src/arch/power/registers.hh
@@ -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 {
diff --git a/src/arch/power/utility.cc b/src/arch/power/utility.cc
index e3fa246fc..7be195b8d 100644
--- a/src/arch/power/utility.cc
+++ b/src/arch/power/utility.cc
@@ -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);
diff --git a/src/arch/sparc/isa.hh b/src/arch/sparc/isa.hh
index 86092f3b5..e6f023bc0 100644
--- a/src/arch/sparc/isa.hh
+++ b/src/arch/sparc/isa.hh
@@ -206,6 +206,13 @@ class ISA : public SimObject
return reg;
}
+ // dummy
+ int
+ flattenCCIndex(int reg)
+ {
+ return reg;
+ }
+
typedef SparcISAParams Params;
const Params *params() const;
diff --git a/src/arch/sparc/registers.hh b/src/arch/sparc/registers.hh
index 0e774b69e..b25f34584 100644
--- a/src/arch/sparc/registers.hh
+++ b/src/arch/sparc/registers.hh
@@ -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
diff --git a/src/arch/sparc/utility.cc b/src/arch/sparc/utility.cc
index d99ef4aa0..9fa102c6a 100644
--- a/src/arch/sparc/utility.cc
+++ b/src/arch/sparc/utility.cc
@@ -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);
diff --git a/src/arch/x86/insts/static_inst.cc b/src/arch/x86/insts/static_inst.cc
index 046a11fb6..39091289f 100644
--- a/src/arch/x86/insts/static_inst.cc
+++ b/src/arch/x86/insts/static_inst.cc
@@ -221,6 +221,10 @@ namespace X86ISA
break;
}
+ case CCRegClass:
+ ccprintf(os, "%%cc%d", rel_reg);
+ break;
+
case MiscRegClass:
switch (rel_reg) {
default:
diff --git a/src/arch/x86/isa.hh b/src/arch/x86/isa.hh
index 3ccc2f0ad..5f36fd7ad 100644
--- a/src/arch/x86/isa.hh
+++ b/src/arch/x86/isa.hh
@@ -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);
diff --git a/src/arch/x86/registers.hh b/src/arch/x86/registers.hh
index bb9f5f7b1..d62992dcd 100644
--- a/src/arch/x86/registers.hh
+++ b/src/arch/x86/registers.hh
@@ -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;
diff --git a/src/arch/x86/utility.cc b/src/arch/x86/utility.cc
index b50b99dfa..df7d3935d 100644
--- a/src/arch/x86/utility.cc
+++ b/src/arch/x86/utility.cc
@@ -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());
}
diff --git a/src/cpu/base_dyn_inst.hh b/src/cpu/base_dyn_inst.hh
index 8989a438a..6aecd32dc 100644
--- a/src/cpu/base_dyn_inst.hh
+++ b/src/cpu/base_dyn_inst.hh
@@ -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)
diff --git a/src/cpu/checker/cpu.hh b/src/cpu/checker/cpu.hh
index 637481706..c49f264f9 100644
--- a/src/cpu/checker/cpu.hh
+++ b/src/cpu/checker/cpu.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
@@ -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)
{
diff --git a/src/cpu/checker/cpu_impl.hh b/src/cpu/checker/cpu_impl.hh
index 185fed88e..e18644e0e 100644
--- a/src/cpu/checker/cpu_impl.hh
+++ b/src/cpu/checker/cpu_impl.hh
@@ -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);
diff --git a/src/cpu/checker/thread_context.hh b/src/cpu/checker/thread_context.hh
index 80726ff19..c06e03fc6 100644
--- a/src/cpu/checker/thread_context.hh
+++ b/src/cpu/checker/thread_context.hh
@@ -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__
diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc
index 32ca2caaf..5a02f94d9 100644
--- a/src/cpu/inorder/cpu.cc
+++ b/src/cpu/inorder/cpu.cc
@@ -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;
diff --git a/src/cpu/inorder/cpu.hh b/src/cpu/inorder/cpu.hh
index d5a31cca8..1183f6fc9 100644
--- a/src/cpu/inorder/cpu.hh
+++ b/src/cpu/inorder/cpu.hh
@@ -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. */
diff --git a/src/cpu/inorder/inorder_dyn_inst.cc b/src/cpu/inorder/inorder_dyn_inst.cc
index c2765a3ba..aedc630f5 100644
--- a/src/cpu/inorder/inorder_dyn_inst.cc
+++ b/src/cpu/inorder/inorder_dyn_inst.cc
@@ -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;
diff --git a/src/cpu/inorder/inorder_dyn_inst.hh b/src/cpu/inorder/inorder_dyn_inst.hh
index afd137a2e..48c15e292 100644
--- a/src/cpu/inorder/inorder_dyn_inst.hh
+++ b/src/cpu/inorder/inorder_dyn_inst.hh
@@ -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);
diff --git a/src/cpu/inorder/thread_context.cc b/src/cpu/inorder/thread_context.cc
index aab8c226a..763cc6df2 100644
--- a/src/cpu/inorder/thread_context.cc
+++ b/src/cpu/inorder/thread_context.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
@@ -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)
{
@@ -221,6 +230,14 @@ InOrderThreadContext::setFloatRegBits(int reg_idx, FloatRegBits val)
}
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);
+}
diff --git a/src/cpu/inorder/thread_context.hh b/src/cpu/inorder/thread_context.hh
index f4847d0b4..5e1c65f8f 100644
--- a/src/cpu/inorder/thread_context.hh
+++ b/src/cpu/inorder/thread_context.hh
@@ -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
diff --git a/src/cpu/o3/O3CPU.py b/src/cpu/o3/O3CPU.py
index e19881248..4b94f3581 100644
--- a/src/cpu/o3/O3CPU.py
+++ b/src/cpu/o3/O3CPU.py
@@ -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")
diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc
index 3e33e139a..f379b1068 100644
--- a/src/cpu/o3/cpu.cc
+++ b/src/cpu/o3/cpu.cc
@@ -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 "
@@ -1366,6 +1412,14 @@ FullO3CPU<Impl>::readFloatRegBits(int 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)
{
@@ -1390,6 +1444,14 @@ FullO3CPU<Impl>::setFloatRegBits(int reg_idx, FloatRegBits 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)
{
@@ -1420,6 +1482,16 @@ FullO3CPU<Impl>::readArchFloatRegInt(int reg_idx, ThreadID tid)
}
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)
{
@@ -1450,6 +1522,16 @@ FullO3CPU<Impl>::setArchFloatRegInt(int reg_idx, uint64_t val, ThreadID tid)
}
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)
{
diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh
index 1a1f8f8a3..18b75948f 100644
--- a/src/cpu/o3/cpu.hh
+++ b/src/cpu/o3/cpu.hh
@@ -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;
diff --git a/src/cpu/o3/dyn_inst.hh b/src/cpu/o3/dyn_inst.hh
index 15a82851b..5477f46d6 100644
--- a/src/cpu/o3/dyn_inst.hh
+++ b/src/cpu/o3/dyn_inst.hh
@@ -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)
{
diff --git a/src/cpu/o3/free_list.cc b/src/cpu/o3/free_list.cc
index 0c8a16d0d..a9544587e 100644
--- a/src/cpu/o3/free_list.cc
+++ b/src/cpu/o3/free_list.cc
@@ -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"
diff --git a/src/cpu/o3/free_list.hh b/src/cpu/o3/free_list.hh
index 3919d0afb..aa805e26e 100644
--- a/src/cpu/o3/free_list.hh
+++ b/src/cpu/o3/free_list.hh
@@ -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
diff --git a/src/cpu/o3/inst_queue.hh b/src/cpu/o3/inst_queue.hh
index 15190970d..212829ec1 100644
--- a/src/cpu/o3/inst_queue.hh
+++ b/src/cpu/o3/inst_queue.hh
@@ -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.
*/
diff --git a/src/cpu/o3/inst_queue_impl.hh b/src/cpu/o3/inst_queue_impl.hh
index 3e3325beb..1c86b7c89 100644
--- a/src/cpu/o3/inst_queue_impl.hh
+++ b/src/cpu/o3/inst_queue_impl.hh
@@ -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.
diff --git a/src/cpu/o3/regfile.cc b/src/cpu/o3/regfile.cc
index 5ba0caefc..96ce44bdd 100644
--- a/src/cpu/o3/regfile.cc
+++ b/src/cpu/o3/regfile.cc
@@ -36,12 +36,23 @@
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++);
+ }
}
diff --git a/src/cpu/o3/regfile.hh b/src/cpu/o3/regfile.hh
index bd3a4f730..8b87725ca 100644
--- a/src/cpu/o3/regfile.hh
+++ b/src/cpu/o3/regfile.hh
@@ -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;
+ }
};
diff --git a/src/cpu/o3/rename_impl.hh b/src/cpu/o3/rename_impl.hh
index 6bfc7d952..38191ce36 100644
--- a/src/cpu/o3/rename_impl.hh
+++ b/src/cpu/o3/rename_impl.hh
@@ -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;
diff --git a/src/cpu/o3/rename_map.cc b/src/cpu/o3/rename_map.cc
index ecee4c721..d816bf1fd 100644
--- a/src/cpu/o3/rename_map.cc
+++ b/src/cpu/o3/rename_map.cc
@@ -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
diff --git a/src/cpu/o3/rename_map.hh b/src/cpu/o3/rename_map.hh
index c989fb88f..751c39f52 100644
--- a/src/cpu/o3/rename_map.hh
+++ b/src/cpu/o3/rename_map.hh
@@ -163,6 +163,9 @@ class UnifiedRenameMap
*/
PhysRegFile *regFile;
+ /** The condition-code register rename map */
+ SimpleRenameMap ccMap;
+
public:
typedef TheISA::RegIndex RegIndex;
@@ -214,6 +217,17 @@ class UnifiedRenameMap
}
/**
+ * 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.
*/
@@ -260,6 +274,17 @@ class UnifiedRenameMap
}
/**
+ * 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.
*/
@@ -302,6 +327,16 @@ class UnifiedRenameMap
}
/**
+ * 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
* this number of entries is available regardless of which class
diff --git a/src/cpu/o3/thread_context.hh b/src/cpu/o3/thread_context.hh
index 4201878af..88cf75f4f 100755
--- a/src/cpu/o3/thread_context.hh
+++ b/src/cpu/o3/thread_context.hh
@@ -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
diff --git a/src/cpu/o3/thread_context_impl.hh b/src/cpu/o3/thread_context_impl.hh
index f818cc3dc..006d325fc 100755
--- a/src/cpu/o3/thread_context_impl.hh
+++ b/src/cpu/o3/thread_context_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
@@ -206,6 +207,13 @@ O3ThreadContext<Impl>::readFloatRegBitsFlat(int reg_idx)
}
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)
{
@@ -234,6 +242,15 @@ O3ThreadContext<Impl>::setFloatRegBitsFlat(int reg_idx, FloatRegBits val)
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)
{
cpu->pcState(val, thread->threadId());
@@ -265,6 +282,13 @@ O3ThreadContext<Impl>::flattenFloatIndex(int 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)
{
diff --git a/src/cpu/ozone/cpu_impl.hh b/src/cpu/ozone/cpu_impl.hh
index fcab901cf..b4b49a55b 100644
--- a/src/cpu/ozone/cpu_impl.hh
+++ b/src/cpu/ozone/cpu_impl.hh
@@ -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
@@ -769,6 +770,13 @@ OzoneCPU<Impl>::OzoneTC::readFloatRegBits(int reg_idx)
}
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)
{
@@ -801,6 +809,17 @@ OzoneCPU<Impl>::OzoneTC::setFloatRegBits(int reg_idx, FloatRegBits val)
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)
{
thread->PC = val;
diff --git a/src/cpu/reg_class.cc b/src/cpu/reg_class.cc
index a3de17b8b..1805eae13 100644
--- a/src/cpu/reg_class.cc
+++ b/src/cpu/reg_class.cc
@@ -33,5 +33,6 @@
const char *RegClassStrings[] = {
"IntRegClass",
"FloatRegClass",
+ "CCRegClass",
"MiscRegClass"
};
diff --git a/src/cpu/reg_class.hh b/src/cpu/reg_class.hh
index c9d4b1c4f..549ebab26 100644
--- a/src/cpu/reg_class.hh
+++ b/src/cpu/reg_class.hh
@@ -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;
diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc
index 012a49253..078f490e8 100644
--- a/src/cpu/simple/base.cc
+++ b/src/cpu/simple/base.cc
@@ -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")
diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh
index f2e1b278a..8134465af 100644
--- a/src/cpu/simple/base.hh
+++ b/src/cpu/simple/base.hh
@@ -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)
{
diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh
index d752ed105..fa0d20b0a 100644
--- a/src/cpu/simple_thread.hh
+++ b/src/cpu/simple_thread.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
@@ -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
};
diff --git a/src/cpu/static_inst.hh b/src/cpu/static_inst.hh
index 0464eda14..66f254e34 100644
--- a/src/cpu/static_inst.hh
+++ b/src/cpu/static_inst.hh
@@ -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]; }
diff --git a/src/cpu/thread_context.cc b/src/cpu/thread_context.cc
index a5a05a264..09f91746a 100644
--- a/src/cpu/thread_context.cc
+++ b/src/cpu/thread_context.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
@@ -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);
diff --git a/src/cpu/thread_context.hh b/src/cpu/thread_context.hh
index dbe3c0ce8..be18f680f 100644
--- a/src/cpu/thread_context.hh
+++ b/src/cpu/thread_context.hh
@@ -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); }
};
/** @{ */