[PATCH] D140815: [AVR] Fix incorrect decoding of RJMP and RCALL.

Ben Shi via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sat Dec 31 22:48:54 PST 2022


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

The offset operand of RCALL/RJMP is inaccurate when decoded by
llvm-objdump. And this patch fixes that issue.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D140815

Files:
  lld/test/ELF/avr-reloc.s
  llvm/lib/Target/AVR/AVRInstrFormats.td
  llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp


Index: llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp
===================================================================
--- llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp
+++ llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp
@@ -123,6 +123,9 @@
 static DecodeStatus decodeMemri(MCInst &Inst, unsigned Insn, uint64_t Address,
                                 const MCDisassembler *Decoder);
 
+static DecodeStatus decodeFBRk(MCInst &Inst, unsigned Insn, uint64_t Address,
+                               const MCDisassembler *Decoder);
+
 static DecodeStatus decodeLoadStore(MCInst &Inst, unsigned Insn,
                                     uint64_t Address,
                                     const MCDisassembler *Decoder);
@@ -265,6 +268,25 @@
   return MCDisassembler::Success;
 }
 
+static DecodeStatus decodeFBRk(MCInst &Inst, unsigned Insn, uint64_t Address,
+                               const MCDisassembler *Decoder) {
+  // Decode the opcode.
+  switch (Insn & 0xf000) {
+  case 0xc000:
+    Inst.setOpcode(AVR::RJMPk);
+    break;
+  case 0xd000:
+    Inst.setOpcode(AVR::RCALLk);
+    break;
+  default: // Unknown relative branch instruction.
+    return MCDisassembler::Fail;
+  }
+  // Decode the relative offset.
+  int16_t Offset = ((int16_t)((Insn & 0xfff) << 4)) >> 3;
+  Inst.addOperand(MCOperand::createImm(Offset));
+  return MCDisassembler::Success;
+}
+
 static DecodeStatus decodeLoadStore(MCInst &Inst, unsigned Insn,
                                     uint64_t Address,
                                     const MCDisassembler *Decoder) {
@@ -275,7 +297,7 @@
   if ((Insn & 0xf000) == 0x8000) {
     unsigned RegBase = (Insn & 0x8) ? AVR::R29R28 : AVR::R31R30;
     unsigned Offset = Insn & 7; // We need not consider offset > 7.
-    if ((Insn & 0x200) == 0) { // Decode LDD.
+    if ((Insn & 0x200) == 0) {  // Decode LDD.
       Inst.setOpcode(AVR::LDDRdPtrQ);
       Inst.addOperand(MCOperand::createReg(RegVal));
       Inst.addOperand(MCOperand::createReg(RegBase));
Index: llvm/lib/Target/AVR/AVRInstrFormats.td
===================================================================
--- llvm/lib/Target/AVR/AVRInstrFormats.td
+++ llvm/lib/Target/AVR/AVRInstrFormats.td
@@ -460,6 +460,8 @@
   let Inst{15 - 13} = 0b110;
   let Inst{12} = f;
   let Inst{11 - 0} = k;
+
+  let DecoderMethod = "decodeFBRk";
 }
 
 //===----------------------------------------------------------------------===//
Index: lld/test/ELF/avr-reloc.s
===================================================================
--- lld/test/ELF/avr-reloc.s
+++ lld/test/ELF/avr-reloc.s
@@ -62,18 +62,23 @@
 sbic  b, 1    ; R_AVR_PORT5
 
 ;; The disassembler is not yet able to decode those opcodes
-;; 0f c0    rjmp   .+30
-;; ee cf    rjmp   .-36
 ;; 69 f0    breq   .+26
 ;; 61 f3    breq   .-40
 .section .PCREL,"ax", at progbits
+; CHECK-LABEL: section .PCREL
+; CHECK:       rjmp   .+30
+; CHECK-NEXT:  rjmp   .-36
+; CHECK:       rcall  .+22
+; CHECK-NEXT:  rcall  .-44
 ; HEX-LABEL: section .PCREL:
-; HEX-NEXT:  0fc0eecf 69f061f3
+; HEX-NEXT:  0fc0eecf 69f061f3 0bd0eadf
 foo:
-rjmp foo + 32  ; R_AVR_13_PCREL
-rjmp foo - 32  ; R_AVR_13_PCREL
-breq foo + 32  ; R_AVR_7_PCREL
-breq foo - 32  ; R_AVR_7_PCREL
+rjmp  foo + 32  ; R_AVR_13_PCREL
+rjmp  foo - 32  ; R_AVR_13_PCREL
+breq  foo + 32  ; R_AVR_7_PCREL
+breq  foo - 32  ; R_AVR_7_PCREL
+rcall foo + 32  ; R_AVR_13_PCREL
+rcall foo - 32  ; R_AVR_13_PCREL
 
 .section .DATA,"ax", at progbits
 ; HEX-LABEL: section .DATA:


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D140815.485796.patch
Type: text/x-patch
Size: 3494 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230101/b40fbb17/attachment.bin>


More information about the llvm-commits mailing list