aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/pa
diff options
context:
space:
mode:
authorJohn David Anglin <dave.anglin@nrc-cnrc.gc.ca>2003-03-09 19:47:54 +0000
committerJohn David Anglin <danglin@gcc.gnu.org>2003-03-09 19:47:54 +0000
commit4677862a0bfa291cf015559f78ee9cbf7d9f0734 (patch)
tree15f04fa68a22dbaa3b962124526e39ef880b4185 /gcc/config/pa
parent2de12bc4884b12681c91d25385353b23afef6ecf (diff)
downloadgcc-4677862a0bfa291cf015559f78ee9cbf7d9f0734.zip
gcc-4677862a0bfa291cf015559f78ee9cbf7d9f0734.tar.gz
gcc-4677862a0bfa291cf015559f78ee9cbf7d9f0734.tar.bz2
re PR middle-end/9986 ([HP-UX] [3.4 regression] Incorrect transformation of fputs_unlocked to fputc_unlocked)
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
Diffstat (limited to 'gcc/config/pa')
-rw-r--r--gcc/config/pa/pa-hpux.h4
-rw-r--r--gcc/config/pa/pa.c12
-rw-r--r--gcc/config/pa/pa.md100
3 files changed, 100 insertions, 16 deletions
diff --git a/gcc/config/pa/pa-hpux.h b/gcc/config/pa/pa-hpux.h
index b9d563e..a4ed77f 100644
--- a/gcc/config/pa/pa-hpux.h
+++ b/gcc/config/pa/pa-hpux.h
@@ -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
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 0f1b894..d087ed8 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -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
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
index ffb28ad..2673739 100644
--- a/gcc/config/pa/pa.md
+++ b/gcc/config/pa/pa.md
@@ -5889,9 +5889,26 @@
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
@@ -6372,9 +6389,26 @@
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
@@ -6868,15 +6902,32 @@
"!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)
@@ -6933,15 +6984,32 @@
"!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)