1 //===-- HexagonVarargsCallingConvention.h - Calling Conventions -*- 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 declares the functions that assign locations to outgoing function
11 // arguments. Adapted from the target independent version but this handles
12 // calls to varargs functions
13 //
14 //===----------------------------------------------------------------------===//
15 //
16
17
18
19
20 static bool RetCC_Hexagon32_VarArgs(unsigned ValNo, EVT ValVT,
21 EVT LocVT, CCValAssign::LocInfo LocInfo,
22 ISD::ArgFlagsTy ArgFlags,
23 Hexagon_CCState &State,
24 int NonVarArgsParams,
25 int CurrentParam,
26 bool ForceMem);
27
28
CC_Hexagon32_VarArgs(unsigned ValNo,EVT ValVT,EVT LocVT,CCValAssign::LocInfo LocInfo,ISD::ArgFlagsTy ArgFlags,Hexagon_CCState & State,int NonVarArgsParams,int CurrentParam,bool ForceMem)29 static bool CC_Hexagon32_VarArgs(unsigned ValNo, EVT ValVT,
30 EVT LocVT, CCValAssign::LocInfo LocInfo,
31 ISD::ArgFlagsTy ArgFlags,
32 Hexagon_CCState &State,
33 int NonVarArgsParams,
34 int CurrentParam,
35 bool ForceMem) {
36 unsigned ByValSize = 0;
37 if (ArgFlags.isByVal() &&
38 ((ByValSize = ArgFlags.getByValSize()) >
39 (MVT(MVT::i64).getSizeInBits() / 8))) {
40 ForceMem = true;
41 }
42
43
44 // Only assign registers for named (non-varargs) arguments
45 if ( !ForceMem && ((NonVarArgsParams == -1) || (CurrentParam <=
46 NonVarArgsParams))) {
47
48 if (LocVT == MVT::i32 ||
49 LocVT == MVT::i16 ||
50 LocVT == MVT::i8 ||
51 LocVT == MVT::f32) {
52 static const unsigned RegList1[] = {
53 Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3, Hexagon::R4,
54 Hexagon::R5
55 };
56 if (unsigned Reg = State.AllocateReg(RegList1, 6)) {
57 State.addLoc(CCValAssign::getReg(ValNo, ValVT.getSimpleVT(), Reg,
58 LocVT.getSimpleVT(), LocInfo));
59 return false;
60 }
61 }
62
63 if (LocVT == MVT::i64 ||
64 LocVT == MVT::f64) {
65 static const unsigned RegList2[] = {
66 Hexagon::D0, Hexagon::D1, Hexagon::D2
67 };
68 if (unsigned Reg = State.AllocateReg(RegList2, 3)) {
69 State.addLoc(CCValAssign::getReg(ValNo, ValVT.getSimpleVT(), Reg,
70 LocVT.getSimpleVT(), LocInfo));
71 return false;
72 }
73 }
74 }
75
76 const Type* ArgTy = LocVT.getTypeForEVT(State.getContext());
77 unsigned Alignment =
78 State.getTarget().getDataLayout()->getABITypeAlignment(ArgTy);
79 unsigned Size =
80 State.getTarget().getDataLayout()->getTypeSizeInBits(ArgTy) / 8;
81
82 // If it's passed by value, then we need the size of the aggregate not of
83 // the pointer.
84 if (ArgFlags.isByVal()) {
85 Size = ByValSize;
86
87 // Hexagon_TODO: Get the alignment of the contained type here.
88 Alignment = 8;
89 }
90
91 unsigned Offset3 = State.AllocateStack(Size, Alignment);
92 State.addLoc(CCValAssign::getMem(ValNo, ValVT.getSimpleVT(), Offset3,
93 LocVT.getSimpleVT(), LocInfo));
94 return false;
95 }
96
97
RetCC_Hexagon32_VarArgs(unsigned ValNo,EVT ValVT,EVT LocVT,CCValAssign::LocInfo LocInfo,ISD::ArgFlagsTy ArgFlags,Hexagon_CCState & State,int NonVarArgsParams,int CurrentParam,bool ForceMem)98 static bool RetCC_Hexagon32_VarArgs(unsigned ValNo, EVT ValVT,
99 EVT LocVT, CCValAssign::LocInfo LocInfo,
100 ISD::ArgFlagsTy ArgFlags,
101 Hexagon_CCState &State,
102 int NonVarArgsParams,
103 int CurrentParam,
104 bool ForceMem) {
105
106 if (LocVT == MVT::i32 ||
107 LocVT == MVT::f32) {
108 static const unsigned RegList1[] = {
109 Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3, Hexagon::R4,
110 Hexagon::R5
111 };
112 if (unsigned Reg = State.AllocateReg(RegList1, 6)) {
113 State.addLoc(CCValAssign::getReg(ValNo, ValVT.getSimpleVT(), Reg,
114 LocVT.getSimpleVT(), LocInfo));
115 return false;
116 }
117 }
118
119 if (LocVT == MVT::i64 ||
120 LocVT == MVT::f64) {
121 static const unsigned RegList2[] = {
122 Hexagon::D0, Hexagon::D1, Hexagon::D2
123 };
124 if (unsigned Reg = State.AllocateReg(RegList2, 3)) {
125 State.addLoc(CCValAssign::getReg(ValNo, ValVT.getSimpleVT(), Reg,
126 LocVT.getSimpleVT(), LocInfo));
127 return false;
128 }
129 }
130
131 const Type* ArgTy = LocVT.getTypeForEVT(State.getContext());
132 unsigned Alignment =
133 State.getTarget().getDataLayout()->getABITypeAlignment(ArgTy);
134 unsigned Size =
135 State.getTarget().getDataLayout()->getTypeSizeInBits(ArgTy) / 8;
136
137 unsigned Offset3 = State.AllocateStack(Size, Alignment);
138 State.addLoc(CCValAssign::getMem(ValNo, ValVT.getSimpleVT(), Offset3,
139 LocVT.getSimpleVT(), LocInfo));
140 return false;
141 }
142