Merge branch 'vendor/GCC44'
[dragonfly.git] / contrib / gcc-4.4 / gcc / config / i386 / i386.c
index f4baaba..a08ad9d 100644 (file)
@@ -1,6 +1,6 @@
 /* Subroutines used for code generation on IA-32.
    Copyright (C) 1988, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-   2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -2358,7 +2358,7 @@ ix86_target_string (int isa, int flags, const char *arch, const char *tune,
   if (flags && add_nl_p)
     {
       opts[num++][0] = target_other;
-      sprintf (target_other, "(other flags: 0x%x)", isa);
+      sprintf (target_other, "(other flags: 0x%x)", flags);
     }
 
   /* Add -fpmath= option.  */
@@ -5657,9 +5657,8 @@ function_arg_advance_64 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
   if (!named && VALID_AVX256_REG_MODE (mode))
     return;
 
-  if (!examine_argument (mode, type, 0, &int_nregs, &sse_nregs))
-    cum->words += words;
-  else if (sse_nregs <= cum->sse_nregs && int_nregs <= cum->nregs)
+  if (examine_argument (mode, type, 0, &int_nregs, &sse_nregs)
+      && sse_nregs <= cum->sse_nregs && int_nregs <= cum->nregs)
     {
       cum->nregs -= int_nregs;
       cum->sse_nregs -= sse_nregs;
@@ -5667,7 +5666,11 @@ function_arg_advance_64 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
       cum->sse_regno += sse_nregs;
     }
   else
-    cum->words += words;
+    {
+      int align = ix86_function_arg_boundary (mode, type) / BITS_PER_WORD;
+      cum->words = (cum->words + align - 1) & ~(align - 1);
+      cum->words += words;
+    }
 }
 
 static void
@@ -5996,7 +5999,7 @@ ix86_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
 /* Return true when TYPE should be 128bit aligned for 32bit argument passing
    ABI.  */
 static bool
-contains_aligned_value_p (tree type)
+contains_aligned_value_p (const_tree type)
 {
   enum machine_mode mode = TYPE_MODE (type);
   if (((TARGET_SSE && SSE_REG_MODE_P (mode))
@@ -6046,7 +6049,7 @@ contains_aligned_value_p (tree type)
    specified mode and type.  */
 
 int
-ix86_function_arg_boundary (enum machine_mode mode, tree type)
+ix86_function_arg_boundary (enum machine_mode mode, const_tree type)
 {
   int align;
   if (type)
@@ -6362,12 +6365,12 @@ ix86_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
 }
 
 /* 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,
+   on Solaris 2.  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.  */
 
 bool
-ix86_sol10_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
+ix86_solaris_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
 {
   int size;
   enum machine_mode mode = type_natural_mode (type, NULL);
@@ -6588,6 +6591,10 @@ setup_incoming_varargs_64 (CUMULATIVE_ARGS *cum)
 
   if (ix86_varargs_fpr_size)
     {
+      /* Stack must be aligned to 16byte for FP register save area.  */
+      if (crtl->stack_alignment_needed < 128)
+       crtl->stack_alignment_needed = 128;
+
       /* Now emit code to save SSE registers.  The AX parameter contains number
         of SSE parameter registers used to call this function.  We use
         sse_prologue_save insn template that produces computed jump across
@@ -8280,13 +8287,10 @@ ix86_expand_prologue (void)
                               GEN_INT (-allocate), -1);
   else
     {
-      /* Only valid for Win32.  */
       rtx eax = gen_rtx_REG (Pmode, AX_REG);
       bool eax_live;
       rtx t;
 
-      gcc_assert (!TARGET_64BIT || cfun->machine->call_abi == MS_ABI);
-
       if (cfun->machine->call_abi == MS_ABI)
        eax_live = false;
       else
@@ -8675,10 +8679,12 @@ ix86_expand_epilogue (int style)
       int param_ptr_offset = (call_used_regs[REGNO (crtl->drap_reg)]
                              ? 0 : UNITS_PER_WORD);
       gcc_assert (stack_realign_drap);
-      emit_insn ((*ix86_gen_add3) (stack_pointer_rtx,
-                                  crtl->drap_reg,
-                                  GEN_INT (-(UNITS_PER_WORD
-                                             + param_ptr_offset))));
+      emit_insn (gen_rtx_SET
+                (VOIDmode, stack_pointer_rtx,
+                 gen_rtx_PLUS (Pmode,
+                               crtl->drap_reg,
+                               GEN_INT (-(UNITS_PER_WORD
+                                          + param_ptr_offset)))));
       if (!call_used_regs[REGNO (crtl->drap_reg)])
        emit_insn ((*ix86_gen_pop1) (crtl->drap_reg));
       
@@ -8878,8 +8884,7 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
      to test cfun for being non-NULL. */
   if (TARGET_K6 && cfun && optimize_function_for_speed_p (cfun)
       && base_reg && !index_reg && !disp
-      && REG_P (base_reg)
-      && REGNO_REG_CLASS (REGNO (base_reg)) == SIREG)
+      && REG_P (base_reg) && REGNO (base_reg) == SI_REG)
     disp = const0_rtx;
 
   /* Special case: encode reg+reg instead of reg*2.  */
@@ -10379,7 +10384,7 @@ i386_output_dwarf_dtprel (FILE *file, int size, rtx x)
 static bool
 ix86_pic_register_p (rtx x)
 {
-  if (GET_CODE (x) == VALUE)
+  if (GET_CODE (x) == VALUE && CSELIB_VAL_PTR (x))
     return (pic_offset_table_rtx
            && rtx_equal_for_cselib_p (x, pic_offset_table_rtx));
   else
@@ -10823,7 +10828,6 @@ get_some_local_dynamic_name (void)
    L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
    C -- print opcode suffix for set/cmov insn.
    c -- like C, but print reversed condition
-   E,e -- likewise, but for compare-and-branch fused insn.
    F,f -- likewise, but for floating-point.
    O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
         otherwise nothing
@@ -11180,14 +11184,6 @@ print_operand (FILE *file, rtx x, int code)
          put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)), 1, 1, file);
          return;
 
-       case 'E':
-         put_condition_code (GET_CODE (x), CCmode, 0, 0, file);
-         return;
-
-       case 'e':
-         put_condition_code (GET_CODE (x), CCmode, 1, 0, file);
-         return;
-
        case 'H':
          /* It doesn't actually matter what mode we use here, as we're
             only going to use this for printing.  */
@@ -11285,10 +11281,8 @@ print_operand (FILE *file, rtx x, int code)
          return;
 
        case ';':
-#if TARGET_MACHO
-         fputs (" ; ", file);
-#else
-         fputc (' ', file);
+#if TARGET_MACHO || !HAVE_AS_IX86_REP_LOCK_PREFIX
+         fputs (";", file);
 #endif
          return;
 
@@ -11313,13 +11307,14 @@ print_operand (FILE *file, rtx x, int code)
            case 2: size = "WORD"; break;
            case 4: size = "DWORD"; break;
            case 8: size = "QWORD"; break;
-           case 12: size = "XWORD"; break;
+           case 12: size = "TBYTE"; break;
            case 16:
              if (GET_MODE (x) == XFmode)
-               size = "XWORD";
+               size = "TBYTE";
               else
                size = "XMMWORD";
               break;
+           case 32: size = "YMMWORD"; break;
            default:
              gcc_unreachable ();
            }
@@ -15674,8 +15669,9 @@ ix86_expand_int_vcond (rtx operands[])
            }
        }
 
-      /* Unsigned parallel compare is not supported by the hardware.  Play some
-        tricks to turn this into a signed comparison against 0.  */
+      /* Unsigned parallel compare is not supported by the hardware.
+        Play some tricks to turn this into a signed comparison
+        against 0.  */
       if (code == GTU)
        {
          cop0 = force_reg (mode, cop0);
@@ -15684,32 +15680,26 @@ ix86_expand_int_vcond (rtx operands[])
            {
            case V4SImode:
            case V2DImode:
-             {
-               rtx t1, t2, mask;
-
-               /* Perform a parallel modulo subtraction.  */
-               t1 = gen_reg_rtx (mode);
-               emit_insn ((mode == V4SImode
-                           ? gen_subv4si3
-                           : gen_subv2di3) (t1, cop0, cop1));
-
-               /* Extract the original sign bit of op0.  */
-               mask = ix86_build_signbit_mask (GET_MODE_INNER (mode),
-                                               true, false);
-               t2 = gen_reg_rtx (mode);
-               emit_insn ((mode == V4SImode
-                           ? gen_andv4si3
-                           : gen_andv2di3) (t2, cop0, mask));
-
-               /* XOR it back into the result of the subtraction.  This results
-                  in the sign bit set iff we saw unsigned underflow.  */
-               x = gen_reg_rtx (mode);
-               emit_insn ((mode == V4SImode
-                           ? gen_xorv4si3
-                           : gen_xorv2di3) (x, t1, t2));
-
-               code = GT;
-             }
+               {
+                 rtx t1, t2, mask;
+                 rtx (*gen_sub3) (rtx, rtx, rtx);
+
+                 /* Subtract (-(INT MAX) - 1) from both operands to make
+                    them signed.  */
+                 mask = ix86_build_signbit_mask (GET_MODE_INNER (mode),
+                                                 true, false);
+                 gen_sub3 = (mode == V4SImode
+                             ? gen_subv4si3 : gen_subv2di3);
+                 t1 = gen_reg_rtx (mode);
+                 emit_insn (gen_sub3 (t1, cop0, mask));
+
+                 t2 = gen_reg_rtx (mode);
+                 emit_insn (gen_sub3 (t2, cop1, mask));
+
+                 cop0 = t1;
+                 cop1 = t2;
+                 code = GT;
+               }
              break;
 
            case V16QImode:
@@ -15719,6 +15709,8 @@ ix86_expand_int_vcond (rtx operands[])
              emit_insn (gen_rtx_SET (VOIDmode, x,
                                      gen_rtx_US_MINUS (mode, cop0, cop1)));
 
+             cop0 = x;
+             cop1 = CONST0_RTX (mode);
              code = EQ;
              negate = !negate;
              break;
@@ -15726,9 +15718,6 @@ ix86_expand_int_vcond (rtx operands[])
            default:
              gcc_unreachable ();
            }
-
-         cop0 = x;
-         cop1 = CONST0_RTX (mode);
        }
     }
 
@@ -20631,6 +20620,7 @@ def_builtin (int mask, const char *name, tree type, enum ix86_builtins code)
     {
       ix86_builtins_isa[(int) code].isa = mask;
 
+      mask &= ~OPTION_MASK_ISA_64BIT;
       if ((mask & ix86_isa_flags) != 0
          || (lang_hooks.builtin_function
              == lang_hooks.builtin_function_ext_scope))
@@ -26850,7 +26840,7 @@ x86_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
   if (TARGET_64BIT)
     {
 #ifndef NO_PROFILE_COUNTERS
-      fprintf (file, "\tleaq\t%sP%d@(%%rip),%%r11\n", LPREFIX, labelno);
+      fprintf (file, "\tleaq\t%sP%d(%%rip),%%r11\n", LPREFIX, labelno);
 #endif
 
       if (DEFAULT_ABI == SYSV_ABI && flag_pic)