X86: Put in the foundation for x87 stack based fp registers.
--HG-- extra : convert_revision : 940f92efd4a9dc59106e991cc6d9836861ab69de
This commit is contained in:
parent
a54ae9f92b
commit
f3f3747431
14 changed files with 83 additions and 16 deletions
|
@ -192,6 +192,11 @@ namespace AlphaISA
|
||||||
return reg;
|
return reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int flattenFloatIndex(ThreadContext * tc, int reg)
|
||||||
|
{
|
||||||
|
return reg;
|
||||||
|
}
|
||||||
|
|
||||||
void copyRegs(ThreadContext *src, ThreadContext *dest);
|
void copyRegs(ThreadContext *src, ThreadContext *dest);
|
||||||
|
|
||||||
void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
|
void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
|
||||||
|
|
|
@ -187,6 +187,11 @@ namespace MipsISA
|
||||||
return reg;
|
return reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int flattenFloatIndex(ThreadContext * tc, int reg)
|
||||||
|
{
|
||||||
|
return reg;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
copyRegs(ThreadContext *src, ThreadContext *dest);
|
copyRegs(ThreadContext *src, ThreadContext *dest);
|
||||||
|
|
||||||
|
|
|
@ -122,6 +122,11 @@ namespace SparcISA
|
||||||
|
|
||||||
int flattenIntIndex(ThreadContext * tc, int reg);
|
int flattenIntIndex(ThreadContext * tc, int reg);
|
||||||
|
|
||||||
|
int flattenFloatIndex(ThreadContext * tc, int reg)
|
||||||
|
{
|
||||||
|
return reg;
|
||||||
|
}
|
||||||
|
|
||||||
void copyRegs(ThreadContext *src, ThreadContext *dest);
|
void copyRegs(ThreadContext *src, ThreadContext *dest);
|
||||||
|
|
||||||
void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
|
void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
|
||||||
|
|
|
@ -101,8 +101,9 @@ namespace X86ISA
|
||||||
std::string getFloatRegName(RegIndex);
|
std::string getFloatRegName(RegIndex);
|
||||||
|
|
||||||
//Each 128 bit xmm register is broken into two effective 64 bit registers.
|
//Each 128 bit xmm register is broken into two effective 64 bit registers.
|
||||||
const int NumFloatArchRegs = NumMMXRegs + 2 * NumXMMRegs + NumMicroFpRegs;
|
const int NumFloatRegs =
|
||||||
const int NumFloatRegs = NumFloatArchRegs;
|
NumMMXRegs + 2 * NumXMMRegs + NumMicroFpRegs;
|
||||||
|
const int NumFloatArchRegs = NumFloatRegs + 8;
|
||||||
|
|
||||||
class FloatRegFile
|
class FloatRegFile
|
||||||
{
|
{
|
||||||
|
|
|
@ -162,6 +162,12 @@ namespace X86ISA
|
||||||
{
|
{
|
||||||
return (FloatRegIndex)(FLOATREG_MICROFP_BASE + index);
|
return (FloatRegIndex)(FLOATREG_MICROFP_BASE + index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline FloatRegIndex
|
||||||
|
FLOATREG_STACK(int index, int top)
|
||||||
|
{
|
||||||
|
return (FloatRegIndex)(NUM_FLOATREGS + ((top - index + 8) % 8));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __ARCH_X86_FLOATREGS_HH__
|
#endif // __ARCH_X86_FLOATREGS_HH__
|
||||||
|
|
|
@ -136,5 +136,10 @@ let {{
|
||||||
|
|
||||||
assembler.symbols["label"] = labeler
|
assembler.symbols["label"] = labeler
|
||||||
|
|
||||||
|
def stack_index(index):
|
||||||
|
return "(NUM_FLOATREGS + (%s))" % index
|
||||||
|
|
||||||
|
assembler.symbols["st"] = stack_index
|
||||||
|
|
||||||
macroopDict = assembler.assemble(microcode)
|
macroopDict = assembler.assemble(microcode)
|
||||||
}};
|
}};
|
||||||
|
|
|
@ -115,6 +115,9 @@ def operands {{
|
||||||
'uIP': ('UPC', 'uqw', None, (None, None, 'IsControl'), 51),
|
'uIP': ('UPC', 'uqw', None, (None, None, 'IsControl'), 51),
|
||||||
'nuIP': ('NUPC', 'uqw', None, (None, None, 'IsControl'), 52),
|
'nuIP': ('NUPC', 'uqw', None, (None, None, 'IsControl'), 52),
|
||||||
'ccFlagBits': ('IntReg', 'uqw', 'INTREG_PSEUDO(0)', None, 60),
|
'ccFlagBits': ('IntReg', 'uqw', 'INTREG_PSEUDO(0)', None, 60),
|
||||||
|
# The TOP register should needs to be more protected so that later
|
||||||
|
# instructions don't map their indexes with an old value.
|
||||||
|
'TOP': ('ControlReg', 'ub', 'MISCREG_X87_TOP', None, 61),
|
||||||
'SegBase': ('ControlReg', 'uqw', 'MISCREG_SEG_BASE(segment)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 70),
|
'SegBase': ('ControlReg', 'uqw', 'MISCREG_SEG_BASE(segment)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 70),
|
||||||
'Mem': ('Mem', 'uqw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 100)
|
'Mem': ('Mem', 'uqw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 100)
|
||||||
}};
|
}};
|
||||||
|
|
|
@ -89,7 +89,9 @@ namespace X86ISA
|
||||||
//mmx/x87 registers
|
//mmx/x87 registers
|
||||||
8 +
|
8 +
|
||||||
//xmm registers
|
//xmm registers
|
||||||
16
|
16 +
|
||||||
|
//The indices that are mapped over the fp stack
|
||||||
|
8
|
||||||
};
|
};
|
||||||
|
|
||||||
// semantically meaningful register indices
|
// semantically meaningful register indices
|
||||||
|
|
|
@ -171,9 +171,12 @@ namespace X86ISA
|
||||||
MISCREG_LDTR_ATTR = MISCREG_SYSSEG_ATTR_BASE,
|
MISCREG_LDTR_ATTR = MISCREG_SYSSEG_ATTR_BASE,
|
||||||
MISCREG_TR_ATTR,
|
MISCREG_TR_ATTR,
|
||||||
|
|
||||||
|
// Floating point control registers
|
||||||
|
MISCREG_X87_TOP = MISCREG_SYSSEG_ATTR_BASE + NumSysSegments,
|
||||||
|
|
||||||
//XXX Add "Model-Specific Registers"
|
//XXX Add "Model-Specific Registers"
|
||||||
|
|
||||||
NUM_MISCREGS = MISCREG_SYSSEG_ATTR_BASE + NumSysSegments
|
NUM_MISCREGS
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline MiscRegIndex
|
static inline MiscRegIndex
|
||||||
|
|
|
@ -85,6 +85,7 @@
|
||||||
* Authors: Gabe Black
|
* Authors: Gabe Black
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "arch/x86/floatregs.hh"
|
||||||
#include "arch/x86/regfile.hh"
|
#include "arch/x86/regfile.hh"
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
#include "sim/serialize.hh"
|
#include "sim/serialize.hh"
|
||||||
|
@ -218,6 +219,15 @@ int X86ISA::flattenIntIndex(ThreadContext * tc, int reg)
|
||||||
return (reg & ~(1 << 6));
|
return (reg & ~(1 << 6));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int X86ISA::flattenFloatIndex(ThreadContext * tc, int reg)
|
||||||
|
{
|
||||||
|
if (reg > NUM_FLOATREGS) {
|
||||||
|
int top = tc->readMiscRegNoEffect(MISCREG_X87_TOP);
|
||||||
|
reg = FLOATREG_STACK(reg - NUM_FLOATREGS, top);
|
||||||
|
}
|
||||||
|
return reg;
|
||||||
|
}
|
||||||
|
|
||||||
void RegFile::serialize(std::ostream &os)
|
void RegFile::serialize(std::ostream &os)
|
||||||
{
|
{
|
||||||
intRegFile.serialize(os);
|
intRegFile.serialize(os);
|
||||||
|
|
|
@ -149,6 +149,8 @@ namespace X86ISA
|
||||||
|
|
||||||
int flattenIntIndex(ThreadContext * tc, int reg);
|
int flattenIntIndex(ThreadContext * tc, int reg);
|
||||||
|
|
||||||
|
int flattenFloatIndex(ThreadContext * tc, int reg);
|
||||||
|
|
||||||
void copyRegs(ThreadContext *src, ThreadContext *dest);
|
void copyRegs(ThreadContext *src, ThreadContext *dest);
|
||||||
|
|
||||||
void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
|
void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
|
||||||
|
|
|
@ -959,9 +959,11 @@ DefaultRename<Impl>::renameSrcRegs(DynInstPtr &inst,unsigned tid)
|
||||||
if (src_reg < TheISA::FP_Base_DepTag) {
|
if (src_reg < TheISA::FP_Base_DepTag) {
|
||||||
flat_src_reg = TheISA::flattenIntIndex(inst->tcBase(), src_reg);
|
flat_src_reg = TheISA::flattenIntIndex(inst->tcBase(), src_reg);
|
||||||
DPRINTF(Rename, "Flattening index %d to %d.\n", (int)src_reg, (int)flat_src_reg);
|
DPRINTF(Rename, "Flattening index %d to %d.\n", (int)src_reg, (int)flat_src_reg);
|
||||||
|
} else if (src_reg < TheISA::Ctrl_Base_DepTag) {
|
||||||
|
src_reg = src_reg - TheISA::FP_Base_DepTag;
|
||||||
|
flat_src_reg = TheISA::flattenFloatIndex(inst->tcBase(), src_reg);
|
||||||
|
flat_src_reg += TheISA::NumIntRegs;
|
||||||
} else {
|
} else {
|
||||||
// Floating point and Miscellaneous registers need their indexes
|
|
||||||
// adjusted to account for the expanded number of flattened int regs.
|
|
||||||
flat_src_reg = src_reg - TheISA::FP_Base_DepTag + TheISA::NumIntRegs;
|
flat_src_reg = src_reg - TheISA::FP_Base_DepTag + TheISA::NumIntRegs;
|
||||||
DPRINTF(Rename, "Adjusting reg index from %d to %d.\n", src_reg, flat_src_reg);
|
DPRINTF(Rename, "Adjusting reg index from %d to %d.\n", src_reg, flat_src_reg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -314,6 +314,7 @@ template <class Impl>
|
||||||
TheISA::FloatReg
|
TheISA::FloatReg
|
||||||
O3ThreadContext<Impl>::readFloatReg(int reg_idx, int width)
|
O3ThreadContext<Impl>::readFloatReg(int reg_idx, int width)
|
||||||
{
|
{
|
||||||
|
reg_idx = TheISA::flattenFloatIndex(this, reg_idx);
|
||||||
switch(width) {
|
switch(width) {
|
||||||
case 32:
|
case 32:
|
||||||
return cpu->readArchFloatRegSingle(reg_idx, thread->readTid());
|
return cpu->readArchFloatRegSingle(reg_idx, thread->readTid());
|
||||||
|
@ -329,6 +330,7 @@ template <class Impl>
|
||||||
TheISA::FloatReg
|
TheISA::FloatReg
|
||||||
O3ThreadContext<Impl>::readFloatReg(int reg_idx)
|
O3ThreadContext<Impl>::readFloatReg(int reg_idx)
|
||||||
{
|
{
|
||||||
|
reg_idx = TheISA::flattenFloatIndex(this, reg_idx);
|
||||||
return cpu->readArchFloatRegSingle(reg_idx, thread->readTid());
|
return cpu->readArchFloatRegSingle(reg_idx, thread->readTid());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,6 +339,7 @@ TheISA::FloatRegBits
|
||||||
O3ThreadContext<Impl>::readFloatRegBits(int reg_idx, int width)
|
O3ThreadContext<Impl>::readFloatRegBits(int reg_idx, int width)
|
||||||
{
|
{
|
||||||
DPRINTF(Fault, "Reading floatint register through the TC!\n");
|
DPRINTF(Fault, "Reading floatint register through the TC!\n");
|
||||||
|
reg_idx = TheISA::flattenFloatIndex(this, reg_idx);
|
||||||
return cpu->readArchFloatRegInt(reg_idx, thread->readTid());
|
return cpu->readArchFloatRegInt(reg_idx, thread->readTid());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -344,6 +347,7 @@ template <class Impl>
|
||||||
TheISA::FloatRegBits
|
TheISA::FloatRegBits
|
||||||
O3ThreadContext<Impl>::readFloatRegBits(int reg_idx)
|
O3ThreadContext<Impl>::readFloatRegBits(int reg_idx)
|
||||||
{
|
{
|
||||||
|
reg_idx = TheISA::flattenFloatIndex(this, reg_idx);
|
||||||
return cpu->readArchFloatRegInt(reg_idx, thread->readTid());
|
return cpu->readArchFloatRegInt(reg_idx, thread->readTid());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,6 +368,7 @@ template <class Impl>
|
||||||
void
|
void
|
||||||
O3ThreadContext<Impl>::setFloatReg(int reg_idx, FloatReg val, int width)
|
O3ThreadContext<Impl>::setFloatReg(int reg_idx, FloatReg val, int width)
|
||||||
{
|
{
|
||||||
|
reg_idx = TheISA::flattenFloatIndex(this, reg_idx);
|
||||||
switch(width) {
|
switch(width) {
|
||||||
case 32:
|
case 32:
|
||||||
cpu->setArchFloatRegSingle(reg_idx, val, thread->readTid());
|
cpu->setArchFloatRegSingle(reg_idx, val, thread->readTid());
|
||||||
|
@ -383,6 +388,7 @@ template <class Impl>
|
||||||
void
|
void
|
||||||
O3ThreadContext<Impl>::setFloatReg(int reg_idx, FloatReg val)
|
O3ThreadContext<Impl>::setFloatReg(int reg_idx, FloatReg val)
|
||||||
{
|
{
|
||||||
|
reg_idx = TheISA::flattenFloatIndex(this, reg_idx);
|
||||||
cpu->setArchFloatRegSingle(reg_idx, val, thread->readTid());
|
cpu->setArchFloatRegSingle(reg_idx, val, thread->readTid());
|
||||||
|
|
||||||
if (!thread->trapPending && !thread->inSyscall) {
|
if (!thread->trapPending && !thread->inSyscall) {
|
||||||
|
@ -396,6 +402,7 @@ O3ThreadContext<Impl>::setFloatRegBits(int reg_idx, FloatRegBits val,
|
||||||
int width)
|
int width)
|
||||||
{
|
{
|
||||||
DPRINTF(Fault, "Setting floatint register through the TC!\n");
|
DPRINTF(Fault, "Setting floatint register through the TC!\n");
|
||||||
|
reg_idx = TheISA::flattenFloatIndex(this, reg_idx);
|
||||||
cpu->setArchFloatRegInt(reg_idx, val, thread->readTid());
|
cpu->setArchFloatRegInt(reg_idx, val, thread->readTid());
|
||||||
|
|
||||||
// Squash if we're not already in a state update mode.
|
// Squash if we're not already in a state update mode.
|
||||||
|
@ -408,6 +415,7 @@ template <class Impl>
|
||||||
void
|
void
|
||||||
O3ThreadContext<Impl>::setFloatRegBits(int reg_idx, FloatRegBits val)
|
O3ThreadContext<Impl>::setFloatRegBits(int reg_idx, FloatRegBits val)
|
||||||
{
|
{
|
||||||
|
reg_idx = TheISA::flattenFloatIndex(this, reg_idx);
|
||||||
cpu->setArchFloatRegInt(reg_idx, val, thread->readTid());
|
cpu->setArchFloatRegInt(reg_idx, val, thread->readTid());
|
||||||
|
|
||||||
// Squash if we're not already in a state update mode.
|
// Squash if we're not already in a state update mode.
|
||||||
|
|
|
@ -235,52 +235,62 @@ class SimpleThread : public ThreadState
|
||||||
//
|
//
|
||||||
uint64_t readIntReg(int reg_idx)
|
uint64_t readIntReg(int reg_idx)
|
||||||
{
|
{
|
||||||
return regs.readIntReg(TheISA::flattenIntIndex(getTC(), reg_idx));
|
int flatIndex = TheISA::flattenIntIndex(getTC(), reg_idx);
|
||||||
|
return regs.readIntReg(flatIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
FloatReg readFloatReg(int reg_idx, int width)
|
FloatReg readFloatReg(int reg_idx, int width)
|
||||||
{
|
{
|
||||||
return regs.readFloatReg(reg_idx, width);
|
int flatIndex = TheISA::flattenIntIndex(getTC(), reg_idx);
|
||||||
|
return regs.readFloatReg(flatIndex, width);
|
||||||
}
|
}
|
||||||
|
|
||||||
FloatReg readFloatReg(int reg_idx)
|
FloatReg readFloatReg(int reg_idx)
|
||||||
{
|
{
|
||||||
return regs.readFloatReg(reg_idx);
|
int flatIndex = TheISA::flattenIntIndex(getTC(), reg_idx);
|
||||||
|
return regs.readFloatReg(flatIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
FloatRegBits readFloatRegBits(int reg_idx, int width)
|
FloatRegBits readFloatRegBits(int reg_idx, int width)
|
||||||
{
|
{
|
||||||
return regs.readFloatRegBits(reg_idx, width);
|
int flatIndex = TheISA::flattenIntIndex(getTC(), reg_idx);
|
||||||
|
return regs.readFloatRegBits(flatIndex, width);
|
||||||
}
|
}
|
||||||
|
|
||||||
FloatRegBits readFloatRegBits(int reg_idx)
|
FloatRegBits readFloatRegBits(int reg_idx)
|
||||||
{
|
{
|
||||||
return regs.readFloatRegBits(reg_idx);
|
int flatIndex = TheISA::flattenIntIndex(getTC(), reg_idx);
|
||||||
|
return regs.readFloatRegBits(flatIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setIntReg(int reg_idx, uint64_t val)
|
void setIntReg(int reg_idx, uint64_t val)
|
||||||
{
|
{
|
||||||
regs.setIntReg(TheISA::flattenIntIndex(getTC(), reg_idx), val);
|
int flatIndex = TheISA::flattenIntIndex(getTC(), reg_idx);
|
||||||
|
regs.setIntReg(flatIndex, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setFloatReg(int reg_idx, FloatReg val, int width)
|
void setFloatReg(int reg_idx, FloatReg val, int width)
|
||||||
{
|
{
|
||||||
regs.setFloatReg(reg_idx, val, width);
|
int flatIndex = TheISA::flattenIntIndex(getTC(), reg_idx);
|
||||||
|
regs.setFloatReg(flatIndex, val, width);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setFloatReg(int reg_idx, FloatReg val)
|
void setFloatReg(int reg_idx, FloatReg val)
|
||||||
{
|
{
|
||||||
regs.setFloatReg(reg_idx, val);
|
int flatIndex = TheISA::flattenIntIndex(getTC(), reg_idx);
|
||||||
|
regs.setFloatReg(flatIndex, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setFloatRegBits(int reg_idx, FloatRegBits val, int width)
|
void setFloatRegBits(int reg_idx, FloatRegBits val, int width)
|
||||||
{
|
{
|
||||||
regs.setFloatRegBits(reg_idx, val, width);
|
int flatIndex = TheISA::flattenIntIndex(getTC(), reg_idx);
|
||||||
|
regs.setFloatRegBits(flatIndex, val, width);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setFloatRegBits(int reg_idx, FloatRegBits val)
|
void setFloatRegBits(int reg_idx, FloatRegBits val)
|
||||||
{
|
{
|
||||||
regs.setFloatRegBits(reg_idx, val);
|
int flatIndex = TheISA::flattenIntIndex(getTC(), reg_idx);
|
||||||
|
regs.setFloatRegBits(flatIndex, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t readPC()
|
uint64_t readPC()
|
||||||
|
|
Loading…
Reference in a new issue