From c65a2abb6c0a9ab1c70f5241716066c9480ce96a Mon Sep 17 00:00:00 2001
From: Jeroen Hofstee <jeroen@myspectrum.nl>
Date: Wed, 30 Jul 2014 21:54:52 +0200
Subject: [PATCH] ARM: make gd a function for clang

"clang does not support global register variables; this is
unlikely to be implemented soon because it requires additional
LLVM backend support" [1]

Workaround it by obtaining the value of gd/r9 by an inline
asm routine. Note there is no set routine added for ARM at the
moment, since most if not all updates of gd from c are actually
not needed for ARM.

[1] http://clang.llvm.org/docs/UsersManual.html

cc: Albert ARIBAUD <albert.u.boot@aribaud.net>
Signed-off-by: Jeroen Hofstee <jeroen@myspectrum.nl>
---
 arch/arm/include/asm/global_data.h | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h
index 63e4ad5a67..c69d0646f5 100644
--- a/arch/arm/include/asm/global_data.h
+++ b/arch/arm/include/asm/global_data.h
@@ -44,10 +44,35 @@ struct arch_global_data {
 
 #include <asm-generic/global_data.h>
 
+#ifdef __clang__
+
+#define DECLARE_GLOBAL_DATA_PTR
+#define gd	get_gd()
+
+static inline gd_t *get_gd(void)
+{
+	gd_t *gd_ptr;
+
+#ifdef CONFIG_ARM64
+	/*
+	 * Make will already error that reserving x18 is not supported at the
+	 * time of writing, clang: error: unknown argument: '-ffixed-x18'
+	 */
+	__asm__ volatile("mov %0, x18\n" : "=r" (gd_ptr));
+#else
+	__asm__ volatile("mov %0, r9\n" : "=r" (gd_ptr));
+#endif
+
+	return gd_ptr;
+}
+
+#else
+
 #ifdef CONFIG_ARM64
 #define DECLARE_GLOBAL_DATA_PTR		register volatile gd_t *gd asm ("x18")
 #else
 #define DECLARE_GLOBAL_DATA_PTR		register volatile gd_t *gd asm ("r9")
 #endif
+#endif
 
 #endif /* __ASM_GBL_DATA_H */
-- 
2.39.5