From f3f3747431e001dc6c80da5b6489516b610c22d6 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 19 Sep 2007 18:26:42 -0700 Subject: [PATCH] X86: Put in the foundation for x87 stack based fp registers. --HG-- extra : convert_revision : 940f92efd4a9dc59106e991cc6d9836861ab69de --- src/arch/alpha/regfile.hh | 5 +++++ src/arch/mips/regfile/regfile.hh | 5 +++++ src/arch/sparc/regfile.hh | 5 +++++ src/arch/x86/floatregfile.hh | 5 +++-- src/arch/x86/floatregs.hh | 6 ++++++ src/arch/x86/isa/microasm.isa | 5 +++++ src/arch/x86/isa/operands.isa | 3 +++ src/arch/x86/isa_traits.hh | 4 +++- src/arch/x86/miscregs.hh | 5 ++++- src/arch/x86/regfile.cc | 10 ++++++++++ src/arch/x86/regfile.hh | 2 ++ src/cpu/o3/rename_impl.hh | 6 ++++-- src/cpu/o3/thread_context_impl.hh | 8 ++++++++ src/cpu/simple_thread.hh | 30 ++++++++++++++++++++---------- 14 files changed, 83 insertions(+), 16 deletions(-) diff --git a/src/arch/alpha/regfile.hh b/src/arch/alpha/regfile.hh index b93707181..792a518fb 100644 --- a/src/arch/alpha/regfile.hh +++ b/src/arch/alpha/regfile.hh @@ -192,6 +192,11 @@ namespace AlphaISA return reg; } + static inline int flattenFloatIndex(ThreadContext * tc, int reg) + { + return reg; + } + void copyRegs(ThreadContext *src, ThreadContext *dest); void copyMiscRegs(ThreadContext *src, ThreadContext *dest); diff --git a/src/arch/mips/regfile/regfile.hh b/src/arch/mips/regfile/regfile.hh index b83bb576b..4be8d399c 100644 --- a/src/arch/mips/regfile/regfile.hh +++ b/src/arch/mips/regfile/regfile.hh @@ -187,6 +187,11 @@ namespace MipsISA return reg; } + static inline int flattenFloatIndex(ThreadContext * tc, int reg) + { + return reg; + } + void copyRegs(ThreadContext *src, ThreadContext *dest); diff --git a/src/arch/sparc/regfile.hh b/src/arch/sparc/regfile.hh index f3e253f7e..7972d6982 100644 --- a/src/arch/sparc/regfile.hh +++ b/src/arch/sparc/regfile.hh @@ -122,6 +122,11 @@ namespace SparcISA 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); diff --git a/src/arch/x86/floatregfile.hh b/src/arch/x86/floatregfile.hh index 14dda443f..b77ddb0eb 100644 --- a/src/arch/x86/floatregfile.hh +++ b/src/arch/x86/floatregfile.hh @@ -101,8 +101,9 @@ namespace X86ISA 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 { diff --git a/src/arch/x86/floatregs.hh b/src/arch/x86/floatregs.hh index b9d6a5c43..30846ec00 100644 --- a/src/arch/x86/floatregs.hh +++ b/src/arch/x86/floatregs.hh @@ -162,6 +162,12 @@ namespace X86ISA { 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__ diff --git a/src/arch/x86/isa/microasm.isa b/src/arch/x86/isa/microasm.isa index 579909506..e961cc63c 100644 --- a/src/arch/x86/isa/microasm.isa +++ b/src/arch/x86/isa/microasm.isa @@ -136,5 +136,10 @@ let {{ assembler.symbols["label"] = labeler + def stack_index(index): + return "(NUM_FLOATREGS + (%s))" % index + + assembler.symbols["st"] = stack_index + macroopDict = assembler.assemble(microcode) }}; diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa index 7b0427b44..05a9f4418 100644 --- a/src/arch/x86/isa/operands.isa +++ b/src/arch/x86/isa/operands.isa @@ -115,6 +115,9 @@ def operands {{ '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) }}; diff --git a/src/arch/x86/isa_traits.hh b/src/arch/x86/isa_traits.hh index 602c99390..f3478d7f6 100644 --- a/src/arch/x86/isa_traits.hh +++ b/src/arch/x86/isa_traits.hh @@ -89,7 +89,9 @@ namespace X86ISA //mmx/x87 registers 8 + //xmm registers - 16 + 16 + + //The indices that are mapped over the fp stack + 8 }; // semantically meaningful register indices diff --git a/src/arch/x86/miscregs.hh b/src/arch/x86/miscregs.hh index 01499e7ad..bab813719 100644 --- a/src/arch/x86/miscregs.hh +++ b/src/arch/x86/miscregs.hh @@ -171,9 +171,12 @@ namespace X86ISA 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 diff --git a/src/arch/x86/regfile.cc b/src/arch/x86/regfile.cc index 96283cada..889f2f5cd 100644 --- a/src/arch/x86/regfile.cc +++ b/src/arch/x86/regfile.cc @@ -85,6 +85,7 @@ * Authors: Gabe Black */ +#include "arch/x86/floatregs.hh" #include "arch/x86/regfile.hh" #include "base/trace.hh" #include "sim/serialize.hh" @@ -218,6 +219,15 @@ int X86ISA::flattenIntIndex(ThreadContext * tc, int reg) 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); diff --git a/src/arch/x86/regfile.hh b/src/arch/x86/regfile.hh index d4425b04c..650181aca 100644 --- a/src/arch/x86/regfile.hh +++ b/src/arch/x86/regfile.hh @@ -149,6 +149,8 @@ namespace X86ISA int flattenIntIndex(ThreadContext * tc, int reg); + int flattenFloatIndex(ThreadContext * tc, int reg); + void copyRegs(ThreadContext *src, ThreadContext *dest); void copyMiscRegs(ThreadContext *src, ThreadContext *dest); diff --git a/src/cpu/o3/rename_impl.hh b/src/cpu/o3/rename_impl.hh index d78de2c87..49c885753 100644 --- a/src/cpu/o3/rename_impl.hh +++ b/src/cpu/o3/rename_impl.hh @@ -959,9 +959,11 @@ DefaultRename::renameSrcRegs(DynInstPtr &inst,unsigned tid) 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); } diff --git a/src/cpu/o3/thread_context_impl.hh b/src/cpu/o3/thread_context_impl.hh index a145e046e..efbbc2329 100755 --- a/src/cpu/o3/thread_context_impl.hh +++ b/src/cpu/o3/thread_context_impl.hh @@ -314,6 +314,7 @@ template TheISA::FloatReg O3ThreadContext::readFloatReg(int reg_idx, int width) { + reg_idx = TheISA::flattenFloatIndex(this, reg_idx); switch(width) { case 32: return cpu->readArchFloatRegSingle(reg_idx, thread->readTid()); @@ -329,6 +330,7 @@ template TheISA::FloatReg O3ThreadContext::readFloatReg(int reg_idx) { + reg_idx = TheISA::flattenFloatIndex(this, reg_idx); return cpu->readArchFloatRegSingle(reg_idx, thread->readTid()); } @@ -337,6 +339,7 @@ TheISA::FloatRegBits O3ThreadContext::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()); } @@ -344,6 +347,7 @@ template TheISA::FloatRegBits O3ThreadContext::readFloatRegBits(int reg_idx) { + reg_idx = TheISA::flattenFloatIndex(this, reg_idx); return cpu->readArchFloatRegInt(reg_idx, thread->readTid()); } @@ -364,6 +368,7 @@ template void O3ThreadContext::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()); @@ -383,6 +388,7 @@ template void O3ThreadContext::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) { @@ -396,6 +402,7 @@ O3ThreadContext::setFloatRegBits(int reg_idx, FloatRegBits val, 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. @@ -408,6 +415,7 @@ template void O3ThreadContext::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. diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh index 1e87b0bb7..c018e3e49 100644 --- a/src/cpu/simple_thread.hh +++ b/src/cpu/simple_thread.hh @@ -235,52 +235,62 @@ class SimpleThread : public ThreadState // 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() -- 2.30.2