Fix h8300 relaxation.
authorNick Clifton <nickc@redhat.com>
Fri, 15 Nov 2002 11:18:49 +0000 (11:18 +0000)
committerNick Clifton <nickc@redhat.com>
Fri, 15 Nov 2002 11:18:49 +0000 (11:18 +0000)
bfd/ChangeLog
bfd/coff-h8300.c
bfd/elf32-h8300.c
ld/testsuite/ChangeLog
ld/testsuite/ld-h8300/h8300.exp [new file with mode: 0644]
ld/testsuite/ld-h8300/relax.d [new file with mode: 0644]
ld/testsuite/ld-h8300/relax.s [new file with mode: 0644]

index 8b096bc294754796c0418c057338d36f5d4ede9f..479674b6c6b381609ebb47bbf5b317b865709124 100644 (file)
@@ -1,3 +1,9 @@
+2002-11-15  Kazu Hirata  <kazu@cs.umass.edu>
+
+       * coff-h8300.c (h8300_reloc16_estimate): Do not optimize away
+       jsr after a short jump.
+       * elf32-h8300.c (elf32_h8_relax_section): Likewise.
+
 2002-11-15  Klee Dienes  <kdienes@apple.com>
 
        * pef.c (bfd_pef_convert_architecture): Move declaration of
index 4aab46bbb224a33a85683ad27ad4076d6abb3f9d..c83015e4efbe2f715994962d637b451bd97828c9 100644 (file)
@@ -4,21 +4,21 @@
    Free Software Foundation, Inc.
    Written by Steve Chamberlain, <sac@cygnus.com>.
 
-This file is part of BFD, the Binary File Descriptor library.
+   This file is part of BFD, the Binary File Descriptor library.
 
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
 
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #include "bfd.h"
 #include "sysdep.h"
@@ -483,6 +483,13 @@ h8300_reloc16_estimate (abfd, input_section, reloc, shrink, link_info)
         closer if we do relax this branch.  */
       if ((int) gap >= -128 && (int) gap <= 128)
        {
+         bfd_byte code;
+
+         if (!bfd_get_section_contents (abfd, input_section, & code,
+                                        reloc->address, 1))
+           break;
+         code = bfd_get_8 (abfd, & code);
+
          /* It's possible we may be able to eliminate this branch entirely;
             if the previous instruction is a branch around this instruction,
             and there's no label at this instruction, then we can reverse
@@ -494,9 +501,25 @@ h8300_reloc16_estimate (abfd, input_section, reloc, shrink, link_info)
                lab1:                           lab1:
 
             This saves 4 bytes instead of two, and should be relatively
-            common.  */
-
-         if (gap <= 126
+            common.
+
+            Only perform this optimisation for jumps (code 0x5a) not
+            subroutine calls, as otherwise it could transform:
+            
+                            mov.w   r0,r0
+                            beq     .L1
+                            jsr     @_bar
+                     .L1:   rts
+                     _bar:  rts
+            into:
+                            mov.w   r0,r0
+                            bne     _bar
+                            rts
+                     _bar:  rts
+            
+            which changes the call (jsr) into a branch (bne).  */
+         if (code == 0x5a
+             && gap <= 126
              && last_reloc
              && last_reloc->howto->type == R_PCRBYTE)
            {
index 1d643cbf0a9c7322c16551fc781de04f1f430f04..9cb900b8b209fb8856737d5f0462937c896e4da6 100644 (file)
@@ -2,21 +2,21 @@
    Copyright 1993, 1995, 1998, 1999, 2001, 2002
    Free Software Foundation, Inc.
 
-This file is part of BFD, the Binary File Descriptor library.
+   This file is part of BFD, the Binary File Descriptor library.
 
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
 
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #include "bfd.h"
 #include "sysdep.h"
@@ -827,14 +827,34 @@ elf32_h8_relax_section (abfd, sec, link_info, again)
                elf_section_data (sec)->this_hdr.contents = contents;
                symtab_hdr->contents = (unsigned char *) isymbuf;
 
+               /* Get the instruction code being relaxed.  */
+               code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
+
                /* If the previous instruction conditionally jumped around
                   this instruction, we may be able to reverse the condition
                   and redirect the previous instruction to the target of
                   this instruction.
 
                   Such sequences are used by the compiler to deal with
-                  long conditional branches.  */
-               if ((int) gap <= 130
+                  long conditional branches.
+
+                  Only perform this optimisation for jumps (code 0x5a) not
+                  subroutine calls, as otherwise it could transform:
+                  
+                                    mov.w   r0,r0
+                                    beq     .L1
+                                    jsr     @_bar
+                             .L1:   rts
+                             _bar:  rts
+                  into:
+                                    mov.w   r0,r0
+                                    bne     _bar
+                                    rts
+                             _bar:  rts
+
+                  which changes the call (jsr) into a branch (bne).  */
+               if (code == 0x5a
+                   && (int) gap <= 130
                    && (int) gap >= -128
                    && last_reloc
                    && ELF32_R_TYPE (last_reloc->r_info) == R_H8_PCREL8
@@ -890,9 +910,6 @@ elf32_h8_relax_section (abfd, sec, link_info, again)
                      }
                  }
 
-               /* We could not eliminate this jump, so just shorten it.  */
-               code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
-
                if (code == 0x5e)
                  bfd_put_8 (abfd, 0x55, contents + irel->r_offset - 1);
                else if (code == 0x5a)
index 118c6e181ddc2d43df378d56d83cb9914e411a17..5460327b68c235bc3948201146d56d48433d0d9c 100644 (file)
@@ -1,3 +1,11 @@
+2002-11-15  Nick Clifton  <nickc@redhat.com>
+
+       * ld-h8300: New directory.
+       * ld-h8300/h8300.exp: New expect script.  Only run tests for h8300
+       targets.
+       * ld-h8300/relax.s: New assembler source file.
+       * ld-h8300/relax.d: New expected output file.
+
 2002-11-11  Hans-Peter Nilsson  <hp@axis.com>
 
        * ld-elf/sec64k.exp: New test.
diff --git a/ld/testsuite/ld-h8300/h8300.exp b/ld/testsuite/ld-h8300/h8300.exp
new file mode 100644 (file)
index 0000000..99542f4
--- /dev/null
@@ -0,0 +1,32 @@
+# Expect script for ld-h8300 tests
+# Copyright 2002 Free Software Foundation, Inc.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# Written by Nick Clifton  <nickc@redhat.com>
+#
+
+# Test h8300
+
+if ![istarget h8300-*-*] {
+    return
+}
+
+set test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]]
+foreach test $test_list {
+    # We need to strip the ".d", but can leave the dirname.
+    verbose [file rootname $test]
+    run_dump_test [file rootname $test]
+}
diff --git a/ld/testsuite/ld-h8300/relax.d b/ld/testsuite/ld-h8300/relax.d
new file mode 100644 (file)
index 0000000..a5672a5
--- /dev/null
@@ -0,0 +1,21 @@
+# name: H8300 Relxation Test
+# ld: --relax
+# objdump: -d --no-show-raw-insn
+
+# Based on the test case reported by Kazu Hirata:
+# http://sources.redhat.com/ml/binutils/2002-11/msg00301.html
+
+.*:     file format .*-h8300
+
+Disassembly of section .text:
+
+00000100 <_start>:
+ 100:  0d 00             mov.w r0,r0
+ 102:  47 02             beq   .+2 \(106\)
+ 104:  55 02             bsr   .+2 \(108\)
+
+00000106 <.L1>:
+ 106:  54 70             rts   
+
+00000108 <_bar>:
+ 108:  54 70             rts   
diff --git a/ld/testsuite/ld-h8300/relax.s b/ld/testsuite/ld-h8300/relax.s
new file mode 100644 (file)
index 0000000..b06f3a9
--- /dev/null
@@ -0,0 +1,10 @@
+       .text
+       .global _start
+_start:
+        mov.w   r0,r0
+        beq     .L1
+        jsr     @_bar
+.L1:
+        rts
+_bar:
+        rts