aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Korobeynikov <asl@math.spbu.ru>2008-03-22 20:37:30 +0000
committerAnton Korobeynikov <asl@math.spbu.ru>2008-03-22 20:37:30 +0000
commit8f88cb08999187b143c6772216dd2ef18d9b7824 (patch)
treef36c86274c594eca7d84137ef81077dc1d2bc6ca
parent299d9d74e9b010c499557380fb6467f5361e141a (diff)
downloadexternal_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.td47
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp12
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)