[llvm-commits] [llvm] r49079 - in /llvm/trunk: include/llvm/CodeGen/CallingConvLower.h lib/Target/TargetCallingConv.td lib/Target/X86/X86CallingConv.td utils/TableGen/CallingConvEmitter.cpp
Anton Korobeynikov
asl at math.spbu.ru
Tue Apr 1 22:23:58 PDT 2008
Author: asl
Date: Wed Apr 2 00:23:57 2008
New Revision: 49079
URL: http://llvm.org/viewvc/llvm-project?rev=49079&view=rev
Log:
Add new CC lowering rule: provide a list of registers, which can be 'shadowed',
when some another register is used for argument passing.
Currently is used on Win64.
Modified:
llvm/trunk/include/llvm/CodeGen/CallingConvLower.h
llvm/trunk/lib/Target/TargetCallingConv.td
llvm/trunk/lib/Target/X86/X86CallingConv.td
llvm/trunk/utils/TableGen/CallingConvEmitter.cpp
Modified: llvm/trunk/include/llvm/CodeGen/CallingConvLower.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/CallingConvLower.h?rev=49079&r1=49078&r2=49079&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/CallingConvLower.h (original)
+++ llvm/trunk/include/llvm/CodeGen/CallingConvLower.h Wed Apr 2 00:23:57 2008
@@ -167,7 +167,15 @@
MarkAllocated(Reg);
return Reg;
}
-
+
+ /// Version of AllocateReg with extra register to be shadowed.
+ unsigned AllocateReg(unsigned Reg, unsigned ShadowReg) {
+ if (isAllocated(Reg)) return 0;
+ MarkAllocated(Reg);
+ MarkAllocated(ShadowReg);
+ return Reg;
+ }
+
/// AllocateReg - Attempt to allocate one of the specified registers. If none
/// are available, return zero. Otherwise, return the first one available,
/// marking it and any aliases as allocated.
@@ -175,13 +183,27 @@
unsigned FirstUnalloc = getFirstUnallocated(Regs, NumRegs);
if (FirstUnalloc == NumRegs)
return 0; // Didn't find the reg.
-
+
// Mark the register and any aliases as allocated.
unsigned Reg = Regs[FirstUnalloc];
MarkAllocated(Reg);
return Reg;
}
-
+
+ /// Version of AllocateReg with list of registers to be shadowed.
+ unsigned AllocateReg(const unsigned *Regs, const unsigned *ShadowRegs,
+ unsigned NumRegs) {
+ unsigned FirstUnalloc = getFirstUnallocated(Regs, NumRegs);
+ if (FirstUnalloc == NumRegs)
+ return 0; // Didn't find the reg.
+
+ // Mark the register and any aliases as allocated.
+ unsigned Reg = Regs[FirstUnalloc], ShadowReg = ShadowRegs[FirstUnalloc];
+ MarkAllocated(Reg);
+ MarkAllocated(ShadowReg);
+ return Reg;
+ }
+
/// AllocateStack - Allocate a chunk of stack space with the specified size
/// and alignment.
unsigned AllocateStack(unsigned Size, unsigned Align) {
Modified: llvm/trunk/lib/Target/TargetCallingConv.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetCallingConv.td?rev=49079&r1=49078&r2=49079&view=diff
==============================================================================
--- llvm/trunk/lib/Target/TargetCallingConv.td (original)
+++ llvm/trunk/lib/Target/TargetCallingConv.td Wed Apr 2 00:23:57 2008
@@ -59,6 +59,14 @@
list<Register> RegList = regList;
}
+/// CCAssignToRegWithShadow - Same as CCAssignToReg, but with list of registers
+/// which became shadowed, when some register is used.
+class CCAssignToRegWithShadow<list<Register> regList,
+ list<Register> shadowList> : CCAction {
+ list<Register> RegList = regList;
+ list<Register> ShadowRegList = shadowList;
+}
+
/// CCAssignToStack - This action always matches: it assigns the value to a
/// stack slot of the specified size and alignment on the stack. If size is
/// zero then the ABI size is used; if align is zero then the ABI alignment
Modified: llvm/trunk/lib/Target/X86/X86CallingConv.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86CallingConv.td?rev=49079&r1=49078&r2=49079&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86CallingConv.td (original)
+++ llvm/trunk/lib/Target/X86/X86CallingConv.td Wed Apr 2 00:23:57 2008
@@ -158,22 +158,29 @@
def CC_X86_Win64_C : CallingConv<[
// FIXME: Handle byval stuff.
// FIXME: Handle fp80.
- // FIXME: Handle shadowed arguments.
- // FIXME: Handle nested functions.
+ // FIXME: Handle varargs.
// Promote i8/i16 arguments to i32.
CCIfType<[i8, i16], CCPromoteToType<i32>>,
+ // The 'nest' parameter, if any, is passed in R10.
+ CCIfNest<CCAssignToReg<[R10]>>,
+
// The first 4 integer arguments are passed in integer registers.
- CCIfType<[i32], CCAssignToReg<[ECX, EDX, R8D, R9D]>>,
- CCIfType<[i64], CCAssignToReg<[RCX, RDX, R8 , R9 ]>>,
+ CCIfType<[i32], CCAssignToRegWithShadow<[ECX , EDX , R8D , R9D ],
+ [XMM0, XMM1, XMM2, XMM3]>>,
+ CCIfType<[i64], CCAssignToRegWithShadow<[RCX , RDX , R8 , R9 ],
+ [XMM0, XMM1, XMM2, XMM3]>>,
// The first 4 FP/Vector arguments are passed in XMM registers.
CCIfType<[f32, f64, v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],
- CCAssignToReg<[XMM0, XMM1, XMM2, XMM3]>>,
+ CCAssignToRegWithShadow<[XMM0, XMM1, XMM2, XMM3],
+ [RCX , RDX , R8 , R9 ]>>,
// The first 4 MMX vector arguments are passed in GPRs.
- CCIfType<[v8i8, v4i16, v2i32, v1i64], CCAssignToReg<[RCX, RDX, R8, R9]>>,
+ CCIfType<[v8i8, v4i16, v2i32, v1i64],
+ CCAssignToRegWithShadow<[RCX , RDX , R8 , R9 ],
+ [XMM0, XMM1, XMM2, XMM3]>>,
// Integer/FP values get stored in stack slots that are 8 bytes in size and
// 16-byte aligned if there are no more registers to hold them.
Modified: llvm/trunk/utils/TableGen/CallingConvEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CallingConvEmitter.cpp?rev=49079&r1=49078&r2=49079&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/CallingConvEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/CallingConvEmitter.cpp Wed Apr 2 00:23:57 2008
@@ -111,6 +111,48 @@
<< "Reg, LocVT, LocInfo));\n";
O << IndentStr << " return false;\n";
O << IndentStr << "}\n";
+ } else if (Action->isSubClassOf("CCAssignToRegWithShadow")) {
+ ListInit *RegList = Action->getValueAsListInit("RegList");
+ ListInit *ShadowRegList = Action->getValueAsListInit("ShadowRegList");
+ if (ShadowRegList->getSize() >0 &&
+ ShadowRegList->getSize() != RegList->getSize())
+ throw "Invalid length of list of shadowed registers";
+
+ if (RegList->getSize() == 1) {
+ O << IndentStr << "if (unsigned Reg = State.AllocateReg(";
+ O << getQualifiedName(RegList->getElementAsRecord(0));
+ O << ", " << getQualifiedName(ShadowRegList->getElementAsRecord(0));
+ O << ")) {\n";
+ } else {
+ unsigned RegListNumber = ++Counter;
+ unsigned ShadowRegListNumber = ++Counter;
+
+ O << IndentStr << "static const unsigned RegList" << RegListNumber
+ << "[] = {\n";
+ O << IndentStr << " ";
+ for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) {
+ if (i != 0) O << ", ";
+ O << getQualifiedName(RegList->getElementAsRecord(i));
+ }
+ O << "\n" << IndentStr << "};\n";
+
+ O << IndentStr << "static const unsigned RegList"
+ << ShadowRegListNumber << "[] = {\n";
+ O << IndentStr << " ";
+ for (unsigned i = 0, e = ShadowRegList->getSize(); i != e; ++i) {
+ if (i != 0) O << ", ";
+ O << getQualifiedName(ShadowRegList->getElementAsRecord(i));
+ }
+ O << "\n" << IndentStr << "};\n";
+
+ O << IndentStr << "if (unsigned Reg = State.AllocateReg(RegList"
+ << RegListNumber << ", " << "RegList" << ShadowRegListNumber
+ << ", " << RegList->getSize() << ")) {\n";
+ }
+ O << IndentStr << " State.addLoc(CCValAssign::getReg(ValNo, ValVT, "
+ << "Reg, LocVT, LocInfo));\n";
+ O << IndentStr << " return false;\n";
+ O << IndentStr << "}\n";
} else if (Action->isSubClassOf("CCAssignToStack")) {
int Size = Action->getValueAsInt("Size");
int Align = Action->getValueAsInt("Align");
More information about the llvm-commits
mailing list