diff options
author | John David Anglin <dave.anglin@nrc-cnrc.gc.ca> | 2003-03-09 19:47:54 +0000 |
---|---|---|
committer | John David Anglin <danglin@gcc.gnu.org> | 2003-03-09 19:47:54 +0000 |
commit | 4677862a0bfa291cf015559f78ee9cbf7d9f0734 (patch) | |
tree | 15f04fa68a22dbaa3b962124526e39ef880b4185 /gcc/config/pa | |
parent | 2de12bc4884b12681c91d25385353b23afef6ecf (diff) | |
download | gcc-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.h | 4 | ||||
-rw-r--r-- | gcc/config/pa/pa.c | 12 | ||||
-rw-r--r-- | gcc/config/pa/pa.md | 100 |
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) |