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 12 namespace v8 { 13 namespace internal { 14 namespace compiler { 15 16 namespace { 17 LinkageLocation 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 PARAM_REGISTERS a0, a1, a2, a3 94 #define CALLEE_SAVE_REGISTERS \ 95 s0.bit() | s1.bit() | s2.bit() | s3.bit() | s4.bit() | s5.bit() | s6.bit() | \ 96 s7.bit() 97 #define CALLEE_SAVE_FP_REGISTERS \ 98 f20.bit() | f22.bit() | f24.bit() | f26.bit() | f28.bit() | f30.bit() 99 100 #elif V8_TARGET_ARCH_MIPS64 101 // =========================================================================== 102 // == mips64 ================================================================= 103 // =========================================================================== 104 #define PARAM_REGISTERS a0, a1, a2, a3, a4, a5, a6, a7 105 #define CALLEE_SAVE_REGISTERS \ 106 s0.bit() | s1.bit() | s2.bit() | s3.bit() | s4.bit() | s5.bit() | s6.bit() | \ 107 s7.bit() 108 #define CALLEE_SAVE_FP_REGISTERS \ 109 f20.bit() | f22.bit() | f24.bit() | f26.bit() | f28.bit() | f30.bit() 110 111 #elif V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_PPC64 112 // =========================================================================== 113 // == ppc & ppc64 ============================================================ 114 // =========================================================================== 115 #define PARAM_REGISTERS r3, r4, r5, r6, r7, r8, r9, r10 116 #define CALLEE_SAVE_REGISTERS \ 117 r14.bit() | r15.bit() | r16.bit() | r17.bit() | r18.bit() | r19.bit() | \ 118 r20.bit() | r21.bit() | r22.bit() | r23.bit() | r24.bit() | r25.bit() | \ 119 r26.bit() | r27.bit() | r28.bit() | r29.bit() | r30.bit() 120 #define CALLEE_SAVE_FP_REGISTERS \ 121 d14.bit() | d15.bit() | d16.bit() | d17.bit() | d18.bit() | d19.bit() | \ 122 d20.bit() | d21.bit() | d22.bit() | d23.bit() | d24.bit() | d25.bit() | \ 123 d26.bit() | d27.bit() | d28.bit() | d29.bit() | d30.bit() | d31.bit() 124 125 #else 126 // =========================================================================== 127 // == unknown ================================================================ 128 // =========================================================================== 129 #define UNSUPPORTED_C_LINKAGE 1 130 #endif 131 } // namespace 132 133 134 // General code uses the above configuration data. 135 CallDescriptor* Linkage::GetSimplifiedCDescriptor( 136 Zone* zone, const MachineSignature* msig) { 137 LocationSignature::Builder locations(zone, msig->return_count(), 138 msig->parameter_count()); 139 #if 0 // TODO(titzer): instruction selector tests break here. 140 // Check the types of the signature. 141 // Currently no floating point parameters or returns are allowed because 142 // on x87 and ia32, the FP top of stack is involved. 143 144 for (size_t i = 0; i < msig->return_count(); i++) { 145 MachineType type = RepresentationOf(msig->GetReturn(i)); 146 CHECK(type != kRepFloat32 && type != kRepFloat64); 147 } 148 for (size_t i = 0; i < msig->parameter_count(); i++) { 149 MachineType type = RepresentationOf(msig->GetParam(i)); 150 CHECK(type != kRepFloat32 && type != kRepFloat64); 151 } 152 #endif 153 154 #ifdef UNSUPPORTED_C_LINKAGE 155 // This method should not be called on unknown architectures. 156 V8_Fatal(__FILE__, __LINE__, 157 "requested C call descriptor on unsupported architecture"); 158 return nullptr; 159 #endif 160 161 // Add return location(s). 162 CHECK(locations.return_count_ <= 2); 163 164 if (locations.return_count_ > 0) { 165 locations.AddReturn(regloc(kReturnRegister0)); 166 } 167 if (locations.return_count_ > 1) { 168 locations.AddReturn(regloc(kReturnRegister1)); 169 } 170 171 const int parameter_count = static_cast<int>(msig->parameter_count()); 172 173 #ifdef PARAM_REGISTERS 174 static const Register kParamRegisters[] = {PARAM_REGISTERS}; 175 static const int kParamRegisterCount = 176 static_cast<int>(arraysize(kParamRegisters)); 177 #else 178 static const Register* kParamRegisters = nullptr; 179 static const int kParamRegisterCount = 0; 180 #endif 181 182 #ifdef STACK_SHADOW_WORDS 183 int stack_offset = STACK_SHADOW_WORDS; 184 #else 185 int stack_offset = 0; 186 #endif 187 // Add register and/or stack parameter(s). 188 for (int i = 0; i < parameter_count; i++) { 189 if (i < kParamRegisterCount) { 190 locations.AddParam(regloc(kParamRegisters[i])); 191 } else { 192 locations.AddParam( 193 LinkageLocation::ForCallerFrameSlot(-1 - stack_offset)); 194 stack_offset++; 195 } 196 } 197 198 #ifdef CALLEE_SAVE_REGISTERS 199 const RegList kCalleeSaveRegisters = CALLEE_SAVE_REGISTERS; 200 #else 201 const RegList kCalleeSaveRegisters = 0; 202 #endif 203 204 #ifdef CALLEE_SAVE_FP_REGISTERS 205 const RegList kCalleeSaveFPRegisters = CALLEE_SAVE_FP_REGISTERS; 206 #else 207 const RegList kCalleeSaveFPRegisters = 0; 208 #endif 209 210 // The target for C calls is always an address (i.e. machine pointer). 211 MachineType target_type = MachineType::Pointer(); 212 LinkageLocation target_loc = LinkageLocation::ForAnyRegister(); 213 return new (zone) CallDescriptor( // -- 214 CallDescriptor::kCallAddress, // kind 215 target_type, // target MachineType 216 target_loc, // target location 217 msig, // machine_sig 218 locations.Build(), // location_sig 219 0, // stack_parameter_count 220 Operator::kNoProperties, // properties 221 kCalleeSaveRegisters, // callee-saved registers 222 kCalleeSaveFPRegisters, // callee-saved fp regs 223 CallDescriptor::kNoFlags, // flags 224 "c-call"); 225 } 226 227 } // namespace compiler 228 } // namespace internal 229 } // namespace v8 230