1234285Sdim//===-- HexagonVarargsCallingConvention.h - Calling Conventions -*- C++ -*-===//
2234285Sdim//
3234285Sdim//                     The LLVM Compiler Infrastructure
4234285Sdim//
5234285Sdim// This file is distributed under the University of Illinois Open Source
6234285Sdim// License. See LICENSE.TXT for details.
7234285Sdim//
8234285Sdim//===----------------------------------------------------------------------===//
9234285Sdim//
10234285Sdim// This file declares the functions that assign locations to outgoing function
11234285Sdim// arguments. Adapted from the target independent version but this handles
12234285Sdim// calls to varargs functions
13234285Sdim//
14234285Sdim//===----------------------------------------------------------------------===//
15234285Sdim//
16234285Sdim
17234285Sdim
18234285Sdim
19234285Sdim
20234285Sdimstatic bool RetCC_Hexagon32_VarArgs(unsigned ValNo, EVT ValVT,
21234285Sdim                                    EVT LocVT, CCValAssign::LocInfo LocInfo,
22234285Sdim                                    ISD::ArgFlagsTy ArgFlags,
23234285Sdim                                    Hexagon_CCState &State,
24234285Sdim                                    int NonVarArgsParams,
25234285Sdim                                    int CurrentParam,
26234285Sdim                                    bool ForceMem);
27234285Sdim
28234285Sdim
29234285Sdimstatic bool CC_Hexagon32_VarArgs(unsigned ValNo, EVT ValVT,
30234285Sdim                                 EVT LocVT, CCValAssign::LocInfo LocInfo,
31234285Sdim                                 ISD::ArgFlagsTy ArgFlags,
32234285Sdim                                 Hexagon_CCState &State,
33234285Sdim                                 int NonVarArgsParams,
34234285Sdim                                 int CurrentParam,
35234285Sdim                                 bool ForceMem) {
36234285Sdim  unsigned ByValSize = 0;
37234285Sdim  if (ArgFlags.isByVal() &&
38234285Sdim      ((ByValSize = ArgFlags.getByValSize()) >
39234285Sdim       (MVT(MVT::i64).getSizeInBits() / 8))) {
40234285Sdim    ForceMem = true;
41234285Sdim  }
42234285Sdim
43234285Sdim
44234285Sdim  // Only assign registers for named (non varargs) arguments
45234285Sdim  if ( !ForceMem && ((NonVarArgsParams == -1) || (CurrentParam <=
46234285Sdim                                                  NonVarArgsParams))) {
47234285Sdim
48234285Sdim    if (LocVT == MVT::i32 ||
49234285Sdim        LocVT == MVT::i16 ||
50234285Sdim        LocVT == MVT::i8 ||
51234285Sdim        LocVT == MVT::f32) {
52234285Sdim      static const unsigned RegList1[] = {
53234285Sdim        Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3, Hexagon::R4,
54234285Sdim        Hexagon::R5
55234285Sdim      };
56234285Sdim      if (unsigned Reg = State.AllocateReg(RegList1, 6)) {
57234285Sdim        State.addLoc(CCValAssign::getReg(ValNo, ValVT.getSimpleVT(), Reg,
58234285Sdim                                         LocVT.getSimpleVT(), LocInfo));
59234285Sdim        return false;
60234285Sdim      }
61234285Sdim    }
62234285Sdim
63234285Sdim    if (LocVT == MVT::i64 ||
64234285Sdim        LocVT == MVT::f64) {
65234285Sdim      static const unsigned RegList2[] = {
66234285Sdim        Hexagon::D0, Hexagon::D1, Hexagon::D2
67234285Sdim      };
68234285Sdim      if (unsigned Reg = State.AllocateReg(RegList2, 3)) {
69234285Sdim        State.addLoc(CCValAssign::getReg(ValNo, ValVT.getSimpleVT(), Reg,
70234285Sdim                                         LocVT.getSimpleVT(), LocInfo));
71234285Sdim        return false;
72234285Sdim      }
73234285Sdim    }
74234285Sdim  }
75234285Sdim
76234285Sdim  const Type* ArgTy = LocVT.getTypeForEVT(State.getContext());
77234285Sdim  unsigned Alignment =
78245431Sdim    State.getTarget().getDataLayout()->getABITypeAlignment(ArgTy);
79234285Sdim  unsigned Size =
80245431Sdim    State.getTarget().getDataLayout()->getTypeSizeInBits(ArgTy) / 8;
81234285Sdim
82234285Sdim  // If it's passed by value, then we need the size of the aggregate not of
83234285Sdim  // the pointer.
84234285Sdim  if (ArgFlags.isByVal()) {
85234285Sdim    Size = ByValSize;
86234285Sdim
87234285Sdim    // Hexagon_TODO: Get the alignment of the contained type here.
88234285Sdim    Alignment = 8;
89234285Sdim  }
90234285Sdim
91234285Sdim  unsigned Offset3 = State.AllocateStack(Size, Alignment);
92234285Sdim  State.addLoc(CCValAssign::getMem(ValNo, ValVT.getSimpleVT(), Offset3,
93234285Sdim                                   LocVT.getSimpleVT(), LocInfo));
94234285Sdim  return false;
95234285Sdim}
96234285Sdim
97234285Sdim
98234285Sdimstatic bool RetCC_Hexagon32_VarArgs(unsigned ValNo, EVT ValVT,
99234285Sdim                                    EVT LocVT, CCValAssign::LocInfo LocInfo,
100234285Sdim                                    ISD::ArgFlagsTy ArgFlags,
101234285Sdim                                    Hexagon_CCState &State,
102234285Sdim                                    int NonVarArgsParams,
103234285Sdim                                    int CurrentParam,
104234285Sdim                                    bool ForceMem) {
105234285Sdim
106234285Sdim  if (LocVT == MVT::i32 ||
107234285Sdim      LocVT == MVT::f32) {
108234285Sdim    static const unsigned RegList1[] = {
109234285Sdim      Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3, Hexagon::R4,
110234285Sdim      Hexagon::R5
111234285Sdim    };
112234285Sdim    if (unsigned Reg = State.AllocateReg(RegList1, 6)) {
113234285Sdim      State.addLoc(CCValAssign::getReg(ValNo, ValVT.getSimpleVT(), Reg,
114234285Sdim                                       LocVT.getSimpleVT(), LocInfo));
115234285Sdim      return false;
116234285Sdim    }
117234285Sdim  }
118234285Sdim
119234285Sdim  if (LocVT == MVT::i64 ||
120234285Sdim      LocVT == MVT::f64) {
121234285Sdim    static const unsigned RegList2[] = {
122234285Sdim      Hexagon::D0, Hexagon::D1, Hexagon::D2
123234285Sdim    };
124234285Sdim    if (unsigned Reg = State.AllocateReg(RegList2, 3)) {
125234285Sdim      State.addLoc(CCValAssign::getReg(ValNo, ValVT.getSimpleVT(), Reg,
126234285Sdim                                       LocVT.getSimpleVT(), LocInfo));
127234285Sdim      return false;
128234285Sdim    }
129234285Sdim  }
130234285Sdim
131234285Sdim  const Type* ArgTy = LocVT.getTypeForEVT(State.getContext());
132234285Sdim  unsigned Alignment =
133245431Sdim    State.getTarget().getDataLayout()->getABITypeAlignment(ArgTy);
134234285Sdim  unsigned Size =
135245431Sdim    State.getTarget().getDataLayout()->getTypeSizeInBits(ArgTy) / 8;
136234285Sdim
137234285Sdim  unsigned Offset3 = State.AllocateStack(Size, Alignment);
138234285Sdim  State.addLoc(CCValAssign::getMem(ValNo, ValVT.getSimpleVT(), Offset3,
139234285Sdim                                   LocVT.getSimpleVT(), LocInfo));
140234285Sdim  return false;
141234285Sdim}
142