changeset 8f1f1bdedf8c in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=8f1f1bdedf8c
description:
        x86: Add helper functions to access rflags

        The rflags register is spread across several different registers. Most
        of the flags are stored in MISCREG_RFLAGS, but some are stored in
        microcode registers. When accessing RFLAGS, we need to reconstruct it
        from these registers. This changeset adds two functions,
        X86ISA::getRFlags() and X86ISA::setRFlags(), that take care of this
        magic.

diffstat:

 src/arch/x86/utility.cc |  31 +++++++++++++++++++++++++++++++
 src/arch/x86/utility.hh |  29 +++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+), 0 deletions(-)

diffs (79 lines):

diff -r 353587055aff -r 8f1f1bdedf8c src/arch/x86/utility.cc
--- a/src/arch/x86/utility.cc   Tue Jun 18 16:10:21 2013 +0200
+++ b/src/arch/x86/utility.cc   Tue Jun 18 16:10:22 2013 +0200
@@ -236,5 +236,36 @@
     panic("Not implemented for x86\n");
 }
 
+uint64_t
+getRFlags(ThreadContext *tc)
+{
+    const uint64_t ncc_flags(tc->readMiscRegNoEffect(MISCREG_RFLAGS));
+    const uint64_t cc_flags(tc->readIntReg(X86ISA::INTREG_PSEUDO(0)));
+    const uint64_t cfof_bits(tc->readIntReg(X86ISA::INTREG_PSEUDO(1)));
+    const uint64_t df_bit(tc->readIntReg(X86ISA::INTREG_PSEUDO(2)));
+    // ecf (PSEUDO(3)) & ezf (PSEUDO(4)) are only visible to
+    // microcode, so we can safely ignore them.
+
+    // Reconstruct the real rflags state, mask out internal flags, and
+    // make sure reserved bits have the expected values.
+    return ((ncc_flags | cc_flags | cfof_bits | df_bit) & 0x3F7FD5)
+        | 0x2;
+}
+
+void
+setRFlags(ThreadContext *tc, uint64_t val)
+{
+    tc->setIntReg(X86ISA::INTREG_PSEUDO(0), val & ccFlagMask);
+    tc->setIntReg(X86ISA::INTREG_PSEUDO(1), val & cfofMask);
+    tc->setIntReg(X86ISA::INTREG_PSEUDO(2), val & DFBit);
+
+    // Internal microcode registers (ECF & EZF)
+    tc->setIntReg(X86ISA::INTREG_PSEUDO(3), 0);
+    tc->setIntReg(X86ISA::INTREG_PSEUDO(4), 0);
+
+    // Update the RFLAGS misc reg with whatever didn't go into the
+    // magic registers.
+    tc->setMiscReg(MISCREG_RFLAGS, val & ~(ccFlagMask | cfofMask | DFBit));
+}
 
 } // namespace X86_ISA
diff -r 353587055aff -r 8f1f1bdedf8c src/arch/x86/utility.hh
--- a/src/arch/x86/utility.hh   Tue Jun 18 16:10:21 2013 +0200
+++ b/src/arch/x86/utility.hh   Tue Jun 18 16:10:22 2013 +0200
@@ -105,6 +105,35 @@
         return 0;
     }
 
+
+    /**
+     * Reconstruct the rflags register from the internal gem5 register
+     * state.
+     *
+     * gem5 stores rflags in several different registers to avoid
+     * pipeline dependencies. In order to get the true rflags value,
+     * we can't simply read the value of MISCREG_RFLAGS. Instead, we
+     * need to read out various state from microcode registers and
+     * merge that with MISCREG_RFLAGS.
+     *
+     * @param tc Thread context to read rflags from.
+     * @return rflags as seen by the guest.
+     */
+    uint64_t getRFlags(ThreadContext *tc);
+
+    /**
+     * Set update the rflags register and internal gem5 state.
+     *
+     * @note This function does not update MISCREG_M5_REG. You might
+     * need to update this register by writing anything to
+     * MISCREG_M5_REG with side-effects.
+     *
+     * @see X86ISA::getRFlags()
+     *
+     * @param tc Thread context to update
+     * @param val New rflags value to store in TC
+     */
+    void setRFlags(ThreadContext *tc, uint64_t val);
 }
 
 #endif // __ARCH_X86_UTILITY_HH__
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to