re PR middle-end/9986 ([HP-UX] [3.4 regression] Incorrect transformation of fputs_unl...
authorJohn David Anglin <dave.anglin@nrc-cnrc.gc.ca>
Sun, 9 Mar 2003 19:47:54 +0000 (19:47 +0000)
committerJohn David Anglin <danglin@gcc.gnu.org>
Sun, 9 Mar 2003 19:47:54 +0000 (19:47 +0000)
PR middle-end/9986
* c-common.c (c_common_nodes_and_builtins): Initialize target builtins
after the common builtins.
* pa-hpux.h (DONT_HAVE_FPUTC_UNLOCKED): Define.
* pa.c (TARGET_INIT_BUILTINS): Define.
(pa_init_builtins): New function.
* pa.md (call, call_value, sibcall, sibcall_value): When sufficient
space has been allocated for the outgoing arguments, set the arg
pointer for a call emitted after virtuals have been instantiated
using the stack pointer offset, otherwise abort.

From-SVN: r64043

gcc/ChangeLog
gcc/c-common.c
gcc/config/pa/pa-hpux.h
gcc/config/pa/pa.c
gcc/config/pa/pa.md

index f43f647cef4729aa6104b97f8f430148f6a01c0b..46f1f23145d688778bc00e95254df78c4f5bfafa 100644 (file)
@@ -1,3 +1,17 @@
+2003-03-09  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
+
+       PR middle-end/9986
+       * c-common.c (c_common_nodes_and_builtins): Initialize target builtins
+       after the common builtins.
+       * pa-hpux.h (DONT_HAVE_FPUTC_UNLOCKED): Define.
+       * pa.c (TARGET_INIT_BUILTINS): Define.
+       (pa_init_builtins): New function.
+
+       * pa.md (call, call_value, sibcall, sibcall_value): When sufficient
+       space has been allocated for the outgoing arguments, set the arg
+       pointer for a call emitted after virtuals have been instantiated
+       using the stack pointer offset, otherwise abort.
+
 2003-03-09  DJ Delorie  <dj@redhat.com>
 
        * config/stormy16/stormy16.h (DWARF_LINE_MIN_INSTR_LENGTH): Revert.
index 65f97992fc855b24c84b6073b140371de9481651..983cd29100ddab49c57b74ccad0145017e5b1c87 100644 (file)
@@ -3428,8 +3428,6 @@ c_common_nodes_and_builtins ()
     = build_pointer_type (build_qualified_type
                          (char_type_node, TYPE_QUAL_CONST));
 
-  (*targetm.init_builtins) ();
-
   /* This is special for C++ so functions can be overloaded.  */
   wchar_type_node = get_identifier (MODIFIED_WCHAR_TYPE);
   wchar_type_node = TREE_TYPE (identifier_global_value (wchar_type_node));
@@ -3618,6 +3616,8 @@ c_common_nodes_and_builtins ()
 #include "builtins.def"
 #undef DEF_BUILTIN
 
+  (*targetm.init_builtins) ();
+
   main_identifier_node = get_identifier ("main");
 }
 
index b9d563e09be25a6feeff4d836f20338b6c548ea1..a4ed77f983efa789fd4c4a1e206678ebc9bf2e45 100644 (file)
@@ -96,3 +96,7 @@ Boston, MA 02111-1307, USA.  */
 /* hpux8 and later have C++ compatible include files, so do not
    pretend they are `extern "C"'.  */
 #define NO_IMPLICIT_EXTERN_C
+
+/* hpux11 and earlier don't have fputc_unlocked, so we must inhibit the
+   transformation of fputs_unlocked and fprintf_unlocked to fputc_unlocked.  */
+#define DONT_HAVE_FPUTC_UNLOCKED
index 0f1b894f89564f4b238bd26dd62020edd9a850e2..d087ed8606bc61247ce1c180d3c3e4529c4962e8 100644 (file)
@@ -130,6 +130,7 @@ static void pa_asm_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
 static void pa_asm_out_constructor PARAMS ((rtx, int));
 static void pa_asm_out_destructor PARAMS ((rtx, int));
 #endif
+static void pa_init_builtins PARAMS ((void));
 static void copy_fp_args PARAMS ((rtx)) ATTRIBUTE_UNUSED;
 static int length_fp_args PARAMS ((rtx)) ATTRIBUTE_UNUSED;
 static struct deferred_plabel *get_plabel PARAMS ((const char *))
@@ -222,6 +223,9 @@ static size_t n_deferred_plabels = 0;
 #define TARGET_ASM_DESTRUCTOR pa_asm_out_destructor
 #endif
 
+#undef TARGET_INIT_BUILTINS
+#define TARGET_INIT_BUILTINS pa_init_builtins
+
 #undef TARGET_RTX_COSTS
 #define TARGET_RTX_COSTS hppa_rtx_costs
 #undef TARGET_ADDRESS_COST
@@ -338,6 +342,14 @@ override_options ()
     }
 }
 
+void
+pa_init_builtins ()
+{
+#ifdef DONT_HAVE_FPUTC_UNLOCKED
+  built_in_decls[(int) BUILT_IN_FPUTC_UNLOCKED] = NULL_TREE;
+#endif
+}
+
 /* Return nonzero only if OP is a register of mode MODE,
    or CONST0_RTX.  */
 int
index ffb28ad4220434affaa56b0fa6f95cfa03300ea5..2673739849f2247b7eba6d72d58fc58d84d1f95d 100644 (file)
     op = XEXP (operands[0], 0);
 
   if (TARGET_64BIT)
-    emit_move_insn (arg_pointer_rtx,
-                   gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
-                                 GEN_INT (64)));
+    {
+      if (!virtuals_instantiated)
+       emit_move_insn (arg_pointer_rtx,
+                       gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
+                                     GEN_INT (64)));
+      else
+       {
+         /* The loop pass can generate new libcalls after the virtual
+            registers are instantiated when fpregs are disabled because
+            the only method that we have for doing DImode multiplication
+            is with a libcall.  This could be trouble if we haven't
+            allocated enough space for the outgoing arguments.  */
+         if (INTVAL (nb) > current_function_outgoing_args_size)
+           abort ();
+
+         emit_move_insn (arg_pointer_rtx,
+                         gen_rtx_PLUS (word_mode, stack_pointer_rtx,
+                                       GEN_INT (STACK_POINTER_OFFSET + 64)));
+       }
+    }
 
   /* Use two different patterns for calls to explicitly named functions
      and calls through function pointers.  This is necessary as these two
     op = XEXP (operands[1], 0);
 
   if (TARGET_64BIT)
-    emit_move_insn (arg_pointer_rtx,
-                   gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
-                                 GEN_INT (64)));
+    {
+      if (!virtuals_instantiated)
+       emit_move_insn (arg_pointer_rtx,
+                       gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
+                                     GEN_INT (64)));
+      else
+       {
+         /* The loop pass can generate new libcalls after the virtual
+            registers are instantiated when fpregs are disabled because
+            the only method that we have for doing DImode multiplication
+            is with a libcall.  This could be trouble if we haven't
+            allocated enough space for the outgoing arguments.  */
+         if (INTVAL (nb) > current_function_outgoing_args_size)
+           abort ();
+
+         emit_move_insn (arg_pointer_rtx,
+                         gen_rtx_PLUS (word_mode, stack_pointer_rtx,
+                                       GEN_INT (STACK_POINTER_OFFSET + 64)));
+       }
+    }
 
   /* Use two different patterns for calls to explicitly named functions
      and calls through function pointers.  This is necessary as these two
   "!TARGET_PORTABLE_RUNTIME"
   "
 {
-  rtx op;
-  rtx call_insn;
+  rtx op, call_insn;
+  rtx nb = operands[1];
 
   op = XEXP (operands[0], 0);
 
   if (TARGET_64BIT)
-    emit_move_insn (arg_pointer_rtx,
-                   gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
-                                 GEN_INT (64)));
+    {
+      if (!virtuals_instantiated)
+       emit_move_insn (arg_pointer_rtx,
+                       gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
+                                     GEN_INT (64)));
+      else
+       {
+         /* The loop pass can generate new libcalls after the virtual
+            registers are instantiated when fpregs are disabled because
+            the only method that we have for doing DImode multiplication
+            is with a libcall.  This could be trouble if we haven't
+            allocated enough space for the outgoing arguments.  */
+         if (INTVAL (nb) > current_function_outgoing_args_size)
+           abort ();
+
+         emit_move_insn (arg_pointer_rtx,
+                         gen_rtx_PLUS (word_mode, stack_pointer_rtx,
+                                       GEN_INT (STACK_POINTER_OFFSET + 64)));
+       }
+    }
 
   /* Indirect sibling calls are not allowed.  */
   if (TARGET_64BIT)
   "!TARGET_PORTABLE_RUNTIME"
   "
 {
-  rtx op;
-  rtx call_insn;
+  rtx op, call_insn;
+  rtx nb = operands[1];
 
   op = XEXP (operands[1], 0);
 
   if (TARGET_64BIT)
-    emit_move_insn (arg_pointer_rtx,
-                   gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
-                                 GEN_INT (64)));
+    {
+      if (!virtuals_instantiated)
+       emit_move_insn (arg_pointer_rtx,
+                       gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
+                                     GEN_INT (64)));
+      else
+       {
+         /* The loop pass can generate new libcalls after the virtual
+            registers are instantiated when fpregs are disabled because
+            the only method that we have for doing DImode multiplication
+            is with a libcall.  This could be trouble if we haven't
+            allocated enough space for the outgoing arguments.  */
+         if (INTVAL (nb) > current_function_outgoing_args_size)
+           abort ();
+
+         emit_move_insn (arg_pointer_rtx,
+                         gen_rtx_PLUS (word_mode, stack_pointer_rtx,
+                                       GEN_INT (STACK_POINTER_OFFSET + 64)));
+       }
+    }
 
   /* Indirect sibling calls are not allowed.  */
   if (TARGET_64BIT)