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