OSDN Git Service

Backport from mainline
authoruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 6 Jan 2013 08:45:43 +0000 (08:45 +0000)
committeruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 6 Jan 2013 08:45:43 +0000 (08:45 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_7-branch@194937 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/i386/cpuid.h
gcc/config/i386/i386-c.c

index bfb5e84..bfffc58 100644 (file)
@@ -1,3 +1,17 @@
+2013-01-06  Uros Bizjak  <ubizjak@gmail.com>
+
+       Backport from mainline
+       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 Henderson  <rth@redhat.com>
 
        * config/i386/i386.c (ix86_expand_move): Always assign to op1
index 5da8fd2..49de691 100644 (file)
 /* %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"                                 \
index 62772b7..86b76b6 100644 (file)
@@ -233,6 +233,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)