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>
* config/rs6000/rs6000.c (rs6000_stack_info): Only require a frame
......
......@@ -100,3 +100,8 @@ Boston, MA 02111-1307, USA. */
/* 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
/* 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 *));
extern const char *output_fp_move_double PARAMS ((rtx *));
extern const char *output_block_move PARAMS ((rtx *, int));
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_bvb PARAMS ((rtx *, int, int, int, rtx, int));
extern const char *output_dbra PARAMS ((rtx *, rtx, int));
......
......@@ -211,6 +211,15 @@ extern int target_flags;
definition symbols is buggy prior to HP-UX 11.X. */
#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
list in braces of target switches with each switch being
{ "NAME", VALUE, "HELP_STRING" }. VALUE is the bits to set,
......@@ -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 stack: 16 bytes for register saves, and 32 bytes for magic.
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 \
(TARGET_64BIT ? -(current_function_outgoing_args_size + 16): -32)
(TARGET_64BIT ? -(current_function_outgoing_args_size + 48): -32)
#define STACK_DYNAMIC_OFFSET(FNDECL) \
(TARGET_64BIT \
......
......@@ -5721,8 +5721,6 @@
""
"*
{
extern int optimize;
if (GET_MODE (insn) == SImode)
return \"b %l0%#\";
......@@ -5731,61 +5729,7 @@
&& get_attr_length (insn) != 16)
return \"b%* %l0\";
/* An unconditional branch which can not reach its target.
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\";
return output_lbranch (operands[0], insn);
}"
[(set_attr "type" "uncond_branch")
(set_attr "pa_combine_type" "uncond_branch")
......@@ -8053,3 +7997,38 @@
emit_insn (gen_blockage ());
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