1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 
6 
7 #ifndef V8_MIPS_FRAMES_MIPS_H_
8 #define V8_MIPS_FRAMES_MIPS_H_
9 
10 namespace v8 {
11 namespace internal {
12 
13 // Register lists.
14 // Note that the bit values must match those used in actual instruction
15 // encoding.
16 const int kNumRegs = 32;
17 
18 const RegList kJSCallerSaved =
19   1 << 2  |  // v0
20   1 << 3  |  // v1
21   1 << 4  |  // a0
22   1 << 5  |  // a1
23   1 << 6  |  // a2
24   1 << 7  |  // a3
25   1 << 8  |  // t0
26   1 << 9  |  // t1
27   1 << 10 |  // t2
28   1 << 11 |  // t3
29   1 << 12 |  // t4
30   1 << 13 |  // t5
31   1 << 14 |  // t6
32   1 << 15;   // t7
33 
34 const int kNumJSCallerSaved = 14;
35 
36 
37 // Return the code of the n-th caller-saved register available to JavaScript
38 // e.g. JSCallerSavedReg(0) returns a0.code() == 4.
39 int JSCallerSavedCode(int n);
40 
41 
42 // Callee-saved registers preserved when switching from C to JavaScript.
43 const RegList kCalleeSaved =
44   1 << 16 |  // s0
45   1 << 17 |  // s1
46   1 << 18 |  // s2
47   1 << 19 |  // s3
48   1 << 20 |  // s4
49   1 << 21 |  // s5
50   1 << 22 |  // s6 (roots in Javascript code)
51   1 << 23 |  // s7 (cp in Javascript code)
52   1 << 30;   // fp/s8
53 
54 const int kNumCalleeSaved = 9;
55 
56 const RegList kCalleeSavedFPU =
57   1 << 20 |  // f20
58   1 << 22 |  // f22
59   1 << 24 |  // f24
60   1 << 26 |  // f26
61   1 << 28 |  // f28
62   1 << 30;   // f30
63 
64 const int kNumCalleeSavedFPU = 6;
65 
66 const RegList kCallerSavedFPU =
67   1 << 0  |  // f0
68   1 << 2  |  // f2
69   1 << 4  |  // f4
70   1 << 6  |  // f6
71   1 << 8  |  // f8
72   1 << 10 |  // f10
73   1 << 12 |  // f12
74   1 << 14 |  // f14
75   1 << 16 |  // f16
76   1 << 18;   // f18
77 
78 
79 // Number of registers for which space is reserved in safepoints. Must be a
80 // multiple of 8.
81 const int kNumSafepointRegisters = 24;
82 
83 // Define the list of registers actually saved at safepoints.
84 // Note that the number of saved registers may be smaller than the reserved
85 // space, i.e. kNumSafepointSavedRegisters <= kNumSafepointRegisters.
86 const RegList kSafepointSavedRegisters = kJSCallerSaved | kCalleeSaved;
87 const int kNumSafepointSavedRegisters =
88     kNumJSCallerSaved + kNumCalleeSaved;
89 
90 const int kUndefIndex = -1;
91 // Map with indexes on stack that corresponds to codes of saved registers.
92 const int kSafepointRegisterStackIndexMap[kNumRegs] = {
93   kUndefIndex,  // zero_reg
94   kUndefIndex,  // at
95   0,   // v0
96   1,   // v1
97   2,   // a0
98   3,   // a1
99   4,   // a2
100   5,   // a3
101   6,   // t0
102   7,   // t1
103   8,   // t2
104   9,   // t3
105   10,  // t4
106   11,  // t5
107   12,  // t6
108   13,  // t7
109   14,  // s0
110   15,  // s1
111   16,  // s2
112   17,  // s3
113   18,  // s4
114   19,  // s5
115   20,  // s6
116   21,  // s7
117   kUndefIndex,  // t8
118   kUndefIndex,  // t9
119   kUndefIndex,  // k0
120   kUndefIndex,  // k1
121   kUndefIndex,  // gp
122   kUndefIndex,  // sp
123   22,  // fp
124   kUndefIndex
125 };
126 
127 
128 // ----------------------------------------------------
129 
130 class EntryFrameConstants : public AllStatic {
131  public:
132   static const int kCallerFPOffset =
133       -(StandardFrameConstants::kFixedFrameSizeFromFp + kPointerSize);
134 };
135 
136 
137 class ExitFrameConstants : public AllStatic {
138  public:
139   static const int kFrameSize = 2 * kPointerSize;
140 
141   static const int kCodeOffset = -2 * kPointerSize;
142   static const int kSPOffset = -1 * kPointerSize;
143 
144   // The caller fields are below the frame pointer on the stack.
145   static const int kCallerFPOffset = +0 * kPointerSize;
146   // The calling JS function is between FP and PC.
147   static const int kCallerPCOffset = +1 * kPointerSize;
148 
149   // MIPS-specific: a pointer to the old sp to avoid unnecessary calculations.
150   static const int kCallerSPOffset = +2 * kPointerSize;
151 
152   // FP-relative displacement of the caller's SP.
153   static const int kCallerSPDisplacement = +2 * kPointerSize;
154 
155   static const int kConstantPoolOffset = 0;  // Not used.
156 };
157 
158 
159 class JavaScriptFrameConstants : public AllStatic {
160  public:
161   // FP-relative.
162   static const int kLocal0Offset = StandardFrameConstants::kExpressionsOffset;
163   static const int kLastParameterOffset = +2 * kPointerSize;
164   static const int kFunctionOffset = StandardFrameConstants::kMarkerOffset;
165 
166   // Caller SP-relative.
167   static const int kParam0Offset   = -2 * kPointerSize;
168   static const int kReceiverOffset = -1 * kPointerSize;
169 };
170 
171 
172 class ArgumentsAdaptorFrameConstants : public AllStatic {
173  public:
174   // FP-relative.
175   static const int kLengthOffset = StandardFrameConstants::kExpressionsOffset;
176 
177   static const int kFrameSize =
178       StandardFrameConstants::kFixedFrameSize + kPointerSize;
179 };
180 
181 
182 class ConstructFrameConstants : public AllStatic {
183  public:
184   // FP-relative.
185   static const int kImplicitReceiverOffset = -6 * kPointerSize;
186   static const int kConstructorOffset      = -5 * kPointerSize;
187   static const int kLengthOffset           = -4 * kPointerSize;
188   static const int kCodeOffset = StandardFrameConstants::kExpressionsOffset;
189 
190   static const int kFrameSize =
191       StandardFrameConstants::kFixedFrameSize + 4 * kPointerSize;
192 };
193 
194 
195 class InternalFrameConstants : public AllStatic {
196  public:
197   // FP-relative.
198   static const int kCodeOffset = StandardFrameConstants::kExpressionsOffset;
199 };
200 
201 
function_slot_object()202 inline Object* JavaScriptFrame::function_slot_object() const {
203   const int offset = JavaScriptFrameConstants::kFunctionOffset;
204   return Memory::Object_at(fp() + offset);
205 }
206 
207 
SetFp(Address slot,Address fp)208 inline void StackHandler::SetFp(Address slot, Address fp) {
209   Memory::Address_at(slot) = fp;
210 }
211 
212 
213 } }  // namespace v8::internal
214 
215 #endif
216