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 = 158 -(StandardFrameConstants::kFixedFrameSizeFromFp + kPointerSize); 159 }; 160 161 162 class ExitFrameConstants : public AllStatic { 163 public: 164 // See some explanation in MacroAssembler::EnterExitFrame. 165 // This marks the top of the extra allocated stack space. 166 static const int kStackSpaceOffset = -3 * kPointerSize; 167 168 static const int kCodeOffset = -2 * kPointerSize; 169 170 static const int kSPOffset = -1 * kPointerSize; 171 172 // The caller fields are below the frame pointer on the stack. 173 static const int kCallerFPOffset = +0 * kPointerSize; 174 // The calling JS function is between FP and PC. 175 static const int kCallerPCOffset = +1 * kPointerSize; 176 177 // MIPS-specific: a pointer to the old sp to avoid unnecessary calculations. 178 static const int kCallerSPOffset = +2 * kPointerSize; 179 180 // FP-relative displacement of the caller's SP. 181 static const int kCallerSPDisplacement = +2 * kPointerSize; 182 }; 183 184 185 class JavaScriptFrameConstants : public AllStatic { 186 public: 187 // FP-relative. 188 static const int kLocal0Offset = StandardFrameConstants::kExpressionsOffset; 189 static const int kLastParameterOffset = +2 * kPointerSize; 190 static const int kFunctionOffset = StandardFrameConstants::kMarkerOffset; 191 192 // Caller SP-relative. 193 static const int kParam0Offset = -2 * kPointerSize; 194 static const int kReceiverOffset = -1 * kPointerSize; 195 }; 196 197 198 class ArgumentsAdaptorFrameConstants : public AllStatic { 199 public: 200 // FP-relative. 201 static const int kLengthOffset = StandardFrameConstants::kExpressionsOffset; 202 203 static const int kFrameSize = 204 StandardFrameConstants::kFixedFrameSize + kPointerSize; 205 }; 206 207 208 class ConstructFrameConstants : public AllStatic { 209 public: 210 // FP-relative. 211 static const int kImplicitReceiverOffset = -6 * kPointerSize; 212 static const int kConstructorOffset = -5 * kPointerSize; 213 static const int kLengthOffset = -4 * kPointerSize; 214 static const int kCodeOffset = StandardFrameConstants::kExpressionsOffset; 215 216 static const int kFrameSize = 217 StandardFrameConstants::kFixedFrameSize + 4 * kPointerSize; 218 }; 219 220 221 class InternalFrameConstants : public AllStatic { 222 public: 223 // FP-relative. 224 static const int kCodeOffset = StandardFrameConstants::kExpressionsOffset; 225 }; 226 227 228 inline Object* JavaScriptFrame::function_slot_object() const { 229 const int offset = JavaScriptFrameConstants::kFunctionOffset; 230 return Memory::Object_at(fp() + offset); 231 } 232 233 234 inline void StackHandler::SetFp(Address slot, Address fp) { 235 Memory::Address_at(slot) = fp; 236 } 237 238 239 } } // namespace v8::internal 240 241 #endif 242