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
10namespace v8 {
11namespace internal {
12
13// Register lists.
14// Note that the bit values must match those used in actual instruction
15// encoding.
16const int kNumRegs = 32;
17
18const 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  |  // a4
26  1 << 9  |  // a5
27  1 << 10 |  // a6
28  1 << 11 |  // a7
29  1 << 12 |  // t0
30  1 << 13 |  // t1
31  1 << 14 |  // t2
32  1 << 15;   // t3
33
34const 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.
39int JSCallerSavedCode(int n);
40
41
42// Callee-saved registers preserved when switching from C to JavaScript.
43const 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
54const int kNumCalleeSaved = 9;
55
56const 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
64const int kNumCalleeSavedFPU = 6;
65
66const 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.
81const 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.
86const RegList kSafepointSavedRegisters = kJSCallerSaved | kCalleeSaved;
87const int kNumSafepointSavedRegisters =
88    kNumJSCallerSaved + kNumCalleeSaved;
89
90const int kUndefIndex = -1;
91// Map with indexes on stack that corresponds to codes of saved registers.
92const 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,   // a4
102  7,   // a5
103  8,   // a6
104  9,   // a7
105  10,  // t0
106  11,  // t1
107  12,  // t2
108  13,  // t3
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
130class EntryFrameConstants : public AllStatic {
131 public:
132  static const int kCallerFPOffset =
133      -(StandardFrameConstants::kFixedFrameSizeFromFp + kPointerSize);
134};
135
136
137class 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
159class 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
172class 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
182class 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
195class InternalFrameConstants : public AllStatic {
196 public:
197  // FP-relative.
198  static const int kCodeOffset = StandardFrameConstants::kExpressionsOffset;
199};
200
201
202inline Object* JavaScriptFrame::function_slot_object() const {
203  const int offset = JavaScriptFrameConstants::kFunctionOffset;
204  return Memory::Object_at(fp() + offset);
205}
206
207
208inline void StackHandler::SetFp(Address slot, Address fp) {
209  Memory::Address_at(slot) = fp;
210}
211
212
213} }  // namespace v8::internal
214
215#endif
216