Commit 685d0e07 by John David Anglin Committed by John David Anglin

re PR target/10062 (internal compiler error: in output_cbranch, at config/pa/pa.c: 5515)

	PR 10062
	* config/pa/pa-hpux.h (TARGET_HPUX_UNWIND_LIBRARY): Redefine.
	* pa-protos.h (output_lbranch): New prototype.
	* pa.c (compute_frame_size): Change size of the frame marker on the
	64-bit ports to 48 bytes.
	(pa_output_function_prologue): Document why SAVE_SP is set.
	(hppa_expand_prologue): Save previous stack pointer into frame marker
	on targets which use the hpux unwind library.
	(output_cbranch): Use output_lbranch.
	(output_lbranch): New function to output long unconditional branches.
	* pa.h (TARGET_HPUX_UNWIND_LIBRARY): Define.
	(STACK_POINTER_OFFSET): Update offset for 48-byte frame marker on
	64-bit ports.
	* pa.md (jump): Use output_lbranch.
	(allocate_stack): New expander for dynamic stack allocation.

From-SVN: r64570
parent 6788f5ca
2003-03-18 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
PR 10062
* config/pa/pa-hpux.h (TARGET_HPUX_UNWIND_LIBRARY): Redefine.
* pa-protos.h (output_lbranch): New prototype.
* pa.c (compute_frame_size): Change size of the frame marker on the
64-bit ports to 48 bytes.
(pa_output_function_prologue): Document why SAVE_SP is set.
(hppa_expand_prologue): Save previous stack pointer into frame marker
on targets which use the hpux unwind library.
(output_cbranch): Use output_lbranch.
(output_lbranch): New function to output long unconditional branches.
* pa.h (TARGET_HPUX_UNWIND_LIBRARY): Define.
(STACK_POINTER_OFFSET): Update offset for 48-byte frame marker on
64-bit ports.
* pa.md (jump): Use output_lbranch.
(allocate_stack): New expander for dynamic stack allocation.
2003-03-19 Alan Modra <amodra@bigpond.net.au> 2003-03-19 Alan Modra <amodra@bigpond.net.au>
* config/rs6000/rs6000.c (rs6000_stack_info): Only require a frame * config/rs6000/rs6000.c (rs6000_stack_info): Only require a frame
......
...@@ -100,3 +100,8 @@ Boston, MA 02111-1307, USA. */ ...@@ -100,3 +100,8 @@ Boston, MA 02111-1307, USA. */
/* hpux11 and earlier don't have fputc_unlocked, so we must inhibit the /* hpux11 and earlier don't have fputc_unlocked, so we must inhibit the
transformation of fputs_unlocked and fprintf_unlocked to fputc_unlocked. */ transformation of fputs_unlocked and fprintf_unlocked to fputc_unlocked. */
#define DONT_HAVE_FPUTC_UNLOCKED #define DONT_HAVE_FPUTC_UNLOCKED
/* We want the entry value of SP saved in the frame marker for
compatibility with the HP-UX unwind library. */
#undef TARGET_HPUX_UNWIND_LIBRARY
#define TARGET_HPUX_UNWIND_LIBRARY 1
...@@ -44,6 +44,7 @@ extern const char *output_move_double PARAMS ((rtx *)); ...@@ -44,6 +44,7 @@ extern const char *output_move_double PARAMS ((rtx *));
extern const char *output_fp_move_double PARAMS ((rtx *)); extern const char *output_fp_move_double PARAMS ((rtx *));
extern const char *output_block_move PARAMS ((rtx *, int)); extern const char *output_block_move PARAMS ((rtx *, int));
extern const char *output_cbranch PARAMS ((rtx *, int, int, int, rtx)); extern const char *output_cbranch PARAMS ((rtx *, int, int, int, rtx));
extern const char *output_lbranch PARAMS ((rtx, rtx));
extern const char *output_bb PARAMS ((rtx *, int, int, int, rtx, int)); extern const char *output_bb PARAMS ((rtx *, int, int, int, rtx, int));
extern const char *output_bvb PARAMS ((rtx *, int, int, int, rtx, int)); extern const char *output_bvb PARAMS ((rtx *, int, int, int, rtx, int));
extern const char *output_dbra PARAMS ((rtx *, rtx, int)); extern const char *output_dbra PARAMS ((rtx *, rtx, int));
......
...@@ -211,6 +211,15 @@ extern int target_flags; ...@@ -211,6 +211,15 @@ extern int target_flags;
definition symbols is buggy prior to HP-UX 11.X. */ definition symbols is buggy prior to HP-UX 11.X. */
#define TARGET_SOM_SDEF 0 #define TARGET_SOM_SDEF 0
/* Define to a C expression evaluating to true to save the entry value
of SP in the current frame marker. This is normally unnecessary.
However, the HP-UX unwind library looks at the SAVE_SP callinfo flag.
HP compilers don't use this flag but it is supported by the assembler.
We set this flag to indicate that register %r3 has been saved at the
start of the frame. Thus, when the HP unwind library is used, we
need to generate additional code to save SP into the frame marker. */
#define TARGET_HPUX_UNWIND_LIBRARY 0
/* Macro to define tables used to set the flags. This is a /* Macro to define tables used to set the flags. This is a
list in braces of target switches with each switch being list in braces of target switches with each switch being
{ "NAME", VALUE, "HELP_STRING" }. VALUE is the bits to set, { "NAME", VALUE, "HELP_STRING" }. VALUE is the bits to set,
...@@ -714,9 +723,13 @@ extern struct rtx_def *hppa_pic_save_rtx PARAMS ((void)); ...@@ -714,9 +723,13 @@ extern struct rtx_def *hppa_pic_save_rtx PARAMS ((void));
/* The weird HPPA calling conventions require a minimum of 48 bytes on /* The weird HPPA calling conventions require a minimum of 48 bytes on
the stack: 16 bytes for register saves, and 32 bytes for magic. the stack: 16 bytes for register saves, and 32 bytes for magic.
This is the difference between the logical top of stack and the This is the difference between the logical top of stack and the
actual sp. */ actual sp.
On the 64-bit port, the HP C compiler allocates a 48-byte frame
marker, although the runtime documentation only describes a 16
byte marker. For compatibility, we allocate 48 bytes. */
#define STACK_POINTER_OFFSET \ #define STACK_POINTER_OFFSET \
(TARGET_64BIT ? -(current_function_outgoing_args_size + 16): -32) (TARGET_64BIT ? -(current_function_outgoing_args_size + 48): -32)
#define STACK_DYNAMIC_OFFSET(FNDECL) \ #define STACK_DYNAMIC_OFFSET(FNDECL) \
(TARGET_64BIT \ (TARGET_64BIT \
......
...@@ -5721,8 +5721,6 @@ ...@@ -5721,8 +5721,6 @@
"" ""
"* "*
{ {
extern int optimize;
if (GET_MODE (insn) == SImode) if (GET_MODE (insn) == SImode)
return \"b %l0%#\"; return \"b %l0%#\";
...@@ -5731,61 +5729,7 @@ ...@@ -5731,61 +5729,7 @@
&& get_attr_length (insn) != 16) && get_attr_length (insn) != 16)
return \"b%* %l0\"; return \"b%* %l0\";
/* An unconditional branch which can not reach its target. return output_lbranch (operands[0], insn);
We need to be able to use %r1 as a scratch register; however,
we can never be sure whether or not it's got a live value in
it. Therefore, we must restore its original value after the
jump.
To make matters worse, we don't have a stack slot which we
can always clobber. sp-12/sp-16 shouldn't ever have a live
value during a non-optimizing compilation, so we use those
slots for now. We don't support very long branches when
optimizing -- they should be quite rare when optimizing.
Really the way to go long term is a register scavenger; goto
the target of the jump and find a register which we can use
as a scratch to hold the value in %r1. */
/* We don't know how to register scavenge yet. */
if (optimize)
abort ();
/* First store %r1 into the stack. */
output_asm_insn (\"stw %%r1,-16(%%r30)\", operands);
/* Now load the target address into %r1 and do an indirect jump
to the value specified in %r1. Be careful to generate PIC
code as needed. */
if (flag_pic)
{
rtx xoperands[2];
xoperands[0] = operands[0];
if (TARGET_SOM || ! TARGET_GAS)
{
xoperands[1] = gen_label_rtx ();
output_asm_insn (\"{bl|b,l} .+8,%%r1\\n\\taddil L'%l0-%l1,%%r1\",
xoperands);
(*targetm.asm_out.internal_label) (asm_out_file, \"L\",
CODE_LABEL_NUMBER (xoperands[1]));
output_asm_insn (\"ldo R'%l0-%l1(%%r1),%%r1\", xoperands);
}
else
{
output_asm_insn (\"{bl|b,l} .+8,%%r1\", xoperands);
output_asm_insn (\"addil L'%l0-$PIC_pcrel$0+4,%%r1\", xoperands);
output_asm_insn (\"ldo R'%l0-$PIC_pcrel$0+8(%%r1),%%r1\", xoperands);
}
output_asm_insn (\"bv %%r0(%%r1)\", xoperands);
}
else
output_asm_insn (\"ldil L'%l0,%%r1\\n\\tbe R'%l0(%%sr4,%%r1)\", operands);;
/* And restore the value of %r1 in the delay slot. We're not optimizing,
so we know nothing else can be in the delay slot. */
return \"ldw -16(%%r30),%%r1\";
}" }"
[(set_attr "type" "uncond_branch") [(set_attr "type" "uncond_branch")
(set_attr "pa_combine_type" "uncond_branch") (set_attr "pa_combine_type" "uncond_branch")
...@@ -8053,3 +7997,38 @@ ...@@ -8053,3 +7997,38 @@
emit_insn (gen_blockage ()); emit_insn (gen_blockage ());
DONE; DONE;
}") }")
;; Allocate new stack space and update the saved stack pointer in the
;; frame marker. The HP C compilers also copy additional words in the
;; frame marker. The 64-bit compiler copies words at -48, -32 and -24.
;; The 32-bit compiler copies the word at -16 (Static Link). We
;; currently don't copy these values.
;;
;; Since the copy of the frame marker can't be done atomically, I
;; suspect that using it for unwind purposes may be somewhat unreliable.
;; The HP compilers appear to raise the stack and copy the frame
;; marker in a strict instruction sequence. This suggests that the
;; unwind library may check for an alloca sequence when ALLOCA_FRAME
;; is set in the callinfo data. We currently don't set ALLOCA_FRAME
;; as GAS doesn't support it, or try to keep the instructions emitted
;; here in strict sequence.
(define_expand "allocate_stack"
[(match_operand 0 "" "")
(match_operand 1 "" "")]
""
"
{
/* Since the stack grows upward, we need to store virtual_stack_dynamic_rtx
in operand 0 before adjusting the stack. */
emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
anti_adjust_stack (operands[1]);
if (TARGET_HPUX_UNWIND_LIBRARY)
{
rtx dst = gen_rtx_MEM (word_mode,
gen_rtx_PLUS (word_mode, stack_pointer_rtx,
GEN_INT (TARGET_64BIT ? -8 : -4)));
emit_move_insn (dst, frame_pointer_rtx);
}
DONE;
}")
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment