OSDN Git Service

* config/alpha/alpha.c (alpha_use_dfa_pipeline_interface): Remove.
[pf3gnuchains/gcc-fork.git] / gcc / config / sparc / sparc.c
index cf2526f..5439f03 100644 (file)
@@ -54,10 +54,10 @@ Boston, MA 02111-1307, USA.  */
    "or %o7,%g0,X; call Y; or X,%g0,%o7" always, so that it can be optimized.
    With sethi/jmp, neither 'as' nor 'ld' has an easy way how to find out if
    somebody does not branch between the sethi and jmp.  */
-#define SIBCALL_SLOT_EMPTY_P 0
+#define LEAF_SIBCALL_SLOT_RESERVED_P 1
 #else
-#define SIBCALL_SLOT_EMPTY_P \
-  ((TARGET_ARCH32 || TARGET_CM_MEDLOW) && ! flag_pic)
+#define LEAF_SIBCALL_SLOT_RESERVED_P \
+  ((TARGET_ARCH64 && !TARGET_CM_MEDLOW) || flag_pic)
 #endif
 
 /* Global variables for machine-dependent things.  */
@@ -161,7 +161,6 @@ static void sparc_elf_asm_named_section (const char *, unsigned int);
 static int sparc_adjust_cost (rtx, rtx, rtx, int);
 static int sparc_issue_rate (void);
 static void sparc_sched_init (FILE *, int, int);
-static int sparc_use_dfa_pipeline_interface (void);
 static int sparc_use_sched_lookahead (void);
 
 static void emit_soft_tfmode_libcall (const char *, int, rtx *);
@@ -242,7 +241,7 @@ enum processor_type sparc_cpu;
 #undef TARGET_SCHED_INIT
 #define TARGET_SCHED_INIT sparc_sched_init
 #undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
-#define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE sparc_use_dfa_pipeline_interface
+#define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE hook_int_void_1
 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD sparc_use_sched_lookahead
 
@@ -2946,7 +2945,7 @@ eligible_for_sibcall_delay (rtx trial)
     {
       /* If the tail call is done using the call instruction,
         we have to restore %o7 in the delay slot.  */
-      if (! SIBCALL_SLOT_EMPTY_P)
+      if (LEAF_SIBCALL_SLOT_RESERVED_P)
        return 0;
 
       /* %g1 is used to build the function address */
@@ -3059,8 +3058,8 @@ sparc_cannot_force_const_mem (rtx x)
 static GTY(()) rtx global_offset_table;
 
 /* The function we use to get at it.  */
-static GTY(()) rtx get_pc_symbol;
-static GTY(()) char get_pc_symbol_name[256];
+static GTY(()) rtx add_pc_to_pic_symbol;
+static GTY(()) char add_pc_to_pic_symbol_name[256];
 
 /* Ensure that we are not using patterns that are not OK with PIC.  */
 
@@ -3643,33 +3642,33 @@ legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, enum machine_mode mode)
 static void
 load_pic_register (void)
 {
-  /* Labels to get the PC in the prologue of this function.  */
   int orig_flag_pic = flag_pic;
 
-  /* If we haven't emitted the special get_pc helper function, do so now.  */
-  if (get_pc_symbol_name[0] == 0)
+  /* If we haven't emitted the special helper function, do so now.  */
+  if (add_pc_to_pic_symbol_name[0] == 0)
     {
+      const char *pic_name = reg_names[REGNO (pic_offset_table_rtx)];
       int align;
 
-      ASM_GENERATE_INTERNAL_LABEL (get_pc_symbol_name, "LGETPC", 0);
+      ASM_GENERATE_INTERNAL_LABEL (add_pc_to_pic_symbol_name, "LADDPC", 0);
       text_section ();
 
       align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
       if (align > 0)
        ASM_OUTPUT_ALIGN (asm_out_file, align);
-      (*targetm.asm_out.internal_label) (asm_out_file, "LGETPC", 0);
-      fputs ("\tretl\n\tadd\t%o7, %l7, %l7\n", asm_out_file);
+      ASM_OUTPUT_LABEL (asm_out_file, add_pc_to_pic_symbol_name);
+      fprintf (asm_out_file, "\tjmp %%o7+8\n\t add\t%%o7, %s, %s\n",
+              pic_name, pic_name);
     }
 
   /* Initialize every time through, since we can't easily
      know this to be permanent.  */
   global_offset_table = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
-  get_pc_symbol = gen_rtx_SYMBOL_REF (Pmode, get_pc_symbol_name);
-  flag_pic = 0;
-
-  emit_insn (gen_get_pc (pic_offset_table_rtx, global_offset_table,
-                        get_pc_symbol));
+  add_pc_to_pic_symbol = gen_rtx_SYMBOL_REF (Pmode, add_pc_to_pic_symbol_name);
 
+  flag_pic = 0;
+  emit_insn (gen_load_pcrel_sym (pic_offset_table_rtx, global_offset_table,
+                                add_pc_to_pic_symbol));
   flag_pic = orig_flag_pic;
 
   /* Need to emit this whether or not we obey regdecls,
@@ -4355,17 +4354,16 @@ sparc_asm_function_epilogue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
 /* Output a 'restore' instruction.  */
  
 static void
-output_restore (rtx insn)
+output_restore (rtx pat)
 {
-  rtx operands[3], pat;
+  rtx operands[3];
 
-  if (! insn)
+  if (! pat)
     {
       fputs ("\t restore\n", asm_out_file);
       return;
     }
 
-  pat = PATTERN (insn);
   if (GET_CODE (pat) != SET)
     abort ();
 
@@ -4483,7 +4481,7 @@ output_return (rtx insn)
            {
              fprintf (asm_out_file, "\tjmp\t%%i7+%d\n",
                       sparc_skip_caller_unimp ? 12 : 8);
-             output_restore (delay);
+             output_restore (pat);
            }
 
          PATTERN (delay) = gen_blockage ();
@@ -4521,7 +4519,7 @@ output_sibcall (rtx insn, rtx call_operand)
         register window.  We simply output the jump to the function and
         the insn in the delay slot (if any).  */
 
-      if (! SIBCALL_SLOT_EMPTY_P && delay_slot_filled_p)
+      if (LEAF_SIBCALL_SLOT_RESERVED_P && delay_slot_filled_p)
        abort();
 
       if (delay_slot_filled_p)
@@ -4560,13 +4558,13 @@ output_sibcall (rtx insn, rtx call_operand)
          if (! delay)
            abort ();
 
-         output_restore (delay);
+         output_restore (PATTERN (delay));
 
          PATTERN (delay) = gen_blockage ();
          INSN_CODE (delay) = -1;
        }
       else
-       output_restore (0);
+       output_restore (NULL_RTX);
     }
 
   return "";
@@ -5825,11 +5823,11 @@ sparc_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
 
    INSN, if set, is the insn.  */
 
-char *
+const char *
 output_cbranch (rtx op, rtx dest, int label, int reversed, int annul,
                int noop, rtx insn)
 {
-  static char string[50];
+  static char string[64];
   enum rtx_code code = GET_CODE (op);
   rtx cc_reg = XEXP (op, 0);
   enum machine_mode mode = GET_MODE (cc_reg);
@@ -5845,7 +5843,7 @@ output_cbranch (rtx op, rtx dest, int label, int reversed, int annul,
      to
 
      be,pn %xcc, .+12
-     nop
+      nop
      ba .LC30
 
      and
@@ -5855,7 +5853,7 @@ output_cbranch (rtx op, rtx dest, int label, int reversed, int annul,
      to
 
      fbe,pt %fcc2, .+16
-     nop
+      nop
      ba .LC29  */
 
   far = get_attr_length (insn) >= 3;
@@ -6048,10 +6046,10 @@ output_cbranch (rtx op, rtx dest, int label, int reversed, int annul,
   p = strchr (p, '\0');
   if (far)
     {
-      strcpy (p, ".+12\n\tnop\n\tb\t");
+      strcpy (p, ".+12\n\t nop\n\tb\t");
       if (annul || noop)
         p[3] = '6';
-      p += 13;
+      p += 14;
     }
   *p++ = '%';
   *p++ = 'l';
@@ -6060,7 +6058,7 @@ output_cbranch (rtx op, rtx dest, int label, int reversed, int annul,
   *p++ = label + '0';
   *p = '\0';
   if (noop)
-    strcpy (p, "\n\tnop");
+    strcpy (p, "\n\t nop");
 
   return string;
 }
@@ -6289,11 +6287,11 @@ sparc_emit_fixunsdi (rtx *operands, enum machine_mode mode)
 
    NOOP is nonzero if we have to follow this branch by a noop.  */
 
-char *
+const char *
 output_v9branch (rtx op, rtx dest, int reg, int label, int reversed,
                 int annul, int noop, rtx insn)
 {
-  static char string[50];
+  static char string[64];
   enum rtx_code code = GET_CODE (op);
   enum machine_mode mode = GET_MODE (XEXP (op, 0));
   rtx note;
@@ -6308,7 +6306,7 @@ output_v9branch (rtx op, rtx dest, int reg, int label, int reversed,
      to
      
      brz,pn %g1, .+12
-     nop
+      nop
      ba,pt %xcc, .LC30
      
      and
@@ -6318,7 +6316,7 @@ output_v9branch (rtx op, rtx dest, int reg, int label, int reversed,
      to
      
      brlz,pt %o1, .+16
-     nop
+      nop
      ba,pt %xcc, .LC29  */
 
   far = get_attr_length (insn) >= 3;
@@ -6399,10 +6397,10 @@ output_v9branch (rtx op, rtx dest, int reg, int label, int reversed,
            veryfar = 0;
        }
 
-      strcpy (p, ".+12\n\tnop\n\t");
+      strcpy (p, ".+12\n\t nop\n\t");
       if (annul || noop)
         p[3] = '6';
-      p += 11;
+      p += 12;
       if (veryfar)
        {
          strcpy (p, "b\t");
@@ -6420,7 +6418,7 @@ output_v9branch (rtx op, rtx dest, int reg, int label, int reversed,
   *p = '\0';
 
   if (noop)
-    strcpy (p, "\n\tnop");
+    strcpy (p, "\n\t nop");
 
   return string;
 }
@@ -7450,18 +7448,6 @@ sparc_sched_init (FILE *dump ATTRIBUTE_UNUSED,
 }
   
 static int
-sparc_use_dfa_pipeline_interface (void)
-{
-  if ((1 << sparc_cpu) &
-      ((1 << PROCESSOR_ULTRASPARC) | (1 << PROCESSOR_CYPRESS) |
-       (1 << PROCESSOR_SUPERSPARC) | (1 << PROCESSOR_HYPERSPARC) |
-       (1 << PROCESSOR_SPARCLITE86X) | (1 << PROCESSOR_TSC701) |
-       (1 << PROCESSOR_ULTRASPARC3)))
-    return 1;
-  return 0;
-}
-
-static int
 sparc_use_sched_lookahead (void)
 {
   if (sparc_cpu == PROCESSOR_ULTRASPARC
@@ -7721,8 +7707,8 @@ sparc_check_64 (rtx x, rtx insn)
 
 /* Returns assembly code to perform a DImode shift using
    a 64-bit global or out register on SPARC-V8+.  */
-char *
-sparc_v8plus_shift (rtx *operands, rtx insn, const char *opcode)
+const char *
+output_v8plus_shift (rtx *operands, rtx insn, const char *opcode)
 {
   static char asm_code[60];
 
@@ -8361,6 +8347,7 @@ sparc_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
   epilogue_completed = 1;
   no_new_pseudos = 1;
   current_function_uses_only_leaf_regs = 1;
+  reset_block_changes ();
 
   emit_note (NOTE_INSN_PROLOGUE_END);