aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJ"orn Rennecke <joern.rennecke@superh.com>2003-03-03 20:57:19 +0000
committerJoern Rennecke <amylaar@gcc.gnu.org>2003-03-03 20:57:19 +0000
commitd44cc4047b5ec4cb74a77f4bc46e6438d83f1ed5 (patch)
tree232365b6c709ead625008c573f69aa1b9152fb89 /gcc
parent53f70c1b3be511895748fa362792d3c5c19bf13b (diff)
downloadgcc-d44cc4047b5ec4cb74a77f4bc46e6438d83f1ed5.zip
gcc-d44cc4047b5ec4cb74a77f4bc46e6438d83f1ed5.tar.gz
gcc-d44cc4047b5ec4cb74a77f4bc46e6438d83f1ed5.tar.bz2
Fix sh-elf linker relaxation:
gcc: * config/sh/sh.h (EXTRA_SPECS): Add subtarget_asm_relax_spec and subtarget_asm_isa_spec. (SUBTARGET_ASM_RELAX_SPEC, SUBTARGET_ASM_ISA_SPEC): Define. (ASM_SPEC): Define as SH_ASM_SPEC. (SH_ASM_SPEC): New; take the role of ASM_SPEC, but safe from svr4.h. Use subtarget_asm_relax_spec and subtarget_asm_isa_spec. * config/sh/elf.h (ASM_SPEC): Use SH_ASM_SPEC. (SUBTARGET_ASM_ISA_SPEC): Undef / define. gcc/testsuite: gcc.dg/sh-relax.c: New test. include/elf: * sh.h (EF_SH_MERGE_MACH): Make sure SH2E & SH3/SH3E merge to SH3E, and SH2E & SH4 merge to SH4, not SH2E. gas: * config/tc-sh.c (sh_dsp): Replace with preset_target_arch. (md_begin): Use preset_target_arch. (md_longopts): Make isa option unconditional. (md_parse_option): Make OPTION_DSP and OPTION_ISA sh4 / any set preset_target_arch. (md_apply_fix3): If BFD_ASSEMBLER, adjust SWITCH_TABLE fixups by -S_GET_VALUE (fixP->fx_subsy). (tc_gen_reloc): For SWITCH_TABLE fixups, the symbol is fixp->fx_subsy, and the addend is 0. Adjust addend of R_SH_IND12W relocations by fixp->fx_offset - 4. * config/tc-sh.h (TC_FORCE_RELOCATION_SUB_LOCAL): Define. bfd: elf32-sh.c (sh_elf_howto_tab): Make R_SH_IND12W into an ordinary relocation (no special function), and make it non-partial_inplace. (sh_elf_relax_section): When creating a bsr, use a consistent value no matter if the symbol is extern or not; set addend to -4. Don't swap load / non-load instructions for SH4. (sh_elf_relax_delete_bytes): In R_SH_IND12W case, check the offset rather than if the symbol is external to determine if adjusting the offset makes sense. Adjust the addend too if appropriate. (sh_elf_relocate_section): In R_SH_IND12W, don't fiddle with the relocation. From-SVN: r63732
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/config/sh/elf.h5
-rw-r--r--gcc/config/sh/sh.h16
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/sh-relax.c40
5 files changed, 73 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 436ee28..dcfe1f9 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,4 +1,13 @@
-Mon Mar 3 19:47:26 2003 J"orn Rennecke <joern.rennecke@superh.com>
+Mon Mar 3 20:45:25 2003 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * config/sh/sh.h (EXTRA_SPECS): Add subtarget_asm_relax_spec and
+ subtarget_asm_isa_spec.
+ (SUBTARGET_ASM_RELAX_SPEC, SUBTARGET_ASM_ISA_SPEC): Define.
+ (ASM_SPEC): Define as SH_ASM_SPEC.
+ (SH_ASM_SPEC): New; take the role of ASM_SPEC, but safe from svr4.h.
+ Use subtarget_asm_relax_spec and subtarget_asm_isa_spec.
+ * config/sh/elf.h (ASM_SPEC): Use SH_ASM_SPEC.
+ (SUBTARGET_ASM_ISA_SPEC): Undef / define.
* sh.h (OVERRIDE_OPTIONS): Set default values for align_loops
and align_jumps if not set.
diff --git a/gcc/config/sh/elf.h b/gcc/config/sh/elf.h
index 858adb1..1eed089 100644
--- a/gcc/config/sh/elf.h
+++ b/gcc/config/sh/elf.h
@@ -68,9 +68,12 @@ Boston, MA 02111-1307, USA. */
#undef PTRDIFF_TYPE
#define PTRDIFF_TYPE (TARGET_SH5 ? "long int" : "int")
+
/* Pass -ml and -mrelax to the assembler and linker. */
#undef ASM_SPEC
-#define ASM_SPEC "%(subtarget_asm_endian_spec) %{mrelax:-relax} \
+#define ASM_SPEC SH_ASM_SPEC
+#undef SUBTARGET_ASM_ISA_SPEC
+#define SUBTARGET_ASM_ISA_SPEC "\
%{m5-compact:--isa=SHcompact} %{m5-compact-nofpu:--isa=SHcompact} \
%{m5-32media:--isa=SHmedia --abi=32} %{m5-32media-nofpu:--isa=SHmedia --abi=32} \
%{m5-64media:--isa=SHmedia --abi=64} %{m5-64media-nofpu:--isa=SHmedia --abi=64}"
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index 5e1712a..0be5f89 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -359,9 +359,21 @@ extern int target_flags;
{ "subtarget_link_emul_suffix", SUBTARGET_LINK_EMUL_SUFFIX }, \
{ "subtarget_link_spec", SUBTARGET_LINK_SPEC }, \
{ "subtarget_asm_endian_spec", SUBTARGET_ASM_ENDIAN_SPEC }, \
+ { "subtarget_asm_relax_spec", SUBTARGET_ASM_RELAX_SPEC }, \
+ { "subtarget_asm_isa_spec", SUBTARGET_ASM_ISA_SPEC }, \
SUBTARGET_EXTRA_SPECS
-#define ASM_SPEC "%(subtarget_asm_endian_spec) %{mrelax:-relax}"
+#if TARGET_CPU_DEFAULT & HARD_SH4_BIT
+#define SUBTARGET_ASM_RELAX_SPEC "%{!m[1235]*:-isa=sh4}"
+#else
+#define SUBTARGET_ASM_RELAX_SPEC "%{m4*:-isa=sh4}"
+#endif
+
+#define SH_ASM_SPEC \
+ "%(subtarget_asm_endian_spec) %{mrelax:-relax %(subtarget_asm_relax_spec)}\
+%(subtarget_asm_isa_spec)"
+
+#define ASM_SPEC SH_ASM_SPEC
#ifndef SUBTARGET_ASM_ENDIAN_SPEC
#if TARGET_ENDIAN_DEFAULT == LITTLE_ENDIAN_BIT
@@ -371,6 +383,8 @@ extern int target_flags;
#endif
#endif
+#define SUBTARGET_ASM_ISA_SPEC ""
+
#define LINK_EMUL_PREFIX "sh%{ml:l}"
#if TARGET_CPU_DEFAULT & SH5_BIT
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 68479e7..7dff81d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+Mon Mar 3 20:42:04 2003 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * gcc.dg/sh-relax.c: New SH-only test.
+
2003-03-03 Geoffrey Keating <geoffk@apple.com>
* gcc.c-torture/compile/20010327-1.c: Back out last change. Add
diff --git a/gcc/testsuite/gcc.dg/sh-relax.c b/gcc/testsuite/gcc.dg/sh-relax.c
new file mode 100644
index 0000000..418a8ca
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/sh-relax.c
@@ -0,0 +1,40 @@
+/* Check that -mrelax works. */
+/* { dg-do run { target sh-*-* sh?-*-* sh64-*-* } } */
+/* { dg-options "-O1 -mrelax" } */
+
+extern int qwerty (int);
+
+int
+f (int i)
+{
+ return qwerty (i) + 1;
+}
+
+int
+qwerty (int i)
+{
+ switch (i)
+ {
+ case 1:
+ return 'q';
+ case 2:
+ return 'w';
+ case 3:
+ return 'e';
+ case 4:
+ return 'r';
+ case 5:
+ return 't';
+ case 6:
+ return 'y';
+ }
+}
+
+int
+main ()
+{
+ if (f (1) != 'q' + 1 || f (2) != 'w' + 1 || f (3) != 'e' + 1
+ || f(4) != 'r' + 1 || f (5) != 't' + 1 || f (6) != 'y' + 1)
+ abort ();
+ return 0;
+}