switch LowerCCCArguments over to using autogenerated CC.

llvm-svn: 34729
This commit is contained in:
Chris Lattner 2007-02-28 05:46:49 +00:00
parent 5958b176f3
commit b9db225049
1 changed files with 62 additions and 94 deletions

View File

@ -667,124 +667,92 @@ SDOperand X86TargetLowering::LowerCCCArguments(SDOperand Op, SelectionDAG &DAG,
MachineFunction &MF = DAG.getMachineFunction(); MachineFunction &MF = DAG.getMachineFunction();
MachineFrameInfo *MFI = MF.getFrameInfo(); MachineFrameInfo *MFI = MF.getFrameInfo();
SDOperand Root = Op.getOperand(0); SDOperand Root = Op.getOperand(0);
SmallVector<SDOperand, 8> ArgValues;
bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0; bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
// Add DAG nodes to load the arguments... On entry to a function on the X86, SmallVector<CCValAssign, 16> ArgLocs;
// the stack frame looks like this: CCState CCInfo(MF.getFunction()->getCallingConv(), getTargetMachine(),
// ArgLocs);
// [ESP] -- return address
// [ESP + 4] -- first argument (leftmost lexically)
// [ESP + 8] -- second argument, if first argument is <= 4 bytes in size
// ...
//
unsigned ArgOffset = 0; // Frame mechanisms handle retaddr slot
unsigned NumSRetBytes= 0; // How much bytes on stack used for struct return
unsigned NumXMMRegs = 0; // XMM regs used for parameter passing.
unsigned NumIntRegs = 0; // Integer regs used for parameter passing
static const unsigned XMMArgRegs[] = { for (unsigned i = 0; i != NumArgs; ++i) {
X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3 MVT::ValueType ArgVT = Op.getValue(i).getValueType();
}; unsigned ArgFlags = cast<ConstantSDNode>(Op.getOperand(3+i))->getValue();
static const unsigned GPRArgRegs[][3] = { if (CC_X86_32_C(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, CCInfo))
{ X86::AL, X86::DL, X86::CL }, assert(0 && "Unhandled argument type!");
{ X86::AX, X86::DX, X86::CX },
{ X86::EAX, X86::EDX, X86::ECX }
};
static const TargetRegisterClass* GPRClasses[3] = {
X86::GR8RegisterClass, X86::GR16RegisterClass, X86::GR32RegisterClass
};
// Handle regparm attribute
SmallVector<bool, 8> ArgInRegs(NumArgs, false);
SmallVector<bool, 8> SRetArgs(NumArgs, false);
if (!isVarArg) {
for (unsigned i = 0; i<NumArgs; ++i) {
unsigned Flags = cast<ConstantSDNode>(Op.getOperand(3+i))->getValue();
ArgInRegs[i] = (Flags >> 1) & 1;
SRetArgs[i] = (Flags >> 2) & 1;
}
} }
for (unsigned i = 0; i < NumArgs; ++i) { SmallVector<SDOperand, 8> ArgValues;
MVT::ValueType ObjectVT = Op.getValue(i).getValueType(); unsigned LastVal = ~0U;
unsigned ArgIncrement = 4; for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
unsigned ObjSize = 0; CCValAssign &VA = ArgLocs[i];
unsigned ObjXMMRegs = 0; // TODO: If an arg is passed in two places (e.g. reg and stack), skip later
unsigned ObjIntRegs = 0; // places.
unsigned Reg = 0; assert(VA.getValNo() != LastVal &&
SDOperand ArgValue; "Don't support value assigned to multiple locs yet");
LastVal = VA.getValNo();
HowToPassCallArgument(ObjectVT,
ArgInRegs[i], if (VA.isRegLoc()) {
NumIntRegs, NumXMMRegs, 3, MVT::ValueType RegVT = VA.getLocVT();
ObjSize, ObjIntRegs, ObjXMMRegs); TargetRegisterClass *RC;
if (RegVT == MVT::i32)
if (ObjSize > 4) RC = X86::GR32RegisterClass;
ArgIncrement = ObjSize; else {
assert(MVT::isVector(RegVT));
if (ObjIntRegs || ObjXMMRegs) { RC = X86::VR128RegisterClass;
switch (ObjectVT) {
default: assert(0 && "Unhandled argument type!");
case MVT::i8:
case MVT::i16:
case MVT::i32: {
unsigned RegToUse = GPRArgRegs[ObjectVT-MVT::i8][NumIntRegs];
Reg = AddLiveIn(MF, RegToUse, GPRClasses[ObjectVT-MVT::i8]);
ArgValue = DAG.getCopyFromReg(Root, Reg, ObjectVT);
break;
}
case MVT::v16i8:
case MVT::v8i16:
case MVT::v4i32:
case MVT::v2i64:
case MVT::v4f32:
case MVT::v2f64:
assert(!isStdCall && "Unhandled argument type!");
Reg = AddLiveIn(MF, XMMArgRegs[NumXMMRegs], X86::VR128RegisterClass);
ArgValue = DAG.getCopyFromReg(Root, Reg, ObjectVT);
break;
} }
NumIntRegs += ObjIntRegs;
NumXMMRegs += ObjXMMRegs;
}
if (ObjSize) {
// XMM arguments have to be aligned on 16-byte boundary.
if (ObjSize == 16)
ArgOffset = ((ArgOffset + 15) / 16) * 16;
// Create the SelectionDAG nodes corresponding to a load from this
// parameter.
int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
SDOperand FIN = DAG.getFrameIndex(FI, getPointerTy());
ArgValue = DAG.getLoad(Op.Val->getValueType(i), Root, FIN, NULL, 0);
ArgOffset += ArgIncrement; // Move on to the next argument. SDOperand ArgValue = DAG.getCopyFromReg(Root, VA.getLocReg(), RegVT);
if (SRetArgs[i]) AddLiveIn(DAG.getMachineFunction(), VA.getLocReg(), RC);
NumSRetBytes += ArgIncrement;
// If this is an 8 or 16-bit value, it is really passed promoted to 32
// bits. Insert an assert[sz]ext to capture this, then truncate to the
// right size.
if (VA.getLocInfo() == CCValAssign::SExt)
ArgValue = DAG.getNode(ISD::AssertSext, RegVT, ArgValue,
DAG.getValueType(VA.getValVT()));
else if (VA.getLocInfo() == CCValAssign::ZExt)
ArgValue = DAG.getNode(ISD::AssertZext, RegVT, ArgValue,
DAG.getValueType(VA.getValVT()));
if (VA.getLocInfo() != CCValAssign::Full)
ArgValue = DAG.getNode(ISD::TRUNCATE, VA.getValVT(), ArgValue);
ArgValues.push_back(ArgValue);
} else {
assert(VA.isMemLoc());
// Create the nodes corresponding to a load from this parameter slot.
int FI = MFI->CreateFixedObject(MVT::getSizeInBits(VA.getValVT())/8,
VA.getLocMemOffset());
SDOperand FIN = DAG.getFrameIndex(FI, getPointerTy());
ArgValues.push_back(DAG.getLoad(VA.getValVT(), Root, FIN, NULL, 0));
} }
ArgValues.push_back(ArgValue);
} }
unsigned StackSize = CCInfo.getNextStackOffset();
ArgValues.push_back(Root); ArgValues.push_back(Root);
// If the function takes variable number of arguments, make a frame index for // If the function takes variable number of arguments, make a frame index for
// the start of the first vararg value... for expansion of llvm.va_start. // the start of the first vararg value... for expansion of llvm.va_start.
if (isVarArg) if (isVarArg)
VarArgsFrameIndex = MFI->CreateFixedObject(1, ArgOffset); VarArgsFrameIndex = MFI->CreateFixedObject(1, StackSize);
if (isStdCall && !isVarArg) { if (isStdCall && !isVarArg) {
BytesToPopOnReturn = ArgOffset; // Callee pops everything.. BytesToPopOnReturn = StackSize; // Callee pops everything..
BytesCallerReserves = 0; BytesCallerReserves = 0;
} else { } else {
BytesToPopOnReturn = NumSRetBytes; // Callee pops hidden struct pointer. BytesToPopOnReturn = 0; // Callee pops hidden struct pointer.
BytesCallerReserves = ArgOffset;
// If this is an sret function, the return should pop the hidden pointer.
if (NumArgs && (cast<ConstantSDNode>(Op.getOperand(3))->getValue() & 4))
BytesToPopOnReturn = 4;
BytesCallerReserves = StackSize;
} }
RegSaveFrameIndex = 0xAAAAAAA; // X86-64 only. RegSaveFrameIndex = 0xAAAAAAA; // X86-64 only.
ReturnAddrIndex = 0; // No return address slot generated yet. ReturnAddrIndex = 0; // No return address slot generated yet.
MF.getInfo<X86FunctionInfo>()->setBytesToPopOnReturn(BytesToPopOnReturn); MF.getInfo<X86FunctionInfo>()->setBytesToPopOnReturn(BytesToPopOnReturn);
// Return the new list of results. // Return the new list of results.