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.h" 6#include "src/macro-assembler.h" 7 8#include "src/compiler/linkage.h" 9 10#include "src/zone.h" 11 12namespace v8 { 13namespace internal { 14namespace compiler { 15 16namespace { 17LinkageLocation regloc(Register reg) { 18 return LinkageLocation::ForRegister(reg.code()); 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. 156CallDescriptor* Linkage::GetSimplifiedCDescriptor( 157 Zone* zone, const MachineSignature* msig, bool set_initialize_root_flag) { 158 LocationSignature::Builder locations(zone, msig->return_count(), 159 msig->parameter_count()); 160 // Check the types of the signature. 161 // Currently no floating point parameters or returns are allowed because 162 // on x87 and ia32, the FP top of stack is involved. 163 for (size_t i = 0; i < msig->return_count(); i++) { 164 MachineRepresentation rep = msig->GetReturn(i).representation(); 165 CHECK_NE(MachineRepresentation::kFloat32, rep); 166 CHECK_NE(MachineRepresentation::kFloat64, rep); 167 } 168 for (size_t i = 0; i < msig->parameter_count(); i++) { 169 MachineRepresentation rep = msig->GetParam(i).representation(); 170 CHECK_NE(MachineRepresentation::kFloat32, rep); 171 CHECK_NE(MachineRepresentation::kFloat64, rep); 172 } 173 174#ifdef UNSUPPORTED_C_LINKAGE 175 // This method should not be called on unknown architectures. 176 V8_Fatal(__FILE__, __LINE__, 177 "requested C call descriptor on unsupported architecture"); 178 return nullptr; 179#endif 180 181 // Add return location(s). 182 CHECK(locations.return_count_ <= 2); 183 184 if (locations.return_count_ > 0) { 185 locations.AddReturn(regloc(kReturnRegister0)); 186 } 187 if (locations.return_count_ > 1) { 188 locations.AddReturn(regloc(kReturnRegister1)); 189 } 190 191 const int parameter_count = static_cast<int>(msig->parameter_count()); 192 193#ifdef PARAM_REGISTERS 194 static const Register kParamRegisters[] = {PARAM_REGISTERS}; 195 static const int kParamRegisterCount = 196 static_cast<int>(arraysize(kParamRegisters)); 197#else 198 static const Register* kParamRegisters = nullptr; 199 static const int kParamRegisterCount = 0; 200#endif 201 202#ifdef STACK_SHADOW_WORDS 203 int stack_offset = STACK_SHADOW_WORDS; 204#else 205 int stack_offset = 0; 206#endif 207 // Add register and/or stack parameter(s). 208 for (int i = 0; i < parameter_count; i++) { 209 if (i < kParamRegisterCount) { 210 locations.AddParam(regloc(kParamRegisters[i])); 211 } else { 212 locations.AddParam( 213 LinkageLocation::ForCallerFrameSlot(-1 - stack_offset)); 214 stack_offset++; 215 } 216 } 217 218#ifdef CALLEE_SAVE_REGISTERS 219 const RegList kCalleeSaveRegisters = CALLEE_SAVE_REGISTERS; 220#else 221 const RegList kCalleeSaveRegisters = 0; 222#endif 223 224#ifdef CALLEE_SAVE_FP_REGISTERS 225 const RegList kCalleeSaveFPRegisters = CALLEE_SAVE_FP_REGISTERS; 226#else 227 const RegList kCalleeSaveFPRegisters = 0; 228#endif 229 230 // The target for C calls is always an address (i.e. machine pointer). 231 MachineType target_type = MachineType::Pointer(); 232 LinkageLocation target_loc = LinkageLocation::ForAnyRegister(); 233 CallDescriptor::Flags flags = CallDescriptor::kUseNativeStack; 234 if (set_initialize_root_flag) { 235 flags |= CallDescriptor::kInitializeRootRegister; 236 } 237 238 return new (zone) CallDescriptor( // -- 239 CallDescriptor::kCallAddress, // kind 240 target_type, // target MachineType 241 target_loc, // target location 242 msig, // machine_sig 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 flags, "c-call"); 249} 250 251} // namespace compiler 252} // namespace internal 253} // namespace v8 254