Line data Source code
1 : // Copyright 2015 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 : #include "src/assembler-inl.h"
6 : #include "src/macro-assembler.h"
7 :
8 : #include "src/compiler/linkage.h"
9 :
10 : #include "src/zone/zone.h"
11 :
12 : namespace v8 {
13 : namespace internal {
14 : namespace compiler {
15 :
16 : namespace {
17 : LinkageLocation regloc(Register reg, MachineType type) {
18 : return LinkageLocation::ForRegister(reg.code(), type);
19 : }
20 :
21 :
22 : // Platform-specific configuration for C calling convention.
23 : #if V8_TARGET_ARCH_IA32
24 : // ===========================================================================
25 : // == ia32 ===================================================================
26 : // ===========================================================================
27 : #define CALLEE_SAVE_REGISTERS esi.bit() | edi.bit() | ebx.bit()
28 :
29 : #elif V8_TARGET_ARCH_X64
30 : // ===========================================================================
31 : // == x64 ====================================================================
32 : // ===========================================================================
33 :
34 : #ifdef _WIN64
35 : // == x64 windows ============================================================
36 : #define STACK_SHADOW_WORDS 4
37 : #define PARAM_REGISTERS rcx, rdx, r8, r9
38 : #define CALLEE_SAVE_REGISTERS \
39 : rbx.bit() | rdi.bit() | rsi.bit() | r12.bit() | r13.bit() | r14.bit() | \
40 : r15.bit()
41 : #define CALLEE_SAVE_FP_REGISTERS \
42 : (1 << xmm6.code()) | (1 << xmm7.code()) | (1 << xmm8.code()) | \
43 : (1 << xmm9.code()) | (1 << xmm10.code()) | (1 << xmm11.code()) | \
44 : (1 << xmm12.code()) | (1 << xmm13.code()) | (1 << xmm14.code()) | \
45 : (1 << xmm15.code())
46 : #else
47 : // == x64 other ==============================================================
48 : #define PARAM_REGISTERS rdi, rsi, rdx, rcx, r8, r9
49 : #define CALLEE_SAVE_REGISTERS \
50 : rbx.bit() | r12.bit() | r13.bit() | r14.bit() | r15.bit()
51 : #endif
52 :
53 : #elif V8_TARGET_ARCH_X87
54 : // ===========================================================================
55 : // == x87 ====================================================================
56 : // ===========================================================================
57 : #define CALLEE_SAVE_REGISTERS esi.bit() | edi.bit() | ebx.bit()
58 :
59 : #elif V8_TARGET_ARCH_ARM
60 : // ===========================================================================
61 : // == arm ====================================================================
62 : // ===========================================================================
63 : #define PARAM_REGISTERS r0, r1, r2, r3
64 : #define CALLEE_SAVE_REGISTERS \
65 : r4.bit() | r5.bit() | r6.bit() | r7.bit() | r8.bit() | r9.bit() | r10.bit()
66 : #define CALLEE_SAVE_FP_REGISTERS \
67 : (1 << d8.code()) | (1 << d9.code()) | (1 << d10.code()) | \
68 : (1 << d11.code()) | (1 << d12.code()) | (1 << d13.code()) | \
69 : (1 << d14.code()) | (1 << d15.code())
70 :
71 :
72 : #elif V8_TARGET_ARCH_ARM64
73 : // ===========================================================================
74 : // == arm64 ====================================================================
75 : // ===========================================================================
76 : #define PARAM_REGISTERS x0, x1, x2, x3, x4, x5, x6, x7
77 : #define CALLEE_SAVE_REGISTERS \
78 : (1 << x19.code()) | (1 << x20.code()) | (1 << x21.code()) | \
79 : (1 << x22.code()) | (1 << x23.code()) | (1 << x24.code()) | \
80 : (1 << x25.code()) | (1 << x26.code()) | (1 << x27.code()) | \
81 : (1 << x28.code()) | (1 << x29.code()) | (1 << x30.code())
82 :
83 :
84 : #define CALLEE_SAVE_FP_REGISTERS \
85 : (1 << d8.code()) | (1 << d9.code()) | (1 << d10.code()) | \
86 : (1 << d11.code()) | (1 << d12.code()) | (1 << d13.code()) | \
87 : (1 << d14.code()) | (1 << d15.code())
88 :
89 : #elif V8_TARGET_ARCH_MIPS
90 : // ===========================================================================
91 : // == mips ===================================================================
92 : // ===========================================================================
93 : #define STACK_SHADOW_WORDS 4
94 : #define PARAM_REGISTERS a0, a1, a2, a3
95 : #define CALLEE_SAVE_REGISTERS \
96 : s0.bit() | s1.bit() | s2.bit() | s3.bit() | s4.bit() | s5.bit() | s6.bit() | \
97 : s7.bit()
98 : #define CALLEE_SAVE_FP_REGISTERS \
99 : f20.bit() | f22.bit() | f24.bit() | f26.bit() | f28.bit() | f30.bit()
100 :
101 : #elif V8_TARGET_ARCH_MIPS64
102 : // ===========================================================================
103 : // == mips64 =================================================================
104 : // ===========================================================================
105 : #define PARAM_REGISTERS a0, a1, a2, a3, a4, a5, a6, a7
106 : #define CALLEE_SAVE_REGISTERS \
107 : s0.bit() | s1.bit() | s2.bit() | s3.bit() | s4.bit() | s5.bit() | s6.bit() | \
108 : s7.bit()
109 : #define CALLEE_SAVE_FP_REGISTERS \
110 : f20.bit() | f22.bit() | f24.bit() | f26.bit() | f28.bit() | f30.bit()
111 :
112 : #elif V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_PPC64
113 : // ===========================================================================
114 : // == ppc & ppc64 ============================================================
115 : // ===========================================================================
116 : #define PARAM_REGISTERS r3, r4, r5, r6, r7, r8, r9, r10
117 : #define CALLEE_SAVE_REGISTERS \
118 : r14.bit() | r15.bit() | r16.bit() | r17.bit() | r18.bit() | r19.bit() | \
119 : r20.bit() | r21.bit() | r22.bit() | r23.bit() | r24.bit() | r25.bit() | \
120 : r26.bit() | r27.bit() | r28.bit() | r29.bit() | r30.bit()
121 : #define CALLEE_SAVE_FP_REGISTERS \
122 : d14.bit() | d15.bit() | d16.bit() | d17.bit() | d18.bit() | d19.bit() | \
123 : d20.bit() | d21.bit() | d22.bit() | d23.bit() | d24.bit() | d25.bit() | \
124 : d26.bit() | d27.bit() | d28.bit() | d29.bit() | d30.bit() | d31.bit()
125 :
126 : #elif V8_TARGET_ARCH_S390X
127 : // ===========================================================================
128 : // == s390x ==================================================================
129 : // ===========================================================================
130 : #define PARAM_REGISTERS r2, r3, r4, r5, r6
131 : #define CALLEE_SAVE_REGISTERS \
132 : r6.bit() | r7.bit() | r8.bit() | r9.bit() | r10.bit() | ip.bit() | r13.bit()
133 : #define CALLEE_SAVE_FP_REGISTERS \
134 : d8.bit() | d9.bit() | d10.bit() | d11.bit() | d12.bit() | d13.bit() | \
135 : d14.bit() | d15.bit()
136 :
137 : #elif V8_TARGET_ARCH_S390
138 : // ===========================================================================
139 : // == s390 ===================================================================
140 : // ===========================================================================
141 : #define PARAM_REGISTERS r2, r3, r4, r5, r6
142 : #define CALLEE_SAVE_REGISTERS \
143 : r6.bit() | r7.bit() | r8.bit() | r9.bit() | r10.bit() | ip.bit() | r13.bit()
144 : #define CALLEE_SAVE_FP_REGISTERS (d4.bit() | d6.bit())
145 :
146 : #else
147 : // ===========================================================================
148 : // == unknown ================================================================
149 : // ===========================================================================
150 : #define UNSUPPORTED_C_LINKAGE 1
151 : #endif
152 : } // namespace
153 :
154 :
155 : // General code uses the above configuration data.
156 255447 : CallDescriptor* Linkage::GetSimplifiedCDescriptor(
157 2036814 : Zone* zone, const MachineSignature* msig, bool set_initialize_root_flag) {
158 : DCHECK_LE(msig->parameter_count(), static_cast<size_t>(kMaxCParameters));
159 :
160 : LocationSignature::Builder locations(zone, msig->return_count(),
161 : msig->parameter_count());
162 : // Check the types of the signature.
163 : // Currently no floating point parameters or returns are allowed because
164 : // on x87 and ia32, the FP top of stack is involved.
165 1021408 : for (size_t i = 0; i < msig->return_count(); i++) {
166 : MachineRepresentation rep = msig->GetReturn(i).representation();
167 255257 : CHECK_NE(MachineRepresentation::kFloat32, rep);
168 255257 : CHECK_NE(MachineRepresentation::kFloat64, rep);
169 : }
170 591915 : for (size_t i = 0; i < msig->parameter_count(); i++) {
171 : MachineRepresentation rep = msig->GetParam(i).representation();
172 168234 : CHECK_NE(MachineRepresentation::kFloat32, rep);
173 168234 : CHECK_NE(MachineRepresentation::kFloat64, rep);
174 : }
175 :
176 : #ifdef UNSUPPORTED_C_LINKAGE
177 : // This method should not be called on unknown architectures.
178 : V8_Fatal(__FILE__, __LINE__,
179 : "requested C call descriptor on unsupported architecture");
180 : return nullptr;
181 : #endif
182 :
183 : // Add return location(s).
184 255447 : CHECK(locations.return_count_ <= 2);
185 :
186 255447 : if (locations.return_count_ > 0) {
187 : locations.AddReturn(regloc(kReturnRegister0, msig->GetReturn(0)));
188 : }
189 255447 : if (locations.return_count_ > 1) {
190 : locations.AddReturn(regloc(kReturnRegister1, msig->GetReturn(1)));
191 : }
192 :
193 255447 : const int parameter_count = static_cast<int>(msig->parameter_count());
194 :
195 : #ifdef PARAM_REGISTERS
196 255447 : const Register kParamRegisters[] = {PARAM_REGISTERS};
197 : const int kParamRegisterCount = static_cast<int>(arraysize(kParamRegisters));
198 : #else
199 : const Register* kParamRegisters = nullptr;
200 : const int kParamRegisterCount = 0;
201 : #endif
202 :
203 : #ifdef STACK_SHADOW_WORDS
204 : int stack_offset = STACK_SHADOW_WORDS;
205 : #else
206 : int stack_offset = 0;
207 : #endif
208 : // Add register and/or stack parameter(s).
209 423681 : for (int i = 0; i < parameter_count; i++) {
210 168234 : if (i < kParamRegisterCount) {
211 166886 : locations.AddParam(regloc(kParamRegisters[i], msig->GetParam(i)));
212 : } else {
213 : locations.AddParam(LinkageLocation::ForCallerFrameSlot(
214 2696 : -1 - stack_offset, msig->GetParam(i)));
215 1348 : stack_offset++;
216 : }
217 : }
218 :
219 : #ifdef CALLEE_SAVE_REGISTERS
220 : const RegList kCalleeSaveRegisters = CALLEE_SAVE_REGISTERS;
221 : #else
222 : const RegList kCalleeSaveRegisters = 0;
223 : #endif
224 :
225 : #ifdef CALLEE_SAVE_FP_REGISTERS
226 : const RegList kCalleeSaveFPRegisters = CALLEE_SAVE_FP_REGISTERS;
227 : #else
228 : const RegList kCalleeSaveFPRegisters = 0;
229 : #endif
230 :
231 : // The target for C calls is always an address (i.e. machine pointer).
232 : MachineType target_type = MachineType::Pointer();
233 : LinkageLocation target_loc = LinkageLocation::ForAnyRegister(target_type);
234 : CallDescriptor::Flags flags = CallDescriptor::kUseNativeStack;
235 255447 : if (set_initialize_root_flag) {
236 : flags |= CallDescriptor::kInitializeRootRegister;
237 : }
238 :
239 : return new (zone) CallDescriptor( // --
240 : CallDescriptor::kCallAddress, // kind
241 : target_type, // target MachineType
242 : target_loc, // target location
243 : locations.Build(), // location_sig
244 : 0, // stack_parameter_count
245 : Operator::kNoProperties, // properties
246 : kCalleeSaveRegisters, // callee-saved registers
247 : kCalleeSaveFPRegisters, // callee-saved fp regs
248 510894 : flags, "c-call");
249 : }
250 :
251 : } // namespace compiler
252 : } // namespace internal
253 : } // namespace v8
|