return reg;
}
+ static inline int flattenFloatIndex(ThreadContext * tc, int reg)
+ {
+ return reg;
+ }
+
void copyRegs(ThreadContext *src, ThreadContext *dest);
void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
return reg;
}
+ static inline int flattenFloatIndex(ThreadContext * tc, int reg)
+ {
+ return reg;
+ }
+
void
copyRegs(ThreadContext *src, ThreadContext *dest);
int flattenIntIndex(ThreadContext * tc, int reg);
+ int flattenFloatIndex(ThreadContext * tc, int reg)
+ {
+ return reg;
+ }
+
void copyRegs(ThreadContext *src, ThreadContext *dest);
void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
std::string getFloatRegName(RegIndex);
//Each 128 bit xmm register is broken into two effective 64 bit registers.
- const int NumFloatArchRegs = NumMMXRegs + 2 * NumXMMRegs + NumMicroFpRegs;
- const int NumFloatRegs = NumFloatArchRegs;
+ const int NumFloatRegs =
+ NumMMXRegs + 2 * NumXMMRegs + NumMicroFpRegs;
+ const int NumFloatArchRegs = NumFloatRegs + 8;
class FloatRegFile
{
{
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__
assembler.symbols["label"] = labeler
+ def stack_index(index):
+ return "(NUM_FLOATREGS + (%s))" % index
+
+ assembler.symbols["st"] = stack_index
+
macroopDict = assembler.assemble(microcode)
}};
'uIP': ('UPC', 'uqw', None, (None, None, 'IsControl'), 51),
'nuIP': ('NUPC', 'uqw', None, (None, None, 'IsControl'), 52),
'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),
'Mem': ('Mem', 'uqw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 100)
}};
//mmx/x87 registers
8 +
//xmm registers
- 16
+ 16 +
+ //The indices that are mapped over the fp stack
+ 8
};
// semantically meaningful register indices
MISCREG_LDTR_ATTR = MISCREG_SYSSEG_ATTR_BASE,
MISCREG_TR_ATTR,
+ // Floating point control registers
+ MISCREG_X87_TOP = MISCREG_SYSSEG_ATTR_BASE + NumSysSegments,
+
//XXX Add "Model-Specific Registers"
- NUM_MISCREGS = MISCREG_SYSSEG_ATTR_BASE + NumSysSegments
+ NUM_MISCREGS
};
static inline MiscRegIndex
* Authors: Gabe Black
*/
+#include "arch/x86/floatregs.hh"
#include "arch/x86/regfile.hh"
#include "base/trace.hh"
#include "sim/serialize.hh"
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)
{
intRegFile.serialize(os);
int flattenIntIndex(ThreadContext * tc, int reg);
+ int flattenFloatIndex(ThreadContext * tc, int reg);
+
void copyRegs(ThreadContext *src, ThreadContext *dest);
void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
if (src_reg < TheISA::FP_Base_DepTag) {
flat_src_reg = TheISA::flattenIntIndex(inst->tcBase(), 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 {
- // 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;
DPRINTF(Rename, "Adjusting reg index from %d to %d.\n", src_reg, flat_src_reg);
}
TheISA::FloatReg
O3ThreadContext<Impl>::readFloatReg(int reg_idx, int width)
{
+ reg_idx = TheISA::flattenFloatIndex(this, reg_idx);
switch(width) {
case 32:
return cpu->readArchFloatRegSingle(reg_idx, thread->readTid());
TheISA::FloatReg
O3ThreadContext<Impl>::readFloatReg(int reg_idx)
{
+ reg_idx = TheISA::flattenFloatIndex(this, reg_idx);
return cpu->readArchFloatRegSingle(reg_idx, thread->readTid());
}
O3ThreadContext<Impl>::readFloatRegBits(int reg_idx, int width)
{
DPRINTF(Fault, "Reading floatint register through the TC!\n");
+ reg_idx = TheISA::flattenFloatIndex(this, reg_idx);
return cpu->readArchFloatRegInt(reg_idx, thread->readTid());
}
TheISA::FloatRegBits
O3ThreadContext<Impl>::readFloatRegBits(int reg_idx)
{
+ reg_idx = TheISA::flattenFloatIndex(this, reg_idx);
return cpu->readArchFloatRegInt(reg_idx, thread->readTid());
}
void
O3ThreadContext<Impl>::setFloatReg(int reg_idx, FloatReg val, int width)
{
+ reg_idx = TheISA::flattenFloatIndex(this, reg_idx);
switch(width) {
case 32:
cpu->setArchFloatRegSingle(reg_idx, val, thread->readTid());
void
O3ThreadContext<Impl>::setFloatReg(int reg_idx, FloatReg val)
{
+ reg_idx = TheISA::flattenFloatIndex(this, reg_idx);
cpu->setArchFloatRegSingle(reg_idx, val, thread->readTid());
if (!thread->trapPending && !thread->inSyscall) {
int width)
{
DPRINTF(Fault, "Setting floatint register through the TC!\n");
+ reg_idx = TheISA::flattenFloatIndex(this, reg_idx);
cpu->setArchFloatRegInt(reg_idx, val, thread->readTid());
// Squash if we're not already in a state update mode.
void
O3ThreadContext<Impl>::setFloatRegBits(int reg_idx, FloatRegBits val)
{
+ reg_idx = TheISA::flattenFloatIndex(this, reg_idx);
cpu->setArchFloatRegInt(reg_idx, val, thread->readTid());
// Squash if we're not already in a state update mode.
//
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)
{
- return regs.readFloatReg(reg_idx, width);
+ int flatIndex = TheISA::flattenIntIndex(getTC(), reg_idx);
+ return regs.readFloatReg(flatIndex, width);
}
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)
{
- return regs.readFloatRegBits(reg_idx, width);
+ int flatIndex = TheISA::flattenIntIndex(getTC(), reg_idx);
+ return regs.readFloatRegBits(flatIndex, width);
}
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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- regs.setFloatRegBits(reg_idx, val);
+ int flatIndex = TheISA::flattenIntIndex(getTC(), reg_idx);
+ regs.setFloatRegBits(flatIndex, val);
}
uint64_t readPC()