diff options
Diffstat (limited to 'lib/Target/Hexagon/HexagonVarargsCallingConvention.h')
-rw-r--r-- | lib/Target/Hexagon/HexagonVarargsCallingConvention.h | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/lib/Target/Hexagon/HexagonVarargsCallingConvention.h b/lib/Target/Hexagon/HexagonVarargsCallingConvention.h new file mode 100644 index 0000000000..21b2d678ac --- /dev/null +++ b/lib/Target/Hexagon/HexagonVarargsCallingConvention.h @@ -0,0 +1,141 @@ +//==-- 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().getTargetData()->getABITypeAlignment(ArgTy); + unsigned Size = + State.getTarget().getTargetData()->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().getTargetData()->getABITypeAlignment(ArgTy); + unsigned Size = + State.getTarget().getTargetData()->getTypeSizeInBits(ArgTy) / 8; + + unsigned Offset3 = State.AllocateStack(Size, Alignment); + State.addLoc(CCValAssign::getMem(ValNo, ValVT.getSimpleVT(), Offset3, + LocVT.getSimpleVT(), LocInfo)); + return false; +} |