diff options
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/c-common.c | 4 | ||||
-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 |
5 files changed, 116 insertions, 18 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f43f647..46f1f23 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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. diff --git a/gcc/c-common.c b/gcc/c-common.c index 65f9799..983cd29 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -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"); } 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) |