Home | History | Annotate | Download | only in compiler
      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