1 // Copyright 2011 the V8 project authors. All rights reserved. 2 // Redistribution and use in source and binary forms, with or without 3 // modification, are permitted provided that the following conditions are 4 // met: 5 // 6 // * Redistributions of source code must retain the above copyright 7 // notice, this list of conditions and the following disclaimer. 8 // * Redistributions in binary form must reproduce the above 9 // copyright notice, this list of conditions and the following 10 // disclaimer in the documentation and/or other materials provided 11 // with the distribution. 12 // * Neither the name of Google Inc. nor the names of its 13 // contributors may be used to endorse or promote products derived 14 // from this software without specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 29 30 #ifndef V8_MIPS_FRAMES_MIPS_H_ 31 #define V8_MIPS_FRAMES_MIPS_H_ 32 33 namespace v8 { 34 namespace internal { 35 36 // Register lists. 37 // Note that the bit values must match those used in actual instruction 38 // encoding. 39 const int kNumRegs = 32; 40 41 const RegList kJSCallerSaved = 42 1 << 2 | // v0 43 1 << 3 | // v1 44 1 << 4 | // a0 45 1 << 5 | // a1 46 1 << 6 | // a2 47 1 << 7 | // a3 48 1 << 8 | // t0 49 1 << 9 | // t1 50 1 << 10 | // t2 51 1 << 11 | // t3 52 1 << 12 | // t4 53 1 << 13 | // t5 54 1 << 14 | // t6 55 1 << 15; // t7 56 57 const int kNumJSCallerSaved = 14; 58 59 60 // Return the code of the n-th caller-saved register available to JavaScript 61 // e.g. JSCallerSavedReg(0) returns a0.code() == 4. 62 int JSCallerSavedCode(int n); 63 64 65 // Callee-saved registers preserved when switching from C to JavaScript. 66 const RegList kCalleeSaved = 67 1 << 16 | // s0 68 1 << 17 | // s1 69 1 << 18 | // s2 70 1 << 19 | // s3 71 1 << 20 | // s4 72 1 << 21 | // s5 73 1 << 22 | // s6 (roots in Javascript code) 74 1 << 23 | // s7 (cp in Javascript code) 75 1 << 30; // fp/s8 76 77 const int kNumCalleeSaved = 9; 78 79 const RegList kCalleeSavedFPU = 80 1 << 20 | // f20 81 1 << 22 | // f22 82 1 << 24 | // f24 83 1 << 26 | // f26 84 1 << 28 | // f28 85 1 << 30; // f30 86 87 const int kNumCalleeSavedFPU = 6; 88 89 const RegList kCallerSavedFPU = 90 1 << 0 | // f0 91 1 << 2 | // f2 92 1 << 4 | // f4 93 1 << 6 | // f6 94 1 << 8 | // f8 95 1 << 10 | // f10 96 1 << 12 | // f12 97 1 << 14 | // f14 98 1 << 16 | // f16 99 1 << 18; // f18 100 101 102 // Number of registers for which space is reserved in safepoints. Must be a 103 // multiple of 8. 104 const int kNumSafepointRegisters = 24; 105 106 // Define the list of registers actually saved at safepoints. 107 // Note that the number of saved registers may be smaller than the reserved 108 // space, i.e. kNumSafepointSavedRegisters <= kNumSafepointRegisters. 109 const RegList kSafepointSavedRegisters = kJSCallerSaved | kCalleeSaved; 110 const int kNumSafepointSavedRegisters = 111 kNumJSCallerSaved + kNumCalleeSaved; 112 113 typedef Object* JSCallerSavedBuffer[kNumJSCallerSaved]; 114 115 const int kUndefIndex = -1; 116 // Map with indexes on stack that corresponds to codes of saved registers. 117 const int kSafepointRegisterStackIndexMap[kNumRegs] = { 118 kUndefIndex, // zero_reg 119 kUndefIndex, // at 120 0, // v0 121 1, // v1 122 2, // a0 123 3, // a1 124 4, // a2 125 5, // a3 126 6, // t0 127 7, // t1 128 8, // t2 129 9, // t3 130 10, // t4 131 11, // t5 132 12, // t6 133 13, // t7 134 14, // s0 135 15, // s1 136 16, // s2 137 17, // s3 138 18, // s4 139 19, // s5 140 20, // s6 141 21, // s7 142 kUndefIndex, // t8 143 kUndefIndex, // t9 144 kUndefIndex, // k0 145 kUndefIndex, // k1 146 kUndefIndex, // gp 147 kUndefIndex, // sp 148 22, // fp 149 kUndefIndex 150 }; 151 152 153 // ---------------------------------------------------- 154 155 class EntryFrameConstants : public AllStatic { 156 public: 157 static const int kCallerFPOffset = -3 * kPointerSize; 158 }; 159 160 161 class ExitFrameConstants : public AllStatic { 162 public: 163 // See some explanation in MacroAssembler::EnterExitFrame. 164 // This marks the top of the extra allocated stack space. 165 static const int kStackSpaceOffset = -3 * kPointerSize; 166 167 static const int kCodeOffset = -2 * kPointerSize; 168 169 static const int kSPOffset = -1 * kPointerSize; 170 171 // The caller fields are below the frame pointer on the stack. 172 static const int kCallerFPOffset = +0 * kPointerSize; 173 // The calling JS function is between FP and PC. 174 static const int kCallerPCOffset = +1 * kPointerSize; 175 176 // MIPS-specific: a pointer to the old sp to avoid unnecessary calculations. 177 static const int kCallerSPOffset = +2 * kPointerSize; 178 179 // FP-relative displacement of the caller's SP. 180 static const int kCallerSPDisplacement = +2 * kPointerSize; 181 }; 182 183 184 class JavaScriptFrameConstants : public AllStatic { 185 public: 186 // FP-relative. 187 static const int kLocal0Offset = StandardFrameConstants::kExpressionsOffset; 188 static const int kLastParameterOffset = +2 * kPointerSize; 189 static const int kFunctionOffset = StandardFrameConstants::kMarkerOffset; 190 191 // Caller SP-relative. 192 static const int kParam0Offset = -2 * kPointerSize; 193 static const int kReceiverOffset = -1 * kPointerSize; 194 }; 195 196 197 class ArgumentsAdaptorFrameConstants : public AllStatic { 198 public: 199 // FP-relative. 200 static const int kLengthOffset = StandardFrameConstants::kExpressionsOffset; 201 202 static const int kFrameSize = 203 StandardFrameConstants::kFixedFrameSize + kPointerSize; 204 }; 205 206 207 class ConstructFrameConstants : public AllStatic { 208 public: 209 // FP-relative. 210 static const int kImplicitReceiverOffset = -6 * kPointerSize; 211 static const int kConstructorOffset = -5 * kPointerSize; 212 static const int kLengthOffset = -4 * kPointerSize; 213 static const int kCodeOffset = StandardFrameConstants::kExpressionsOffset; 214 215 static const int kFrameSize = 216 StandardFrameConstants::kFixedFrameSize + 4 * kPointerSize; 217 }; 218 219 220 class InternalFrameConstants : public AllStatic { 221 public: 222 // FP-relative. 223 static const int kCodeOffset = StandardFrameConstants::kExpressionsOffset; 224 }; 225 226 227 inline Object* JavaScriptFrame::function_slot_object() const { 228 const int offset = JavaScriptFrameConstants::kFunctionOffset; 229 return Memory::Object_at(fp() + offset); 230 } 231 232 233 inline void StackHandler::SetFp(Address slot, Address fp) { 234 Memory::Address_at(slot) = fp; 235 } 236 237 238 } } // namespace v8::internal 239 240 #endif 241