[PATCH] D142691: [AVR] Fix inaccurate offsets in PC relative branch instructions

Ben Shi via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 26 23:12:40 PST 2023


benshi001 created this revision.
benshi001 added a reviewer: aykevl.
Herald added subscribers: Jim, hiraditya, dylanmckay.
Herald added a project: All.
benshi001 requested review of this revision.
Herald added subscribers: llvm-commits, jacquesguan.
Herald added a project: LLVM.

In avr-gcc, the destination of `rjmp label+offset` is address
`label+offset`, while destination of `rjmp .+offset` is `address_of_rjmp+offset+2`.

Clang is in accordance with avr-gcc for `rjmp label+offset`, but
emits the destination of `rjmp .+offset` to `address_of_rjmp+offset`.

This patch fixes the above issue.

Fixes https://github.com/llvm/llvm-project/issues/60019


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D142691

Files:
  llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp
  llvm/test/MC/AVR/relocations.s


Index: llvm/test/MC/AVR/relocations.s
===================================================================
--- llvm/test/MC/AVR/relocations.s
+++ llvm/test/MC/AVR/relocations.s
@@ -2,6 +2,24 @@
 
 ; CHECK: RELOCATION RECORDS FOR
 
+; CHECK:      R_AVR_13_PCREL .text+0x4
+rjmp .+2
+
+; CHECK-NEXT: R_AVR_13_PCREL .text+0x4
+rjmp .
+
+; CHECK-NEXT: R_AVR_13_PCREL .text+0x4
+rjmp .-2
+
+; CHECK-NEXT: R_AVR_7_PCREL .text+0xa
+breq .+2
+
+; CHECK-NEXT: R_AVR_7_PCREL .text+0xa
+breq .
+
+; CHECK-NEXT: R_AVR_7_PCREL .text+0xa
+breq .-2
+
 .global bar
 bar:
   jmp bar
Index: llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp
===================================================================
--- llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp
+++ llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp
@@ -514,6 +514,21 @@
   // Fixups which should always be recorded as relocations.
   case AVR::fixup_7_pcrel:
   case AVR::fixup_13_pcrel:
+    // Fix inaccurate PC relative offsets. These errors are introduced by
+    // instructions such as "rjmp .+off" or "breq .+off", which mean branch
+    // to address_of_current_instruction+off+2 in avr-gcc.
+    // TODO: Find a better way to fix, maybe by inheriting the virtual function
+    // 'bool MCAsmBackend::evaluateTargetFixup(...)'.
+    if (const auto *SymA = Target.getSymA())
+      if (SymA->getSymbol().getName().size() == 0) {
+        // Adjust the offset to offset+2, while other fields are not changed.
+        const auto *SymB = Target.getSymB();
+        const int64_t C = Target.getConstant() + 2;
+        const uint32_t RefKind = Target.getRefKind();
+        MCValue &MCV = const_cast<MCValue &>(Target);
+        MCV = MCValue::get(SymA, SymB, C, RefKind);
+      }
+    [[fallthrough]];
   case AVR::fixup_call:
     return true;
   }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D142691.492649.patch
Type: text/x-patch
Size: 1808 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230127/4f6e860f/attachment.bin>


More information about the llvm-commits mailing list