[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp
Evan Cheng
evan.cheng at apple.com
Thu Apr 27 01:31:23 PDT 2006
Changes in directory llvm/lib/Target/X86:
X86ISelLowering.cpp updated: 1.192 -> 1.193
---
Log message:
Support for passing 128-bit vector arguments via XMM registers.
---
Diffs of the changes: (+97 -27)
X86ISelLowering.cpp | 124 ++++++++++++++++++++++++++++++++++++++++------------
1 files changed, 97 insertions(+), 27 deletions(-)
Index: llvm/lib/Target/X86/X86ISelLowering.cpp
diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.192 llvm/lib/Target/X86/X86ISelLowering.cpp:1.193
--- llvm/lib/Target/X86/X86ISelLowering.cpp:1.192 Thu Apr 27 00:44:50 2006
+++ llvm/lib/Target/X86/X86ISelLowering.cpp Thu Apr 27 03:31:10 2006
@@ -413,10 +413,13 @@
return VReg;
}
-/// getFormalArgSize - Return the minimum size of the stack frame needed to store
-/// an object of the specified type.
-static unsigned getFormalArgSize(MVT::ValueType ObjectVT) {
- unsigned ObjSize = 0;
+/// HowToPassCCCArgument - Returns how an formal argument of the specified type
+/// should be passed. If it is through stack, returns the size of the stack
+/// frame; if it is through XMM register, returns the number of XMM registers
+/// are needed.
+static void
+HowToPassCCCArgument(MVT::ValueType ObjectVT, unsigned NumXMMRegs,
+ unsigned &ObjSize, unsigned &ObjXMMRegs) {
switch (ObjectVT) {
default: assert(0 && "Unhandled argument type!");
case MVT::i1:
@@ -426,8 +429,18 @@
case MVT::i64: ObjSize = 8; 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 < 3)
+ ObjXMMRegs = 1;
+ else
+ ObjSize = 16;
+ break;
}
- return ObjSize;
}
/// getFormalArgObjects - Returns itself if Op is a FORMAL_ARGUMENTS, otherwise
@@ -466,6 +479,8 @@
// ...
//
unsigned ArgOffset = 0; // Frame mechanisms handle retaddr slot
+ unsigned NumXMMRegs = 0; // XMM regs used for parameter passing.
+ unsigned XMMArgRegs[] = { X86::XMM0, X86::XMM1, X86::XMM2 };
for (unsigned i = 0; i < NumArgs; ++i) {
SDOperand Op = Args[i];
std::vector<SDOperand> Objs = getFormalArgObjects(Op);
@@ -474,16 +489,29 @@
SDOperand Obj = *I;
MVT::ValueType ObjectVT = Obj.getValueType();
unsigned ArgIncrement = 4;
- unsigned ObjSize = getFormalArgSize(ObjectVT);
- if (ObjSize == 8)
- ArgIncrement = 8;
-
- // Create the frame index object for this incoming parameter...
- int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
- std::pair<FALocInfo, FALocInfo> Loc =
- std::make_pair(FALocInfo(FALocInfo::StackFrameLoc, FI), FALocInfo());
- FormalArgLocs.push_back(Loc);
- ArgOffset += ArgIncrement; // Move on to the next argument...
+ unsigned ObjSize = 0;
+ unsigned ObjXMMRegs = 0;
+ HowToPassCCCArgument(ObjectVT, NumXMMRegs, ObjSize, ObjXMMRegs);
+ if (ObjSize >= 8)
+ ArgIncrement = ObjSize;
+
+ if (ObjXMMRegs) {
+ // Passed in a XMM register.
+ unsigned Reg = AddLiveIn(MF, XMMArgRegs[NumXMMRegs],
+ X86::VR128RegisterClass);
+ std::pair<FALocInfo, FALocInfo> Loc =
+ std::make_pair(FALocInfo(FALocInfo::LiveInRegLoc, Reg, ObjectVT),
+ FALocInfo());
+ FormalArgLocs.push_back(Loc);
+ NumXMMRegs += ObjXMMRegs;
+ } else {
+ // Create the frame index object for this incoming parameter...
+ int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
+ std::pair<FALocInfo, FALocInfo> Loc =
+ std::make_pair(FALocInfo(FALocInfo::StackFrameLoc, FI), FALocInfo());
+ FormalArgLocs.push_back(Loc);
+ ArgOffset += ArgIncrement; // Move on to the next argument...
+ }
}
}
@@ -502,11 +530,19 @@
MachineFrameInfo *MFI = MF.getFrameInfo();
for (unsigned i = 0; i < NumArgs; ++i) {
- // Create the SelectionDAG nodes corresponding to a load from this parameter
- unsigned FI = FormalArgLocs[i].first.Loc;
- SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32);
- SDOperand ArgValue = DAG.getLoad(Op.Val->getValueType(i),DAG.getEntryNode(),
- FIN, DAG.getSrcValue(NULL));
+ std::pair<FALocInfo, FALocInfo> Loc = FormalArgLocs[i];
+ SDOperand ArgValue;
+ if (Loc.first.Kind == FALocInfo::StackFrameLoc) {
+ // Create the SelectionDAG nodes corresponding to a load from this parameter
+ unsigned FI = FormalArgLocs[i].first.Loc;
+ SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32);
+ ArgValue = DAG.getLoad(Op.Val->getValueType(i),
+ DAG.getEntryNode(), FIN, DAG.getSrcValue(NULL));
+ } else {
+ // Must be a CopyFromReg
+ ArgValue= DAG.getCopyFromReg(DAG.getEntryNode(), Loc.first.Loc,
+ Loc.first.Typ);
+ }
FormalArgs.push_back(ArgValue);
}
}
@@ -741,9 +777,15 @@
static unsigned FASTCC_NUM_INT_ARGS_INREGS = 0;
+/// HowToPassFastCCArgument - Returns how an formal argument of the specified
+/// type should be passed. If it is through stack, returns the size of the stack
+/// frame; if it is through integer or XMM register, returns the number of
+/// integer or XMM registers are needed.
static void
-HowToPassFastCCArgument(MVT::ValueType ObjectVT, unsigned NumIntRegs,
- unsigned &ObjSize, unsigned &ObjIntRegs) {
+HowToPassFastCCArgument(MVT::ValueType ObjectVT,
+ unsigned NumIntRegs, unsigned NumXMMRegs,
+ unsigned &ObjSize, unsigned &ObjIntRegs,
+ unsigned &ObjXMMRegs) {
ObjSize = 0;
NumIntRegs = 0;
@@ -782,6 +824,17 @@
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 < 3)
+ ObjXMMRegs = 1;
+ else
+ ObjSize = 16;
+ break;
}
}
@@ -805,6 +858,8 @@
// 0 (neither EAX or EDX used), 1 (EAX is used) or 2 (EAX and EDX are both
// used).
unsigned NumIntRegs = 0;
+ unsigned NumXMMRegs = 0; // XMM regs used for parameter passing.
+ unsigned XMMArgRegs[] = { X86::XMM0, X86::XMM1, X86::XMM2 };
for (unsigned i = 0; i < NumArgs; ++i) {
SDOperand Op = Args[i];
@@ -816,10 +871,12 @@
unsigned ArgIncrement = 4;
unsigned ObjSize = 0;
unsigned ObjIntRegs = 0;
+ unsigned ObjXMMRegs = 0;
- HowToPassFastCCArgument(ObjectVT, NumIntRegs, ObjSize, ObjIntRegs);
- if (ObjSize == 8)
- ArgIncrement = 8;
+ HowToPassFastCCArgument(ObjectVT, NumIntRegs, NumXMMRegs,
+ ObjSize, ObjIntRegs, ObjXMMRegs);
+ if (ObjSize >= 8)
+ ArgIncrement = ObjSize;
unsigned Reg;
std::pair<FALocInfo,FALocInfo> Loc = std::make_pair(FALocInfo(),
@@ -862,8 +919,20 @@
Loc.second.Typ = MVT::i32;
}
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);
+ Loc.first.Kind = FALocInfo::LiveInRegLoc;
+ Loc.first.Loc = Reg;
+ Loc.first.Typ = ObjectVT;
+ break;
}
NumIntRegs += ObjIntRegs;
+ NumXMMRegs += ObjXMMRegs;
}
if (ObjSize) {
int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
@@ -928,7 +997,8 @@
DAG.getSrcValue(NULL));
} else {
// Must be a CopyFromReg
- ArgValue= DAG.getCopyFromReg(DAG.getRoot(), Loc.first.Loc, Loc.first.Typ);
+ ArgValue= DAG.getCopyFromReg(DAG.getEntryNode(), Loc.first.Loc,
+ Loc.first.Typ);
}
if (Loc.second.Kind != FALocInfo::None) {
@@ -940,7 +1010,7 @@
DAG.getSrcValue(NULL));
} else {
// Must be a CopyFromReg
- ArgValue2 = DAG.getCopyFromReg(DAG.getRoot(),
+ ArgValue2 = DAG.getCopyFromReg(DAG.getEntryNode(),
Loc.second.Loc, Loc.second.Typ);
}
ArgValue = DAG.getNode(ISD::BUILD_PAIR, VT, ArgValue, ArgValue2);
More information about the llvm-commits
mailing list