summaryrefslogtreecommitdiffstats
path: root/gcc/config/sparc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/sparc')
-rw-r--r--gcc/config/sparc/linux.h4
-rw-r--r--gcc/config/sparc/linux64.h7
-rw-r--r--gcc/config/sparc/sparc.c14
-rw-r--r--gcc/config/sparc/sparc.h12
4 files changed, 29 insertions, 8 deletions
diff --git a/gcc/config/sparc/linux.h b/gcc/config/sparc/linux.h
index 75d09273e80..b92ecd57631 100644
--- a/gcc/config/sparc/linux.h
+++ b/gcc/config/sparc/linux.h
@@ -179,6 +179,7 @@ Boston, MA 02111-1307, USA. */
#endif
#else
#define LINK_SPEC "-m elf32_sparc -Y P,/usr/lib %{shared:-shared} \
+ %{!mno-relax:%{!r:-relax}} \
%{!shared: \
%{!ibcs: \
%{!static: \
@@ -191,7 +192,8 @@ Boston, MA 02111-1307, USA. */
It's safe to pass -s always, even if -g is not used. */
#undef ASM_SPEC
#define ASM_SPEC \
- "%{V} %{v:%{!V:-V}} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Wa,*:%*} -s %{fpic:-K PIC} %{fPIC:-K PIC}"
+ "%{V} %{v:%{!V:-V}} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Wa,*:%*} -s %{fpic:-K PIC} \
+ %{fPIC:-K PIC} %(asm_relax)"
/* Same as sparc.h */
#undef DBX_REGISTER_NUMBER
diff --git a/gcc/config/sparc/linux64.h b/gcc/config/sparc/linux64.h
index 18a7f8b2c34..0f87b2cfc06 100644
--- a/gcc/config/sparc/linux64.h
+++ b/gcc/config/sparc/linux64.h
@@ -246,6 +246,7 @@ Boston, MA 02111-1307, USA. */
#define LINK_SPEC "\
%(link_arch) \
%{mlittle-endian:-EL} \
+%{!mno-relax:%{!r:-relax}} \
"
#undef CC1_SPEC
@@ -283,7 +284,7 @@ Boston, MA 02111-1307, USA. */
#else /* !SPARC_BI_ARCH */
#undef LINK_SPEC
-#define LINK_ARCH_SPEC "-m elf64_sparc -Y P,/usr/lib64 %{shared:-shared} \
+#define LINK_SPEC "-m elf64_sparc -Y P,/usr/lib64 %{shared:-shared} \
%{!shared: \
%{!ibcs: \
%{!static: \
@@ -291,6 +292,7 @@ Boston, MA 02111-1307, USA. */
%{!dynamic-linker:-dynamic-linker /lib64/ld-linux.so.2}} \
%{static:-static}}} \
%{mlittle-endian:-EL} \
+%{!mno-relax:%{!r:-relax}} \
"
#endif /* !SPARC_BI_ARCH */
@@ -308,8 +310,7 @@ Boston, MA 02111-1307, USA. */
%{Wa,*:%*} \
-s %{fpic:-K PIC} %{fPIC:-K PIC} \
%{mlittle-endian:-EL} \
-%(asm_cpu) %(asm_arch) \
-"
+%(asm_cpu) %(asm_arch) %(asm_relax)"
/* Same as sparc.h */
#undef DBX_REGISTER_NUMBER
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 18873966f2f..2b44d2f1bc1 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -3737,7 +3737,15 @@ output_sibcall (insn, call_operand)
if (leaf_regs)
{
+#ifdef HAVE_AS_RELAX_OPTION
+ /* If as and ld are relaxing tail call insns into branch always,
+ use or %o7,%g0,X; call Y; or X,%g0,%o7 always, so that it can
+ be optimized. With sethi/jmpl as nor ld has no easy way how to
+ find out if somebody does not branch between the sethi and jmpl. */
+ int spare_slot = 0;
+#else
int spare_slot = ((TARGET_ARCH32 || TARGET_CM_MEDLOW) && ! flag_pic);
+#endif
int size = 0;
if ((actual_fsize || ! spare_slot) && delay_slot)
@@ -3786,9 +3794,11 @@ output_sibcall (insn, call_operand)
{
if (size)
fprintf (asm_out_file, "\tsub\t%%sp, -%d, %%sp\n", size);
- output_asm_insn ("mov\t%%o7, %%g1", operands);
+ /* Use or with rs2 %%g0 instead of mov, so that as/ld can optimize
+ it into branch if possible. */
+ output_asm_insn ("or\t%%o7, %%g0, %%g1", operands);
output_asm_insn ("call\t%a0, 0", operands);
- output_asm_insn (" mov\t%%g1, %%o7", operands);
+ output_asm_insn (" or\t%%g1, %%g0, %%o7", operands);
}
return "";
}
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index 5b226578d8b..1a584cda69b 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -324,12 +324,17 @@ Unrecognized value in TARGET_CPU_DEFAULT.
%{!m32:%{!m64:%(asm_arch_default)}} \
"
+#ifdef HAVE_AS_RELAX_OPTION
+#define ASM_RELAX_SPEC "%{!mno-relax:-relax}"
+#else
+#define ASM_RELAX_SPEC ""
+#endif
+
/* Special flags to the Sun-4 assembler when using pipe for input. */
#define ASM_SPEC "\
%| %{R} %{!pg:%{!p:%{fpic:-k} %{fPIC:-k}}} %{keep-local-as-symbols:-L} \
-%(asm_cpu) \
-"
+%(asm_cpu) %(asm_relax)"
#define LIB_SPEC "%{!shared:%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p} %{g:-lg}}"
@@ -362,6 +367,7 @@ Unrecognized value in TARGET_CPU_DEFAULT.
{ "asm_cpu_default", ASM_CPU_DEFAULT_SPEC }, \
{ "asm_arch32", ASM_ARCH32_SPEC }, \
{ "asm_arch64", ASM_ARCH64_SPEC }, \
+ { "asm_relax", ASM_RELAX_SPEC }, \
{ "asm_arch_default", ASM_ARCH_DEFAULT_SPEC },\
{ "asm_arch", ASM_ARCH_SPEC }, \
SUBTARGET_EXTRA_SPECS
@@ -606,6 +612,8 @@ extern int target_flags;
{"no-stack-bias", -MASK_STACK_BIAS, "Do not use stack bias" }, \
{"faster-structs", MASK_FASTER_STRUCTS, "Use structs on stronger alignment for double-word copies" }, \
{"no-faster-structs", -MASK_FASTER_STRUCTS, "Do not use structs on stronger alignment for double-word copies" }, \
+ {"relax", 0, "Optimize tail call instructions in assembler and linker" }, \
+ {"no-relax", 0, "Do not optimize tail call instructions in assembler or linker" }, \
SUBTARGET_SWITCHES \
{ "", TARGET_DEFAULT, ""}}
OpenPOWER on IntegriCloud