1/* 2 * Copyright (C) 2012, 2013 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 TempRegisterSet_h 27#define TempRegisterSet_h 28 29#if ENABLE(JIT) 30 31#include "FPRInfo.h" 32#include "GPRInfo.h" 33 34namespace JSC { 35 36class RegisterSet; 37 38class TempRegisterSet { 39public: 40 TempRegisterSet() 41 { 42 clearAll(); 43 } 44 45 TempRegisterSet(const RegisterSet&); 46 47 void set(GPRReg reg) 48 { 49 setBit(GPRInfo::toIndex(reg)); 50 } 51 52 void set(JSValueRegs regs) 53 { 54 if (regs.tagGPR() != InvalidGPRReg) 55 set(regs.tagGPR()); 56 set(regs.payloadGPR()); 57 } 58 59 void setGPRByIndex(unsigned index) 60 { 61 ASSERT(index < GPRInfo::numberOfRegisters); 62 setBit(index); 63 } 64 65 void clear(GPRReg reg) 66 { 67 clearBit(GPRInfo::toIndex(reg)); 68 } 69 70 bool get(GPRReg reg) const 71 { 72 return getBit(GPRInfo::toIndex(reg)); 73 } 74 75 bool getGPRByIndex(unsigned index) const 76 { 77 ASSERT(index < GPRInfo::numberOfRegisters); 78 return getBit(index); 79 } 80 81 // Return the index'th free GPR. 82 GPRReg getFreeGPR(unsigned index = 0) const 83 { 84 for (unsigned i = GPRInfo::numberOfRegisters; i--;) { 85 if (!getGPRByIndex(i) && !index--) 86 return GPRInfo::toRegister(i); 87 } 88 return InvalidGPRReg; 89 } 90 91 void set(FPRReg reg) 92 { 93 setBit(GPRInfo::numberOfRegisters + FPRInfo::toIndex(reg)); 94 } 95 96 void setFPRByIndex(unsigned index) 97 { 98 ASSERT(index < FPRInfo::numberOfRegisters); 99 setBit(GPRInfo::numberOfRegisters + index); 100 } 101 102 void clear(FPRReg reg) 103 { 104 clearBit(GPRInfo::numberOfRegisters + FPRInfo::toIndex(reg)); 105 } 106 107 bool get(FPRReg reg) const 108 { 109 return getBit(GPRInfo::numberOfRegisters + FPRInfo::toIndex(reg)); 110 } 111 112 bool getFPRByIndex(unsigned index) const 113 { 114 ASSERT(index < FPRInfo::numberOfRegisters); 115 return getBit(GPRInfo::numberOfRegisters + index); 116 } 117 118 template<typename BankInfo> 119 void setByIndex(unsigned index) 120 { 121 set(BankInfo::toRegister(index)); 122 } 123 124 template<typename BankInfo> 125 bool getByIndex(unsigned index) 126 { 127 return get(BankInfo::toRegister(index)); 128 } 129 130 unsigned numberOfSetGPRs() const 131 { 132 unsigned result = 0; 133 for (unsigned i = GPRInfo::numberOfRegisters; i--;) { 134 if (!getBit(i)) 135 continue; 136 result++; 137 } 138 return result; 139 } 140 141 unsigned numberOfSetFPRs() const 142 { 143 unsigned result = 0; 144 for (unsigned i = FPRInfo::numberOfRegisters; i--;) { 145 if (!getBit(GPRInfo::numberOfRegisters + i)) 146 continue; 147 result++; 148 } 149 return result; 150 } 151 152 unsigned numberOfSetRegisters() const 153 { 154 unsigned result = 0; 155 for (unsigned i = totalNumberOfRegisters; i--;) { 156 if (!getBit(i)) 157 continue; 158 result++; 159 } 160 return result; 161 } 162 163private: 164 void clearAll() 165 { 166 for (unsigned i = numberOfBytesInTempRegisterSet; i--;) 167 m_set[i] = 0; 168 } 169 170 void setBit(unsigned i) 171 { 172 ASSERT(i < totalNumberOfRegisters); 173 m_set[i >> 3] |= (1 << (i & 7)); 174 } 175 176 void clearBit(unsigned i) 177 { 178 ASSERT(i < totalNumberOfRegisters); 179 m_set[i >> 3] &= ~(1 << (i & 7)); 180 } 181 182 bool getBit(unsigned i) const 183 { 184 ASSERT(i < totalNumberOfRegisters); 185 return !!(m_set[i >> 3] & (1 << (i & 7))); 186 } 187 188 static const unsigned totalNumberOfRegisters = 189 GPRInfo::numberOfRegisters + FPRInfo::numberOfRegisters; 190 191 static const unsigned numberOfBytesInTempRegisterSet = 192 (totalNumberOfRegisters + 7) >> 3; 193 194 uint8_t m_set[numberOfBytesInTempRegisterSet]; 195}; 196 197} // namespace JSC 198 199#else // ENABLE(JIT) -> so if JIT is disabled 200 201namespace JSC { 202 203// Define TempRegisterSet to something, to make it easier to refer to this type in code that 204// make be compiled when the JIT is disabled. 205 206struct TempRegisterSet { }; 207 208} // namespace JSC 209 210#endif // ENABLE(JIT) 211 212#endif // TempRegisterSet_h 213 214