OSDN Git Service

2007-05-18 H.J. Lu <hongjiu.lu@intel.com>
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.c
index cefe8ae..1bea8d7 100644 (file)
@@ -1026,8 +1026,7 @@ unsigned int ix86_tune_features[X86_TUNE_LAST] = {
   m_486 | m_PENT | m_PPRO | m_ATHLON_K8_AMDFAM10 | m_K6 | m_CORE2 | m_GENERIC,
 
   /* X86_TUNE_DEEP_BRANCH_PREDICTION */
-  m_PPRO | m_K6_GEODE | m_ATHLON_K8_AMDFAM10 | m_PENT4
-  | m_NOCONA | m_CORE2 | m_GENERIC,
+  m_PPRO | m_K6_GEODE | m_ATHLON_K8_AMDFAM10 | m_PENT4 | m_GENERIC,
 
   /* X86_TUNE_BRANCH_PREDICTION_HINTS: Branch hints were put in P4 based
      on simulation result. But after P4 was made, no performance benefit
@@ -1652,7 +1651,7 @@ override_options (void)
       {&core2_cost, 0, 0, 16, 7, 16, 7, 16},
       {&generic32_cost, 0, 0, 16, 7, 16, 7, 16},
       {&generic64_cost, 0, 0, 16, 7, 16, 7, 16},
-      {&amdfam10_cost, 0, 0, 32, 7, 32, 7, 32}
+      {&amdfam10_cost, 0, 0, 32, 24, 32, 7, 32}
     };
 
   static const char * const cpu_names[] = TARGET_CPU_DEFAULT_NAMES;
@@ -1727,12 +1726,21 @@ override_options (void)
       {"k8", PROCESSOR_K8, PTA_MMX | PTA_PREFETCH_SSE | PTA_3DNOW | PTA_64BIT
                                      | PTA_3DNOW_A | PTA_SSE | PTA_SSE2
                                      | PTA_NO_SAHF},
+      {"k8-sse3", PROCESSOR_K8, PTA_MMX | PTA_PREFETCH_SSE | PTA_3DNOW | PTA_64BIT
+                                      | PTA_3DNOW_A | PTA_SSE | PTA_SSE2
+                                     | PTA_SSE3 | PTA_NO_SAHF},
       {"opteron", PROCESSOR_K8, PTA_MMX | PTA_PREFETCH_SSE | PTA_3DNOW
                                        | PTA_64BIT | PTA_3DNOW_A | PTA_SSE
                                        | PTA_SSE2 | PTA_NO_SAHF},
+      {"opteron-sse3", PROCESSOR_K8, PTA_MMX | PTA_PREFETCH_SSE | PTA_3DNOW
+                                       | PTA_64BIT | PTA_3DNOW_A | PTA_SSE
+                                       | PTA_SSE2 | PTA_SSE3 | PTA_NO_SAHF},
       {"athlon64", PROCESSOR_K8, PTA_MMX | PTA_PREFETCH_SSE | PTA_3DNOW
                                         | PTA_64BIT | PTA_3DNOW_A | PTA_SSE
                                         | PTA_SSE2 | PTA_NO_SAHF},
+      {"athlon64-sse3", PROCESSOR_K8, PTA_MMX | PTA_PREFETCH_SSE | PTA_3DNOW
+                                        | PTA_64BIT | PTA_3DNOW_A | PTA_SSE
+                                         | PTA_SSE2 | PTA_SSE3 | PTA_NO_SAHF},
       {"athlon-fx", PROCESSOR_K8, PTA_MMX | PTA_PREFETCH_SSE | PTA_3DNOW
                                          | PTA_64BIT | PTA_3DNOW_A | PTA_SSE
                                          | PTA_SSE2 | PTA_NO_SAHF},
@@ -2784,7 +2792,8 @@ ix86_function_regparm (tree type, tree decl)
     return 2;
 
   /* Use register calling convention for local functions when possible.  */
-  if (decl && flag_unit_at_a_time && !profile_flag)
+  if (decl && TREE_CODE (decl) == FUNCTION_DECL
+      && flag_unit_at_a_time && !profile_flag)
     {
       struct cgraph_local_info *i = cgraph_local_info (decl);
       if (i && i->local)
@@ -2895,12 +2904,15 @@ ix86_eax_live_at_start_p (void)
 static bool
 type_has_variadic_args_p (tree type)
 {
-  tree t;
+  tree n, t = TYPE_ARG_TYPES (type);
 
-  for (t = TYPE_ARG_TYPES (type); t; t = TREE_CHAIN (t))
-    if (t == void_list_node)
-      return false;
-  return true;
+  if (t == NULL)
+    return false;
+
+  while ((n = TREE_CHAIN (t)) != NULL)
+    t = n;
+
+  return TREE_VALUE (t) != void_type_node;
 }
 
 /* Value is the number of bytes of arguments automatically
@@ -3039,7 +3051,10 @@ init_cumulative_args (CUMULATIVE_ARGS *cum,  /* Argument info to initialize */
     cum->mmx_nregs = MMX_REGPARM_MAX;
   cum->warn_sse = true;
   cum->warn_mmx = true;
-  cum->maybe_vaarg = (fntype ? type_has_variadic_args_p (fntype) : !libname);
+  cum->maybe_vaarg = (fntype
+                     ? (!TYPE_ARG_TYPES (fntype)
+                        || type_has_variadic_args_p (fntype))
+                     : !libname);
 
   if (!TARGET_64BIT)
     {
@@ -4370,6 +4385,43 @@ ix86_return_in_memory (tree type)
     return return_in_memory_32 (type, mode);
 }
 
+/* Return false iff TYPE is returned in memory.  This version is used
+   on Solaris 10.  It is similar to the generic ix86_return_in_memory,
+   but differs notably in that when MMX is available, 8-byte vectors
+   are returned in memory, rather than in MMX registers.  */
+
+int 
+ix86_sol10_return_in_memory (tree type)
+{
+  int size;
+  enum machine_mode mode = type_natural_mode (type);
+
+  if (TARGET_64BIT)
+    return return_in_memory_64 (type, mode);
+
+  if (mode == BLKmode)
+    return 1;
+
+  size = int_size_in_bytes (type);
+
+  if (VECTOR_MODE_P (mode))
+    {
+      /* Return in memory only if MMX registers *are* available.  This
+        seems backwards, but it is consistent with the existing
+        Solaris x86 ABI.  */
+      if (size == 8)
+       return TARGET_MMX;
+      if (size == 16)
+       return !TARGET_SSE;
+    }
+  else if (mode == TImode)
+    return !TARGET_SSE;
+  else if (mode == XFmode)
+    return 0;
+
+  return size > 12;
+}
+
 /* When returning SSE vector types, we have a choice of either
      (1) being abi incompatible with a -march switch, or
      (2) generating an error.
@@ -7249,6 +7301,7 @@ legitimize_tls_address (rtx x, enum tls_model model, int for_mov)
          insns = get_insns ();
          end_sequence ();
 
+         CONST_OR_PURE_CALL_P (insns) = 1;
          emit_libcall_block (insns, dest, rax, x);
        }
       else if (TARGET_64BIT && TARGET_GNU2_TLS)
@@ -7279,6 +7332,7 @@ legitimize_tls_address (rtx x, enum tls_model model, int for_mov)
 
          note = gen_rtx_EXPR_LIST (VOIDmode, const0_rtx, NULL);
          note = gen_rtx_EXPR_LIST (VOIDmode, ix86_tls_get_addr (), note);
+         CONST_OR_PURE_CALL_P (insns) = 1;
          emit_libcall_block (insns, base, rax, note);
        }
       else if (TARGET_64BIT && TARGET_GNU2_TLS)
@@ -8324,9 +8378,15 @@ print_operand (FILE *file, rtx x, int code)
              return;
 
            case 2:
+             if (MEM_P (x))
+               {
 #ifdef HAVE_GAS_FILDS_FISTS
-             putc ('s', file);
+                 putc ('s', file);
 #endif
+                 return;
+               }
+             else
+               putc ('w', file);
              return;
 
            case 4:
@@ -17765,7 +17825,6 @@ ix86_expand_sse_comi (const struct builtin_description *d, tree exp,
   tree arg1 = CALL_EXPR_ARG (exp, 1);
   rtx op0 = expand_normal (arg0);
   rtx op1 = expand_normal (arg1);
-  rtx op2;
   enum machine_mode mode0 = insn_data[d->icode].operand[0].mode;
   enum machine_mode mode1 = insn_data[d->icode].operand[1].mode;
   enum rtx_code comparison = d->comparison;
@@ -17795,7 +17854,6 @@ ix86_expand_sse_comi (const struct builtin_description *d, tree exp,
       || !(*insn_data[d->icode].operand[1].predicate) (op1, mode1))
     op1 = copy_to_mode_reg (mode1, op1);
 
-  op2 = gen_rtx_fmt_ee (comparison, mode0, op0, op1);
   pat = GEN_FCN (d->icode) (op0, op1);
   if (! pat)
     return 0;
@@ -21109,6 +21167,8 @@ ix86_scalar_mode_supported_p (enum machine_mode mode)
 {
   if (DECIMAL_FLOAT_MODE_P (mode))
     return true;
+  else if (mode == TFmode)
+    return TARGET_64BIT;
   else
     return default_scalar_mode_supported_p (mode);
 }