HexagonVarargsCallingConvention.h revision 243830
1157016Sdes//===-- HexagonVarargsCallingConvention.h - Calling Conventions -*- C++ -*-===//
2137015Sdes//
3137015Sdes//                     The LLVM Compiler Infrastructure
4137015Sdes//
5137015Sdes// This file is distributed under the University of Illinois Open Source
6137015Sdes// License. See LICENSE.TXT for details.
7137015Sdes//
8137015Sdes//===----------------------------------------------------------------------===//
9137015Sdes//
10137015Sdes// This file declares the functions that assign locations to outgoing function
11137015Sdes// arguments. Adapted from the target independent version but this handles
12137015Sdes// calls to varargs functions
13137015Sdes//
14137015Sdes//===----------------------------------------------------------------------===//
15137015Sdes//
16137015Sdes
17204861Sdes
18204861Sdes
19137015Sdes
20137015Sdesstatic bool RetCC_Hexagon32_VarArgs(unsigned ValNo, EVT ValVT,
21137015Sdes                                    EVT LocVT, CCValAssign::LocInfo LocInfo,
22137015Sdes                                    ISD::ArgFlagsTy ArgFlags,
23218767Sdes                                    Hexagon_CCState &State,
24294328Sdes                                    int NonVarArgsParams,
25137015Sdes                                    int CurrentParam,
26137015Sdes                                    bool ForceMem);
27137015Sdes
28323134Sdes
29323134Sdesstatic bool CC_Hexagon32_VarArgs(unsigned ValNo, EVT ValVT,
30323134Sdes                                 EVT LocVT, CCValAssign::LocInfo LocInfo,
31137015Sdes                                 ISD::ArgFlagsTy ArgFlags,
32137015Sdes                                 Hexagon_CCState &State,
33137015Sdes                                 int NonVarArgsParams,
34137015Sdes                                 int CurrentParam,
35137015Sdes                                 bool ForceMem) {
36137015Sdes  unsigned ByValSize = 0;
37218767Sdes  if (ArgFlags.isByVal() &&
38218767Sdes      ((ByValSize = ArgFlags.getByValSize()) >
39218767Sdes       (MVT(MVT::i64).getSizeInBits() / 8))) {
40294328Sdes    ForceMem = true;
41294328Sdes  }
42294328Sdes
43137015Sdes
44137015Sdes  // Only assign registers for named (non varargs) arguments
45137015Sdes  if ( !ForceMem && ((NonVarArgsParams == -1) || (CurrentParam <=
46137015Sdes                                                  NonVarArgsParams))) {
47137015Sdes
48137015Sdes    if (LocVT == MVT::i32 ||
49137015Sdes        LocVT == MVT::i16 ||
50137015Sdes        LocVT == MVT::i8 ||
51137015Sdes        LocVT == MVT::f32) {
52137015Sdes      static const unsigned RegList1[] = {
53137015Sdes        Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3, Hexagon::R4,
54137015Sdes        Hexagon::R5
55137015Sdes      };
56137015Sdes      if (unsigned Reg = State.AllocateReg(RegList1, 6)) {
57137015Sdes        State.addLoc(CCValAssign::getReg(ValNo, ValVT.getSimpleVT(), Reg,
58137015Sdes                                         LocVT.getSimpleVT(), LocInfo));
59137015Sdes        return false;
60137015Sdes      }
61137015Sdes    }
62137015Sdes
63137015Sdes    if (LocVT == MVT::i64 ||
64137015Sdes        LocVT == MVT::f64) {
65137015Sdes      static const unsigned RegList2[] = {
66137015Sdes        Hexagon::D0, Hexagon::D1, Hexagon::D2
67137015Sdes      };
68137015Sdes      if (unsigned Reg = State.AllocateReg(RegList2, 3)) {
69137015Sdes        State.addLoc(CCValAssign::getReg(ValNo, ValVT.getSimpleVT(), Reg,
70137015Sdes                                         LocVT.getSimpleVT(), LocInfo));
71137015Sdes        return false;
72137015Sdes      }
73137015Sdes    }
74137015Sdes  }
75137015Sdes
76137015Sdes  const Type* ArgTy = LocVT.getTypeForEVT(State.getContext());
77137015Sdes  unsigned Alignment =
78137015Sdes    State.getTarget().getDataLayout()->getABITypeAlignment(ArgTy);
79137015Sdes  unsigned Size =
80137015Sdes    State.getTarget().getDataLayout()->getTypeSizeInBits(ArgTy) / 8;
81137015Sdes
82137015Sdes  // If it's passed by value, then we need the size of the aggregate not of
83137015Sdes  // the pointer.
84137015Sdes  if (ArgFlags.isByVal()) {
85137015Sdes    Size = ByValSize;
86137015Sdes
87137015Sdes    // Hexagon_TODO: Get the alignment of the contained type here.
88137015Sdes    Alignment = 8;
89137015Sdes  }
90137015Sdes
91137015Sdes  unsigned Offset3 = State.AllocateStack(Size, Alignment);
92137015Sdes  State.addLoc(CCValAssign::getMem(ValNo, ValVT.getSimpleVT(), Offset3,
93                                   LocVT.getSimpleVT(), LocInfo));
94  return false;
95}
96
97
98static 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