OSDN Git Service

Some SSE fixes
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.c
index 5291d9c..caccc7e 100644 (file)
@@ -375,6 +375,7 @@ const int x86_memory_mismatch_stall = m_ATHLON | m_PENT4;
 const int x86_accumulate_outgoing_args = m_ATHLON | m_PENT4 | m_PPRO;
 const int x86_prologue_using_move = m_ATHLON | m_PENT4 | m_PPRO;
 const int x86_epilogue_using_move = m_ATHLON | m_PENT4 | m_PPRO;
+const int x86_decompose_lea = m_PENT4;
 
 /* In case the avreage insn count for single function invocation is
    lower than this constant, emit fast (but longer) prologue and
@@ -795,19 +796,21 @@ override_options ()
       const int target_enable;                 /* Target flags to enable.  */
       const int target_disable;                        /* Target flags to disable.  */
       const int align_loop;                    /* Default alignments.  */
+      const int align_loop_max_skip;
       const int align_jump;
+      const int align_jump_max_skip;
       const int align_func;
       const int branch_cost;
     }
   const processor_target_table[PROCESSOR_max] =
     {
-      {&i386_cost, 0, 0, 2, 2, 2, 1},
-      {&i486_cost, 0, 0, 4, 4, 4, 1},
-      {&pentium_cost, 0, 0, -4, -4, -4, 1},
-      {&pentiumpro_cost, 0, 0, 4, -4, 4, 1},
-      {&k6_cost, 0, 0, -5, -5, 4, 1},
-      {&athlon_cost, 0, 0, 4, -4, 4, 1},
-      {&pentium4_cost, 0, 0, 2, 2, 2, 1}
+      {&i386_cost, 0, 0, 4, 3, 4, 3, 4, 1},
+      {&i486_cost, 0, 0, 16, 15, 16, 15, 16, 1},
+      {&pentium_cost, 0, 0, 16, 7, 16, 7, 16, 1},
+      {&pentiumpro_cost, 0, 0, 16, 15, 16, 7, 16, 1},
+      {&k6_cost, 0, 0, 32, 7, 32, 7, 32, 1},
+      {&athlon_cost, 0, 0, 16, 7, 64, 7, 16, 1},
+      {&pentium4_cost, 0, 0, 0, 0, 0, 0, 0, 1}
     };
 
   static struct pta
@@ -966,11 +969,19 @@ override_options ()
   /* Default align_* from the processor table.  */
 #define abs(n) (n < 0 ? -n : n)
   if (align_loops == 0)
-    align_loops = 1 << abs (processor_target_table[ix86_cpu].align_loop);
+    {
+      align_loops = processor_target_table[ix86_cpu].align_loop;
+      align_loops_max_skip = processor_target_table[ix86_cpu].align_loop_max_skip;
+    }
   if (align_jumps == 0)
-    align_jumps = 1 << abs (processor_target_table[ix86_cpu].align_jump);
+    {
+      align_jumps = processor_target_table[ix86_cpu].align_jump;
+      align_jumps_max_skip = processor_target_table[ix86_cpu].align_jump_max_skip;
+    }
   if (align_functions == 0)
-    align_functions = 1 << abs (processor_target_table[ix86_cpu].align_func);
+    {
+      align_functions = processor_target_table[ix86_cpu].align_func;
+    }
 
   /* Validate -mpreferred-stack-boundary= value, or provide default.
      The default of 128 bits is for Pentium III's SSE __m128, but we
@@ -1178,8 +1189,8 @@ ix86_osf_output_function_prologue (file, size)
      FILE *file;
      HOST_WIDE_INT size;
 {
-  char *prefix = "";
-  char *lprefix = LPREFIX;
+  const char *prefix = "";
+  const char *const lprefix = LPREFIX;
   int labelno = profile_label_no;
 
 #ifdef OSF_OS
@@ -1418,7 +1429,7 @@ init_cumulative_args (cum, fntype, libname)
 }
 
 /* x86-64 register passing impleemntation.  See x86-64 ABI for details.  Goal
-   of this code is to classify each 8bytes of incomming argument by the register
+   of this code is to classify each 8bytes of incoming argument by the register
    class and assign registers accordingly.  */
 
 /* Return the union class of CLASS1 and CLASS2.
@@ -1616,7 +1627,7 @@ classify_argument (mode, type, classes, bit_offset)
        mode_alignment = 128;
       else if (mode == XCmode)
        mode_alignment = 256;
-      /* Missalignmed fields are always returned in memory.  */
+      /* Misaligned fields are always returned in memory.  */
       if (bit_offset % mode_alignment)
        return 0;
     }
@@ -1678,7 +1689,7 @@ classify_argument (mode, type, classes, bit_offset)
 }
 
 /* Examine the argument and return set number of register required in each
-   class.  Return 0 ifif parameter should be passed in memory.  */
+   class.  Return 0 iff parameter should be passed in memory.  */
 static int
 examine_argument (mode, type, in_return, int_nregs, sse_nregs)
      enum machine_mode mode;
@@ -2060,7 +2071,7 @@ ix86_function_value (valtype)
     return gen_rtx_REG (TYPE_MODE (valtype), VALUE_REGNO (TYPE_MODE (valtype)));
 }
 
-/* Return false ifif type is returned in memory.  */
+/* Return false iff type is returned in memory.  */
 int
 ix86_return_in_memory (type)
      tree type;
@@ -2249,14 +2260,16 @@ ix86_setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
         pointing 127 bytes after first byte to store - this is needed to keep
         instruction size limited by 4 bytes.  */
       tmp_reg = gen_reg_rtx (Pmode);
-      emit_insn (gen_rtx_SET(VOIDmode, tmp_reg,
-                            plus_constant (save_area, 8 * REGPARM_MAX + 127)));
+      emit_insn (gen_rtx_SET (VOIDmode, tmp_reg,
+                             plus_constant (save_area,
+                                            8 * REGPARM_MAX + 127)));
       mem = gen_rtx_MEM (BLKmode, plus_constant (tmp_reg, -127));
       set_mem_alias_set (mem, set);
+      set_mem_align (mem, BITS_PER_WORD);
 
       /* And finally do the dirty job!  */
-      emit_insn (gen_sse_prologue_save (mem, nsse_reg, GEN_INT (next_cum.sse_regno),
-                label));
+      emit_insn (gen_sse_prologue_save (mem, nsse_reg,
+                                       GEN_INT (next_cum.sse_regno), label));
     }
 
 }
@@ -2431,7 +2444,7 @@ ix86_va_arg (valist, type)
                                   (gpr, NULL_RTX, SImode, EXPAND_NORMAL),
                                   GEN_INT ((REGPARM_MAX - needed_intregs +
                                             1) * 8), GE, const1_rtx, SImode,
-                                  1, 1, lab_false);
+                                  1, lab_false);
        }
       if (needed_sseregs)
        {
@@ -2440,7 +2453,7 @@ ix86_va_arg (valist, type)
                                   GEN_INT ((SSE_REGPARM_MAX -
                                             needed_sseregs + 1) * 16 +
                                            REGPARM_MAX * 8), GE, const1_rtx,
-                                  SImode, 1, 1, lab_false);
+                                  SImode, 1, lab_false);
        }
 
       /* Compute index to start of area used for integer regs.  */
@@ -2467,6 +2480,7 @@ ix86_va_arg (valist, type)
          addr_rtx = XEXP (assign_temp (type, 0, 1, 0), 0);
          mem = gen_rtx_MEM (BLKmode, addr_rtx);
          set_mem_alias_set (mem, get_varargs_alias_set ());
+         set_mem_align (mem, BITS_PER_UNIT);
 
          for (i = 0; i < XVECLEN (container, 0); i++)
            {
@@ -2492,7 +2506,6 @@ ix86_va_arg (valist, type)
              set_mem_alias_set (src_mem, get_varargs_alias_set ());
              src_mem = adjust_address (src_mem, mode, src_offset);
              dest_mem = adjust_address (mem, mode, INTVAL (XEXP (slot, 1)));
-             PUT_MODE (dest_mem, mode);
              emit_move_insn (dest_mem, src_mem);
            }
        }
@@ -2851,7 +2864,7 @@ incdec_operand (op, mode)
      register rtx op;
      enum machine_mode mode ATTRIBUTE_UNUSED;
 {
-  /* On Pentium4, the inc and dec operations causes extra dependancy on flag
+  /* On Pentium4, the inc and dec operations causes extra dependency on flag
      registers, since carry flag is not set.  */
   if (TARGET_PENTIUM4 && !optimize_size)
     return 0;
@@ -3799,7 +3812,7 @@ ix86_compute_frame_layout (frame)
 
   /* Do some sanity checking of stack_alignment_needed and
      preferred_alignment, since i386 port is the only using those features
-     that may break easilly.  */
+     that may break easily.  */
 
   if (size && !stack_alignment_needed)
     abort ();
@@ -4172,7 +4185,7 @@ ix86_expand_epilogue (style)
          }
       if (frame_pointer_needed)
        {
-         /* Leave results in shorter depdendancy chains on CPUs that are
+         /* Leave results in shorter dependency chains on CPUs that are
             able to grok it fast.  */
          if (TARGET_USE_LEAVE)
            emit_insn (TARGET_64BIT ? gen_leave_rex64 () : gen_leave ());
@@ -4694,7 +4707,7 @@ legitimate_address_p (mode, addr, strict)
 
             This code is nonsensical, but results in addressing
             GOT table with pic_offset_table_rtx base.  We can't
-            just refuse it easilly, since it gets matched by
+            just refuse it easily, since it gets matched by
             "addsi3" pattern, that later gets split to lea in the
             case output register differs from input.  While this
             can be handled by separate addsi pattern for this case
@@ -5199,11 +5212,11 @@ i386_dwarf_output_addr_const (file, x)
      rtx x;
 {
 #ifdef ASM_QUAD
-  fprintf (file, "%s", TARGET_64BIT ? ASM_QUAD : INT_ASM_OP);
+  fprintf (file, "%s", TARGET_64BIT ? ASM_QUAD : ASM_LONG);
 #else
   if (TARGET_64BIT)
     abort ();
-  fprintf (file, "%s", INT_ASM_OP);
+  fprintf (file, "%s", ASM_LONG);
 #endif
   if (flag_pic)
     output_pic_addr_const (file, x, '\0');
@@ -8958,7 +8971,7 @@ ix86_expand_aligntest (variable, value)
   else
     emit_insn (gen_andsi3 (tmpcount, variable, GEN_INT (value)));
   emit_cmp_and_jump_insns (tmpcount, const0_rtx, EQ, 0, GET_MODE (variable),
-                          1, 0, label);
+                          1, label);
   return label;
 }
 
@@ -9006,7 +9019,7 @@ ix86_expand_movstr (dst, src, count_exp, align_exp)
   if (GET_CODE (align_exp) == CONST_INT)
     align = INTVAL (align_exp);
 
-  /* This simple hack avoids all inlining code and simplifies code bellow.  */
+  /* This simple hack avoids all inlining code and simplifies code below.  */
   if (!TARGET_ALIGN_STRINGOPS)
     align = 64;
 
@@ -9125,7 +9138,7 @@ ix86_expand_movstr (dst, src, count_exp, align_exp)
        {
          label = gen_label_rtx ();
          emit_cmp_and_jump_insns (countreg, GEN_INT (UNITS_PER_WORD - 1),
-                                  LEU, 0, counter_mode, 1, 0, label);
+                                  LEU, 0, counter_mode, 1, label);
        }
       if (align <= 1)
        {
@@ -9227,7 +9240,7 @@ ix86_expand_clrstr (src, count_exp, align_exp)
   if (GET_CODE (align_exp) == CONST_INT)
     align = INTVAL (align_exp);
 
-  /* This simple hack avoids all inlining code and simplifies code bellow.  */
+  /* This simple hack avoids all inlining code and simplifies code below.  */
   if (!TARGET_ALIGN_STRINGOPS)
     align = 32;
 
@@ -9321,7 +9334,7 @@ ix86_expand_clrstr (src, count_exp, align_exp)
        {
          label = gen_label_rtx ();
          emit_cmp_and_jump_insns (countreg, GEN_INT (UNITS_PER_WORD - 1),
-                                  LEU, 0, counter_mode, 1, 0, label);
+                                  LEU, 0, counter_mode, 1, label);
        }
       if (align <= 1)
        {
@@ -9527,11 +9540,11 @@ ix86_expand_strlensi_unroll_1 (out, align_rtx)
                                    NULL_RTX, 0, OPTAB_WIDEN);
 
          emit_cmp_and_jump_insns (align_rtx, const0_rtx, EQ, NULL,
-                                  Pmode, 1, 0, align_4_label);
+                                  Pmode, 1, align_4_label);
          emit_cmp_and_jump_insns (align_rtx, GEN_INT (2), EQ, NULL,
-                                  Pmode, 1, 0, align_2_label);
+                                  Pmode, 1, align_2_label);
          emit_cmp_and_jump_insns (align_rtx, GEN_INT (2), GTU, NULL,
-                                  Pmode, 1, 0, align_3_label);
+                                  Pmode, 1, align_3_label);
        }
       else
         {
@@ -9542,7 +9555,7 @@ ix86_expand_strlensi_unroll_1 (out, align_rtx)
                                    NULL_RTX, 0, OPTAB_WIDEN);
 
          emit_cmp_and_jump_insns (align_rtx, const0_rtx, EQ, NULL,
-                                  Pmode, 1, 0, align_4_label);
+                                  Pmode, 1, align_4_label);
         }
 
       mem = gen_rtx_MEM (QImode, out);
@@ -9551,7 +9564,7 @@ ix86_expand_strlensi_unroll_1 (out, align_rtx)
 
       /* Compare the first n unaligned byte on a byte per byte basis.  */
       emit_cmp_and_jump_insns (mem, const0_rtx, EQ, NULL,
-                              QImode, 1, 0, end_0_label);
+                              QImode, 1, end_0_label);
 
       /* Increment the address.  */
       if (TARGET_64BIT)
@@ -9564,8 +9577,8 @@ ix86_expand_strlensi_unroll_1 (out, align_rtx)
        {
          emit_label (align_2_label);
 
-         emit_cmp_and_jump_insns (mem, const0_rtx, EQ, NULL,
-                                  QImode, 1, 0, end_0_label);
+         emit_cmp_and_jump_insns (mem, const0_rtx, EQ, NULL, QImode, 1,
+                                  end_0_label);
 
          if (TARGET_64BIT)
            emit_insn (gen_adddi3 (out, out, const1_rtx));
@@ -9575,8 +9588,8 @@ ix86_expand_strlensi_unroll_1 (out, align_rtx)
          emit_label (align_3_label);
        }
 
-      emit_cmp_and_jump_insns (mem, const0_rtx, EQ, NULL,
-                              QImode, 1, 0, end_0_label);
+      emit_cmp_and_jump_insns (mem, const0_rtx, EQ, NULL, QImode, 1,
+                              end_0_label);
 
       if (TARGET_64BIT)
        emit_insn (gen_adddi3 (out, out, const1_rtx));
@@ -9605,8 +9618,8 @@ ix86_expand_strlensi_unroll_1 (out, align_rtx)
   emit_insn (gen_andsi3 (tmpreg, tmpreg,
                         GEN_INT (trunc_int_for_mode
                                  (0x80808080, SImode))));
-  emit_cmp_and_jump_insns (tmpreg, const0_rtx, EQ, 0,
-                          SImode, 1, 0, align_4_label);
+  emit_cmp_and_jump_insns (tmpreg, const0_rtx, EQ, 0, SImode, 1,
+                          align_4_label);
 
   if (TARGET_CMOVE)
     {
@@ -9906,7 +9919,7 @@ ix86_flags_dependant (insn, dep_insn, insn_type)
   if (GET_CODE (set) != REG || REGNO (set) != FLAGS_REG)
     return 0;
 
-  /* This test is true if the dependant insn reads the flags but
+  /* This test is true if the dependent insn reads the flags but
      not any other potentially set register.  */
   if (!reg_overlap_mentioned_p (set, PATTERN (insn)))
     return 0;
@@ -11635,7 +11648,11 @@ ix86_expand_sse_comi (d, arglist, target)
   if (! pat)
     return 0;
   emit_insn (pat);
-  emit_insn (gen_setcc_2 (target, op2));
+  emit_insn (gen_rtx_SET (VOIDmode,
+                         gen_rtx_STRICT_LOW_PART (VOIDmode, target),
+                         gen_rtx_fmt_ee (comparison, QImode,
+                                         gen_rtx_REG (CCmode, FLAGS_REG),
+                                         const0_rtx)));
 
   return target;
 }
@@ -11923,12 +11940,12 @@ ix86_expand_builtin (exp, target, subtarget, mode, ignore)
       op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
       op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
       tmode = insn_data[icode].operand[0].mode;
-      mode0 = insn_data[icode].operand[2].mode;
-      mode1 = insn_data[icode].operand[3].mode;
+      mode1 = insn_data[icode].operand[1].mode;
+      mode2 = insn_data[icode].operand[2].mode;
 
-      if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
-       op0 = copy_to_mode_reg (mode0, op0);
-      if (! (*insn_data[icode].operand[3].predicate) (op1, mode1))
+      if (! (*insn_data[icode].operand[1].predicate) (op0, mode1))
+       op0 = copy_to_mode_reg (mode1, op0);
+      if (! (*insn_data[icode].operand[2].predicate) (op1, mode2))
        {
          /* @@@ better error message */
          error ("mask must be an immediate");
@@ -11938,7 +11955,7 @@ ix86_expand_builtin (exp, target, subtarget, mode, ignore)
          || GET_MODE (target) != tmode
          || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
        target = gen_reg_rtx (tmode);
-      pat = GEN_FCN (icode) (target, target, op0, op1);
+      pat = GEN_FCN (icode) (target, op0, op1);
       if (! pat)
        return 0;
       emit_insn (pat);
@@ -12131,7 +12148,7 @@ ix86_expand_builtin (exp, target, subtarget, mode, ignore)
 }
 
 /* Store OPERAND to the memory after reload is completed.  This means
-   that we can't easilly use assign_stack_local.  */
+   that we can't easily use assign_stack_local.  */
 rtx
 ix86_force_to_memory (mode, operand)
      enum machine_mode mode;
@@ -12238,7 +12255,7 @@ ix86_free_from_memory (mode)
 /* Put float CONST_DOUBLE in the constant pool instead of fp regs.
    QImode must go into class Q_REGS.
    Narrow ALL_REGS to GENERAL_REGS.  This supports allowing movsf and
-   movdf to do mem-to-mem moves through integer regs. */
+   movdf to do mem-to-mem moves through integer regs.  */
 enum reg_class
 ix86_preferred_reload_class (x, class)
      rtx x;