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
20static 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
29static 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
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