Home | History | Annotate | Download | only in X86
      1 //=== X86CallingConv.h - X86 Custom Calling Convention Routines -*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file contains the custom routines for the X86 Calling Convention that
     11 // aren't done by tablegen.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_LIB_TARGET_X86_X86CALLINGCONV_H
     16 #define LLVM_LIB_TARGET_X86_X86CALLINGCONV_H
     17 
     18 #include "MCTargetDesc/X86MCTargetDesc.h"
     19 #include "llvm/CodeGen/CallingConvLower.h"
     20 #include "llvm/IR/CallingConv.h"
     21 
     22 namespace llvm {
     23 
     24 inline bool CC_X86_32_VectorCallIndirect(unsigned &ValNo, MVT &ValVT,
     25                                          MVT &LocVT,
     26                                          CCValAssign::LocInfo &LocInfo,
     27                                          ISD::ArgFlagsTy &ArgFlags,
     28                                          CCState &State) {
     29   // Similar to CCPassIndirect, with the addition of inreg.
     30   LocVT = MVT::i32;
     31   LocInfo = CCValAssign::Indirect;
     32   ArgFlags.setInReg();
     33   return false; // Continue the search, but now for i32.
     34 }
     35 
     36 
     37 inline bool CC_X86_AnyReg_Error(unsigned &, MVT &, MVT &,
     38                                 CCValAssign::LocInfo &, ISD::ArgFlagsTy &,
     39                                 CCState &) {
     40   llvm_unreachable("The AnyReg calling convention is only supported by the " \
     41                    "stackmap and patchpoint intrinsics.");
     42   // gracefully fallback to X86 C calling convention on Release builds.
     43   return false;
     44 }
     45 
     46 inline bool CC_X86_32_MCUInReg(unsigned &ValNo, MVT &ValVT,
     47                                          MVT &LocVT,
     48                                          CCValAssign::LocInfo &LocInfo,
     49                                          ISD::ArgFlagsTy &ArgFlags,
     50                                          CCState &State) {
     51   // This is similar to CCAssignToReg<[EAX, EDX, ECX]>, but makes sure
     52   // not to split i64 and double between a register and stack
     53   static const MCPhysReg RegList[] = {X86::EAX, X86::EDX, X86::ECX};
     54   static const unsigned NumRegs = sizeof(RegList)/sizeof(RegList[0]);
     55 
     56   SmallVectorImpl<CCValAssign> &PendingMembers = State.getPendingLocs();
     57 
     58   // If this is the first part of an double/i64/i128, or if we're already
     59   // in the middle of a split, add to the pending list. If this is not
     60   // the end of the split, return, otherwise go on to process the pending
     61   // list
     62   if (ArgFlags.isSplit() || !PendingMembers.empty()) {
     63     PendingMembers.push_back(
     64         CCValAssign::getPending(ValNo, ValVT, LocVT, LocInfo));
     65     if (!ArgFlags.isSplitEnd())
     66       return true;
     67   }
     68 
     69   // If there are no pending members, we are not in the middle of a split,
     70   // so do the usual inreg stuff.
     71   if (PendingMembers.empty()) {
     72     if (unsigned Reg = State.AllocateReg(RegList)) {
     73       State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
     74       return true;
     75     }
     76     return false;
     77   }
     78 
     79   assert(ArgFlags.isSplitEnd());
     80 
     81   // We now have the entire original argument in PendingMembers, so decide
     82   // whether to use registers or the stack.
     83   // Per the MCU ABI:
     84   // a) To use registers, we need to have enough of them free to contain
     85   // the entire argument.
     86   // b) We never want to use more than 2 registers for a single argument.
     87 
     88   unsigned FirstFree = State.getFirstUnallocated(RegList);
     89   bool UseRegs = PendingMembers.size() <= std::min(2U, NumRegs - FirstFree);
     90 
     91   for (auto &It : PendingMembers) {
     92     if (UseRegs)
     93       It.convertToReg(State.AllocateReg(RegList[FirstFree++]));
     94     else
     95       It.convertToMem(State.AllocateStack(4, 4));
     96     State.addLoc(It);
     97   }
     98 
     99   PendingMembers.clear();
    100 
    101   return true;
    102 }
    103 
    104 } // End llvm namespace
    105 
    106 #endif
    107 
    108