aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUros Bizjak <ubizjak@gmail.com>2013-01-03 18:16:08 +0100
committerUros Bizjak <uros@gcc.gnu.org>2013-01-03 18:16:08 +0100
commitbb664f09f774164415abc2eccd6e1052e6ddb3c0 (patch)
treed62b57e5e7741281f539bb6486428f328cc1f7b6
parent49c01f87ba0b28fa7021d75bfd4b68a75f15ab48 (diff)
downloadgcc-bb664f09f774164415abc2eccd6e1052e6ddb3c0.zip
gcc-bb664f09f774164415abc2eccd6e1052e6ddb3c0.tar.gz
gcc-bb664f09f774164415abc2eccd6e1052e6ddb3c0.tar.bz2
re PR target/55712 (cpuinfo.c doesn't compile for x86-64 with medium memory model)
PR target/55712 * config/i386/i386-c.c (ix86_target_macros_internal): Depending on selected code model, define __code_mode_small__, __code_model_medium__, __code_model_large__, __code_model_32__ or __code_model_kernel__. * config/i386/cpuid.h (__cpuid, __cpuid_count) [__i386__]: Prefix xchg temporary register with %k. Declare temporary register as early clobbered. [__x86_64__]: For medium and large code models, preserve %rbx register. From-SVN: r194862
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/config/i386/cpuid.h41
-rw-r--r--gcc/config/i386/i386-c.c26
3 files changed, 64 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 033d272..740b8ac 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2013-01-03 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/55712
+ * config/i386/i386-c.c (ix86_target_macros_internal): Depending on
+ selected code model, define __code_mode_small__, __code_model_medium__,
+ __code_model_large__, __code_model_32__ or __code_model_kernel__.
+ * config/i386/cpuid.h (__cpuid, __cpuid_count) [__i386__]: Prefix
+ xchg temporary register with %k. Declare temporary register as
+ early clobbered.
+ [__x86_64__]: For medium and large code models, preserve %rbx register.
+
2013-01-03 Richard Biener <rguenther@suse.de>
* tree-data-ref.c (dump_conflict_function): Use less vertical
diff --git a/gcc/config/i386/cpuid.h b/gcc/config/i386/cpuid.h
index 1f76d3a..7711c9b 100644
--- a/gcc/config/i386/cpuid.h
+++ b/gcc/config/i386/cpuid.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012
+ * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013
* Free Software Foundation, Inc.
*
* This file is free software; you can redistribute it and/or modify it
@@ -136,35 +136,50 @@
/* %ebx may be the PIC register. */
#if __GNUC__ >= 3
#define __cpuid(level, a, b, c, d) \
- __asm__ ("xchg{l}\t{%%}ebx, %1\n\t" \
+ __asm__ ("xchg{l}\t{%%}ebx, %k1\n\t" \
"cpuid\n\t" \
- "xchg{l}\t{%%}ebx, %1\n\t" \
- : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
+ "xchg{l}\t{%%}ebx, %k1\n\t" \
+ : "=a" (a), "=&r" (b), "=c" (c), "=d" (d) \
: "0" (level))
#define __cpuid_count(level, count, a, b, c, d) \
- __asm__ ("xchg{l}\t{%%}ebx, %1\n\t" \
+ __asm__ ("xchg{l}\t{%%}ebx, %k1\n\t" \
"cpuid\n\t" \
- "xchg{l}\t{%%}ebx, %1\n\t" \
- : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
+ "xchg{l}\t{%%}ebx, %k1\n\t" \
+ : "=a" (a), "=&r" (b), "=c" (c), "=d" (d) \
: "0" (level), "2" (count))
#else
/* Host GCCs older than 3.0 weren't supporting Intel asm syntax
nor alternatives in i386 code. */
#define __cpuid(level, a, b, c, d) \
- __asm__ ("xchgl\t%%ebx, %1\n\t" \
+ __asm__ ("xchgl\t%%ebx, %k1\n\t" \
"cpuid\n\t" \
- "xchgl\t%%ebx, %1\n\t" \
- : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
+ "xchgl\t%%ebx, %k1\n\t" \
+ : "=a" (a), "=&r" (b), "=c" (c), "=d" (d) \
: "0" (level))
#define __cpuid_count(level, count, a, b, c, d) \
- __asm__ ("xchgl\t%%ebx, %1\n\t" \
+ __asm__ ("xchgl\t%%ebx, %k1\n\t" \
"cpuid\n\t" \
- "xchgl\t%%ebx, %1\n\t" \
- : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
+ "xchgl\t%%ebx, %k1\n\t" \
+ : "=a" (a), "=&r" (b), "=c" (c), "=d" (d) \
: "0" (level), "2" (count))
#endif
+#elif defined(__x86_64__) && (defined(__code_model_medium__) || defined(__code_model_large__)) && defined(__PIC__)
+/* %rbx may be the PIC register. */
+#define __cpuid(level, a, b, c, d) \
+ __asm__ ("xchg{q}\t{%%}rbx, %q1\n\t" \
+ "cpuid\n\t" \
+ "xchg{q}\t{%%}rbx, %q1\n\t" \
+ : "=a" (a), "=&r" (b), "=c" (c), "=d" (d) \
+ : "0" (level))
+
+#define __cpuid_count(level, count, a, b, c, d) \
+ __asm__ ("xchg{q}\t{%%}rbx, %q1\n\t" \
+ "cpuid\n\t" \
+ "xchg{q}\t{%%}rbx, %q1\n\t" \
+ : "=a" (a), "=&r" (b), "=c" (c), "=d" (d) \
+ : "0" (level), "2" (count))
#else
#define __cpuid(level, a, b, c, d) \
__asm__ ("cpuid\n\t" \
diff --git a/gcc/config/i386/i386-c.c b/gcc/config/i386/i386-c.c
index 22e5e9b..05a3476 100644
--- a/gcc/config/i386/i386-c.c
+++ b/gcc/config/i386/i386-c.c
@@ -1,5 +1,5 @@
/* Subroutines used for macro/preprocessor support on the ia-32.
- Copyright (C) 2008, 2009, 2010, 2011, 2012
+ Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013
Free Software Foundation, Inc.
This file is part of GCC.
@@ -243,6 +243,30 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag,
break;
}
+ switch (ix86_cmodel)
+ {
+ case CM_SMALL:
+ case CM_SMALL_PIC:
+ def_or_undef (parse_in, "__code_model_small__");
+ break;
+ case CM_MEDIUM:
+ case CM_MEDIUM_PIC:
+ def_or_undef (parse_in, "__code_model_medium__");
+ break;
+ case CM_LARGE:
+ case CM_LARGE_PIC:
+ def_or_undef (parse_in, "__code_model_large__");
+ break;
+ case CM_32:
+ def_or_undef (parse_in, "__code_model_32__");
+ break;
+ case CM_KERNEL:
+ def_or_undef (parse_in, "__code_model_kernel__");
+ break;
+ default:
+ ;
+ }
+
if (isa_flag & OPTION_MASK_ISA_MMX)
def_or_undef (parse_in, "__MMX__");
if (isa_flag & OPTION_MASK_ISA_3DNOW)