diff options
author | Uros Bizjak <ubizjak@gmail.com> | 2013-01-03 18:16:08 +0100 |
---|---|---|
committer | Uros Bizjak <uros@gcc.gnu.org> | 2013-01-03 18:16:08 +0100 |
commit | bb664f09f774164415abc2eccd6e1052e6ddb3c0 (patch) | |
tree | d62b57e5e7741281f539bb6486428f328cc1f7b6 | |
parent | 49c01f87ba0b28fa7021d75bfd4b68a75f15ab48 (diff) | |
download | gcc-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/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/config/i386/cpuid.h | 41 | ||||
-rw-r--r-- | gcc/config/i386/i386-c.c | 26 |
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) |