| //===-- 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; |
| } |