LCOV - code coverage report
Current view: top level - src/compiler - c-linkage.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 20 20 100.0 %
Date: 2019-04-17 Functions: 2 2 100.0 %

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

Generated by: LCOV version 1.10