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 
8 namespace v8 {
9 namespace internal {
10 
11 // Register list in load/store instructions
12 // Note that the bit values must match those used in actual instruction encoding
13 const int kNumRegs = 16;
14 
15 // Caller-saved/arguments registers
16 const RegList kJSCallerSaved = 1 << 1 | 1 << 2 |  // r2  a1
17                                1 << 3 |           // r3  a2
18                                1 << 4 |           // r4  a3
19                                1 << 5;            // r5  a4
20 
21 const 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
25 int JSCallerSavedCode(int n);
26 
27 // Callee-saved registers preserved when switching from C to JavaScript
28 const 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 
42 const int kNumCalleeSaved = 8;
43 
44 #ifdef V8_TARGET_ARCH_S390X
45 
46 const 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 
55 const int kNumCallerSavedDoubles = 8;
56 
57 const 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 
66 const int kNumCalleeSavedDoubles = 8;
67 
68 #else
69 
70 const 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 
85 const int kNumCallerSavedDoubles = 14;
86 
87 const RegList kCalleeSavedDoubles = 1 << 4 |  // d4
88                                     1 << 6;   // d6
89 
90 const 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.
97 const 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
119 const int kNumRequiredStackFrameSlots = 20;
120 const int kStackFrameRASlot = 14;
121 const int kStackFrameSPSlot = 15;
122 const 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
134 const int kNumRequiredStackFrameSlots = 24;
135 const int kStackFrameRASlot = 14;
136 const int kStackFrameSPSlot = 15;
137 const 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
143 const int kCalleeRegisterSaveAreaSize = 160;
144 #elif V8_TARGET_ARCH_S390
145 const int kCalleeRegisterSaveAreaSize = 96;
146 #else
147 const int kCalleeRegisterSaveAreaSize = 0;
148 #endif
149 
150 // ----------------------------------------------------
151 
152 class EntryFrameConstants : public AllStatic {
153  public:
154   static const int kCallerFPOffset =
155       -(StandardFrameConstants::kFixedFrameSizeFromFp + kPointerSize);
156 };
157 
158 class 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 
174 class 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