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/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 CallDescriptor* 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, msig->GetReturn(0))); 186 } 187 if (locations.return_count_ > 1) { 188 locations.AddReturn(regloc(kReturnRegister1, msig->GetReturn(1))); 189 } 190 191 const int parameter_count = static_cast<int>(msig->parameter_count()); 192 193 #ifdef PARAM_REGISTERS 194 const Register kParamRegisters[] = {PARAM_REGISTERS}; 195 const int kParamRegisterCount = static_cast<int>(arraysize(kParamRegisters)); 196 #else 197 const Register* kParamRegisters = nullptr; 198 const int kParamRegisterCount = 0; 199 #endif 200 201 #ifdef STACK_SHADOW_WORDS 202 int stack_offset = STACK_SHADOW_WORDS; 203 #else 204 int stack_offset = 0; 205 #endif 206 // Add register and/or stack parameter(s). 207 for (int i = 0; i < parameter_count; i++) { 208 if (i < kParamRegisterCount) { 209 locations.AddParam(regloc(kParamRegisters[i], msig->GetParam(i))); 210 } else { 211 locations.AddParam(LinkageLocation::ForCallerFrameSlot( 212 -1 - stack_offset, msig->GetParam(i))); 213 stack_offset++; 214 } 215 } 216 217 #ifdef CALLEE_SAVE_REGISTERS 218 const RegList kCalleeSaveRegisters = CALLEE_SAVE_REGISTERS; 219 #else 220 const RegList kCalleeSaveRegisters = 0; 221 #endif 222 223 #ifdef CALLEE_SAVE_FP_REGISTERS 224 const RegList kCalleeSaveFPRegisters = CALLEE_SAVE_FP_REGISTERS; 225 #else 226 const RegList kCalleeSaveFPRegisters = 0; 227 #endif 228 229 // The target for C calls is always an address (i.e. machine pointer). 230 MachineType target_type = MachineType::Pointer(); 231 LinkageLocation target_loc = LinkageLocation::ForAnyRegister(target_type); 232 CallDescriptor::Flags flags = CallDescriptor::kUseNativeStack; 233 if (set_initialize_root_flag) { 234 flags |= CallDescriptor::kInitializeRootRegister; 235 } 236 237 return new (zone) CallDescriptor( // -- 238 CallDescriptor::kCallAddress, // kind 239 target_type, // target MachineType 240 target_loc, // target location 241 locations.Build(), // location_sig 242 0, // stack_parameter_count 243 Operator::kNoProperties, // properties 244 kCalleeSaveRegisters, // callee-saved registers 245 kCalleeSaveFPRegisters, // callee-saved fp regs 246 flags, "c-call"); 247 } 248 249 } // namespace compiler 250 } // namespace internal 251 } // namespace v8 252