[cfe-commits] [PATCH] Win64 (esp. mingw64) stuff

NAKAMURA Takumi geek4civic at gmail.com
Fri Jan 14 00:43:53 PST 2011


Good evening guys!

I can build Win64 clang/llvm with clang selfhost.
At the first step, I disclose patches I think obvious.

Please give me any feedbacks, thank you!

* 0001-lib-Basic-Targets.cpp-Set-user_label_prefix-on-W.patch.txt

  Both mingw64 and msvc do not use prefix "_".

* 0002-lib-Basic-Targets.cpp-Fix-__declspec-on-Mingw-w6.patch.txt

  On mingw64, -D__declspec=__declspec would be required as same as mingw32.

* 0003-lib-Basic-Targets.cpp-__builtin_va_list-is-as-sa.patch.txt

  On win64, the implementation of va_list is not same as AMD64.

* 0004-lib-Sema-SemaExpr.cpp-__null-should-be-LongLongT.patch.txt

  On Win64, __null should be i64. it is neither IntTy nor LongTy with LLP64.

* 0005-lib-CodeGen-TargetInfo.cpp-Add-Win64-calling-con.patch.txt

  Win64 calling conversion is quite different from AMD64 cc.

  FIXME:
  AFAIK, mingw64-gcc has one incompatibility against Microsoft's Win64 cc,
  128-bit integer or structure would be split into two i64 similar to AMD64 cc.

...Takumi
-------------- next part --------------
From 4badc21618a16c46eb0693eba6755e3d52e7244c Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi <geek4civic at gmail.com>
Date: Mon, 6 Dec 2010 22:03:36 +0900
Subject: [PATCH 01/13] lib/Basic/Targets.cpp: Set user_label_prefix on Win64 both mingw and msvc.

---
 lib/Basic/Targets.cpp |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index 4faeac6..0552544 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -1579,6 +1579,7 @@ public:
     SizeType = UnsignedLongLong;
     PtrDiffType = SignedLongLong;
     IntPtrType = SignedLongLong;
+    this->UserLabelPrefix = "";
   }
   virtual void getTargetDefines(const LangOptions &Opts,
                                 MacroBuilder &Builder) const {
-- 
1.7.1.GIT

-------------- next part --------------
From 61a470aa3e3b9cd12491bef9a75ab08647ffb7fa Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi <geek4civic at gmail.com>
Date: Mon, 6 Dec 2010 22:03:36 +0900
Subject: [PATCH 02/13] lib/Basic/Targets.cpp: Fix __declspec() on Mingw-w64.

It should be defined as-is. Some headers would detect existence of __declspec and use one.
---
 lib/Basic/Targets.cpp |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index 0552544..2ba09a9 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -1622,7 +1622,7 @@ public:
     DefineStd(Builder, "WIN64", Opts);
     Builder.defineMacro("__MSVCRT__");
     Builder.defineMacro("__MINGW64__");
-    Builder.defineMacro("__declspec");
+    Builder.defineMacro("__declspec", "__declspec");
   }
 };
 } // end anonymous namespace
-- 
1.7.1.GIT

-------------- next part --------------
From 1b72560a040696d22c6bcec61c70390d6039d0bc Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi <geek4civic at gmail.com>
Date: Thu, 16 Dec 2010 17:16:08 +0900
Subject: [PATCH 03/13] lib/Basic/Targets.cpp: __builtin_va_list is as same on win64 mingw64!

---
 lib/Basic/Targets.cpp |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index 2ba09a9..19e7587 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -1586,6 +1586,9 @@ public:
     WindowsTargetInfo<X86_64TargetInfo>::getTargetDefines(Opts, Builder);
     Builder.defineMacro("_WIN64");
   }
+  virtual const char *getVAListDeclaration() const {
+    return "typedef char* __builtin_va_list;";
+  }
 };
 } // end anonymous namespace
 
@@ -1603,9 +1606,6 @@ public:
     Builder.defineMacro("_M_X64");
     Builder.defineMacro("_M_AMD64");
   }
-  virtual const char *getVAListDeclaration() const {
-    return "typedef char* __builtin_va_list;";
-  }
 };
 } // end anonymous namespace
 
-- 
1.7.1.GIT

-------------- next part --------------
From 88298c67cd8935bfc596a5daf3dfb68b0d39ba3e Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi <geek4civic at gmail.com>
Date: Thu, 16 Dec 2010 01:35:29 +0900
Subject: [PATCH 04/13] lib/Sema/SemaExpr.cpp: __null should be LongLongTy on LLP64 Win64.

---
 lib/Sema/SemaExpr.cpp |    9 ++++++---
 1 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 902afac..f7bbf3e 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -8575,10 +8575,13 @@ ExprResult Sema::ActOnGNUNullExpr(SourceLocation TokenLoc) {
   // The type of __null will be int or long, depending on the size of
   // pointers on the target.
   QualType Ty;
-  if (Context.Target.getPointerWidth(0) == Context.Target.getIntWidth())
-    Ty = Context.IntTy;
-  else
+  unsigned pw = Context.Target.getPointerWidth(0);
+  if (pw == Context.Target.getLongWidth())
     Ty = Context.LongTy;
+  else if (pw == Context.Target.getLongLongWidth())
+    Ty = Context.LongLongTy;
+  else
+    Ty = Context.IntTy;
 
   return Owned(new (Context) GNUNullExpr(Ty, TokenLoc));
 }
-- 
1.7.1.GIT

-------------- next part --------------
From 96f680ce556d2ebe291f1e6a566b93843b25ce32 Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi <geek4civic at gmail.com>
Date: Sat, 18 Dec 2010 11:19:41 +0900
Subject: [PATCH 05/13] lib/CodeGen/TargetInfo.cpp: Add Win64 calling conversion.

FIXME: It would be incompatible to Microsoft's in one point.
On mingw64-gcc, {i128} is expanded for args and returned as {rax, rdx}.
---
 lib/CodeGen/TargetInfo.cpp |   51 ++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 49 insertions(+), 2 deletions(-)

diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp
index 9c606f0..71fe907 100644
--- a/lib/CodeGen/TargetInfo.cpp
+++ b/lib/CodeGen/TargetInfo.cpp
@@ -859,9 +859,14 @@ public:
 };
 
 /// WinX86_64ABIInfo - The Windows X86_64 ABI information.
-class WinX86_64ABIInfo : public X86_64ABIInfo {
+class WinX86_64ABIInfo : public ABIInfo {
+
+  ABIArgInfo classify(QualType Ty) const;
+
 public:
-  WinX86_64ABIInfo(CodeGen::CodeGenTypes &CGT) : X86_64ABIInfo(CGT) {}
+  WinX86_64ABIInfo(CodeGen::CodeGenTypes &CGT) : ABIInfo(CGT) {}
+
+  virtual void computeInfo(CGFunctionInfo &FI) const;
 
   virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
                                  CodeGenFunction &CGF) const;
@@ -2063,6 +2068,48 @@ llvm::Value *X86_64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
   return ResAddr;
 }
 
+ABIArgInfo WinX86_64ABIInfo::classify(QualType Ty) const {
+
+  if (Ty->isVoidType())
+    return ABIArgInfo::getIgnore();
+
+  if (const EnumType *EnumTy = Ty->getAs<EnumType>())
+    Ty = EnumTy->getDecl()->getIntegerType();
+
+  uint64_t Size = getContext().getTypeSize(Ty);
+
+  if (const RecordType *RT = Ty->getAs<RecordType>()) {
+    if (hasNonTrivialDestructorOrCopyConstructor(RT)
+        || RT->getDecl()->hasFlexibleArrayMember())
+      return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
+
+    // FIXME: mingw64-gcc emits 128-bit struct as i128
+    if (Size <= 128
+        && (Size & (Size - 1)) == 0)
+      return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(),
+                                                          Size));
+
+    return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
+  }
+
+  if (Ty->isPromotableIntegerType())
+    return ABIArgInfo::getExtend();
+
+  return ABIArgInfo::getDirect();
+}
+
+void WinX86_64ABIInfo::computeInfo(CGFunctionInfo &FI) const {
+
+  QualType RetTy = FI.getReturnType();
+  FI.getReturnInfo() = classify(RetTy);
+
+  // AMD64-ABI 3.2.3p3: Once arguments are classified, the registers
+  // get assigned (in left-to-right order) for passing as follows...
+  for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
+       it != ie; ++it)
+    it->info = classify(it->type);
+}
+
 llvm::Value *WinX86_64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
                                       CodeGenFunction &CGF) const {
   const llvm::Type *BP = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
-- 
1.7.1.GIT



More information about the cfe-commits mailing list