1 //=== X86CallingConv.cpp - X86 Custom Calling Convention Impl   -*- 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 implementation of custom routines for the X86
11 // Calling Convention that aren't done by tablegen.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "MCTargetDesc/X86MCTargetDesc.h"
16 #include "llvm/CodeGen/CallingConvLower.h"
17 #include "llvm/IR/CallingConv.h"
18 
19 namespace llvm {
20 
21 bool CC_X86_32_RegCall_Assign2Regs(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
22                                    CCValAssign::LocInfo &LocInfo,
23                                    ISD::ArgFlagsTy &ArgFlags, CCState &State) {
24   // List of GPR registers that are available to store values in regcall
25   // calling convention.
26   static const MCPhysReg RegList[] = {X86::EAX, X86::ECX, X86::EDX, X86::EDI,
27                                       X86::ESI};
28 
29   // The vector will save all the available registers for allocation.
30   SmallVector<unsigned, 5> AvailableRegs;
31 
32   // searching for the available registers.
33   for (auto Reg : RegList) {
34     if (!State.isAllocated(Reg))
35       AvailableRegs.push_back(Reg);
36   }
37 
38   const size_t RequiredGprsUponSplit = 2;
39   if (AvailableRegs.size() < RequiredGprsUponSplit)
40     return false; // Not enough free registers - continue the search.
41 
42   // Allocating the available registers
43   for (unsigned I = 0; I < RequiredGprsUponSplit; I++) {
44 
45     // Marking the register as located
46     unsigned Reg = State.AllocateReg(AvailableRegs[I]);
47 
48     // Since we previously made sure that 2 registers are available
49     // we expect that a real register number will be returned
50     assert(Reg && "Expecting a register will be available");
51 
52     // Assign the value to the allocated register
53     State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
54   }
55 
56   // Successful in allocating regsiters - stop scanning next rules.
57   return true;
58 }
59 
60 } // End llvm namespace
61