/* * Copyright (C) 2014 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(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; } bool isSet() const { return m_index != invalid(); } bool operator!() const { return !isSet(); } 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::firstRegister() + m_index); } MacroAssembler::FPRegisterID fpr() const { ASSERT(isFPR()); return static_cast( 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; private: static uint8_t invalid() { return 0xff; } uint8_t m_index; }; } // namespace JSC #endif // ENABLE(JIT) #endif // Reg_h