OSDN Git Service

* config/rs6000/rs6000.h (FUNCTION_MODE): Always use SImode.
authordje <dje@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 8 Jan 2003 23:05:22 +0000 (23:05 +0000)
committerdje <dje@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 8 Jan 2003 23:05:22 +0000 (23:05 +0000)
        * config/rs6000/rs6000.c (TARGET_ASM_CAN_OUTPUT_MI_THUNK): Redefine
        as hook_bool_tree_hwi_hwi_tree_true.
        (rs6000_emit_allocate_stack): Use TARGET_32BIT.
        (rs6000_emit_epilogue): Same.
        (rs6000_output_mi_thunk): Re-implement as RTL.
        * config/rs6000/xcoff.h (ASM_DECLARE_FUNCTION_NAME): Call
        xcoffout_declare_function if any debugging enabled.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@61058 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h
gcc/config/rs6000/xcoff.h

index 91d8a3d..ed19269 100644 (file)
@@ -1,3 +1,14 @@
+2003-01-08  David Edelsohn  <edelsohn@gnu.org>
+
+       * config/rs6000/rs6000.h (FUNCTION_MODE): Always use SImode.
+       * config/rs6000/rs6000.c (TARGET_ASM_CAN_OUTPUT_MI_THUNK): Redefine
+       as hook_bool_tree_hwi_hwi_tree_true.
+       (rs6000_emit_allocate_stack): Use TARGET_32BIT.
+       (rs6000_emit_epilogue): Same.
+       (rs6000_output_mi_thunk): Re-implement as RTL.
+       * config/rs6000/xcoff.h (ASM_DECLARE_FUNCTION_NAME): Call
+       xcoffout_declare_function if any debugging enabled.
+
 2003-01-08  Chris Demetriou  <cgd@broadcom.com>
 
        * config.gcc (mipsisa32r2-*-elf*, mipsisa32r2el-*-elf*): New
index 0daf648..292a0b8 100644 (file)
@@ -207,7 +207,7 @@ static unsigned int rs6000_elf_section_type_flags PARAMS ((tree, const char *,
 static void rs6000_elf_asm_out_constructor PARAMS ((rtx, int));
 static void rs6000_elf_asm_out_destructor PARAMS ((rtx, int));
 static void rs6000_elf_select_section PARAMS ((tree, int,
-                                                unsigned HOST_WIDE_INT));
+                                              unsigned HOST_WIDE_INT));
 static void rs6000_elf_unique_section PARAMS ((tree, int));
 static void rs6000_elf_select_rtx_section PARAMS ((enum machine_mode, rtx,
                                                   unsigned HOST_WIDE_INT));
@@ -388,12 +388,8 @@ static const char alt_reg_names[][8] =
 #undef TARGET_ASM_OUTPUT_MI_THUNK
 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
 
-/* ??? Should work everywhere, but ask dje@watson.ibm.com before
-   enabling for AIX.  */
-#if TARGET_OBJECT_FORMAT != OBJECT_XCOFF
 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
-#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
-#endif
+#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
 
 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
@@ -9916,14 +9912,14 @@ rs6000_emit_allocate_stack (size, copy_r12)
          && REGNO (stack_limit_rtx) > 1 
          && REGNO (stack_limit_rtx) <= 31)
        {
-         emit_insn (Pmode == SImode
+         emit_insn (TARGET_32BIT
                     ? gen_addsi3 (tmp_reg,
                                   stack_limit_rtx,
                                   GEN_INT (size))
                     : gen_adddi3 (tmp_reg,
                                   stack_limit_rtx,
                                   GEN_INT (size)));
-         
+
          emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
                                    const0_rtx));
        }
@@ -9935,7 +9931,7 @@ rs6000_emit_allocate_stack (size, copy_r12)
                                      gen_rtx_PLUS (Pmode, 
                                                    stack_limit_rtx, 
                                                    GEN_INT (size)));
-         
+
          emit_insn (gen_elf_high (tmp_reg, toload));
          emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
          emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
@@ -9959,24 +9955,22 @@ rs6000_emit_allocate_stack (size, copy_r12)
          try_split (PATTERN (insn), insn, 0);
          todec = tmp_reg;
        }
-      
-      if (Pmode == SImode)
-       insn = emit_insn (gen_movsi_update (stack_reg, stack_reg, 
-                                           todec, stack_reg));
-      else
-       insn = emit_insn (gen_movdi_update (stack_reg, stack_reg, 
+
+      insn = emit_insn (TARGET_32BIT
+                       ? gen_movsi_update (stack_reg, stack_reg,
+                                           todec, stack_reg)
+                       : gen_movdi_update (stack_reg, stack_reg, 
                                            todec, stack_reg));
     }
   else
     {
-      if (Pmode == SImode)
-       insn = emit_insn (gen_addsi3 (stack_reg, stack_reg, todec));
-      else
-       insn = emit_insn (gen_adddi3 (stack_reg, stack_reg, todec));
+      insn = emit_insn (TARGET_32BIT
+                       ? gen_addsi3 (stack_reg, stack_reg, todec)
+                       : gen_adddi3 (stack_reg, stack_reg, todec));
       emit_move_insn (gen_rtx_MEM (Pmode, stack_reg),
                      gen_rtx_REG (Pmode, 12));
     }
-  
   RTX_FRAME_RELATED_P (insn) = 1;
   REG_NOTES (insn) = 
     gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
@@ -10970,7 +10964,7 @@ rs6000_emit_epilogue (sibcall)
        }
       else if (sp_offset != 0)
        {
-         emit_insn (Pmode == SImode
+         emit_insn (TARGET_32BIT
                     ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
                                   GEN_INT (sp_offset))
                     : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
@@ -10981,7 +10975,7 @@ rs6000_emit_epilogue (sibcall)
   if (current_function_calls_eh_return)
     {
       rtx sa = EH_RETURN_STACKADJ_RTX;
-      emit_insn (Pmode == SImode
+      emit_insn (TARGET_32BIT
                 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx, sa)
                 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx, sa));
     }
@@ -11344,159 +11338,99 @@ rs6000_output_mi_thunk (file, thunk_fndecl, delta, vcall_offset, function)
      FILE *file;
      tree thunk_fndecl ATTRIBUTE_UNUSED;
      HOST_WIDE_INT delta;
-     HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED;
+     HOST_WIDE_INT vcall_offset;
      tree function;
 {
-  const char *this_reg =
-    reg_names[ aggregate_value_p (TREE_TYPE (TREE_TYPE (function))) ? 4 : 3 ];
-  const char *prefix;
-  const char *fname;
-  const char *r0        = reg_names[0];
-  const char *toc       = reg_names[2];
-  const char *schain    = reg_names[11];
-  const char *r12       = reg_names[12];
-  char buf[512];
-  static int labelno = 0;
-
-  /* Small constants that can be done by one add instruction.  */
-  if (delta >= -32768 && delta <= 32767)
-    {
-      if (! TARGET_NEW_MNEMONICS)
-       fprintf (file, "\tcal %s,%d(%s)\n", this_reg, (int) delta, this_reg);
-      else
-       fprintf (file, "\taddi %s,%s,%d\n", this_reg, this_reg, (int) delta);
-    }
+  rtx this, insn, funexp;
 
-  /* 64-bit constants.  If "int" is 32 bits, we'll never hit this abort.  */
-  else if (TARGET_64BIT && (delta < -2147483647 - 1 || delta > 2147483647))
-    abort ();
+  reload_completed = 1;
+  no_new_pseudos = 1;
 
-  /* Large constants that can be done by one addis instruction.  */
-  else if ((delta & 0xffff) == 0)
-    asm_fprintf (file, "\t{cau|addis} %s,%s,%d\n", this_reg, this_reg,
-                (int) (delta >> 16));
+  /* Mark the end of the (empty) prologue.  */
+  emit_note (NULL, NOTE_INSN_PROLOGUE_END);
 
-  /* 32-bit constants that can be done by an add and addis instruction.  */
+  /* Find the "this" pointer.  If the function returns a structure,
+     the structure return pointer is in r3.  */
+  if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function))))
+    this = gen_rtx_REG (Pmode, 4);
   else
-    {
-      /* Break into two pieces, propagating the sign bit from the low
-        word to the upper word.  */
-      int delta_low  = ((delta & 0xffff) ^ 0x8000) - 0x8000;
-      int delta_high = (delta - delta_low) >> 16;
+    this = gen_rtx_REG (Pmode, 3);
 
-      asm_fprintf (file, "\t{cau|addis} %s,%s,%d\n", this_reg, this_reg,
-                  delta_high);
-
-      if (! TARGET_NEW_MNEMONICS)
-       fprintf (file, "\tcal %s,%d(%s)\n", this_reg, delta_low, this_reg);
-      else
-       fprintf (file, "\taddi %s,%s,%d\n", this_reg, this_reg, delta_low);
+  /* Apply the constant offset, if required.  */
+  if (delta)
+    {
+      rtx delta_rtx = GEN_INT (delta);
+      emit_insn (TARGET_32BIT
+                ? gen_addsi3 (this, this, delta_rtx)
+                : gen_adddi3 (this, this, delta_rtx));
     }
 
-  /* Get the prefix in front of the names.  */
-  switch (DEFAULT_ABI)
+  /* Apply the offset from the vtable, if required.  */
+  if (vcall_offset)
     {
-    default:
-      abort ();
+      rtx vcall_offset_rtx = GEN_INT (vcall_offset);
+      rtx tmp = gen_rtx_REG (Pmode, 12);
 
-    case ABI_AIX:
-      prefix = ".";
-      break;
-
-    case ABI_V4:
-    case ABI_AIX_NODESC:
-    case ABI_DARWIN:
-      prefix = "";
-      break;
+      emit_move_insn (tmp, gen_rtx_MEM (Pmode, this));
+      emit_insn (TARGET_32BIT
+                ? gen_addsi3 (tmp, tmp, vcall_offset_rtx)
+                : gen_adddi3 (tmp, tmp, vcall_offset_rtx));
+      emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
+      emit_insn (TARGET_32BIT
+                ? gen_addsi3 (this, this, tmp)
+                : gen_adddi3 (this, this, tmp));
     }
 
-  /* If the function is compiled in this module, jump to it directly.
-     Otherwise, load up its address and jump to it.  */
-
-  fname = XSTR (XEXP (DECL_RTL (function), 0), 0);
+  /* Generate a tail call to the target function.  */
+  if (!TREE_USED (function))
+    {
+      assemble_external (function);
+      TREE_USED (function) = 1;
+    }
+  funexp = XEXP (DECL_RTL (function), 0);
 
-  if (current_file_function_operand (XEXP (DECL_RTL (function), 0), VOIDmode)
+  SYMBOL_REF_FLAG (funexp) = 0;
+  if (current_file_function_operand (funexp, VOIDmode)
       && (! lookup_attribute ("longcall",
                              TYPE_ATTRIBUTES (TREE_TYPE (function)))
          || lookup_attribute ("shortcall",
                               TYPE_ATTRIBUTES (TREE_TYPE (function)))))
-    {
-      fprintf (file, "\tb %s", prefix);
-      assemble_name (file, fname);
-      if (DEFAULT_ABI == ABI_V4 && flag_pic) fputs ("@local", file);
-      putc ('\n', file);
-    }
-
-  else
-    {
-      switch (DEFAULT_ABI)
-       {
-       default:
-         abort ();
-
-       case ABI_AIX:
-         /* Set up a TOC entry for the function.  */
-         ASM_GENERATE_INTERNAL_LABEL (buf, "Lthunk", labelno);
-         toc_section ();
-         (*targetm.asm_out.internal_label) (file, "Lthunk", labelno);
-         labelno++;
+    SYMBOL_REF_FLAG (funexp) = 1;
 
-         if (TARGET_MINIMAL_TOC)
-           fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
-         else
-           {
-             fputs ("\t.tc ", file);
-             assemble_name (file, fname);
-             fputs ("[TC],", file);
-           }
-         assemble_name (file, fname);
-         putc ('\n', file);
-         function_section (current_function_decl);
-         if (TARGET_MINIMAL_TOC)
-           asm_fprintf (file, (TARGET_32BIT)
-                        ? "\t{l|lwz} %s,%s(%s)\n" : "\tld %s,%s(%s)\n", r12,
-                        TARGET_ELF ? ".LCTOC0@toc" : ".LCTOC..1", toc);
-         asm_fprintf (file, (TARGET_32BIT) ? "\t{l|lwz} %s," : "\tld %s,", r12);
-         assemble_name (file, buf);
-         if (TARGET_ELF && TARGET_MINIMAL_TOC)
-           fputs ("-(.LCTOC1)", file);
-         asm_fprintf (file, "(%s)\n", TARGET_MINIMAL_TOC ? r12 : toc);
-         asm_fprintf (file,
-                      (TARGET_32BIT) ? "\t{l|lwz} %s,0(%s)\n" : "\tld %s,0(%s)\n",
-                      r0, r12);
-
-         asm_fprintf (file,
-                      (TARGET_32BIT) ? "\t{l|lwz} %s,4(%s)\n" : "\tld %s,8(%s)\n",
-                      toc, r12);
-
-         asm_fprintf (file, "\tmtctr %s\n", r0);
-         asm_fprintf (file,
-                      (TARGET_32BIT) ? "\t{l|lwz} %s,8(%s)\n" : "\tld %s,16(%s)\n",
-                      schain, r12);
-
-         asm_fprintf (file, "\tbctr\n");
-         break;
-
-       case ABI_AIX_NODESC:
-       case ABI_V4:
-         fprintf (file, "\tb %s", prefix);
-         assemble_name (file, fname);
-         if (flag_pic) fputs ("@plt", file);
-         putc ('\n', file);
-         break;
+  funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
 
 #if TARGET_MACHO
-       case ABI_DARWIN:
-         fprintf (file, "\tb %s", prefix);
-         if (flag_pic && !machopic_name_defined_p (fname))
-           assemble_name (file, machopic_stub_name (fname));
-         else
-           assemble_name (file, fname);
-         putc ('\n', file);
-         break;
+  if (flag_pic)
+    funexp = machopic_indirect_call_target (funexp);
 #endif
-       }
-    }
+
+  /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
+     generate sibcall RTL explicitly to avoid constraint abort.  */
+  insn = emit_call_insn (
+          gen_rtx_PARALLEL (VOIDmode,
+            gen_rtvec (4,
+                       gen_rtx_CALL (VOIDmode,
+                                     funexp, const0_rtx),
+                       gen_rtx_USE (VOIDmode, const0_rtx),
+                       gen_rtx_USE (VOIDmode,
+                                    gen_rtx_REG (SImode,
+                                                 LINK_REGISTER_REGNUM)),
+                       gen_rtx_RETURN (VOIDmode))));
+  SIBLING_CALL_P (insn) = 1;
+  emit_barrier ();
+
+  /* Run just enough of rest_of_compilation to get the insns emitted.
+     There's not really enough bulk here to make other passes such as
+     instruction scheduling worth while.  Note that use_thunk calls
+     assemble_start_function and assemble_end_function.  */
+  insn = get_insns ();
+  shorten_branches (insn);
+  final_start_function (insn, file, 1);
+  final (insn, file, 1, 0);
+  final_end_function ();
+
+  reload_completed = 0;
+  no_new_pseudos = 0;
 }
 \f
 /* A quick summary of the various types of 'constant-pool tables'
index 08f32be..6756804 100644 (file)
@@ -2274,7 +2274,7 @@ do {                                                                           \
 
 /* Mode of a function address in a call instruction (for indexing purposes).
    Doesn't matter on RS/6000.  */
-#define FUNCTION_MODE (TARGET_32BIT ? SImode : DImode)
+#define FUNCTION_MODE SImode
 
 /* Define this if addresses of constant functions
    shouldn't be put through pseudo regs where they can be cse'd.
index 64a0dcd..890e30d 100644 (file)
@@ -296,11 +296,7 @@ toc_section ()                                             \
   putc ('.', FILE);                                            \
   RS6000_OUTPUT_BASENAME (FILE, NAME);                         \
   fputs (":\n", FILE);                                         \
-  if (write_symbols == XCOFF_DEBUG                             \
-      /* When called before targetm.asm_out.output_mi_thunk,   \
-        we won't be emitting the rest of the debug info that   \
-        goes along with this, leading to assembler errors.  */ \
-      && !(current_function_is_thunk && !no_new_pseudos))      \
+  if (write_symbols != NO_DEBUG)                               \
     xcoffout_declare_function (FILE, DECL, NAME);              \
 }