1/* 2 * Copyright (C) 2014 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#ifndef Reg_h 27#define Reg_h 28 29#if ENABLE(JIT) 30 31#include "MacroAssembler.h" 32 33namespace JSC { 34 35// Reg is a polymorphic register class. It can refer to either integer or float registers. 36// Here are some use cases: 37// 38// GPRReg gpr; 39// Reg reg = gpr; 40// reg.isSet() == true 41// reg.isGPR() == true 42// reg.isFPR() == false 43// 44// for (Reg reg = Reg::first(); reg <= Reg::last(); reg = reg.next()) { 45// if (reg.isGPR()) { 46// } else /* reg.isFPR() */ { 47// } 48// } 49// 50// The above loop could have also used !!reg or reg.isSet() as a condition. 51 52class Reg { 53public: 54 Reg() 55 : m_index(invalid()) 56 { 57 } 58 59 Reg(MacroAssembler::RegisterID reg) 60 : m_index(MacroAssembler::registerIndex(reg)) 61 { 62 } 63 64 Reg(MacroAssembler::FPRegisterID reg) 65 : m_index(MacroAssembler::registerIndex(reg)) 66 { 67 } 68 69 static Reg fromIndex(unsigned index) 70 { 71 Reg result; 72 result.m_index = index; 73 return result; 74 } 75 76 static Reg first() 77 { 78 Reg result; 79 result.m_index = 0; 80 return result; 81 } 82 83 static Reg last() 84 { 85 Reg result; 86 result.m_index = MacroAssembler::numberOfRegisters() + MacroAssembler::numberOfFPRegisters() - 1; 87 return result; 88 } 89 90 Reg next() const 91 { 92 ASSERT(!!*this); 93 if (*this == last()) 94 return Reg(); 95 Reg result; 96 result.m_index = m_index + 1; 97 return result; 98 } 99 100 unsigned index() const { return m_index; } 101 102 bool isSet() const { return m_index != invalid(); } 103 bool operator!() const { return !isSet(); } 104 105 bool isGPR() const 106 { 107 return m_index < MacroAssembler::numberOfRegisters(); 108 } 109 110 bool isFPR() const 111 { 112 return (m_index - MacroAssembler::numberOfRegisters()) < MacroAssembler::numberOfFPRegisters(); 113 } 114 115 MacroAssembler::RegisterID gpr() const 116 { 117 ASSERT(isGPR()); 118 return static_cast<MacroAssembler::RegisterID>(MacroAssembler::firstRegister() + m_index); 119 } 120 121 MacroAssembler::FPRegisterID fpr() const 122 { 123 ASSERT(isFPR()); 124 return static_cast<MacroAssembler::FPRegisterID>( 125 MacroAssembler::firstFPRegister() + (m_index - MacroAssembler::numberOfRegisters())); 126 } 127 128 bool operator==(const Reg& other) const 129 { 130 return m_index == other.m_index; 131 } 132 133 bool operator!=(const Reg& other) const 134 { 135 return m_index != other.m_index; 136 } 137 138 bool operator<(const Reg& other) const 139 { 140 return m_index < other.m_index; 141 } 142 143 bool operator>(const Reg& other) const 144 { 145 return m_index > other.m_index; 146 } 147 148 bool operator<=(const Reg& other) const 149 { 150 return m_index <= other.m_index; 151 } 152 153 bool operator>=(const Reg& other) const 154 { 155 return m_index >= other.m_index; 156 } 157 158 unsigned hash() const 159 { 160 return m_index; 161 } 162 163 void dump(PrintStream&) const; 164 165private: 166 static uint8_t invalid() { return 0xff; } 167 168 uint8_t m_index; 169}; 170 171} // namespace JSC 172 173#endif // ENABLE(JIT) 174 175#endif // Reg_h 176 177