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.
This commit is contained in:
parent
5526221847
commit
2c293823aa
57 changed files with 806 additions and 36 deletions
|
@ -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' ])
|
||||
|
|
|
@ -103,6 +103,13 @@ namespace AlphaISA
|
|||
return reg;
|
||||
}
|
||||
|
||||
// dummy
|
||||
int
|
||||
flattenCCIndex(int reg)
|
||||
{
|
||||
return reg;
|
||||
}
|
||||
|
||||
const Params *params() const;
|
||||
|
||||
ISA(Params *p);
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -140,6 +140,13 @@ namespace ArmISA
|
|||
return reg;
|
||||
}
|
||||
|
||||
// dummy
|
||||
int
|
||||
flattenCCIndex(int reg)
|
||||
{
|
||||
return reg;
|
||||
}
|
||||
|
||||
int
|
||||
flattenMiscIndex(int reg)
|
||||
{
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -177,6 +177,13 @@ namespace MipsISA
|
|||
{
|
||||
return reg;
|
||||
}
|
||||
|
||||
// dummy
|
||||
int
|
||||
flattenCCIndex(int reg)
|
||||
{
|
||||
return reg;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -206,6 +206,13 @@ class ISA : public SimObject
|
|||
return reg;
|
||||
}
|
||||
|
||||
// dummy
|
||||
int
|
||||
flattenCCIndex(int reg)
|
||||
{
|
||||
return reg;
|
||||
}
|
||||
|
||||
typedef SparcISAParams Params;
|
||||
const Params *params() const;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -221,6 +221,10 @@ namespace X86ISA
|
|||
break;
|
||||
}
|
||||
|
||||
case CCRegClass:
|
||||
ccprintf(os, "%%cc%d", rel_reg);
|
||||
break;
|
||||
|
||||
case MiscRegClass:
|
||||
switch (rel_reg) {
|
||||
default:
|
||||
|
|
|
@ -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 §ion);
|
||||
void startup(ThreadContext *tc);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 ®_type, ThreadID tid);
|
||||
|
||||
/** Reads a miscellaneous register. */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2012 ARM Limited
|
||||
* Copyright (c) 2013 Advanced Micro Devices, Inc.
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
|
@ -190,6 +191,14 @@ InOrderThreadContext::readFloatRegBits(int reg_idx)
|
|||
return cpu->readFloatRegBits(reg_idx, tid);
|
||||
}
|
||||
|
||||
CCReg
|
||||
InOrderThreadContext::readCCReg(int reg_idx)
|
||||
{
|
||||
ThreadID tid = thread->threadId();
|
||||
reg_idx = cpu->isa[tid]->flattenCCIndex(reg_idx);
|
||||
return cpu->readCCReg(reg_idx, tid);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
InOrderThreadContext::readRegOtherThread(int reg_idx, ThreadID tid)
|
||||
{
|
||||
|
@ -220,6 +229,14 @@ InOrderThreadContext::setFloatRegBits(int reg_idx, FloatRegBits val)
|
|||
cpu->setFloatRegBits(reg_idx, val, tid);
|
||||
}
|
||||
|
||||
void
|
||||
InOrderThreadContext::setCCReg(int reg_idx, CCReg val)
|
||||
{
|
||||
ThreadID tid = thread->threadId();
|
||||
reg_idx = cpu->isa[tid]->flattenCCIndex(reg_idx);
|
||||
cpu->setCCReg(reg_idx, val, tid);
|
||||
}
|
||||
|
||||
void
|
||||
InOrderThreadContext::setRegOtherThread(int misc_reg, const MiscReg &val,
|
||||
ThreadID tid)
|
||||
|
@ -281,3 +298,17 @@ InOrderThreadContext::setFloatRegBitsFlat(int idx, FloatRegBits val)
|
|||
const ThreadID tid = thread->threadId();
|
||||
cpu->setFloatRegBits(idx, val, tid);
|
||||
}
|
||||
|
||||
CCReg
|
||||
InOrderThreadContext::readCCRegFlat(int idx)
|
||||
{
|
||||
const ThreadID tid = thread->threadId();
|
||||
return cpu->readCCReg(idx, tid);
|
||||
}
|
||||
|
||||
void
|
||||
InOrderThreadContext::setCCRegFlat(int idx, CCReg val)
|
||||
{
|
||||
const ThreadID tid = thread->threadId();
|
||||
cpu->setCCReg(idx, val, tid);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
|
||||
|
|
|
@ -225,7 +225,8 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
|
|||
commit(this, params),
|
||||
|
||||
regFile(params->numPhysIntRegs,
|
||||
params->numPhysFloatRegs),
|
||||
params->numPhysFloatRegs,
|
||||
params->numPhysCCRegs),
|
||||
|
||||
freeList(name() + ".freelist", ®File),
|
||||
|
||||
|
@ -327,6 +328,7 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
|
|||
//Make Sure That this a Valid Architeture
|
||||
assert(params->numPhysIntRegs >= numThreads * TheISA::NumIntRegs);
|
||||
assert(params->numPhysFloatRegs >= numThreads * TheISA::NumFloatRegs);
|
||||
assert(params->numPhysCCRegs >= numThreads * TheISA::NumCCRegs);
|
||||
|
||||
rename.setScoreboard(&scoreboard);
|
||||
iew.setScoreboard(&scoreboard);
|
||||
|
@ -368,6 +370,12 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
|
|||
renameMap[tid].setFloatEntry(ridx, phys_reg);
|
||||
commitRenameMap[tid].setFloatEntry(ridx, phys_reg);
|
||||
}
|
||||
|
||||
for (RegIndex ridx = 0; ridx < TheISA::NumCCRegs; ++ridx) {
|
||||
PhysRegIndex phys_reg = freeList.getCCReg();
|
||||
renameMap[tid].setCCEntry(ridx, phys_reg);
|
||||
commitRenameMap[tid].setCCEntry(ridx, phys_reg);
|
||||
}
|
||||
}
|
||||
|
||||
rename.setRenameMap(renameMap);
|
||||
|
@ -555,6 +563,16 @@ FullO3CPU<Impl>::regStats()
|
|||
.desc("number of floating regfile writes")
|
||||
.prereq(fpRegfileWrites);
|
||||
|
||||
ccRegfileReads
|
||||
.name(name() + ".cc_regfile_reads")
|
||||
.desc("number of cc regfile reads")
|
||||
.prereq(ccRegfileReads);
|
||||
|
||||
ccRegfileWrites
|
||||
.name(name() + ".cc_regfile_writes")
|
||||
.desc("number of cc regfile writes")
|
||||
.prereq(ccRegfileWrites);
|
||||
|
||||
miscRegfileReads
|
||||
.name(name() + ".misc_regfile_reads")
|
||||
.desc("number of misc regfile reads")
|
||||
|
@ -842,13 +860,24 @@ FullO3CPU<Impl>::insertThread(ThreadID tid)
|
|||
}
|
||||
|
||||
//Bind Float Regs to Rename Map
|
||||
for (int freg = 0; freg < TheISA::NumFloatRegs; freg++) {
|
||||
int max_reg = TheISA::NumIntRegs + TheISA::NumFloatRegs;
|
||||
for (int freg = TheISA::NumIntRegs; freg < max_reg; freg++) {
|
||||
PhysRegIndex phys_reg = freeList.getFloatReg();
|
||||
|
||||
renameMap[tid].setEntry(freg,phys_reg);
|
||||
scoreboard.setReg(phys_reg);
|
||||
}
|
||||
|
||||
//Bind condition-code Regs to Rename Map
|
||||
max_reg = TheISA::NumIntRegs + TheISA::NumFloatRegs + TheISA::NumCCRegs;
|
||||
for (int creg = TheISA::NumIntRegs + TheISA::NumFloatRegs;
|
||||
creg < max_reg; creg++) {
|
||||
PhysRegIndex phys_reg = freeList.getCCReg();
|
||||
|
||||
renameMap[tid].setEntry(creg,phys_reg);
|
||||
scoreboard.setReg(phys_reg);
|
||||
}
|
||||
|
||||
//Copy Thread Data Into RegFile
|
||||
//this->copyFromTC(tid);
|
||||
|
||||
|
@ -888,13 +917,24 @@ FullO3CPU<Impl>::removeThread(ThreadID tid)
|
|||
}
|
||||
|
||||
// Unbind Float Regs from Rename Map
|
||||
for (int freg = TheISA::NumIntRegs; freg < TheISA::NumFloatRegs; freg++) {
|
||||
int max_reg = TheISA::NumIntRegs + TheISA::NumFloatRegs;
|
||||
for (int freg = TheISA::NumIntRegs; freg < max_reg; freg++) {
|
||||
PhysRegIndex phys_reg = renameMap[tid].lookup(freg);
|
||||
|
||||
scoreboard.unsetReg(phys_reg);
|
||||
freeList.addReg(phys_reg);
|
||||
}
|
||||
|
||||
// Unbind condition-code Regs from Rename Map
|
||||
max_reg = TheISA::NumIntRegs + TheISA::NumFloatRegs + TheISA::NumCCRegs;
|
||||
for (int creg = TheISA::NumIntRegs + TheISA::NumFloatRegs;
|
||||
creg < max_reg; creg++) {
|
||||
PhysRegIndex phys_reg = renameMap[tid].lookup(creg);
|
||||
|
||||
scoreboard.unsetReg(phys_reg);
|
||||
freeList.addReg(phys_reg);
|
||||
}
|
||||
|
||||
// Squash Throughout Pipeline
|
||||
DynInstPtr inst = commit.rob->readHeadInst(tid);
|
||||
InstSeqNum squash_seq_num = inst->seqNum;
|
||||
|
@ -934,6 +974,7 @@ FullO3CPU<Impl>::activateWhenReady(ThreadID tid)
|
|||
|
||||
bool ready = true;
|
||||
|
||||
// Should these all be '<' not '>='? This seems backwards...
|
||||
if (freeList.numFreeIntRegs() >= TheISA::NumIntRegs) {
|
||||
DPRINTF(O3CPU,"[tid:%i] Suspending thread due to not enough "
|
||||
"Phys. Int. Regs.\n",
|
||||
|
@ -944,6 +985,11 @@ FullO3CPU<Impl>::activateWhenReady(ThreadID tid)
|
|||
"Phys. Float. Regs.\n",
|
||||
tid);
|
||||
ready = false;
|
||||
} else if (freeList.numFreeCCRegs() >= TheISA::NumCCRegs) {
|
||||
DPRINTF(O3CPU,"[tid:%i] Suspending thread due to not enough "
|
||||
"Phys. CC. Regs.\n",
|
||||
tid);
|
||||
ready = false;
|
||||
} else if (commit.rob->numFreeEntries() >=
|
||||
commit.rob->entryAmount(activeThreads.size() + 1)) {
|
||||
DPRINTF(O3CPU,"[tid:%i] Suspending thread due to not enough "
|
||||
|
@ -1365,6 +1411,14 @@ FullO3CPU<Impl>::readFloatRegBits(int reg_idx)
|
|||
return regFile.readFloatRegBits(reg_idx);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
CCReg
|
||||
FullO3CPU<Impl>::readCCReg(int reg_idx)
|
||||
{
|
||||
ccRegfileReads++;
|
||||
return regFile.readCCReg(reg_idx);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
FullO3CPU<Impl>::setIntReg(int reg_idx, uint64_t val)
|
||||
|
@ -1389,6 +1443,14 @@ FullO3CPU<Impl>::setFloatRegBits(int reg_idx, FloatRegBits val)
|
|||
regFile.setFloatRegBits(reg_idx, val);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
FullO3CPU<Impl>::setCCReg(int reg_idx, CCReg val)
|
||||
{
|
||||
ccRegfileWrites++;
|
||||
regFile.setCCReg(reg_idx, val);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
uint64_t
|
||||
FullO3CPU<Impl>::readArchIntReg(int reg_idx, ThreadID tid)
|
||||
|
@ -1419,6 +1481,16 @@ FullO3CPU<Impl>::readArchFloatRegInt(int reg_idx, ThreadID tid)
|
|||
return regFile.readFloatRegBits(phys_reg);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
CCReg
|
||||
FullO3CPU<Impl>::readArchCCReg(int reg_idx, ThreadID tid)
|
||||
{
|
||||
ccRegfileReads++;
|
||||
PhysRegIndex phys_reg = commitRenameMap[tid].lookupCC(reg_idx);
|
||||
|
||||
return regFile.readCCReg(phys_reg);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
FullO3CPU<Impl>::setArchIntReg(int reg_idx, uint64_t val, ThreadID tid)
|
||||
|
@ -1449,6 +1521,16 @@ FullO3CPU<Impl>::setArchFloatRegInt(int reg_idx, uint64_t val, ThreadID tid)
|
|||
regFile.setFloatRegBits(phys_reg, val);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
FullO3CPU<Impl>::setArchCCReg(int reg_idx, CCReg val, ThreadID tid)
|
||||
{
|
||||
ccRegfileWrites++;
|
||||
PhysRegIndex phys_reg = commitRenameMap[tid].lookupCC(reg_idx);
|
||||
|
||||
regFile.setCCReg(phys_reg, val);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
TheISA::PCState
|
||||
FullO3CPU<Impl>::pcState(ThreadID tid)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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++);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -163,6 +163,9 @@ class UnifiedRenameMap
|
|||
*/
|
||||
PhysRegFile *regFile;
|
||||
|
||||
/** The condition-code register rename map */
|
||||
SimpleRenameMap ccMap;
|
||||
|
||||
public:
|
||||
typedef TheISA::RegIndex RegIndex;
|
||||
|
||||
|
@ -213,6 +216,17 @@ class UnifiedRenameMap
|
|||
return info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform rename() on a condition-code register, given a relative
|
||||
* condition-code register index.
|
||||
*/
|
||||
RenameInfo renameCC(RegIndex rel_arch_reg)
|
||||
{
|
||||
RenameInfo info = ccMap.rename(rel_arch_reg);
|
||||
assert(regFile->isCCPhysReg(info.first));
|
||||
return info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform rename() on a misc register, given a relative
|
||||
* misc register index.
|
||||
|
@ -259,6 +273,17 @@ class UnifiedRenameMap
|
|||
return phys_reg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform lookup() on a condition-code register, given a relative
|
||||
* condition-code register index.
|
||||
*/
|
||||
PhysRegIndex lookupCC(RegIndex rel_arch_reg) const
|
||||
{
|
||||
PhysRegIndex phys_reg = ccMap.lookup(rel_arch_reg);
|
||||
assert(regFile->isCCPhysReg(phys_reg));
|
||||
return phys_reg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform lookup() on a misc register, given a relative
|
||||
* misc register index.
|
||||
|
@ -301,6 +326,16 @@ class UnifiedRenameMap
|
|||
floatMap.setEntry(arch_reg, phys_reg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform setEntry() on a condition-code register, given a relative
|
||||
* condition-code register index.
|
||||
*/
|
||||
void setCCEntry(RegIndex arch_reg, PhysRegIndex phys_reg)
|
||||
{
|
||||
assert(regFile->isCCPhysReg(phys_reg));
|
||||
ccMap.setEntry(arch_reg, phys_reg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the minimum number of free entries across all of the
|
||||
* register classes. The minimum is used so we guarantee that
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2012 ARM Limited
|
||||
* Copyright (c) 2013 Advanced Micro Devices, Inc.
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
|
@ -205,6 +206,13 @@ O3ThreadContext<Impl>::readFloatRegBitsFlat(int reg_idx)
|
|||
return cpu->readArchFloatRegInt(reg_idx, thread->threadId());
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
TheISA::CCReg
|
||||
O3ThreadContext<Impl>::readCCRegFlat(int reg_idx)
|
||||
{
|
||||
return cpu->readArchCCReg(reg_idx, thread->threadId());
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
O3ThreadContext<Impl>::setIntRegFlat(int reg_idx, uint64_t val)
|
||||
|
@ -232,6 +240,15 @@ O3ThreadContext<Impl>::setFloatRegBitsFlat(int reg_idx, FloatRegBits val)
|
|||
conditionalSquash();
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
O3ThreadContext<Impl>::setCCRegFlat(int reg_idx, TheISA::CCReg val)
|
||||
{
|
||||
cpu->setArchCCReg(reg_idx, val, thread->threadId());
|
||||
|
||||
conditionalSquash();
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
O3ThreadContext<Impl>::pcState(const TheISA::PCState &val)
|
||||
|
@ -264,6 +281,13 @@ O3ThreadContext<Impl>::flattenFloatIndex(int reg)
|
|||
return cpu->isa[thread->threadId()]->flattenFloatIndex(reg);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
int
|
||||
O3ThreadContext<Impl>::flattenCCIndex(int reg)
|
||||
{
|
||||
return cpu->isa[thread->threadId()]->flattenCCIndex(reg);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
O3ThreadContext<Impl>::setMiscRegNoEffect(int misc_reg, const MiscReg &val)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2006 The Regents of The University of Michigan
|
||||
* Copyright (c) 2013 Advanced Micro Devices, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -768,6 +769,13 @@ OzoneCPU<Impl>::OzoneTC::readFloatRegBits(int reg_idx)
|
|||
return thread->renameTable[idx]->readIntResult();
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
CCReg
|
||||
OzoneCPU<Impl>::OzoneTC::readCCReg(int reg_idx)
|
||||
{
|
||||
return thread->renameTable[reg_idx]->readCCResult();
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
OzoneCPU<Impl>::OzoneTC::setIntReg(int reg_idx, uint64_t val)
|
||||
|
@ -799,6 +807,17 @@ OzoneCPU<Impl>::OzoneTC::setFloatRegBits(int reg_idx, FloatRegBits val)
|
|||
panic("Unimplemented!");
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
OzoneCPU<Impl>::OzoneTC::setCCReg(int reg_idx, CCReg val)
|
||||
{
|
||||
thread->renameTable[reg_idx]->setCCResult(val);
|
||||
|
||||
if (!thread->noSquashFromTC) {
|
||||
cpu->squashFromTC();
|
||||
}
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
OzoneCPU<Impl>::OzoneTC::setPC(Addr val)
|
||||
|
|
|
@ -33,5 +33,6 @@
|
|||
const char *RegClassStrings[] = {
|
||||
"IntRegClass",
|
||||
"FloatRegClass",
|
||||
"CCRegClass",
|
||||
"MiscRegClass"
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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]; }
|
||||
|
|
|
@ -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 §ion)
|
|||
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);
|
||||
|
|
|
@ -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); }
|
||||
};
|
||||
|
||||
/** @{ */
|
||||
|
|
Loading…
Reference in a new issue