diff options
author | Anton Korobeynikov <asl@math.spbu.ru> | 2008-03-22 20:37:30 +0000 |
---|---|---|
committer | Anton Korobeynikov <asl@math.spbu.ru> | 2008-03-22 20:37:30 +0000 |
commit | 8f88cb08999187b143c6772216dd2ef18d9b7824 (patch) | |
tree | f36c86274c594eca7d84137ef81077dc1d2bc6ca | |
parent | 299d9d74e9b010c499557380fb6467f5361e141a (diff) | |
download | external_llvm-8f88cb08999187b143c6772216dd2ef18d9b7824.zip external_llvm-8f88cb08999187b143c6772216dd2ef18d9b7824.tar.gz external_llvm-8f88cb08999187b143c6772216dd2ef18d9b7824.tar.bz2 |
Initial support for Win64 calling conventions. Still in early state.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48690 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/X86/X86CallingConv.td | 47 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelLowering.cpp | 12 |
2 files changed, 54 insertions, 5 deletions
diff --git a/lib/Target/X86/X86CallingConv.td b/lib/Target/X86/X86CallingConv.td index 70f18c5..3206e18 100644 --- a/lib/Target/X86/X86CallingConv.td +++ b/lib/Target/X86/X86CallingConv.td @@ -78,6 +78,16 @@ def RetCC_X86_64_C : CallingConv<[ CCDelegateTo<RetCC_X86Common> ]>; +// 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]>>, + + // Otherwise, everything is the same as 'norma' X86-64 C CC + CCDelegateTo<RetCC_X86_64_C> +]>; + + // This is the root return-value convention for the X86-32 backend. def RetCC_X86_32 : CallingConv<[ // If FastCC, use RetCC_X86_32_Fast. @@ -90,7 +100,11 @@ def RetCC_X86_32 : CallingConv<[ // This is the root return-value convention for the X86-64 backend. def RetCC_X86_64 : CallingConv<[ - // Always just the same as C calling conv for X86-64. + // Mingw64 and native Win64 use Win64 CC + CCIfSubtarget<"isTargetMingw()", CCDelegateTo<RetCC_X86_Win64_C>>, + CCIfSubtarget<"isTargetWindows()", CCDelegateTo<RetCC_X86_Win64_C>>, + + // Otherwise, drop to normal X86-64 CC CCDelegateTo<RetCC_X86_64_C> ]>; @@ -141,6 +155,37 @@ def CC_X86_64_C : CallingConv<[ CCIfType<[v8i8, v4i16, v2i32, v1i64], CCAssignToStack<8, 8>> ]>; +// Calling convention used on Win64 +def CC_X86_Win64_C : CallingConv<[ + // FIXME: Handle byval stuff + // FIXME: Handle fp80 + // FIXME: Handle shadowed arguments + + // Promote i8/i16 arguments to i32. + CCIfType<[i8, i16], CCPromoteToType<i32>>, + + // The first 4 integer arguments are passed in integer registers. + CCIfType<[i32], CCAssignToReg<[ECX, EDX, R8D, R9D]>>, + CCIfType<[i64], CCAssignToReg<[RCX, RDX, R8 , R9 ]>>, + + // 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]>>, + + // The first 4 MMX vector arguments are passed in GPRs. + CCIfType<[v8i8, v4i16, v2i32, v1i64], CCAssignToReg<[RCX, RDX, R8, R9]>>, + + // 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>>, + + // 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>> +]>; + // Tail call convention (fast): One register is reserved for target address, // namely R9 def CC_X86_64_TailCall : CallingConv<[ diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 9d22fbe..933c33e 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -1009,10 +1009,14 @@ CCAssignFn *X86TargetLowering::CCAssignFnForNode(SDOperand Op) const { unsigned CC = cast<ConstantSDNode>(Op.getOperand(1))->getValue(); if (Subtarget->is64Bit()) { - if (CC == CallingConv::Fast && PerformTailCallOpt) - return CC_X86_64_TailCall; - else - return CC_X86_64_C; + if (Subtarget->isTargetWindows() || Subtarget->isTargetMingw()) + return CC_X86_Win64_C; + else { + if (CC == CallingConv::Fast && PerformTailCallOpt) + return CC_X86_64_TailCall; + else + return CC_X86_64_C; + } } if (CC == CallingConv::X86_FastCall) |