aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn David Anglin <danglin@gcc.gnu.org>2014-01-26 16:30:27 +0000
committerJohn David Anglin <danglin@gcc.gnu.org>2014-01-26 16:30:27 +0000
commit5aa3c7625258745e8867c128a95c3cc8c121bef8 (patch)
tree898a7858166664e9711e645bc93fd20f2a0b02d9
parentcc5cec10532400521b1e04129530007a724ff493 (diff)
downloadgcc-5aa3c7625258745e8867c128a95c3cc8c121bef8.zip
gcc-5aa3c7625258745e8867c128a95c3cc8c121bef8.tar.gz
gcc-5aa3c7625258745e8867c128a95c3cc8c121bef8.tar.bz2
pa.md (call): Generate indirect long calls to non-local functions when outputing 32-bit code.
* config/pa/pa.md (call): Generate indirect long calls to non-local functions when outputing 32-bit code. (call_value): Likewise except for special call to buggy powf function. From-SVN: r207121
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/config/pa/pa.md43
2 files changed, 37 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 460af5b..226b721 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,9 @@
2014-01-26 John David Anglin <danglin@gcc.gnu.org>
+ * config/pa/pa.md (call): Generate indirect long calls to non-local
+ functions when outputing 32-bit code.
+ (call_value): Likewise except for special call to buggy powf function.
+
* config/pa/pa.c (pa_attr_length_indirect_call): Adjust length of
portable runtime and PIC indirect calls.
(pa_output_indirect_call): Remove unnecessary nop from portable runtime
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
index 94ba162..e55d0b8 100644
--- a/gcc/config/pa/pa.md
+++ b/gcc/config/pa/pa.md
@@ -7087,7 +7087,17 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
if (TARGET_PORTABLE_RUNTIME)
op = force_reg (SImode, XEXP (operands[0], 0));
else
- op = XEXP (operands[0], 0);
+ {
+ op = XEXP (operands[0], 0);
+
+ /* Generate indirect long calls to non-local functions. */
+ if (!TARGET_64BIT && TARGET_LONG_CALLS && GET_CODE (op) == SYMBOL_REF)
+ {
+ tree call_decl = SYMBOL_REF_DECL (op);
+ if (!(call_decl && targetm.binds_local_p (call_decl)))
+ op = force_reg (word_mode, op);
+ }
+ }
if (TARGET_64BIT)
{
@@ -7575,11 +7585,29 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
rtx op;
rtx dst = operands[0];
rtx nb = operands[2];
+ bool call_powf = false;
if (TARGET_PORTABLE_RUNTIME)
op = force_reg (SImode, XEXP (operands[1], 0));
else
- op = XEXP (operands[1], 0);
+ {
+ op = XEXP (operands[1], 0);
+ if (GET_CODE (op) == SYMBOL_REF)
+ {
+ /* Handle special call to buggy powf function. */
+ if (TARGET_HPUX && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT
+ && !strcmp (targetm.strip_name_encoding (XSTR (op, 0)), "powf"))
+ call_powf = true;
+
+ /* Generate indirect long calls to non-local functions. */
+ else if (!TARGET_64BIT && TARGET_LONG_CALLS)
+ {
+ tree call_decl = SYMBOL_REF_DECL (op);
+ if (!(call_decl && targetm.binds_local_p (call_decl)))
+ op = force_reg (word_mode, op);
+ }
+ }
+ }
if (TARGET_64BIT)
{
@@ -7639,8 +7667,7 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
rtx r4 = gen_rtx_REG (word_mode, 4);
if (GET_CODE (op) == SYMBOL_REF)
{
- if (TARGET_HPUX && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT
- && !strcmp (targetm.strip_name_encoding (XSTR (op, 0)), "powf"))
+ if (call_powf)
emit_call_insn (gen_call_val_powf_64bit (dst, op, nb, r4));
else
emit_call_insn (gen_call_val_symref_64bit (dst, op, nb, r4));
@@ -7659,18 +7686,14 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
{
rtx r4 = gen_rtx_REG (word_mode, 4);
- if (TARGET_HPUX && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT
- && !strcmp (targetm.strip_name_encoding (XSTR (op, 0)),
- "powf"))
+ if (call_powf)
emit_call_insn (gen_call_val_powf_pic (dst, op, nb, r4));
else
emit_call_insn (gen_call_val_symref_pic (dst, op, nb, r4));
}
else
{
- if (TARGET_HPUX && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT
- && !strcmp (targetm.strip_name_encoding (XSTR (op, 0)),
- "powf"))
+ if (call_powf)
emit_call_insn (gen_call_val_powf (dst, op, nb));
else
emit_call_insn (gen_call_val_symref (dst, op, nb));