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
22namespace llvm {
23
24inline 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
37inline 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
46inline 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