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