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