[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