diff options
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 6 | ||||
-rw-r--r-- | bfd/elf32-avr.c | 18 |
2 files changed, 21 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 |