[llvmlinux] [PATCH 1/2] [mips] Replace named register fix with an upstreamable version.

Daniel Sanders daniel.sanders at imgtec.com
Fri Jan 9 14:20:21 UTC 2015


Also include the necessary LLVM patch which was previously omitted.

---

I've submitted the kernel patch upstream.

 ...REAM-mips-Remove-all-instances-of-explici.patch | 426 ---------------------
 ...-current_thread_info-to-an-equivalent-sup.patch |  50 +++
 arch/mips/patches/series                           |   3 +-
 .../clang/patches/llvm/mips-named-registers.patch  |  39 ++
 toolchain/clang/patches/llvm/series                |   1 +
 5 files changed, 91 insertions(+), 428 deletions(-)
 delete mode 100644 arch/mips/patches/mips-DO-NOT-UPSTREAM-mips-Remove-all-instances-of-explici.patch
 create mode 100644 arch/mips/patches/mips-change-current_thread_info-to-an-equivalent-sup.patch
 create mode 100644 toolchain/clang/patches/llvm/mips-named-registers.patch

diff --git a/arch/mips/patches/mips-DO-NOT-UPSTREAM-mips-Remove-all-instances-of-explici.patch b/arch/mips/patches/mips-DO-NOT-UPSTREAM-mips-Remove-all-instances-of-explici.patch
deleted file mode 100644
index c661a8a..0000000
--- a/arch/mips/patches/mips-DO-NOT-UPSTREAM-mips-Remove-all-instances-of-explici.patch
+++ /dev/null
@@ -1,426 +0,0 @@
-From f7d74e066df8cd92e5c310d2354e84e5e26c2dff Mon Sep 17 00:00:00 2001
-From: Daniel Sanders <daniel.sanders at imgtec.com>
-Date: Fri, 19 Dec 2014 13:48:39 +0000
-Subject: [PATCH 2/2] [DO-NOT-UPSTREAM][mips] Remove all instances of explicit
- register variables from the mips arch.
-
-Clang accepts the syntax but does not honour them. I've asked a colleague to
-look into supporting explicit register variables in clang. For now, remove the
-uses of this feature and accept the unnecessary moves.
-
-Signed-off-by: Daniel Sanders <daniel.sanders at imgtec.com>
----
- .../mips-remove-explicit-register-variables.patch  | 391 +++++++++++++++++++++
- arch/mips/patches/series                           |   1 +
- 2 files changed, 392 insertions(+)
- create mode 100644 arch/mips/patches/mips-remove-explicit-register-variables.patch
-
-diff --git a/arch/mips/patches/mips-remove-explicit-register-variables.patch b/arch/mips/patches/mips-remove-explicit-register-variables.patch
-new file mode 100644
-index 0000000..320831a
---- /dev/null
-+++ b/arch/mips/patches/mips-remove-explicit-register-variables.patch
-@@ -0,0 +1,391 @@
-+From 437530253edbf21d60e98259096a532a90579b8d Mon Sep 17 00:00:00 2001
-+From: Daniel Sanders <daniel.sanders at imgtec.com>
-+Date: Fri, 19 Dec 2014 13:44:48 +0000
-+Subject: [PATCH 2/2] [DO-NOT-UPSTREAM][mips] Remove all instances of explicit
-+ register variables from the mips arch.
-+
-+Clang accepts the syntax but does not honour them. I've asked a colleague to
-+look into supporting explicit register variables in clang. For now, remove the
-+uses of this feature and accept the unnecessary moves.
-+
-+Signed-off-by: Daniel Sanders <daniel.sanders at imgtec.com>
-+---
-+ arch/mips/include/asm/kvm_para.h    | 34 ++++++++++-----
-+ arch/mips/include/asm/sgiarcs.h     | 42 ++++++++++++------
-+ arch/mips/include/asm/thread_info.h |  4 +-
-+ arch/mips/include/asm/uaccess.h     | 85 ++++++++++++++++++++++---------------
-+ arch/mips/lib/uncached.c            |  5 ++-
-+ 5 files changed, 108 insertions(+), 62 deletions(-)
-+
-+diff --git a/arch/mips/include/asm/kvm_para.h b/arch/mips/include/asm/kvm_para.h
-+index 5a9aa91..b8e987c 100644
-+--- a/arch/mips/include/asm/kvm_para.h
-++++ b/arch/mips/include/asm/kvm_para.h
-+@@ -14,12 +14,14 @@
-+  */
-+ static inline unsigned long kvm_hypercall0(unsigned long num)
-+ {
-+-	register unsigned long n asm("v0");
-+-	register unsigned long r asm("v0");
-++	register unsigned long n;
-++	register unsigned long r;
-+ 
-+ 	n = num;
-+ 	__asm__ __volatile__(
-++                "move $v0,%1\n\t"
-+ 		KVM_HYPERCALL
-++                "move %0,$v0\n\t"
-+ 		: "=r" (r) : "r" (n) : "memory"
-+ 		);
-+ 
-+@@ -29,14 +31,17 @@ static inline unsigned long kvm_hypercall0(unsigned long num)
-+ static inline unsigned long kvm_hypercall1(unsigned long num,
-+ 					unsigned long arg0)
-+ {
-+-	register unsigned long n asm("v0");
-+-	register unsigned long r asm("v0");
-+-	register unsigned long a0 asm("a0");
-++	register unsigned long n;
-++	register unsigned long r;
-++	register unsigned long a0;
-+ 
-+ 	n = num;
-+ 	a0 = arg0;
-+ 	__asm__ __volatile__(
-++                "move $v0,%1\n\t"
-++                "move $a0,%2\n\t"
-+ 		KVM_HYPERCALL
-++                "move %0,$v0\n\t"
-+ 		: "=r" (r) : "r" (n), "r" (a0) : "memory"
-+ 		);
-+ 
-+@@ -55,7 +60,11 @@ static inline unsigned long kvm_hypercall2(unsigned long num,
-+ 	a0 = arg0;
-+ 	a1 = arg1;
-+ 	__asm__ __volatile__(
-++                "move $v0,%1\n\t"
-++                "move $a0,%2\n\t"
-++                "move $a1,%3\n\t"
-+ 		KVM_HYPERCALL
-++                "move $v0,%0\n\t"
-+ 		: "=r" (r) : "r" (n), "r" (a0), "r" (a1) : "memory"
-+ 		);
-+ 
-+@@ -65,18 +74,23 @@ static inline unsigned long kvm_hypercall2(unsigned long num,
-+ static inline unsigned long kvm_hypercall3(unsigned long num,
-+ 	unsigned long arg0, unsigned long arg1, unsigned long arg2)
-+ {
-+-	register unsigned long n asm("v0");
-+-	register unsigned long r asm("v0");
-+-	register unsigned long a0 asm("a0");
-+-	register unsigned long a1 asm("a1");
-+-	register unsigned long a2 asm("a2");
-++	register unsigned long n;
-++	register unsigned long r;
-++	register unsigned long a0;
-++	register unsigned long a1;
-++	register unsigned long a2;
-+ 
-+ 	n = num;
-+ 	a0 = arg0;
-+ 	a1 = arg1;
-+ 	a2 = arg2;
-+ 	__asm__ __volatile__(
-++                "move $v0,%1\n\t"
-++                "move $a0,%2\n\t"
-++                "move $a1,%3\n\t"
-++                "move $a2,%4\n\t"
-+ 		KVM_HYPERCALL
-++                "move $v0,%0\n\t"
-+ 		: "=r" (r) : "r" (n), "r" (a0), "r" (a1), "r" (a2) : "memory"
-+ 		);
-+ 
-+diff --git a/arch/mips/include/asm/sgiarcs.h b/arch/mips/include/asm/sgiarcs.h
-+index 26ddfff..a62c267 100644
-+--- a/arch/mips/include/asm/sgiarcs.h
-++++ b/arch/mips/include/asm/sgiarcs.h
-+@@ -388,9 +388,10 @@ struct linux_smonblock {
-+ 
-+ #define ARC_CALL1(dest, a1)						\
-+ ({	long __res;							\
-+-	register signed int __a1 __asm__("$4") = (int) (long) (a1);	\
-++	register signed int __a1 = (int) (long) (a1);	\
-+ 	long __vec = (long) romvec->dest;				\
-+ 	__asm__ __volatile__(						\
-++        "move\t$4,%3\n\t" \
-+ 	"dsubu\t$29, 32\n\t"						\
-+ 	"jalr\t%1\n\t"							\
-+ 	"daddu\t$29, 32\n\t"						\
-+@@ -403,10 +404,12 @@ struct linux_smonblock {
-+ 
-+ #define ARC_CALL2(dest, a1, a2)						\
-+ ({	long __res;							\
-+-	register signed int __a1 __asm__("$4") = (int) (long) (a1);	\
-+-	register signed int __a2 __asm__("$5") = (int) (long) (a2);	\
-++	register signed int __a1 = (int) (long) (a1);	\
-++	register signed int __a2 = (int) (long) (a2);	\
-+ 	long __vec = (long) romvec->dest;				\
-+ 	__asm__ __volatile__(						\
-++        "move\t$4,%3\n\t" \
-++        "move\t$5,%4\n\t" \
-+ 	"dsubu\t$29, 32\n\t"						\
-+ 	"jalr\t%1\n\t"							\
-+ 	"daddu\t$29, 32\n\t"						\
-+@@ -419,11 +422,14 @@ struct linux_smonblock {
-+ 
-+ #define ARC_CALL3(dest, a1, a2, a3)					\
-+ ({	long __res;							\
-+-	register signed int __a1 __asm__("$4") = (int) (long) (a1);	\
-+-	register signed int __a2 __asm__("$5") = (int) (long) (a2);	\
-+-	register signed int __a3 __asm__("$6") = (int) (long) (a3);	\
-++	register signed int __a1 = (int) (long) (a1);	\
-++	register signed int __a2 = (int) (long) (a2);	\
-++	register signed int __a3 = (int) (long) (a3);	\
-+ 	long __vec = (long) romvec->dest;				\
-+ 	__asm__ __volatile__(						\
-++        "move\t$4,%3\n\t" \
-++        "move\t$5,%4\n\t" \
-++        "move\t$6,%5\n\t" \
-+ 	"dsubu\t$29, 32\n\t"						\
-+ 	"jalr\t%1\n\t"							\
-+ 	"daddu\t$29, 32\n\t"						\
-+@@ -436,12 +442,16 @@ struct linux_smonblock {
-+ 
-+ #define ARC_CALL4(dest, a1, a2, a3, a4)					\
-+ ({	long __res;							\
-+-	register signed int __a1 __asm__("$4") = (int) (long) (a1);	\
-+-	register signed int __a2 __asm__("$5") = (int) (long) (a2);	\
-+-	register signed int __a3 __asm__("$6") = (int) (long) (a3);	\
-+-	register signed int __a4 __asm__("$7") = (int) (long) (a4);	\
-++	register signed int __a1 = (int) (long) (a1);	\
-++	register signed int __a2 = (int) (long) (a2);	\
-++	register signed int __a3 = (int) (long) (a3);	\
-++	register signed int __a4 = (int) (long) (a4);	\
-+ 	long __vec = (long) romvec->dest;				\
-+ 	__asm__ __volatile__(						\
-++        "move\t$4,%3\n\t" \
-++        "move\t$5,%4\n\t" \
-++        "move\t$6,%5\n\t" \
-++        "move\t$7,%6\n\t" \
-+ 	"dsubu\t$29, 32\n\t"						\
-+ 	"jalr\t%1\n\t"							\
-+ 	"daddu\t$29, 32\n\t"						\
-+@@ -455,13 +465,17 @@ struct linux_smonblock {
-+ 
-+ #define ARC_CALL5(dest, a1, a2, a3, a4, a5)					\
-+ ({	long __res;							\
-+-	register signed int __a1 __asm__("$4") = (int) (long) (a1);	\
-+-	register signed int __a2 __asm__("$5") = (int) (long) (a2);	\
-+-	register signed int __a3 __asm__("$6") = (int) (long) (a3);	\
-+-	register signed int __a4 __asm__("$7") = (int) (long) (a4);	\
-++	register signed int __a1 = (int) (long) (a1);	\
-++	register signed int __a2 = (int) (long) (a2);	\
-++	register signed int __a3 = (int) (long) (a3);	\
-++	register signed int __a4 = (int) (long) (a4);	\
-+ 	register signed int __a5 = (int) (long) (a5);			\
-+ 	long __vec = (long) romvec->dest;				\
-+ 	__asm__ __volatile__(						\
-++        "move\t$4,%3\n\t" \
-++        "move\t$5,%4\n\t" \
-++        "move\t$6,%5\n\t" \
-++        "move\t$7,%6\n\t" \
-+ 	"dsubu\t$29, 32\n\t"						\
-+ 	"sw\t%7, 16($29)\n\t"						\
-+ 	"jalr\t%1\n\t"							\
-+diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h
-+index 99eea59..c148256 100644
-+--- a/arch/mips/include/asm/thread_info.h
-++++ b/arch/mips/include/asm/thread_info.h
-+@@ -60,7 +60,9 @@ struct thread_info {
-+ /* How to get the thread information struct from C.  */
-+ static inline struct thread_info *current_thread_info(void)
-+ {
-+-	register struct thread_info *__current_thread_info __asm__("$28");
-++	register struct thread_info *__current_thread_info;
-++
-++        __asm__("move %0, $28": "=r"(__current_thread_info));
-+ 
-+ 	return __current_thread_info;
-+ }
-+diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h
-+index bf8b324..96698c6 100644
-+--- a/arch/mips/include/asm/uaccess.h
-++++ b/arch/mips/include/asm/uaccess.h
-+@@ -788,18 +788,21 @@ extern size_t __copy_user(void *__to, const void *__from, size_t __n);
-+ #ifndef CONFIG_EVA
-+ #define __invoke_copy_to_user(to, from, n)				\
-+ ({									\
-+-	register void __user *__cu_to_r __asm__("$4");			\
-+-	register const void *__cu_from_r __asm__("$5");			\
-+-	register long __cu_len_r __asm__("$6");				\
-++	register void __user *__cu_to_r = (to);       			\
-++	register const void *__cu_from_r = (from);      		\
-++	register long __cu_len_r = (n);        				\
-+ 									\
-+-	__cu_to_r = (to);						\
-+-	__cu_from_r = (from);						\
-+-	__cu_len_r = (n);						\
-+ 	__asm__ __volatile__(						\
-++        "move $4, %0\n\t"                                                   \
-++        "move $5, %1\n\t"                                                   \
-++        "move $6, %2\n\t"                                                   \
-+ 	__MODULE_JAL(__copy_user)					\
-++        "move %0, $4\n\t"                                                   \
-++        "move %1, $5\n\t"                                                   \
-++        "move %2, $6\n\t"                                                   \
-+ 	: "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r)	\
-+ 	:								\
-+-	: "$8", "$9", "$10", "$11", "$12", "$14", "$15", "$24", "$31",	\
-++	: "$4", "$5", "$6", "$8", "$9", "$10", "$11", "$12", "$14", "$15", "$24", "$31",	\
-+ 	  DADDI_SCRATCH, "memory");					\
-+ 	__cu_len_r;							\
-+ })
-+@@ -923,23 +926,26 @@ extern size_t __copy_user_inatomic(void *__to, const void *__from, size_t __n);
-+ 
-+ #define __invoke_copy_from_user(to, from, n)				\
-+ ({									\
-+-	register void *__cu_to_r __asm__("$4");				\
-+-	register const void __user *__cu_from_r __asm__("$5");		\
-+-	register long __cu_len_r __asm__("$6");				\
-++	register void *__cu_to_r = (to);       				\
-++	register const void __user *__cu_from_r = (from);      	        \
-++	register long __cu_len_r = (n);         			\
-+ 									\
-+-	__cu_to_r = (to);						\
-+-	__cu_from_r = (from);						\
-+-	__cu_len_r = (n);						\
-+ 	__asm__ __volatile__(						\
-+ 	".set\tnoreorder\n\t"						\
-++        "move $4, %0\n\t"                                                   \
-++        "move $5, %1\n\t"                                                   \
-++        "move $6, %2\n\t"                                                   \
-+ 	__MODULE_JAL(__copy_user)					\
-+ 	".set\tnoat\n\t"						\
-+ 	__UA_ADDU "\t$1, %1, %2\n\t"					\
-++        "move %0, $4\n\t"                                                   \
-++        "move %1, $5\n\t"                                                   \
-++        "move %2, $6\n\t"                                                   \
-+ 	".set\tat\n\t"							\
-+ 	".set\treorder"							\
-+ 	: "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r)	\
-+ 	:								\
-+-	: "$8", "$9", "$10", "$11", "$12", "$14", "$15", "$24", "$31",	\
-++	: "$4", "$5", "$6", "$8", "$9", "$10", "$11", "$12", "$14", "$15", "$24", "$31",	\
-+ 	  DADDI_SCRATCH, "memory");					\
-+ 	__cu_len_r;							\
-+ })
-+@@ -957,23 +963,26 @@ extern size_t __copy_user_inatomic(void *__to, const void *__from, size_t __n);
-+ 
-+ #define __invoke_copy_from_user_inatomic(to, from, n)			\
-+ ({									\
-+-	register void *__cu_to_r __asm__("$4");				\
-+-	register const void __user *__cu_from_r __asm__("$5");		\
-+-	register long __cu_len_r __asm__("$6");				\
-++	register void *__cu_to_r = (to);       				\
-++	register const void __user *__cu_from_r = (from);       \
-++	register long __cu_len_r = (n);           			\
-+ 									\
-+-	__cu_to_r = (to);						\
-+-	__cu_from_r = (from);						\
-+-	__cu_len_r = (n);						\
-+ 	__asm__ __volatile__(						\
-+ 	".set\tnoreorder\n\t"						\
-++        "move $4, %0\n\t"                                                   \
-++        "move $5, %1\n\t"                                                   \
-++        "move $6, %2\n\t"                                                   \
-+ 	__MODULE_JAL(__copy_user_inatomic)				\
-+ 	".set\tnoat\n\t"						\
-+ 	__UA_ADDU "\t$1, %1, %2\n\t"					\
-++        "move %0, $4\n\t"                                                   \
-++        "move %1, $5\n\t"                                                   \
-++        "move %2, $6\n\t"                                                   \
-+ 	".set\tat\n\t"							\
-+ 	".set\treorder"							\
-+ 	: "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r)	\
-+ 	:								\
-+-	: "$8", "$9", "$10", "$11", "$12", "$14", "$15", "$24", "$31",	\
-++	: "$4", "$5", "$6", "$8", "$9", "$10", "$11", "$12", "$14", "$15", "$24", "$31",	\
-+ 	  DADDI_SCRATCH, "memory");					\
-+ 	__cu_len_r;							\
-+ })
-+@@ -995,41 +1004,47 @@ extern size_t __copy_in_user_eva(void *__to, const void *__from, size_t __n);
-+ 
-+ #define __invoke_copy_from_user_eva_generic(to, from, n, func_ptr)	\
-+ ({									\
-+-	register void *__cu_to_r __asm__("$4");				\
-+-	register const void __user *__cu_from_r __asm__("$5");		\
-+-	register long __cu_len_r __asm__("$6");				\
-++	register void *__cu_to_r = (to);        			\
-++	register const void __user *__cu_from_r = (from);       \
-++	register long __cu_len_r = (n);          		\
-+ 									\
-+-	__cu_to_r = (to);						\
-+-	__cu_from_r = (from);						\
-+-	__cu_len_r = (n);						\
-+ 	__asm__ __volatile__(						\
-+ 	".set\tnoreorder\n\t"						\
-++        "move $4, %0\n\t"                                                   \
-++        "move $5, %1\n\t"                                                   \
-++        "move $6, %2\n\t"                                                   \
-+ 	__MODULE_JAL(func_ptr)						\
-+ 	".set\tnoat\n\t"						\
-+ 	__UA_ADDU "\t$1, %1, %2\n\t"					\
-++        "move %0, $4\n\t"                                                   \
-++        "move %1, $5\n\t"                                                   \
-++        "move %2, $6\n\t"                                                   \
-+ 	".set\tat\n\t"							\
-+ 	".set\treorder"							\
-+ 	: "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r)	\
-+ 	:								\
-+-	: "$8", "$9", "$10", "$11", "$12", "$14", "$15", "$24", "$31",	\
-++	: "$4", "$5", "$6", "$8", "$9", "$10", "$11", "$12", "$14", "$15", "$24", "$31",	\
-+ 	  DADDI_SCRATCH, "memory");					\
-+ 	__cu_len_r;							\
-+ })
-+ 
-+ #define __invoke_copy_to_user_eva_generic(to, from, n, func_ptr)	\
-+ ({									\
-+-	register void *__cu_to_r __asm__("$4");				\
-+-	register const void __user *__cu_from_r __asm__("$5");		\
-+-	register long __cu_len_r __asm__("$6");				\
-++	register void *__cu_to_r = (to);        			\
-++	register const void __user *__cu_from_r = (from);        	\
-++	register long __cu_len_r = (n);				\
-+ 									\
-+-	__cu_to_r = (to);						\
-+-	__cu_from_r = (from);						\
-+-	__cu_len_r = (n);						\
-+ 	__asm__ __volatile__(						\
-++        "move $4, %0\n\t"                                                   \
-++        "move $5, %1\n\t"                                                   \
-++        "move $6, %2\n\t"                                                   \
-+ 	__MODULE_JAL(func_ptr)						\
-++        "move %0, $4\n\t"                                                   \
-++        "move %1, $5\n\t"                                                   \
-++        "move %2, $6\n\t"                                                   \
-+ 	: "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r)	\
-+ 	:								\
-+-	: "$8", "$9", "$10", "$11", "$12", "$14", "$15", "$24", "$31",	\
-++	: "$4", "$5", "$6", "$8", "$9", "$10", "$11", "$12", "$14", "$15", "$24", "$31",	\
-+ 	  DADDI_SCRATCH, "memory");					\
-+ 	__cu_len_r;							\
-+ })
-+diff --git a/arch/mips/lib/uncached.c b/arch/mips/lib/uncached.c
-+index 09d5dee..c520eb1 100644
-+--- a/arch/mips/lib/uncached.c
-++++ b/arch/mips/lib/uncached.c
-+@@ -37,8 +37,9 @@
-+  */
-+ unsigned long run_uncached(void *func)
-+ {
-+-	register long sp __asm__("$sp");
-+-	register long ret __asm__("$2");
-++	register long sp;
-++        __asm__ volatile ("move %0, $sp" : "=r"(sp));
-++	register long ret;
-+ 	long lfunc = (long)func, ufunc;
-+ 	long usp;
-+ 
-+-- 
-+2.1.3
-+
-diff --git a/arch/mips/patches/series b/arch/mips/patches/series
-index 1aaf96a..e219c25 100644
---- a/arch/mips/patches/series
-+++ b/arch/mips/patches/series
-@@ -2,3 +2,4 @@ mips-fix-cast-to-type-not-present-in-union.patch
- mips-fix-inline-asm-input-output-type-mismatch.patch
- mips-silence-variable-self-assignment-warnings.patch
- mips-silence-unicode-warnings.patch
-+mips-remove-explicit-register-variables.patch
--- 
-2.1.3
-
diff --git a/arch/mips/patches/mips-change-current_thread_info-to-an-equivalent-sup.patch b/arch/mips/patches/mips-change-current_thread_info-to-an-equivalent-sup.patch
new file mode 100644
index 0000000..83b17ce
--- /dev/null
+++ b/arch/mips/patches/mips-change-current_thread_info-to-an-equivalent-sup.patch
@@ -0,0 +1,50 @@
+From 3e8b879d48a805fdad49914259511d7f47b36a73 Mon Sep 17 00:00:00 2001
+From: Daniel Sanders <daniel.sanders at imgtec.com>
+Date: Fri, 9 Jan 2015 10:54:22 +0000
+Subject: [PATCH] MIPS: Changed current_thread_info() to an equivalent
+ supported by both clang and GCC
+
+Without this, a 'break' instruction is executed very early in the boot and
+the boot hangs.
+
+The problem is that clang doesn't honour named registers on local variables
+and silently treats them as normal uninitialized variables. However, it
+does honour them on global variables.
+
+Signed-off-by: Daniel Sanders <daniel.sanders at imgtec.com>
+---
+ arch/mips/include/asm/thread_info.h | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+For reference, a similar patch for ARM's stack pointer has already been merged:
+  0abc08b ARM: 8170/1: Add global named register current_stack_pointer for ARM
+
+This is part of a patch series to get Linux for Mips working when compiled with
+clang. I've chosen to submit this patch individually since it's my first kernel
+patch and I'd like to be sure I'm following your processes correctly before I
+submit all of them.
+
+Please CC me on replies since I'm not subscribed to the mailing list.
+
+diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h
+index 99eea59..2a2f3c4 100644
+--- a/arch/mips/include/asm/thread_info.h
++++ b/arch/mips/include/asm/thread_info.h
+@@ -58,11 +58,11 @@ struct thread_info {
+ #define init_stack		(init_thread_union.stack)
+ 
+ /* How to get the thread information struct from C.  */
++register struct thread_info *current_gp_register asm("$28");
++
+ static inline struct thread_info *current_thread_info(void)
+ {
+-	register struct thread_info *__current_thread_info __asm__("$28");
+-
+-	return __current_thread_info;
++	return current_gp_register;
+ }
+ 
+ #endif /* !__ASSEMBLY__ */
+-- 
+2.1.4
+
diff --git a/arch/mips/patches/series b/arch/mips/patches/series
index ad1334a..7fc1a7d 100644
--- a/arch/mips/patches/series
+++ b/arch/mips/patches/series
@@ -2,5 +2,4 @@ mips-fix-cast-to-type-not-present-in-union.patch
 mips-fix-inline-asm-input-output-type-mismatch.patch
 mips-silence-variable-self-assignment-warnings.patch
 mips-silence-unicode-warnings.patch
-mips-WIP-Fix-slab-allocator-bootstrap.patch
-mips-DO-NOT-UPSTREAM-mips-Remove-all-instances-of-explici.patch
+mips-change-current_thread_info-to-an-equivalent-sup.patch
diff --git a/toolchain/clang/patches/llvm/mips-named-registers.patch b/toolchain/clang/patches/llvm/mips-named-registers.patch
new file mode 100644
index 0000000..99d0888
--- /dev/null
+++ b/toolchain/clang/patches/llvm/mips-named-registers.patch
@@ -0,0 +1,39 @@
+--- llvm.orig/lib/Target/Mips/MipsISelLowering.cpp
++++ llvm/lib/Target/Mips/MipsISelLowering.cpp
+@@ -3836,3 +3836,25 @@
+ 
+   return BB;
+ }
++
++// FIXME? Maybe this could be a TableGen attribute on some registers and
++// this table could be generated automatically from RegInfo.
++unsigned MipsTargetLowering::getRegisterByName(const char* RegName,
++                                               EVT VT) const {
++  // Named registers is expected to be fairly rare. For now, just support $28
++  // since the linux kernel uses it.
++  if (Subtarget.isGP64bit()) {
++    unsigned Reg = StringSwitch<unsigned>(RegName)
++                         .Case("$28", Mips::GP_64)
++                         .Default(0);
++    if (Reg)
++      return Reg;
++  } else {
++    unsigned Reg = StringSwitch<unsigned>(RegName)
++                         .Case("$28", Mips::GP)
++                         .Default(0);
++    if (Reg)
++      return Reg;
++  }
++  report_fatal_error("Invalid register name global variable");
++}
+--- llvm.orig/lib/Target/Mips/MipsISelLowering.h
++++ llvm/lib/Target/Mips/MipsISelLowering.h
+@@ -262,6 +262,8 @@
+ 
+     void HandleByVal(CCState *, unsigned &, unsigned) const override;
+ 
++    unsigned getRegisterByName(const char* RegName, EVT VT) const;
++
+   protected:
+     SDValue getGlobalReg(SelectionDAG &DAG, EVT Ty) const;
+ 
diff --git a/toolchain/clang/patches/llvm/series b/toolchain/clang/patches/llvm/series
index f0b4536..b65b208 100644
--- a/toolchain/clang/patches/llvm/series
+++ b/toolchain/clang/patches/llvm/series
@@ -1 +1,2 @@
 call_graph.patch
+mips-named-registers.patch
-- 
2.1.4



More information about the LLVMLinux mailing list