1// Copyright 2014 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#ifndef V8_S390_FRAMES_S390_H_
6#define V8_S390_FRAMES_S390_H_
7
8namespace v8 {
9namespace internal {
10
11// Register list in load/store instructions
12// Note that the bit values must match those used in actual instruction encoding
13const int kNumRegs = 16;
14
15// Caller-saved/arguments registers
16const RegList kJSCallerSaved = 1 << 1 | 1 << 2 |  // r2  a1
17                               1 << 3 |           // r3  a2
18                               1 << 4 |           // r4  a3
19                               1 << 5;            // r5  a4
20
21const int kNumJSCallerSaved = 5;
22
23// Return the code of the n-th caller-saved register available to JavaScript
24// e.g. JSCallerSavedReg(0) returns r0.code() == 0
25int JSCallerSavedCode(int n);
26
27// Callee-saved registers preserved when switching from C to JavaScript
28const RegList kCalleeSaved =
29    1 << 6 |   // r6 (argument passing in CEntryStub)
30               //    (HandleScope logic in MacroAssembler)
31    1 << 7 |   // r7 (argument passing in CEntryStub)
32               //    (HandleScope logic in MacroAssembler)
33    1 << 8 |   // r8 (argument passing in CEntryStub)
34               //    (HandleScope logic in MacroAssembler)
35    1 << 9 |   // r9 (HandleScope logic in MacroAssembler)
36    1 << 10 |  // r10 (Roots register in Javascript)
37    1 << 11 |  // r11 (fp in Javascript)
38    1 << 12 |  // r12 (ip in Javascript)
39    1 << 13;   // r13 (cp in Javascript)
40// 1 << 15;   // r15 (sp in Javascript)
41
42const int kNumCalleeSaved = 8;
43
44#ifdef V8_TARGET_ARCH_S390X
45
46const RegList kCallerSavedDoubles = 1 << 0 |  // d0
47                                    1 << 1 |  // d1
48                                    1 << 2 |  // d2
49                                    1 << 3 |  // d3
50                                    1 << 4 |  // d4
51                                    1 << 5 |  // d5
52                                    1 << 6 |  // d6
53                                    1 << 7;   // d7
54
55const int kNumCallerSavedDoubles = 8;
56
57const RegList kCalleeSavedDoubles = 1 << 8 |   // d8
58                                    1 << 9 |   // d9
59                                    1 << 10 |  // d10
60                                    1 << 11 |  // d11
61                                    1 << 12 |  // d12
62                                    1 << 13 |  // d12
63                                    1 << 14 |  // d12
64                                    1 << 15;   // d13
65
66const int kNumCalleeSavedDoubles = 8;
67
68#else
69
70const RegList kCallerSavedDoubles = 1 << 14 |  // d14
71                                    1 << 15 |  // d15
72                                    1 << 0 |   // d0
73                                    1 << 1 |   // d1
74                                    1 << 2 |   // d2
75                                    1 << 3 |   // d3
76                                    1 << 5 |   // d5
77                                    1 << 7 |   // d7
78                                    1 << 8 |   // d8
79                                    1 << 9 |   // d9
80                                    1 << 10 |  // d10
81                                    1 << 11 |  // d10
82                                    1 << 12 |  // d10
83                                    1 << 13;   // d11
84
85const int kNumCallerSavedDoubles = 14;
86
87const RegList kCalleeSavedDoubles = 1 << 4 |  // d4
88                                    1 << 6;   // d6
89
90const int kNumCalleeSavedDoubles = 2;
91
92#endif
93
94// Number of registers for which space is reserved in safepoints. Must be a
95// multiple of 8.
96// TODO(regis): Only 8 registers may actually be sufficient. Revisit.
97const int kNumSafepointRegisters = 16;
98
99// Define the list of registers actually saved at safepoints.
100// Note that the number of saved registers may be smaller than the reserved
101// space, i.e. kNumSafepointSavedRegisters <= kNumSafepointRegisters.
102// const RegList kSafepointSavedRegisters = kJSCallerSaved | kCalleeSaved;
103// const int kNumSafepointSavedRegisters = kNumJSCallerSaved + kNumCalleeSaved;
104
105// The following constants describe the stack frame linkage area as
106// defined by the ABI.
107
108#if V8_TARGET_ARCH_S390X
109// [0] Back Chain
110// [1] Reserved for compiler use
111// [2] GPR 2
112// [3] GPR 3
113// ...
114// [15] GPR 15
115// [16] FPR 0
116// [17] FPR 2
117// [18] FPR 4
118// [19] FPR 6
119const int kNumRequiredStackFrameSlots = 20;
120const int kStackFrameRASlot = 14;
121const int kStackFrameSPSlot = 15;
122const int kStackFrameExtraParamSlot = 20;
123#else
124// [0] Back Chain
125// [1] Reserved for compiler use
126// [2] GPR 2
127// [3] GPR 3
128// ...
129// [15] GPR 15
130// [16..17] FPR 0
131// [18..19] FPR 2
132// [20..21] FPR 4
133// [22..23] FPR 6
134const int kNumRequiredStackFrameSlots = 24;
135const int kStackFrameRASlot = 14;
136const int kStackFrameSPSlot = 15;
137const int kStackFrameExtraParamSlot = 24;
138#endif
139
140// zLinux ABI requires caller frames to include sufficient space for
141// callee preserved register save area.
142#if V8_TARGET_ARCH_S390X
143const int kCalleeRegisterSaveAreaSize = 160;
144#elif V8_TARGET_ARCH_S390
145const int kCalleeRegisterSaveAreaSize = 96;
146#else
147const int kCalleeRegisterSaveAreaSize = 0;
148#endif
149
150// ----------------------------------------------------
151
152class EntryFrameConstants : public AllStatic {
153 public:
154  static const int kCallerFPOffset =
155      -(StandardFrameConstants::kFixedFrameSizeFromFp + kPointerSize);
156};
157
158class ExitFrameConstants : public TypedFrameConstants {
159 public:
160  static const int kSPOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
161  static const int kCodeOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(1);
162  DEFINE_TYPED_FRAME_SIZES(2);
163
164  // The caller fields are below the frame pointer on the stack.
165  static const int kCallerFPOffset = 0 * kPointerSize;
166  // The calling JS function is below FP.
167  static const int kCallerPCOffset = 1 * kPointerSize;
168
169  // FP-relative displacement of the caller's SP.  It points just
170  // below the saved PC.
171  static const int kCallerSPDisplacement = 2 * kPointerSize;
172};
173
174class JavaScriptFrameConstants : public AllStatic {
175 public:
176  // FP-relative.
177  static const int kLocal0Offset = StandardFrameConstants::kExpressionsOffset;
178  static const int kLastParameterOffset = +2 * kPointerSize;
179  static const int kFunctionOffset = StandardFrameConstants::kFunctionOffset;
180
181  // Caller SP-relative.
182  static const int kParam0Offset = -2 * kPointerSize;
183  static const int kReceiverOffset = -1 * kPointerSize;
184};
185
186}  // namespace internal
187}  // namespace v8
188
189#endif  // V8_S390_FRAMES_S390_H_
190