summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/jit/Reg.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/jit/Reg.h')
-rw-r--r--Source/JavaScriptCore/jit/Reg.h250
1 files changed, 250 insertions, 0 deletions
diff --git a/Source/JavaScriptCore/jit/Reg.h b/Source/JavaScriptCore/jit/Reg.h
new file mode 100644
index 000000000..4db916321
--- /dev/null
+++ b/Source/JavaScriptCore/jit/Reg.h
@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) 2014, 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef Reg_h
+#define Reg_h
+
+#if ENABLE(JIT)
+
+#include "MacroAssembler.h"
+
+namespace JSC {
+
+// Reg is a polymorphic register class. It can refer to either integer or float registers.
+// Here are some use cases:
+//
+// GPRReg gpr;
+// Reg reg = gpr;
+// reg.isSet() == true
+// reg.isGPR() == true
+// reg.isFPR() == false
+//
+// for (Reg reg = Reg::first(); reg <= Reg::last(); reg = reg.next()) {
+// if (reg.isGPR()) {
+// } else /* reg.isFPR() */ {
+// }
+// }
+//
+// The above loop could have also used !!reg or reg.isSet() as a condition.
+
+class Reg {
+public:
+ Reg()
+ : m_index(invalid())
+ {
+ }
+
+ Reg(WTF::HashTableDeletedValueType)
+ : m_index(deleted())
+ {
+ }
+
+ Reg(MacroAssembler::RegisterID reg)
+ : m_index(MacroAssembler::registerIndex(reg))
+ {
+ }
+
+ Reg(MacroAssembler::FPRegisterID reg)
+ : m_index(MacroAssembler::registerIndex(reg))
+ {
+ }
+
+ static Reg fromIndex(unsigned index)
+ {
+ Reg result;
+ result.m_index = index;
+ return result;
+ }
+
+ static Reg first()
+ {
+ Reg result;
+ result.m_index = 0;
+ return result;
+ }
+
+ static Reg last()
+ {
+ Reg result;
+ result.m_index = MacroAssembler::numberOfRegisters() + MacroAssembler::numberOfFPRegisters() - 1;
+ return result;
+ }
+
+ Reg next() const
+ {
+ ASSERT(!!*this);
+ if (*this == last())
+ return Reg();
+ Reg result;
+ result.m_index = m_index + 1;
+ return result;
+ }
+
+ unsigned index() const { return m_index; }
+
+ static unsigned maxIndex()
+ {
+ return last().index();
+ }
+
+ bool isSet() const { return m_index != invalid(); }
+ explicit operator bool() const { return isSet(); }
+
+ bool isHashTableDeletedValue() const { return m_index == deleted(); }
+
+ bool isGPR() const
+ {
+ return m_index < MacroAssembler::numberOfRegisters();
+ }
+
+ bool isFPR() const
+ {
+ return (m_index - MacroAssembler::numberOfRegisters()) < MacroAssembler::numberOfFPRegisters();
+ }
+
+ MacroAssembler::RegisterID gpr() const
+ {
+ ASSERT(isGPR());
+ return static_cast<MacroAssembler::RegisterID>(MacroAssembler::firstRegister() + m_index);
+ }
+
+ MacroAssembler::FPRegisterID fpr() const
+ {
+ ASSERT(isFPR());
+ return static_cast<MacroAssembler::FPRegisterID>(
+ MacroAssembler::firstFPRegister() + (m_index - MacroAssembler::numberOfRegisters()));
+ }
+
+ bool operator==(const Reg& other) const
+ {
+ return m_index == other.m_index;
+ }
+
+ bool operator!=(const Reg& other) const
+ {
+ return m_index != other.m_index;
+ }
+
+ bool operator<(const Reg& other) const
+ {
+ return m_index < other.m_index;
+ }
+
+ bool operator>(const Reg& other) const
+ {
+ return m_index > other.m_index;
+ }
+
+ bool operator<=(const Reg& other) const
+ {
+ return m_index <= other.m_index;
+ }
+
+ bool operator>=(const Reg& other) const
+ {
+ return m_index >= other.m_index;
+ }
+
+ unsigned hash() const
+ {
+ return m_index;
+ }
+
+ void dump(PrintStream&) const;
+
+ class AllRegsIterable {
+ public:
+
+ class iterator {
+ public:
+ iterator() { }
+
+ explicit iterator(Reg reg)
+ : m_regIndex(reg.index())
+ {
+ }
+
+ Reg operator*() const { return Reg::fromIndex(m_regIndex); }
+
+ iterator& operator++()
+ {
+ m_regIndex = Reg::fromIndex(m_regIndex).next().index();
+ return *this;
+ }
+
+ bool operator==(const iterator& other) const
+ {
+ return m_regIndex == other.m_regIndex;
+ }
+
+ bool operator!=(const iterator& other) const
+ {
+ return !(*this == other);
+ }
+
+ private:
+ unsigned m_regIndex;
+ };
+
+ iterator begin() const { return iterator(Reg::first()); }
+ iterator end() const { return iterator(Reg()); }
+ };
+
+ static AllRegsIterable all() { return AllRegsIterable(); }
+
+private:
+ static uint8_t invalid() { return 0xff; }
+
+ static uint8_t deleted() { return 0xfe; }
+
+ uint8_t m_index;
+};
+
+struct RegHash {
+ static unsigned hash(const Reg& key) { return key.hash(); }
+ static bool equal(const Reg& a, const Reg& b) { return a == b; }
+ static const bool safeToCompareToEmptyOrDeleted = true;
+};
+
+} // namespace JSC
+
+namespace WTF {
+
+template<typename T> struct DefaultHash;
+template<> struct DefaultHash<JSC::Reg> {
+ typedef JSC::RegHash Hash;
+};
+
+template<typename T> struct HashTraits;
+template<> struct HashTraits<JSC::Reg> : SimpleClassHashTraits<JSC::Reg> {
+ static const bool emptyValueIsZero = false;
+ };
+
+} // namespace WTF
+
+#endif // ENABLE(JIT)
+
+#endif // Reg_h
+