switch LowerFastCCArguments over to using the autogenerated Fastcall description.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34733 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 111bfb6..397afb2 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -601,66 +601,6 @@
return VReg;
}
-/// HowToPassArgument - Returns how an formal argument of the specified type
-/// should be passed. If it is through stack, returns the size of the stack
-/// slot; if it is through integer or XMM register, returns the number of
-/// integer or XMM registers are needed.
-static void
-HowToPassCallArgument(MVT::ValueType ObjectVT,
- bool ArgInReg,
- unsigned NumIntRegs, unsigned NumXMMRegs,
- unsigned MaxNumIntRegs,
- unsigned &ObjSize, unsigned &ObjIntRegs,
- unsigned &ObjXMMRegs) {
- ObjSize = 0;
- ObjIntRegs = 0;
- ObjXMMRegs = 0;
-
- if (MaxNumIntRegs>3) {
- // We don't have too much registers on ia32! :)
- MaxNumIntRegs = 3;
- }
-
- switch (ObjectVT) {
- default: assert(0 && "Unhandled argument type!");
- case MVT::i8:
- if (ArgInReg && (NumIntRegs < MaxNumIntRegs))
- ObjIntRegs = 1;
- else
- ObjSize = 1;
- break;
- case MVT::i16:
- if (ArgInReg && (NumIntRegs < MaxNumIntRegs))
- ObjIntRegs = 1;
- else
- ObjSize = 2;
- break;
- case MVT::i32:
- if (ArgInReg && (NumIntRegs < MaxNumIntRegs))
- ObjIntRegs = 1;
- else
- ObjSize = 4;
- break;
- case MVT::f32:
- ObjSize = 4;
- break;
- case MVT::f64:
- ObjSize = 8;
- break;
- case MVT::v16i8:
- case MVT::v8i16:
- case MVT::v4i32:
- case MVT::v2i64:
- case MVT::v4f32:
- case MVT::v2f64:
- if (NumXMMRegs < 4)
- ObjXMMRegs = 1;
- else
- ObjSize = 16;
- break;
- }
-}
-
SDOperand X86TargetLowering::LowerCCCArguments(SDOperand Op, SelectionDAG &DAG,
bool isStdCall) {
unsigned NumArgs = Op.Val->getNumValues() - 1;
@@ -929,138 +869,83 @@
MachineFunction &MF = DAG.getMachineFunction();
MachineFrameInfo *MFI = MF.getFrameInfo();
SDOperand Root = Op.getOperand(0);
- SmallVector<SDOperand, 8> ArgValues;
- // Add DAG nodes to load the arguments... On entry to a function the stack
- // frame looks like this:
- //
- // [ESP] -- return address
- // [ESP + 4] -- first nonreg argument (leftmost lexically)
- // [ESP + 8] -- second nonreg argument, if 1st argument is <= 4 bytes in size
- // ...
- unsigned ArgOffset = 0; // Frame mechanisms handle retaddr slot
-
- // Keep track of the number of integer regs passed so far. This can be either
- // 0 (neither EAX/ECX or EDX used), 1 (EAX/ECX is used) or 2 (EAX/ECX and EDX
- // are both used).
- unsigned NumIntRegs = 0;
- unsigned NumXMMRegs = 0; // XMM regs used for parameter passing.
-
- static const unsigned XMMArgRegs[] = {
- X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3
- };
-
- static const unsigned GPRArgRegs[][2] = {
- { X86::CL, X86::DL },
- { X86::CX, X86::DX },
- { X86::ECX, X86::EDX }
- };
-
- static const TargetRegisterClass* GPRClasses[3] = {
- X86::GR8RegisterClass, X86::GR16RegisterClass, X86::GR32RegisterClass
- };
-
- for (unsigned i = 0; i < NumArgs; ++i) {
- MVT::ValueType ObjectVT = Op.getValue(i).getValueType();
- unsigned ArgIncrement = 4;
- unsigned ObjSize = 0;
- unsigned ObjXMMRegs = 0;
- unsigned ObjIntRegs = 0;
- unsigned Reg = 0;
- SDOperand ArgValue;
-
- HowToPassCallArgument(ObjectVT,
- true, // Use as much registers as possible
- NumIntRegs, NumXMMRegs, 2,
- ObjSize, ObjIntRegs, ObjXMMRegs);
-
- if (ObjSize > 4)
- ArgIncrement = ObjSize;
-
- if (ObjIntRegs || ObjXMMRegs) {
- 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: {
- 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.
- }
-
- ArgValues.push_back(ArgValue);
+ SmallVector<CCValAssign, 16> ArgLocs;
+ CCState CCInfo(MF.getFunction()->getCallingConv(), getTargetMachine(),
+ ArgLocs);
+
+ for (unsigned i = 0; i != NumArgs; ++i) {
+ MVT::ValueType ArgVT = Op.getValue(i).getValueType();
+ unsigned ArgFlags = cast<ConstantSDNode>(Op.getOperand(3+i))->getValue();
+ if (CC_X86_32_FastCall(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags,CCInfo))
+ assert(0 && "Unhandled argument type!");
}
-
+
+ SmallVector<SDOperand, 8> ArgValues;
+ unsigned LastVal = ~0U;
+ for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
+ CCValAssign &VA = ArgLocs[i];
+ // TODO: If an arg is passed in two places (e.g. reg and stack), skip later
+ // places.
+ assert(VA.getValNo() != LastVal &&
+ "Don't support value assigned to multiple locs yet");
+ LastVal = VA.getValNo();
+
+ if (VA.isRegLoc()) {
+ MVT::ValueType RegVT = VA.getLocVT();
+ TargetRegisterClass *RC;
+ if (RegVT == MVT::i32)
+ RC = X86::GR32RegisterClass;
+ else {
+ assert(MVT::isVector(RegVT));
+ RC = X86::VR128RegisterClass;
+ }
+
+ SDOperand ArgValue = DAG.getCopyFromReg(Root, VA.getLocReg(), RegVT);
+ AddLiveIn(DAG.getMachineFunction(), VA.getLocReg(), RC);
+
+ // 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(Root);
+ unsigned StackSize = CCInfo.getNextStackOffset();
+
// Make sure the instruction takes 8n+4 bytes to make sure the start of the
// arguments and the arguments after the retaddr has been pushed are aligned.
- if ((ArgOffset & 7) == 0)
- ArgOffset += 4;
+ if ((StackSize & 7) == 0)
+ StackSize += 4;
VarArgsFrameIndex = 0xAAAAAAA; // fastcc functions can't have varargs.
RegSaveFrameIndex = 0xAAAAAAA; // X86-64 only.
ReturnAddrIndex = 0; // No return address slot generated yet.
- BytesToPopOnReturn = ArgOffset; // Callee pops all stack arguments.
+ BytesToPopOnReturn = StackSize; // Callee pops all stack arguments.
BytesCallerReserves = 0;
MF.getInfo<X86FunctionInfo>()->setBytesToPopOnReturn(BytesToPopOnReturn);
- // Finally, inform the code generator which regs we return values in.
- switch (getValueType(MF.getFunction()->getReturnType())) {
- default: assert(0 && "Unknown type!");
- case MVT::isVoid: break;
- case MVT::i1:
- case MVT::i8:
- case MVT::i16:
- case MVT::i32:
- MF.addLiveOut(X86::EAX);
- break;
- case MVT::i64:
- MF.addLiveOut(X86::EAX);
- MF.addLiveOut(X86::EDX);
- break;
- case MVT::f32:
- case MVT::f64:
- MF.addLiveOut(X86::ST0);
- break;
- case MVT::v16i8:
- case MVT::v8i16:
- case MVT::v4i32:
- case MVT::v2i64:
- case MVT::v4f32:
- case MVT::v2f64:
- MF.addLiveOut(X86::XMM0);
- break;
- }
-
// Return the new list of results.
return DAG.getNode(ISD::MERGE_VALUES, Op.Val->getVTList(),
&ArgValues[0], ArgValues.size()).getValue(Op.ResNo);