aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog6
-rw-r--r--bfd/elf32-avr.c18
-rw-r--r--ld/ChangeLog6
-rw-r--r--ld/testsuite/ld-avr/relax-insn-at-range-boundary.d17
-rw-r--r--ld/testsuite/ld-avr/relax-insn-at-range-boundary.s11
5 files changed, 55 insertions, 3 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 0d7eda4..7d22cc0 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,11 @@
2019-05-21 Senthil Kumar Selvaraj <senthilkumar.selvaraj@microchip.com>
+ PR ld/24571
+ * bfd/elf32-avr.c (elf32_avr_relax_section): Adjust range check
+ when computing distance_short_enough.
+
+2019-05-21 Senthil Kumar Selvaraj <senthilkumar.selvaraj@microchip.com>
+
PR ld/24564
* bfd/elf32-avr.c (avr_relative_distance_considering_wrap_around):
Wrap around even if distance equals avr_pc_wrap_around.
diff --git a/bfd/elf32-avr.c b/bfd/elf32-avr.c
index f8a843e..34ad423 100644
--- a/bfd/elf32-avr.c
+++ b/bfd/elf32-avr.c
@@ -2643,16 +2643,28 @@ elf32_avr_relax_section (bfd *abfd,
/* Compute the distance from this insn to the branch target. */
gap = value - dot;
+ /* The ISA manual states that addressable range is PC - 2k + 1 to
+ PC + 2k. In bytes, that would be -4094 <= PC <= 4096. The range
+ is shifted one word to the right, because pc-relative instructions
+ implicitly add one word i.e. rjmp 0 jumps to next insn, not the
+ current one.
+ Therefore, for the !shrinkable case, the range is as above.
+ If shrinkable, then the current code only deletes bytes 3 and
+ 4 of the absolute call/jmp, so the forward jump range increases
+ by 2 bytes, but the backward (negative) jump range remains
+ the same. */
+
+
/* Check if the gap falls in the range that can be accommodated
in 13bits signed (It is 12bits when encoded, as we deal with
word addressing). */
- if (!shrinkable && ((int) gap >= -4096 && (int) gap <= 4095))
+ if (!shrinkable && ((int) gap >= -4094 && (int) gap <= 4096))
distance_short_enough = 1;
/* If shrinkable, then we can check for a range of distance which
- is two bytes farther on both the directions because the call
+ is two bytes farther on the positive direction because the call
or jump target will be closer by two bytes after the
relaxation. */
- else if (shrinkable && ((int) gap >= -4094 && (int) gap <= 4097))
+ else if (shrinkable && ((int) gap >= -4094 && (int) gap <= 4098))
distance_short_enough = 1;
/* Here we handle the wrap-around case. E.g. for a 16k device
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 20be135..e038e40 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,5 +1,11 @@
2019-05-21 Senthil Kumar Selvaraj <senthilkumar.selvaraj@microchip.com>
+ PR ld/24571
+ * ld/testsuite/ld-avr/relax-insn-at-range-boundary.d: New test.
+ * ld/testsuite/ld-avr/relax-insn-at-range-boundary.s: New test.
+
+2019-05-21 Senthil Kumar Selvaraj <senthilkumar.selvaraj@microchip.com>
+
PR ld/24564
* testsuite/ld-avr/wraparound-range-boundary.d: New test.
* testsuite/ld-avr/wraparound-range-boundary.s: New test.
diff --git a/ld/testsuite/ld-avr/relax-insn-at-range-boundary.d b/ld/testsuite/ld-avr/relax-insn-at-range-boundary.d
new file mode 100644
index 0000000..6183896
--- /dev/null
+++ b/ld/testsuite/ld-avr/relax-insn-at-range-boundary.d
@@ -0,0 +1,17 @@
+#name: AVR relaxation, jump to symbol at ends of pc-relative range boundary
+#as: -mlink-relax -mavr51
+#ld: --relax -mavr51
+#source: relax-insn-at-range-boundary.s
+#objdump: -d
+#target: avr-*-*
+
+#...
+00000000.*
+ ...
+ ffc: 00 00 nop
+ ffe: 00 c8 rjmp .-4096 ; 0x0 .*
+ 1000: ff c7 rjmp .+4094 ; 0x2000 <forward_target>
+ ...
+
+00002000 <forward_target>:
+#...
diff --git a/ld/testsuite/ld-avr/relax-insn-at-range-boundary.s b/ld/testsuite/ld-avr/relax-insn-at-range-boundary.s
new file mode 100644
index 0000000..4d710df
--- /dev/null
+++ b/ld/testsuite/ld-avr/relax-insn-at-range-boundary.s
@@ -0,0 +1,11 @@
+.section ".text", "ax",@progbits
+.global main
+main:
+backward_target: ; Exactly -4094 bytes from jmp
+ .ds.b 4094, 0
+ jmp backward_target
+ jmp forward_target
+ .ds.b 4094, 0
+forward_target: ; Exactly 4098 bytes before relax, 4096 bytes after relax
+ nop
+