From 8f88cb08999187b143c6772216dd2ef18d9b7824 Mon Sep 17 00:00:00 2001 From: Anton Korobeynikov Date: Sat, 22 Mar 2008 20:37:30 +0000 Subject: [PATCH] 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 --- lib/Target/X86/X86CallingConv.td | 47 +++++++++++++++++++++++++++++- 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 70f18c57897..3206e183eb7 100644 --- a/lib/Target/X86/X86CallingConv.td +++ b/lib/Target/X86/X86CallingConv.td @@ -78,6 +78,16 @@ def RetCC_X86_64_C : CallingConv<[ CCDelegateTo ]>; +// 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 +]>; + + // 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>, + CCIfSubtarget<"isTargetWindows()", CCDelegateTo>, + + // Otherwise, drop to normal X86-64 CC CCDelegateTo ]>; @@ -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>, + + // 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 9d22fbeaaad..933c33e3d4d 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(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)