[llvm-branch-commits] [llvm-branch] r78238 - in /llvm/branches/Apple/Bender-SWB: include/llvm/CodeGen/CallingConvLower.h include/llvm/Target/TargetCallingConv.td lib/Target/X86/X86CallingConv.td lib/Target/X86/X86CompilationCallback_Win64.asm lib/Target/X86/X86FastISel.cpp lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86Instr64bit.td lib/Target/X86/X86InstrInfo.td lib/Target/X86/X86InstrMMX.td lib/Target/X86/X86RegisterInfo.cpp lib/Target/X86/X86TargetMachine.cpp utils/TableGen/CallingConvEmitter.cpp

Bill Wendling isanbard at gmail.com
Wed Aug 5 13:16:28 PDT 2009


Author: void
Date: Wed Aug  5 15:16:25 2009
New Revision: 78238

URL: http://llvm.org/viewvc/llvm-project?rev=78238&view=rev
Log:
--- Merging r77962 into '.':
U    lib/Target/X86/X86Instr64bit.td
U    lib/Target/X86/X86InstrInfo.td
U    lib/Target/X86/X86RegisterInfo.cpp
U    lib/Target/X86/X86ISelLowering.cpp
U    lib/Target/X86/X86CompilationCallback_Win64.asm
U    lib/Target/X86/X86CallingConv.td
U    lib/Target/X86/X86TargetMachine.cpp
[bitters:Bender-SWB] svn merge -c 77963 https://llvm.org/svn/llvm-project/llvm/trunk .
--- Merging r77963 into '.':
G    lib/Target/X86/X86ISelLowering.cpp
G    lib/Target/X86/X86CallingConv.td
[bitters:Bender-SWB] svn merge -c 77964 https://llvm.org/svn/llvm-project/llvm/trunk .
--- Merging r77964 into '.':
U    include/llvm/Target/TargetCallingConv.td
U    include/llvm/CodeGen/CallingConvLower.h
U    utils/TableGen/CallingConvEmitter.cpp
G    lib/Target/X86/X86ISelLowering.cpp
G    lib/Target/X86/X86CallingConv.td
[bitters:Bender-SWB] svn merge -c 77965 https://llvm.org/svn/llvm-project/llvm/trunk .
--- Merging r77965 into '.':
G    lib/Target/X86/X86ISelLowering.cpp
[bitters:Bender-SWB] svn merge -c 77966 https://llvm.org/svn/llvm-project/llvm/trunk .
--- Merging r77966 into '.':
G    lib/Target/X86/X86RegisterInfo.cpp
[bitters:Bender-SWB] svn merge -c 77968 https://llvm.org/svn/llvm-project/llvm/trunk .
--- Merging r77968 into '.':
G    lib/Target/X86/X86CompilationCallback_Win64.asm

Back-port a series of patches from Anton to fix <rdar://problem/7085558>.

Modified:
    llvm/branches/Apple/Bender-SWB/include/llvm/CodeGen/CallingConvLower.h
    llvm/branches/Apple/Bender-SWB/include/llvm/Target/TargetCallingConv.td
    llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86CallingConv.td
    llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86CompilationCallback_Win64.asm
    llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86FastISel.cpp
    llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86ISelLowering.cpp
    llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86Instr64bit.td
    llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86InstrInfo.td
    llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86InstrMMX.td
    llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86RegisterInfo.cpp
    llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86TargetMachine.cpp
    llvm/branches/Apple/Bender-SWB/utils/TableGen/CallingConvEmitter.cpp

Modified: llvm/branches/Apple/Bender-SWB/include/llvm/CodeGen/CallingConvLower.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Bender-SWB/include/llvm/CodeGen/CallingConvLower.h?rev=78238&r1=78237&r2=78238&view=diff

==============================================================================
--- llvm/branches/Apple/Bender-SWB/include/llvm/CodeGen/CallingConvLower.h (original)
+++ llvm/branches/Apple/Bender-SWB/include/llvm/CodeGen/CallingConvLower.h Wed Aug  5 15:16:25 2009
@@ -33,32 +33,33 @@
     SExt,   // The value is sign extended in the location.
     ZExt,   // The value is zero extended in the location.
     AExt,   // The value is extended with undefined upper bits.
-    BCvt    // The value is bit-converted in the location.
+    BCvt,   // The value is bit-converted in the location.
+    Indirect // The location contains pointer to the value.
     // TODO: a subset of the value is in the location.
   };
 private:
   /// ValNo - This is the value number begin assigned (e.g. an argument number).
   unsigned ValNo;
-  
+
   /// Loc is either a stack offset or a register number.
   unsigned Loc;
-  
+
   /// isMem - True if this is a memory loc, false if it is a register loc.
   bool isMem : 1;
-  
+
   /// isCustom - True if this arg/retval requires special handling.
   bool isCustom : 1;
 
   /// Information about how the value is assigned.
   LocInfo HTP : 6;
-  
+
   /// ValVT - The type of the value being assigned.
   MVT ValVT;
 
   /// LocVT - The type of the location being assigned to.
   MVT LocVT;
 public:
-    
+
   static CCValAssign getReg(unsigned ValNo, MVT ValVT,
                             unsigned RegNo, MVT LocVT,
                             LocInfo HTP) {
@@ -95,7 +96,7 @@
     Ret.LocVT = LocVT;
     return Ret;
   }
-  
+
   static CCValAssign getCustomMem(unsigned ValNo, MVT ValVT,
                                   unsigned Offset, MVT LocVT,
                                   LocInfo HTP) {
@@ -110,14 +111,18 @@
 
   bool isRegLoc() const { return !isMem; }
   bool isMemLoc() const { return isMem; }
-  
+
   bool needsCustom() const { return isCustom; }
 
   unsigned getLocReg() const { assert(isRegLoc()); return Loc; }
   unsigned getLocMemOffset() const { assert(isMemLoc()); return Loc; }
   MVT getLocVT() const { return LocVT; }
-  
+
   LocInfo getLocInfo() const { return HTP; }
+  bool isExtInLoc() const {
+    return (HTP == AExt || HTP == SExt || HTP == ZExt);
+  }
+
 };
 
 /// CCAssignFn - This function assigns a location for Val, updating State to
@@ -142,21 +147,21 @@
   const TargetMachine &TM;
   const TargetRegisterInfo &TRI;
   SmallVector<CCValAssign, 16> &Locs;
-  
+
   unsigned StackOffset;
   SmallVector<uint32_t, 16> UsedRegs;
 public:
   CCState(unsigned CC, bool isVarArg, const TargetMachine &TM,
           SmallVector<CCValAssign, 16> &locs);
-  
+
   void addLoc(const CCValAssign &V) {
     Locs.push_back(V);
   }
-  
+
   const TargetMachine &getTarget() const { return TM; }
   unsigned getCallingConv() const { return CallingConv; }
   bool isVarArg() const { return IsVarArg; }
-  
+
   unsigned getNextStackOffset() const { return StackOffset; }
 
   /// isAllocated - Return true if the specified register (or an alias) is
@@ -164,15 +169,15 @@
   bool isAllocated(unsigned Reg) const {
     return UsedRegs[Reg/32] & (1 << (Reg&31));
   }
-  
+
   /// AnalyzeFormalArguments - Analyze an ISD::FORMAL_ARGUMENTS node,
   /// incorporating info about the formals into this state.
   void AnalyzeFormalArguments(SDNode *TheArgs, CCAssignFn Fn);
-  
+
   /// AnalyzeReturn - Analyze the returned values of an ISD::RET node,
   /// incorporating info about the result values into this state.
   void AnalyzeReturn(SDNode *TheRet, CCAssignFn Fn);
-  
+
   /// AnalyzeCallOperands - Analyze an ISD::CALL node, incorporating info
   /// about the passed values into this state.
   void AnalyzeCallOperands(CallSDNode *TheCall, CCAssignFn Fn);
@@ -186,7 +191,7 @@
   /// AnalyzeCallResult - Analyze the return values of an ISD::CALL node,
   /// incorporating info about the passed values into this state.
   void AnalyzeCallResult(CallSDNode *TheCall, CCAssignFn Fn);
-  
+
   /// AnalyzeCallResult - Same as above except it's specialized for calls which
   /// produce a single value.
   void AnalyzeCallResult(MVT VT, CCAssignFn Fn);
@@ -199,7 +204,7 @@
         return i;
     return NumRegs;
   }
-  
+
   /// AllocateReg - Attempt to allocate one register.  If it is not available,
   /// return zero.  Otherwise, return the register, marking it and any aliases
   /// as allocated.

Modified: llvm/branches/Apple/Bender-SWB/include/llvm/Target/TargetCallingConv.td
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Bender-SWB/include/llvm/Target/TargetCallingConv.td?rev=78238&r1=78237&r2=78238&view=diff

==============================================================================
--- llvm/branches/Apple/Bender-SWB/include/llvm/Target/TargetCallingConv.td (original)
+++ llvm/branches/Apple/Bender-SWB/include/llvm/Target/TargetCallingConv.td Wed Aug  5 15:16:25 2009
@@ -101,6 +101,12 @@
   ValueType DestTy = destTy;
 }
 
+/// CCPassIndirect - If applied, this stores the value to stack and passes the pointer
+/// as normal argument.
+class CCPassIndirect<ValueType destTy> : CCAction {
+  ValueType DestTy = destTy;
+}
+
 /// CCDelegateTo - This action invokes the specified sub-calling-convention.  It
 /// is successful if the specified CC matches.
 class CCDelegateTo<CallingConv cc> : CCAction {

Modified: llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86CallingConv.td
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86CallingConv.td?rev=78238&r1=78237&r2=78238&view=diff

==============================================================================
--- llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86CallingConv.td (original)
+++ llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86CallingConv.td Wed Aug  5 15:16:25 2009
@@ -89,7 +89,7 @@
 // X86-Win64 C return-value convention.
 def RetCC_X86_Win64_C : CallingConv<[
   // The X86-Win64 calling convention always returns __m64 values in RAX.
-  CCIfType<[v8i8, v4i16, v2i32, v1i64], CCAssignToReg<[RAX]>>,
+  CCIfType<[v8i8, v4i16, v2i32, v1i64], CCBitConvertToType<i64>>,
 
   // And FP in XMM0 only.
   CCIfType<[f32], CCAssignToReg<[XMM0]>>,
@@ -137,26 +137,26 @@
   // The 'nest' parameter, if any, is passed in R10.
   CCIfNest<CCAssignToReg<[R10]>>,
 
+  // The first 6 v1i64 vector arguments are passed in GPRs on Darwin.
+  CCIfType<[v1i64],
+            CCIfSubtarget<"isTargetDarwin()",
+            CCBitConvertToType<i64>>>,
+
   // The first 6 integer arguments are passed in integer registers.
   CCIfType<[i32], CCAssignToReg<[EDI, ESI, EDX, ECX, R8D, R9D]>>,
   CCIfType<[i64], CCAssignToReg<[RDI, RSI, RDX, RCX, R8 , R9 ]>>,
-  
-  // The first 8 FP/Vector arguments are passed in XMM registers.
-  CCIfType<[f32, f64, v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],
-            CCIfSubtarget<"hasSSE1()",
-            CCAssignToReg<[XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7]>>>,
 
   // The first 8 MMX (except for v1i64) vector arguments are passed in XMM
   // registers on Darwin.
   CCIfType<[v8i8, v4i16, v2i32, v2f32],
             CCIfSubtarget<"isTargetDarwin()",
             CCIfSubtarget<"hasSSE2()",
-            CCAssignToReg<[XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7]>>>>,
+            CCPromoteToType<v2i64>>>>,
 
-  // The first 8 v1i64 vector arguments are passed in GPRs on Darwin.
-  CCIfType<[v1i64],
-            CCIfSubtarget<"isTargetDarwin()",
-            CCAssignToReg<[RDI, RSI, RDX, RCX, R8]>>>,
+  // The first 8 FP/Vector arguments are passed in XMM registers.
+  CCIfType<[f32, f64, v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],
+            CCIfSubtarget<"hasSSE1()",
+            CCAssignToReg<[XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7]>>>,
  
   // Integer/FP values get stored in stack slots that are 8 bytes in size and
   // 8-byte aligned if there are no more registers to hold them.
@@ -184,6 +184,13 @@
   // The 'nest' parameter, if any, is passed in R10.
   CCIfNest<CCAssignToReg<[R10]>>,
 
+  // 128 bit vectors are passed by pointer
+  CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], CCPassIndirect<i64>>,
+
+  // The first 4 MMX vector arguments are passed in GPRs.
+  CCIfType<[v8i8, v4i16, v2i32, v1i64, v2f32],
+           CCBitConvertToType<i64>>,
+
   // The first 4 integer arguments are passed in integer registers.
   CCIfType<[i32], CCAssignToRegWithShadow<[ECX , EDX , R8D , R9D ],
                                           [XMM0, XMM1, XMM2, XMM3]>>,
@@ -195,24 +202,16 @@
            CCAssignToRegWithShadow<[XMM0, XMM1, XMM2, XMM3],
                                    [RCX , RDX , R8  , R9  ]>>,
 
-  // The first 4 MMX vector arguments are passed in GPRs.
-  CCIfType<[v8i8, v4i16, v2i32, v1i64, v2f32],
-           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.
-  CCIfType<[i32, i64, f32, f64], CCAssignToStack<8, 16>>,
+  // 8-byte aligned if there are no more registers to hold them.
+  CCIfType<[i32, i64, f32, f64], CCAssignToStack<8, 8>>,
 
   // Long doubles get stack slots whose size and alignment depends on the
   // subtarget.
   CCIfType<[f80], CCAssignToStack<0, 0>>,
 
-  // Vectors get 16-byte stack slots that are 16-byte aligned.
-  CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], CCAssignToStack<16, 16>>,
-
-  // __m64 vectors get 8-byte stack slots that are 16-byte aligned.
-  CCIfType<[v8i8, v4i16, v2i32, v1i64], CCAssignToStack<8, 16>>
+  // __m64 vectors get 8-byte stack slots that are 8-byte aligned.
+  CCIfType<[v8i8, v4i16, v2i32, v1i64], CCAssignToStack<8, 8>>
 ]>;
 
 // Tail call convention (fast): One register is reserved for target address,

Modified: llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86CompilationCallback_Win64.asm
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86CompilationCallback_Win64.asm?rev=78238&r1=78237&r2=78238&view=diff

==============================================================================
--- llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86CompilationCallback_Win64.asm (original)
+++ llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86CompilationCallback_Win64.asm Wed Aug  5 15:16:25 2009
@@ -17,10 +17,11 @@
 X86CompilationCallback proc
     push    rbp
 
-    ; Save RSP
+    ; Save RSP.
     mov     rbp, rsp
 
     ; Save all int arg registers
+    ; WARNING: We cannot use register spill area - we're generating stubs by hands!
     push    rcx
     push    rdx
     push    r8
@@ -29,27 +30,27 @@
     ; Align stack on 16-byte boundary.
     and     rsp, -16
 
-    ; Save all XMM arg registers
-    sub     rsp, 64
-    movaps  [rsp],     xmm0
-    movaps  [rsp+16],  xmm1
-    movaps  [rsp+32],  xmm2
-    movaps  [rsp+48],  xmm3
+    ; Save all XMM arg registers. Also allocate reg spill area.
+    sub     rsp, 96
+    movaps  [rsp   +32],  xmm0
+    movaps  [rsp+16+32],  xmm1
+    movaps  [rsp+32+32],  xmm2
+    movaps  [rsp+48+32],  xmm3
 
     ; JIT callee
 
-    ; Pass prev frame and return address
+    ; Pass prev frame and return address.
     mov     rcx, rbp
     mov     rdx, qword ptr [rbp+8]
     call    X86CompilationCallback2
 
-    ; Restore all XMM arg registers
-    movaps  xmm3, [rsp+48]
-    movaps  xmm2, [rsp+32]
-    movaps  xmm1, [rsp+16]
-    movaps  xmm0, [rsp]
+    ; Restore all XMM arg registers.
+    movaps  xmm3, [rsp+48+32]
+    movaps  xmm2, [rsp+32+32]
+    movaps  xmm1, [rsp+16+32]
+    movaps  xmm0, [rsp   +32]
 
-    ; Restore RSP
+    ; Restore RSP.
     mov     rsp, rbp
 
     ; Restore all int arg registers
@@ -59,7 +60,7 @@
     pop     rdx
     pop     rcx
 
-    ; Restore RBP
+    ; Restore RBP.
     pop     rbp
     ret
 X86CompilationCallback endp

Modified: llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86FastISel.cpp?rev=78238&r1=78237&r2=78238&view=diff

==============================================================================
--- llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86FastISel.cpp (original)
+++ llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86FastISel.cpp Wed Aug  5 15:16:25 2009
@@ -1247,6 +1247,14 @@
       ArgVT = VA.getLocVT();
       break;
     }
+    case CCValAssign::BCvt: {
+      unsigned BC = FastEmit_r(ArgVT.getSimpleVT(), VA.getLocVT().getSimpleVT(),
+                               ISD::BIT_CONVERT, Arg);
+      assert(BC != 0 && "Failed to emit a bitcast!");
+      Arg = BC;
+      ArgVT = VA.getLocVT();
+      break;
+    }
     }
     
     if (VA.isRegLoc()) {

Modified: llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86ISelLowering.cpp?rev=78238&r1=78237&r2=78238&view=diff

==============================================================================
--- llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86ISelLowering.cpp Wed Aug  5 15:16:25 2009
@@ -1107,7 +1107,7 @@
                                    MVT::v2i64, InFlag).getValue(1);
         Val = Chain.getValue(0);
         Val = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i64,
-                          Val, DAG.getConstant(0, MVT::i64));        
+                          Val, DAG.getConstant(0, MVT::i64));
       } else {
         Chain = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(),
                                    MVT::i64, InFlag).getValue(1);
@@ -1307,6 +1307,7 @@
 
   SmallVector<SDValue, 8> ArgValues;
   unsigned LastVal = ~0U;
+  SDValue ArgValue;
   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
@@ -1328,27 +1329,13 @@
         RC = X86::FR64RegisterClass;
       else if (RegVT.isVector() && RegVT.getSizeInBits() == 128)
         RC = X86::VR128RegisterClass;
-      else if (RegVT.isVector()) {
-        assert(RegVT.getSizeInBits() == 64);
-        if (!Is64Bit)
-          RC = X86::VR64RegisterClass;     // MMX values are passed in MMXs.
-        else {
-          // Darwin calling convention passes MMX values in either GPRs or
-          // XMMs in x86-64. Other targets pass them in memory.
-          if (RegVT != MVT::v1i64 && Subtarget->hasSSE2()) {
-            RC = X86::VR128RegisterClass;  // MMX values are passed in XMMs.
-            RegVT = MVT::v2i64;
-          } else {
-            RC = X86::GR64RegisterClass;   // v1i64 values are passed in GPRs.
-            RegVT = MVT::i64;
-          }
-        }
-      } else {
+      else if (RegVT.isVector() && RegVT.getSizeInBits() == 64)
+        RC = X86::VR64RegisterClass;
+      else
         assert(0 && "Unknown argument type!");
-      }
 
       unsigned Reg = DAG.getMachineFunction().addLiveIn(VA.getLocReg(), RC);
-      SDValue ArgValue = DAG.getCopyFromReg(Root, dl, Reg, RegVT);
+      ArgValue = DAG.getCopyFromReg(Root, dl, Reg, RegVT);
 
       // 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
@@ -1359,26 +1346,28 @@
       else if (VA.getLocInfo() == CCValAssign::ZExt)
         ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue,
                                DAG.getValueType(VA.getValVT()));
+      else if (VA.getLocInfo() == CCValAssign::BCvt)
+        ArgValue = DAG.getNode(ISD::BIT_CONVERT, dl, VA.getValVT(), ArgValue);
 
-      if (VA.getLocInfo() != CCValAssign::Full)
-        ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue);
-
-      // Handle MMX values passed in GPRs.
-      if (Is64Bit && RegVT != VA.getLocVT()) {
-        if (RegVT.getSizeInBits() == 64 && RC == X86::GR64RegisterClass)
-          ArgValue = DAG.getNode(ISD::BIT_CONVERT, dl, VA.getLocVT(), ArgValue);
-        else if (RC == X86::VR128RegisterClass) {
+      if (VA.isExtInLoc()) {
+        // Handle MMX values passed in XMM regs.
+        if (RegVT.isVector()) {
           ArgValue = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i64,
                                  ArgValue, DAG.getConstant(0, MVT::i64));
-          ArgValue = DAG.getNode(ISD::BIT_CONVERT, dl, VA.getLocVT(), ArgValue);
-        }
+          ArgValue = DAG.getNode(ISD::BIT_CONVERT, dl, VA.getValVT(), ArgValue);
+        } else
+          ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue);
       }
-
-      ArgValues.push_back(ArgValue);
     } else {
       assert(VA.isMemLoc());
-      ArgValues.push_back(LowerMemArgument(Op, DAG, VA, MFI, CC, Root, i));
+      ArgValue = LowerMemArgument(Op, DAG, VA, MFI, CC, Root, i);
     }
+
+    // If value is passed via pointer - do a load.
+    if (VA.getLocInfo() == CCValAssign::Indirect)
+      ArgValue = DAG.getLoad(VA.getValVT(), dl, Root, ArgValue, NULL, 0);
+
+    ArgValues.push_back(ArgValue);
   }
 
   // The x86-64 ABI for returning structs by value requires that we copy
@@ -1527,8 +1516,9 @@
                                     const CCValAssign &VA,
                                     SDValue Chain,
                                     SDValue Arg, ISD::ArgFlagsTy Flags) {
+  const unsigned FirstStackArgOffset = (Subtarget->isTargetWin64() ? 32 : 0);
   DebugLoc dl = TheCall->getDebugLoc();
-  unsigned LocMemOffset = VA.getLocMemOffset();
+  unsigned LocMemOffset = FirstStackArgOffset + VA.getLocMemOffset();
   SDValue PtrOff = DAG.getIntPtrConstant(LocMemOffset);
   PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(), StackPtr, PtrOff);
   if (Flags.isByVal()) {
@@ -1632,6 +1622,7 @@
   // of tail call optimization arguments are handle later.
   for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
     CCValAssign &VA = ArgLocs[i];
+    MVT RegVT = VA.getLocVT();
     SDValue Arg = TheCall->getArg(i);
     ISD::ArgFlagsTy Flags = TheCall->getArgFlags(i);
     bool isByVal = Flags.isByVal();
@@ -1641,39 +1632,35 @@
     default: assert(0 && "Unknown loc info!");
     case CCValAssign::Full: break;
     case CCValAssign::SExt:
-      Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
+      Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, RegVT, Arg);
       break;
     case CCValAssign::ZExt:
-      Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
+      Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, RegVT, Arg);
       break;
     case CCValAssign::AExt:
-      Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg);
+      if (RegVT.isVector() && RegVT.getSizeInBits() == 128) {
+        // Special case: passing MMX values in XMM registers.
+        Arg = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i64, Arg);
+        Arg = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, MVT::v2i64, Arg);
+        Arg = getMOVL(DAG, dl, MVT::v2i64, DAG.getUNDEF(MVT::v2i64), Arg);
+      } else
+        Arg = DAG.getNode(ISD::ANY_EXTEND, dl, RegVT, Arg);
+      break;
+    case CCValAssign::BCvt:
+      Arg = DAG.getNode(ISD::BIT_CONVERT, dl, RegVT, Arg);
+      break;
+    case CCValAssign::Indirect: {
+      // Store the argument.
+      SDValue SpillSlot = DAG.CreateStackTemporary(VA.getValVT());
+      int FI = cast<FrameIndexSDNode>(SpillSlot)->getIndex();
+      Chain = DAG.getStore(Chain, dl, Arg, SpillSlot,
+                           PseudoSourceValue::getFixedStack(FI), 0);
+      Arg = SpillSlot;
       break;
     }
+    }
 
     if (VA.isRegLoc()) {
-      if (Is64Bit) {
-        MVT RegVT = VA.getLocVT();
-        if (RegVT.isVector() && RegVT.getSizeInBits() == 64)
-          switch (VA.getLocReg()) {
-          default:
-            break;
-          case X86::RDI: case X86::RSI: case X86::RDX: case X86::RCX:
-          case X86::R8: {
-            // Special case: passing MMX values in GPR registers.
-            Arg = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i64, Arg);
-            break;
-          }
-          case X86::XMM0: case X86::XMM1: case X86::XMM2: case X86::XMM3:
-          case X86::XMM4: case X86::XMM5: case X86::XMM6: case X86::XMM7: {
-            // Special case: passing MMX values in XMM registers.
-            Arg = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i64, Arg);
-            Arg = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, MVT::v2i64, Arg);
-            Arg = getMOVL(DAG, dl, MVT::v2i64, DAG.getUNDEF(MVT::v2i64), Arg);
-            break;
-          }
-          }
-      }
       RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
     } else {
       if (!IsTailCall || (IsTailCall && isByVal)) {

Modified: llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86Instr64bit.td
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86Instr64bit.td?rev=78238&r1=78237&r2=78238&view=diff

==============================================================================
--- llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86Instr64bit.td (original)
+++ llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86Instr64bit.td Wed Aug  5 15:16:25 2009
@@ -116,13 +116,37 @@
     def CALL64pcrel32 : Ii32<0xE8, RawFrm,
                           (outs), (ins i64i32imm:$dst, variable_ops),
                           "call\t${dst:call}", []>,
-                        Requires<[In64BitMode]>;
+                        Requires<[In64BitMode, NotWin64]>;
     def CALL64r       : I<0xFF, MRM2r, (outs), (ins GR64:$dst, variable_ops),
-                          "call\t{*}$dst", [(X86call GR64:$dst)]>;
+                          "call\t{*}$dst", [(X86call GR64:$dst)]>,
+                        Requires<[NotWin64]>;
     def CALL64m       : I<0xFF, MRM2m, (outs), (ins i64mem:$dst, variable_ops),
-                          "call\t{*}$dst", [(X86call (loadi64 addr:$dst))]>;
+                          "call\t{*}$dst", [(X86call (loadi64 addr:$dst))]>,
+                        Requires<[NotWin64]>;
   }
 
+  // FIXME: We need to teach codegen about single list of call-clobbered registers.
+let isCall = 1 in
+  // All calls clobber the non-callee saved registers. RSP is marked as
+  // a use to prevent stack-pointer assignments that appear immediately
+  // before calls from potentially appearing dead. Uses for argument
+  // registers are added manually.
+  let Defs = [RAX, RCX, RDX, R8, R9, R10, R11,
+              FP0, FP1, FP2, FP3, FP4, FP5, FP6, ST0, ST1,
+              MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7,
+              XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, EFLAGS],
+      Uses = [RSP] in {
+    def WINCALL64pcrel32 : I<0xE8, RawFrm,
+                             (outs), (ins i64i32imm:$dst, variable_ops),
+                             "call\t${dst:call}", [(X86call imm:$dst)]>,
+                           Requires<[IsWin64]>;
+    def WINCALL64r       : I<0xFF, MRM2r, (outs), (ins GR64:$dst, variable_ops),
+                             "call\t{*}$dst",
+                             [(X86call GR64:$dst)]>, Requires<[IsWin64]>;
+    def WINCALL64m       : I<0xFF, MRM2m, (outs), (ins i64mem:$dst, variable_ops),
+                             "call\t{*}$dst",
+                             [(X86call (loadi64 addr:$dst))]>, Requires<[IsWin64]>;
+  }
 
 
 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
@@ -1444,9 +1468,14 @@
 // Direct PC relative function call for small code model. 32-bit displacement
 // sign extended to 64-bit.
 def : Pat<(X86call (i64 tglobaladdr:$dst)),
-          (CALL64pcrel32 tglobaladdr:$dst)>;
+          (CALL64pcrel32 tglobaladdr:$dst)>, Requires<[NotWin64]>;
 def : Pat<(X86call (i64 texternalsym:$dst)),
-          (CALL64pcrel32 texternalsym:$dst)>;
+          (CALL64pcrel32 texternalsym:$dst)>, Requires<[NotWin64]>;
+
+def : Pat<(X86call (i64 tglobaladdr:$dst)),
+          (WINCALL64pcrel32 tglobaladdr:$dst)>, Requires<[IsWin64]>;
+def : Pat<(X86call (i64 texternalsym:$dst)),
+          (WINCALL64pcrel32 texternalsym:$dst)>, Requires<[IsWin64]>;
 
 def : Pat<(X86tailcall (i64 tglobaladdr:$dst)),
           (CALL64pcrel32 tglobaladdr:$dst)>;

Modified: llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86InstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86InstrInfo.td?rev=78238&r1=78237&r2=78238&view=diff

==============================================================================
--- llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86InstrInfo.td (original)
+++ llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86InstrInfo.td Wed Aug  5 15:16:25 2009
@@ -232,6 +232,8 @@
 def FPStackf64   : Predicate<"!Subtarget->hasSSE2()">;
 def In32BitMode  : Predicate<"!Subtarget->is64Bit()">;
 def In64BitMode  : Predicate<"Subtarget->is64Bit()">;
+def IsWin64      : Predicate<"Subtarget->isTargetWin64()">;
+def NotWin64     : Predicate<"!Subtarget->isTargetWin64()">;
 def SmallCode    : Predicate<"TM.getCodeModel() == CodeModel::Small">;
 def NotSmallCode : Predicate<"TM.getCodeModel() != CodeModel::Small">;
 def IsStatic     : Predicate<"TM.getRelocationModel() == Reloc::Static">;

Modified: llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86InstrMMX.td
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86InstrMMX.td?rev=78238&r1=78237&r2=78238&view=diff

==============================================================================
--- llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86InstrMMX.td (original)
+++ llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86InstrMMX.td Wed Aug  5 15:16:25 2009
@@ -164,9 +164,15 @@
                              []>;
 
 let neverHasSideEffects = 1 in
-def MMX_MOVD64from64rr : MMXRI<0x7E, MRMSrcReg,
+// These are 64 bit moves, but since the OS X assembler doesn't
+// recognize a register-register movq, we write them as
+// movd.
+def MMX_MOVD64from64rr : MMXRI<0x7E, MRMDestReg,
                                (outs GR64:$dst), (ins VR64:$src),
                                "movd\t{$src, $dst|$dst, $src}", []>;
+def MMX_MOVD64rrv164 : MMXI<0x6E, MRMSrcReg, (outs VR64:$dst), (ins GR64:$src),
+                            "movd\t{$src, $dst|$dst, $src}",
+                            [(set VR64:$dst, (v1i64 (scalar_to_vector GR64:$src)))]>;
 
 let neverHasSideEffects = 1 in
 def MMX_MOVQ64rr : MMXI<0x6F, MRMSrcReg, (outs VR64:$dst), (ins VR64:$src),

Modified: llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86RegisterInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86RegisterInfo.cpp?rev=78238&r1=78237&r2=78238&view=diff

==============================================================================
--- llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86RegisterInfo.cpp (original)
+++ llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86RegisterInfo.cpp Wed Aug  5 15:16:25 2009
@@ -347,15 +347,18 @@
 
 int
 X86RegisterInfo::getFrameIndexOffset(MachineFunction &MF, int FI) const {
-  int Offset = MF.getFrameInfo()->getObjectOffset(FI) + SlotSize;
-  uint64_t StackSize = MF.getFrameInfo()->getStackSize();
+  const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo();
+  MachineFrameInfo *MFI = MF.getFrameInfo();
+
+  int Offset = MFI->getObjectOffset(FI) - TFI.getOffsetOfLocalArea();
+  uint64_t StackSize = MFI->getStackSize();
 
   if (needsStackRealignment(MF)) {
     if (FI < 0)
       // Skip the saved EBP
       Offset += SlotSize;
     else {
-      unsigned Align = MF.getFrameInfo()->getObjectAlignment(FI);
+      unsigned Align = MFI->getObjectAlignment(FI);
       assert( (-(Offset + StackSize)) % Align == 0);
       Align = 0;
       return Offset + StackSize;
@@ -485,18 +488,19 @@
 void
 X86RegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
                                                       RegScavenger *RS) const {
-  MachineFrameInfo *FFI = MF.getFrameInfo();
+  MachineFrameInfo *MFI = MF.getFrameInfo();
 
   // Calculate and set max stack object alignment early, so we can decide
   // whether we will need stack realignment (and thus FP).
-  unsigned MaxAlign = std::max(FFI->getMaxAlignment(),
-                               calculateMaxStackAlignment(FFI));
+  unsigned MaxAlign = std::max(MFI->getMaxAlignment(),
+                               calculateMaxStackAlignment(MFI));
 
-  FFI->setMaxAlignment(MaxAlign);
+  MFI->setMaxAlignment(MaxAlign);
 }
 
 void
 X86RegisterInfo::processFunctionBeforeFrameFinalized(MachineFunction &MF) const{
+  MachineFrameInfo *MFI = MF.getFrameInfo();
   X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
   int32_t TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta();
   if (TailCallReturnAddrDelta < 0) {
@@ -509,18 +513,20 @@
     //     ...
     //   }
     //   [EBP]
-    MF.getFrameInfo()->
-      CreateFixedObject(-TailCallReturnAddrDelta,
-                        (-1*SlotSize)+TailCallReturnAddrDelta);
+    MFI->CreateFixedObject(-TailCallReturnAddrDelta,
+                           (-1*SlotSize)+TailCallReturnAddrDelta);
   }
+
   if (hasFP(MF)) {
     assert((TailCallReturnAddrDelta <= 0) &&
            "The Delta should always be zero or negative");
+    const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo();
     // Create a frame entry for the EBP register that must be saved.
-    int FrameIdx = MF.getFrameInfo()->CreateFixedObject(SlotSize,
-                                                        (int)SlotSize * -2+
-                                                       TailCallReturnAddrDelta);
-    assert(FrameIdx == MF.getFrameInfo()->getObjectIndexBegin() &&
+    int FrameIdx = MFI->CreateFixedObject(SlotSize,
+                                          -(int)SlotSize +
+                                          TFI.getOffsetOfLocalArea() +
+                                          TailCallReturnAddrDelta);
+    assert(FrameIdx == MFI->getObjectIndexBegin() &&
            "Slot for EBP register must be last in order to be found!");
     FrameIdx = 0;
   }
@@ -752,6 +758,11 @@
     StackSize = std::max(MinSize,
                          StackSize > 128 ? StackSize - 128 : 0);
     MFI->setStackSize(StackSize);
+  } else if (Subtarget->isTargetWin64()) {
+    // We need to always allocate 32 bytes as register spill area.
+    // FIXME: we might reuse these 32 bytes for leaf functions.
+    StackSize += 32;
+    MFI->setStackSize(StackSize);
   }
 
   // Insert stack pointer adjustment for later moving of return addr.  Only

Modified: llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86TargetMachine.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86TargetMachine.cpp?rev=78238&r1=78237&r2=78238&view=diff

==============================================================================
--- llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86TargetMachine.cpp (original)
+++ llvm/branches/Apple/Bender-SWB/lib/Target/X86/X86TargetMachine.cpp Wed Aug  5 15:16:25 2009
@@ -132,7 +132,9 @@
   : Subtarget(M, FS, is64Bit),
     DataLayout(Subtarget.getDataLayout()),
     FrameInfo(TargetFrameInfo::StackGrowsDown,
-              Subtarget.getStackAlignment(), Subtarget.is64Bit() ? -8 : -4),
+              Subtarget.getStackAlignment(),
+              (Subtarget.isTargetWin64() ? -40 :
+               (Subtarget.is64Bit() ? -8 : -4))),
     InstrInfo(*this), JITInfo(*this), TLInfo(*this) {
   DefRelocModel = getRelocationModel();
   // FIXME: Correctly select PIC model for Win64 stuff

Modified: llvm/branches/Apple/Bender-SWB/utils/TableGen/CallingConvEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Bender-SWB/utils/TableGen/CallingConvEmitter.cpp?rev=78238&r1=78237&r2=78238&view=diff

==============================================================================
--- llvm/branches/Apple/Bender-SWB/utils/TableGen/CallingConvEmitter.cpp (original)
+++ llvm/branches/Apple/Bender-SWB/utils/TableGen/CallingConvEmitter.cpp Wed Aug  5 15:16:25 2009
@@ -186,6 +186,10 @@
       Record *DestTy = Action->getValueAsDef("DestTy");
       O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n";
       O << IndentStr << "LocInfo = CCValAssign::BCvt;\n";
+    } else if (Action->isSubClassOf("CCPassIndirect")) {
+      Record *DestTy = Action->getValueAsDef("DestTy");
+      O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n";
+      O << IndentStr << "LocInfo = CCValAssign::Indirect;\n";
     } else if (Action->isSubClassOf("CCPassByVal")) {
       int Size = Action->getValueAsInt("Size");
       int Align = Action->getValueAsInt("Align");





More information about the llvm-branch-commits mailing list