[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