//===-- HexagonVarargsCallingConvention.h - Calling Conventions -*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file declares the functions that assign locations to outgoing function // arguments. Adapted from the target independent version but this handles // calls to varargs functions // //===----------------------------------------------------------------------===// // static bool RetCC_Hexagon32_VarArgs(unsigned ValNo, EVT ValVT, EVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Hexagon_CCState &State, int NonVarArgsParams, int CurrentParam, bool ForceMem); static bool CC_Hexagon32_VarArgs(unsigned ValNo, EVT ValVT, EVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Hexagon_CCState &State, int NonVarArgsParams, int CurrentParam, bool ForceMem) { unsigned ByValSize = 0; if (ArgFlags.isByVal() && ((ByValSize = ArgFlags.getByValSize()) > (MVT(MVT::i64).getSizeInBits() / 8))) { ForceMem = true; } // Only assign registers for named (non-varargs) arguments if ( !ForceMem && ((NonVarArgsParams == -1) || (CurrentParam <= NonVarArgsParams))) { if (LocVT == MVT::i32 || LocVT == MVT::i16 || LocVT == MVT::i8 || LocVT == MVT::f32) { static const unsigned RegList1[] = { Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3, Hexagon::R4, Hexagon::R5 }; if (unsigned Reg = State.AllocateReg(RegList1, 6)) { State.addLoc(CCValAssign::getReg(ValNo, ValVT.getSimpleVT(), Reg, LocVT.getSimpleVT(), LocInfo)); return false; } } if (LocVT == MVT::i64 || LocVT == MVT::f64) { static const unsigned RegList2[] = { Hexagon::D0, Hexagon::D1, Hexagon::D2 }; if (unsigned Reg = State.AllocateReg(RegList2, 3)) { State.addLoc(CCValAssign::getReg(ValNo, ValVT.getSimpleVT(), Reg, LocVT.getSimpleVT(), LocInfo)); return false; } } } const Type* ArgTy = LocVT.getTypeForEVT(State.getContext()); unsigned Alignment = State.getTarget().getDataLayout()->getABITypeAlignment(ArgTy); unsigned Size = State.getTarget().getDataLayout()->getTypeSizeInBits(ArgTy) / 8; // If it's passed by value, then we need the size of the aggregate not of // the pointer. if (ArgFlags.isByVal()) { Size = ByValSize; // Hexagon_TODO: Get the alignment of the contained type here. Alignment = 8; } unsigned Offset3 = State.AllocateStack(Size, Alignment); State.addLoc(CCValAssign::getMem(ValNo, ValVT.getSimpleVT(), Offset3, LocVT.getSimpleVT(), LocInfo)); return false; } static bool RetCC_Hexagon32_VarArgs(unsigned ValNo, EVT ValVT, EVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Hexagon_CCState &State, int NonVarArgsParams, int CurrentParam, bool ForceMem) { if (LocVT == MVT::i32 || LocVT == MVT::f32) { static const unsigned RegList1[] = { Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3, Hexagon::R4, Hexagon::R5 }; if (unsigned Reg = State.AllocateReg(RegList1, 6)) { State.addLoc(CCValAssign::getReg(ValNo, ValVT.getSimpleVT(), Reg, LocVT.getSimpleVT(), LocInfo)); return false; } } if (LocVT == MVT::i64 || LocVT == MVT::f64) { static const unsigned RegList2[] = { Hexagon::D0, Hexagon::D1, Hexagon::D2 }; if (unsigned Reg = State.AllocateReg(RegList2, 3)) { State.addLoc(CCValAssign::getReg(ValNo, ValVT.getSimpleVT(), Reg, LocVT.getSimpleVT(), LocInfo)); return false; } } const Type* ArgTy = LocVT.getTypeForEVT(State.getContext()); unsigned Alignment = State.getTarget().getDataLayout()->getABITypeAlignment(ArgTy); unsigned Size = State.getTarget().getDataLayout()->getTypeSizeInBits(ArgTy) / 8; unsigned Offset3 = State.AllocateStack(Size, Alignment); State.addLoc(CCValAssign::getMem(ValNo, ValVT.getSimpleVT(), Offset3, LocVT.getSimpleVT(), LocInfo)); return false; }