aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--qemu-common.h16
-rw-r--r--target-arm/exec.h6
-rw-r--r--target-i386/exec.h6
-rw-r--r--target-mips/exec.h2
-rw-r--r--tcg/tcg.c9
5 files changed, 28 insertions, 11 deletions
diff --git a/qemu-common.h b/qemu-common.h
index 79ac779..097e1fc 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -408,4 +408,20 @@ typedef enum DisplayType
#define CLAMP_MAC_TIMEOUT(to) ((void)0)
#endif // _DARWIN_C_SOURCE
+#if defined(__clang__) || defined(__llvm__)
+/* Clang and llvm-gcc don't support global register variable (GRV).
+ Clang issues compile-time error for GRV. llvm-gcc accepts GRV (because
+ its front-end is gcc) but ignores it in the llvm-based back-end.
+ Undefining GRV decl to allow external/qemu and the rest of Android
+ to compile. But emulator built w/o GRV support will not function
+ correctly. User will be greeted with an error message (issued
+ in tcg/tcg.c) when emulator built this way is launched.
+ */
+#define SUPPORT_GLOBAL_REGISTER_VARIABLE 0
+#define GLOBAL_REGISTER_VARIABLE_DECL
+#else
+#define SUPPORT_GLOBAL_REGISTER_VARIABLE 1
+#define GLOBAL_REGISTER_VARIABLE_DECL register
+#endif /* __clang__ || __llvm__ */
+
#endif
diff --git a/target-arm/exec.h b/target-arm/exec.h
index 83571e6..43bfaa9 100644
--- a/target-arm/exec.h
+++ b/target-arm/exec.h
@@ -19,11 +19,7 @@
#include "config.h"
#include "dyngen-exec.h"
-/* Xcode 4.3 doesn't support global register variables */
-#if !defined(__APPLE_CC__) || __APPLE_CC__ < 5621
- register
-#endif
-struct CPUARMState *env asm(AREG0);
+GLOBAL_REGISTER_VARIABLE_DECL struct CPUARMState *env asm(AREG0);
#include "cpu.h"
#include "exec-all.h"
diff --git a/target-i386/exec.h b/target-i386/exec.h
index d194f89..5d04b7f 100644
--- a/target-i386/exec.h
+++ b/target-i386/exec.h
@@ -29,11 +29,7 @@
#include "cpu-defs.h"
-/* Xcode 4.3 doesn't support global register variables */
-#if !defined(__APPLE_CC__) || __APPLE_CC__ < 5621
- register
-#endif
-struct CPUX86State *env asm(AREG0);
+GLOBAL_REGISTER_VARIABLE_DECL struct CPUX86State *env asm(AREG0);
#include "qemu-common.h"
#include "qemu-log.h"
diff --git a/target-mips/exec.h b/target-mips/exec.h
index 0720366..0d55790 100644
--- a/target-mips/exec.h
+++ b/target-mips/exec.h
@@ -8,7 +8,7 @@
#include "dyngen-exec.h"
#include "cpu-defs.h"
-register struct CPUMIPSState *env asm(AREG0);
+GLOBAL_REGISTER_VARIABLE_DECL struct CPUMIPSState *env asm(AREG0);
#include "cpu.h"
#include "exec-all.h"
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 5882f00..66529f5 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -2030,6 +2030,15 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
unsigned int tpc2gpc_index = 0;
#endif // CONFIG_MEMCHECK
+#if !SUPPORT_GLOBAL_REGISTER_VARIABLE
+ printf("ERROR: This emulator is built by compiler without global register variable\n"
+ "support! Emulator reserves a register to point to target architecture state\n"
+ "for better code generation. LLVM-based compilers such as clang and llvm-gcc\n"
+ "currently don't support global register variable. Please see\n"
+ "http://source.android.com/source/initializing.html for detail.\n\n");
+ tcg_abort();
+#endif
+
#ifdef DEBUG_DISAS
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
qemu_log("OP:\n");