The attached change fixes the PR. This problem affects building
texmaker and a few other Debian
packages.
The code in pa_asm_output_mi_thunk originally checked whether the
function was reachable with
a pc-relative branch, but the assembler complains if the branch can't
reach the stub table. I don't think
thunks need to reach the stub table in this case but it's probably
hard to distinguish in the assembler
this case from situations where a "call" needs to reach the stub
table. So, I fixed the problem in the compiler.
In debugging this problem, I noticed a small regression in the
computation of last_address which was
introduced when we changed to using final_start_function and
final_end_function to get debug info for
thunks. The final_end_function call messed up the value of
last_address.
Tested on hppa2.0w-hp-hpux11.11, hppa64-hp-hpux11.11 and hppa-unknown-
linux-gnu. Committed
to trunk, 4.9 and 4.8.
Dave
--
John David Anglin dave.ang...@bell.net
2014-08-23 John David Anglin <dang...@gcc.gnu.org>
PR target/62038
* config/pa/pa.c (pa_output_function_epilogue): Don't set
last_address when the current function is a thunk.
(pa_asm_output_mi_thunk): When we don't have named sections or they
are not being used, check that thunk can reach the stub table with a
short branch.
Index: config/pa/pa.c
===================================================================
--- config/pa/pa.c (revision 214251)
+++ config/pa/pa.c (working copy)
@@ -4137,9 +4137,8 @@
pa_output_function_epilogue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
{
rtx insn = get_last_insn ();
+ bool extra_nop;
- last_address = 0;
-
/* pa_expand_epilogue does the dirty work now. We just need
to output the assembler directives which denote the end
of a function.
@@ -4162,8 +4161,10 @@
if (insn && CALL_P (insn))
{
fputs ("\tnop\n", file);
- last_address += 4;
+ extra_nop = true;
}
+ else
+ extra_nop = false;
fputs ("\t.EXIT\n\t.PROCEND\n", file);
@@ -4176,12 +4177,13 @@
cfun->machine->in_nsubspa = 2;
}
- /* Thunks do their own accounting. */
+ /* Thunks do their own insn accounting. */
if (cfun->is_thunk)
return;
if (INSN_ADDRESSES_SET_P ())
{
+ last_address = extra_nop ? 4 : 0;
insn = get_last_nonnote_insn ();
last_address += INSN_ADDRESSES (INSN_UID (insn));
if (INSN_P (insn))
@@ -8275,12 +8277,16 @@
|| ((DECL_SECTION_NAME (thunk_fndecl)
== DECL_SECTION_NAME (function))
&& last_address < 262132)))
+ /* In this case, we need to be able to reach the start of
+ the stub table even though the function is likely closer
+ and can be jumped to directly. */
|| (targetm_common.have_named_sections
&& DECL_SECTION_NAME (thunk_fndecl) == NULL
&& DECL_SECTION_NAME (function) == NULL
- && last_address < 262132)
+ && total_code_bytes < MAX_PCREL17F_OFFSET)
+ /* Likewise. */
|| (!targetm_common.have_named_sections
- && last_address < 262132))))
+ && total_code_bytes < MAX_PCREL17F_OFFSET))))
{
if (!val_14)
output_asm_insn ("addil L'%2,%%r26", xoperands);