OSDN Git Service

2007-11-27 H.J. Lu <hongjiu.lu@intel.com>
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.c
index 5ed8e2d..afed858 100644 (file)
@@ -1963,7 +1963,31 @@ override_options (void)
       {&amdfam10_cost, 32, 24, 32, 7, 32}
     };
 
-  static const char * const cpu_names[] = TARGET_CPU_DEFAULT_NAMES;
+  static const char *const cpu_names[TARGET_CPU_DEFAULT_max] =
+    {
+      "generic",
+      "i386",
+      "i486",
+      "pentium",
+      "pentium-mmx",
+      "pentiumpro",
+      "pentium2",
+      "pentium3",
+      "pentium4",
+      "pentium-m",
+      "prescott",
+      "nocona",
+      "core2",
+      "geode",
+      "k6",
+      "k6-2",
+      "k6-3",
+      "athlon",
+      "athlon-4",
+      "k8",
+      "amdfam10"
+    };
+
   enum pta_flags
     {
       PTA_SSE = 1 << 0,
@@ -2138,7 +2162,7 @@ override_options (void)
        ix86_tune_string = ix86_arch_string;
       if (!ix86_tune_string)
        {
-         ix86_tune_string = cpu_names [TARGET_CPU_DEFAULT];
+         ix86_tune_string = cpu_names[TARGET_CPU_DEFAULT];
          ix86_tune_defaulted = 1;
        }
 
@@ -4229,10 +4253,13 @@ function_arg_32 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
          int regno = cum->regno;
 
          /* Fastcall allocates the first two DWORD (SImode) or
-            smaller arguments to ECX and EDX.  */
+            smaller arguments to ECX and EDX if it isn't an
+            aggregate type .  */
          if (cum->fastcall)
            {
-             if (mode == BLKmode || mode == DImode)
+             if (mode == BLKmode
+                 || mode == DImode
+                 || (type && AGGREGATE_TYPE_P (type)))
                break;
 
              /* ECX not EAX is the first allocated register.  */
@@ -6757,7 +6784,7 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
 
   /* Special case: on K6, [%esi] makes the instruction vector decoded.
      Avoid this by transforming to [%esi+0].  */
-  if (ix86_tune == PROCESSOR_K6 && !optimize_size
+  if (TARGET_K6 && !optimize_size
       && base_reg && !index_reg && !disp
       && REG_P (base_reg)
       && REGNO_REG_CLASS (REGNO (base_reg)) == SIREG)
@@ -8185,7 +8212,8 @@ output_pic_addr_const (FILE *file, rtx x, int code)
          fputs ("@PLTOFF", file);
          break;
        case UNSPEC_GOTPCREL:
-         fputs ("@GOTPCREL(%rip)", file);
+         fputs (ASSEMBLER_DIALECT == ASM_ATT ?
+                "@GOTPCREL(%rip)" : "@GOTPCREL[rip]", file);
          break;
        case UNSPEC_GOTTPOFF:
          /* FIXME: This might be @TPOFF in Sun ld too.  */
@@ -8205,7 +8233,8 @@ output_pic_addr_const (FILE *file, rtx x, int code)
          break;
        case UNSPEC_GOTNTPOFF:
          if (TARGET_64BIT)
-           fputs ("@GOTTPOFF(%rip)", file);
+           fputs (ASSEMBLER_DIALECT == ASM_ATT ?
+                  "@GOTTPOFF(%rip)": "@GOTTPOFF[rip]", file);
          else
            fputs ("@GOTNTPOFF", file);
          break;
@@ -8531,15 +8560,23 @@ put_condition_code (enum rtx_code code, enum machine_mode mode, int reverse,
 void
 print_reg (rtx x, int code, FILE *file)
 {
-  gcc_assert (REGNO (x) != ARG_POINTER_REGNUM
-             && REGNO (x) != FRAME_POINTER_REGNUM
-             && REGNO (x) != FLAGS_REG
-             && REGNO (x) != FPSR_REG
-             && REGNO (x) != FPCR_REG);
+  gcc_assert (x == pc_rtx
+             || (REGNO (x) != ARG_POINTER_REGNUM
+                 && REGNO (x) != FRAME_POINTER_REGNUM
+                 && REGNO (x) != FLAGS_REG
+                 && REGNO (x) != FPSR_REG
+                 && REGNO (x) != FPCR_REG));
 
-  if (ASSEMBLER_DIALECT == ASM_ATT || USER_LABEL_PREFIX[0] == 0)
+  if (ASSEMBLER_DIALECT == ASM_ATT)
     putc ('%', file);
 
+  if (x == pc_rtx)
+    {
+      gcc_assert (TARGET_64BIT);
+      fputs ("rip", file);
+      return;
+    }
+
   if (code == 'w' || MMX_REG_P (x))
     code = 2;
   else if (code == 'b')
@@ -9036,8 +9073,9 @@ print_operand (FILE *file, rtx x, int code)
 
   else if (MEM_P (x))
     {
-      /* No `byte ptr' prefix for call instructions.  */
-      if (ASSEMBLER_DIALECT == ASM_INTEL && code != 'X' && code != 'P')
+      /* No `byte ptr' prefix for call instructions or BLKmode operands.  */
+      if (ASSEMBLER_DIALECT == ASM_INTEL && code != 'X' && code != 'P'
+         && GET_MODE (x) != BLKmode)
        {
          const char * size;
          switch (GET_MODE_SIZE (GET_MODE (x)))
@@ -9047,7 +9085,12 @@ print_operand (FILE *file, rtx x, int code)
            case 4: size = "DWORD"; break;
            case 8: size = "QWORD"; break;
            case 12: size = "XWORD"; break;
-           case 16: size = "XMMWORD"; break;
+           case 16:
+             if (GET_MODE (x) == XFmode)
+               size = "XWORD";
+              else
+               size = "XMMWORD";
+              break;
            default:
              gcc_unreachable ();
            }
@@ -9165,7 +9208,7 @@ print_operand_address (FILE *file, rtx addr)
       break;
     case SEG_FS:
     case SEG_GS:
-      if (USER_LABEL_PREFIX[0] == 0)
+      if (ASSEMBLER_DIALECT == ASM_ATT)
        putc ('%', file);
       fputs ((parts.seg == SEG_FS ? "fs:" : "gs:"), file);
       break;
@@ -9173,6 +9216,21 @@ print_operand_address (FILE *file, rtx addr)
       gcc_unreachable ();
     }
 
+  /* Use one byte shorter RIP relative addressing for 64bit mode.  */
+  if (TARGET_64BIT && !base && !index)
+    {
+      rtx symbol = disp;
+
+      if (GET_CODE (disp) == CONST
+         && GET_CODE (XEXP (disp, 0)) == PLUS
+         && CONST_INT_P (XEXP (XEXP (disp, 0), 1)))
+       symbol = XEXP (XEXP (disp, 0), 0);
+
+      if (GET_CODE (symbol) == LABEL_REF
+         || (GET_CODE (symbol) == SYMBOL_REF
+             && SYMBOL_REF_TLS_MODEL (symbol) == 0))
+       base = pc_rtx;
+    }
   if (!base && !index)
     {
       /* Displacement only requires special attention.  */
@@ -9180,30 +9238,13 @@ print_operand_address (FILE *file, rtx addr)
       if (CONST_INT_P (disp))
        {
          if (ASSEMBLER_DIALECT == ASM_INTEL && parts.seg == SEG_DEFAULT)
-           {
-             if (USER_LABEL_PREFIX[0] == 0)
-               putc ('%', file);
-             fputs ("ds:", file);
-           }
+           fputs ("ds:", file);
          fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (disp));
        }
       else if (flag_pic)
        output_pic_addr_const (file, disp, 0);
       else
        output_addr_const (file, disp);
-
-      /* Use one byte shorter RIP relative addressing for 64bit mode.  */
-      if (TARGET_64BIT)
-       {
-         if (GET_CODE (disp) == CONST
-             && GET_CODE (XEXP (disp, 0)) == PLUS
-             && CONST_INT_P (XEXP (XEXP (disp, 0), 1)))
-           disp = XEXP (XEXP (disp, 0), 0);
-         if (GET_CODE (disp) == LABEL_REF
-             || (GET_CODE (disp) == SYMBOL_REF
-                 && SYMBOL_REF_TLS_MODEL (disp) == 0))
-           fputs ("(%rip)", file);
-       }
     }
   else
     {
@@ -9319,7 +9360,8 @@ output_addr_const_extra (FILE *file, rtx x)
     case UNSPEC_GOTNTPOFF:
       output_addr_const (file, op);
       if (TARGET_64BIT)
-       fputs ("@GOTTPOFF(%rip)", file);
+       fputs (ASSEMBLER_DIALECT == ASM_ATT ?
+              "@GOTTPOFF(%rip)" : "@GOTTPOFF[rip]", file);
       else
        fputs ("@GOTNTPOFF", file);
       break;
@@ -15327,12 +15369,7 @@ ix86_expand_movmem (rtx dst, rtx src, rtx count_exp, rtx align_exp,
 
   /* Alignment code needs count to be in register.  */
   if (CONST_INT_P (count_exp) && desired_align > align)
-    {
-      enum machine_mode mode = SImode;
-      if (TARGET_64BIT && (count & ~0xffffffff))
-       mode = DImode;
-      count_exp = force_reg (mode, count_exp);
-    }
+    count_exp = force_reg (counter_mode (count_exp), count_exp);
   gcc_assert (desired_align >= 1 && align >= 1);
 
   /* Ensure that alignment prologue won't copy past end of block.  */
@@ -15343,29 +15380,48 @@ ix86_expand_movmem (rtx dst, rtx src, rtx count_exp, rtx align_exp,
         Make sure it is power of 2.  */
       epilogue_size_needed = smallest_pow2_greater_than (epilogue_size_needed);
 
-      label = gen_label_rtx ();
-      emit_cmp_and_jump_insns (count_exp,
-                              GEN_INT (epilogue_size_needed),
-                              LTU, 0, counter_mode (count_exp), 1, label);
-      if (GET_CODE (count_exp) == CONST_INT)
-       ;
-      else if (expected_size == -1 || expected_size < epilogue_size_needed)
-       predict_jump (REG_BR_PROB_BASE * 60 / 100);
+      if (CONST_INT_P (count_exp))
+       {
+         if (UINTVAL (count_exp) < (unsigned HOST_WIDE_INT)epilogue_size_needed)
+           goto epilogue;
+       }
       else
-       predict_jump (REG_BR_PROB_BASE * 20 / 100);
+       {
+         label = gen_label_rtx ();
+         emit_cmp_and_jump_insns (count_exp,
+                                  GEN_INT (epilogue_size_needed),
+                                  LTU, 0, counter_mode (count_exp), 1, label);
+         if (expected_size == -1 || expected_size < epilogue_size_needed)
+           predict_jump (REG_BR_PROB_BASE * 60 / 100);
+         else
+           predict_jump (REG_BR_PROB_BASE * 20 / 100);
+       }
     }
+
   /* Emit code to decide on runtime whether library call or inline should be
      used.  */
   if (dynamic_check != -1)
     {
-      rtx hot_label = gen_label_rtx ();
-      jump_around_label = gen_label_rtx ();
-      emit_cmp_and_jump_insns (count_exp, GEN_INT (dynamic_check - 1),
-                              LEU, 0, GET_MODE (count_exp), 1, hot_label);
-      predict_jump (REG_BR_PROB_BASE * 90 / 100);
-      emit_block_move_via_libcall (dst, src, count_exp, false);
-      emit_jump (jump_around_label);
-      emit_label (hot_label);
+      if (CONST_INT_P (count_exp))
+       {
+         if (UINTVAL (count_exp) >= (unsigned HOST_WIDE_INT)dynamic_check)
+           {
+             emit_block_move_via_libcall (dst, src, count_exp, false);
+             count_exp = const0_rtx;
+             goto epilogue;
+           }
+       }
+      else
+       {
+         rtx hot_label = gen_label_rtx ();
+         jump_around_label = gen_label_rtx ();
+         emit_cmp_and_jump_insns (count_exp, GEN_INT (dynamic_check - 1),
+                                  LEU, 0, GET_MODE (count_exp), 1, hot_label);
+         predict_jump (REG_BR_PROB_BASE * 90 / 100);
+         emit_block_move_via_libcall (dst, src, count_exp, false);
+         emit_jump (jump_around_label);
+         emit_label (hot_label);
+       }
     }
 
   /* Step 2: Alignment prologue.  */
@@ -15438,7 +15494,7 @@ ix86_expand_movmem (rtx dst, rtx src, rtx count_exp, rtx align_exp,
     }
 
   /* Step 4: Epilogue to copy the remaining bytes.  */
-
+ epilogue:
   if (label)
     {
       /* When the main loop is done, COUNT_EXP might hold original count,
@@ -16622,15 +16678,18 @@ ix86_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
 static int
 ia32_multipass_dfa_lookahead (void)
 {
-  if (ix86_tune == PROCESSOR_PENTIUM)
-    return 2;
+  switch (ix86_tune)
+    {
+    case PROCESSOR_PENTIUM:
+      return 2;
 
-  if (ix86_tune == PROCESSOR_PENTIUMPRO
-      || ix86_tune == PROCESSOR_K6)
-    return 1;
+    case PROCESSOR_PENTIUMPRO:
+    case PROCESSOR_K6:
+      return 1;
 
-  else
-    return 0;
+    default:
+      return 0;
+    }
 }
 
 \f
@@ -22736,7 +22795,7 @@ x86_file_start (void)
   if (X86_FILE_START_FLTUSED)
     fputs ("\t.global\t__fltused\n", asm_out_file);
   if (ix86_asm_dialect == ASM_INTEL)
-    fputs ("\t.intel_syntax\n", asm_out_file);
+    fputs ("\t.intel_syntax noprefix\n", asm_out_file);
 }
 
 int
@@ -24841,7 +24900,8 @@ ix86_expand_round (rtx operand0, rtx operand1)
    NUM is the number of operands.
    USES_OC0 is true if the instruction uses OC0 and provides 4 variants.
    NUM_MEMORY is the maximum number of memory operands to accept.  */
-bool ix86_sse5_valid_op_p (rtx operands[], rtx insn, int num, bool uses_oc0, int num_memory)
+bool
+ix86_sse5_valid_op_p (rtx operands[], rtx insn, int num, bool uses_oc0, int num_memory)
 {
   int mem_mask;
   int mem_count;