142 lines
5.0 KiB
C
142 lines
5.0 KiB
C
|
//===-- 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;
|
||
|
}
|