[llvm] 6dc85bd - [AVR] Fix incorrect decoding of RJMP and RCALL
Ben Shi via llvm-commits
llvm-commits at lists.llvm.org
Sat Jan 7 07:32:28 PST 2023
Author: Ben Shi
Date: 2023-01-07T23:26:40+08:00
New Revision: 6dc85bd3fde7df2999fda07e9e9f2e83d52c6125
URL: https://github.com/llvm/llvm-project/commit/6dc85bd3fde7df2999fda07e9e9f2e83d52c6125
DIFF: https://github.com/llvm/llvm-project/commit/6dc85bd3fde7df2999fda07e9e9f2e83d52c6125.diff
LOG: [AVR] Fix incorrect decoding of RJMP and RCALL
This patch fixes the inaccurate decoding of the offset operand of
the RCALL & RJMP instructions.
Reviewed By: aykevl, MaskRay
Differential Revision: https://reviews.llvm.org/D140815
Added:
Modified:
llvm/lib/Target/AVR/AVRInstrFormats.td
llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp
llvm/test/MC/AVR/inst-rcall.s
llvm/test/MC/AVR/inst-rjmp.s
Removed:
################################################################################
diff --git a/llvm/lib/Target/AVR/AVRInstrFormats.td b/llvm/lib/Target/AVR/AVRInstrFormats.td
index dd8da7092d471..96b48a504376a 100644
--- a/llvm/lib/Target/AVR/AVRInstrFormats.td
+++ b/llvm/lib/Target/AVR/AVRInstrFormats.td
@@ -460,6 +460,8 @@ class FBRk<bit f, dag outs, dag ins, string asmstr, list<dag> pattern>
let Inst{15 - 13} = 0b110;
let Inst{12} = f;
let Inst{11 - 0} = k;
+
+ let DecoderMethod = "decodeFBRk";
}
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp
index d8734596148d5..7674d9e354faf 100644
--- a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp
+++ b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp
@@ -123,6 +123,9 @@ static DecodeStatus decodeFMUL2RdRr(MCInst &Inst, unsigned Insn,
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 @@ static DecodeStatus decodeMemri(MCInst &Inst, unsigned Insn, uint64_t Address,
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 @@ static DecodeStatus decodeLoadStore(MCInst &Inst, unsigned Insn,
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));
diff --git a/llvm/test/MC/AVR/inst-rcall.s b/llvm/test/MC/AVR/inst-rcall.s
index 84a7343c52517..4e75620b147e7 100644
--- a/llvm/test/MC/AVR/inst-rcall.s
+++ b/llvm/test/MC/AVR/inst-rcall.s
@@ -1,4 +1,6 @@
; RUN: llvm-mc -triple avr -show-encoding < %s | FileCheck %s
+; RUN: llvm-mc -filetype=obj -triple avr < %s \
+; RUN: | llvm-objdump -d - | FileCheck --check-prefix=INST %s
foo:
@@ -7,6 +9,7 @@ foo:
rcall .-8
rcall .+12
rcall .+46
+ .short 0xdfea
; CHECK: rcall .Ltmp0+0 ; encoding: [A,0b1101AAAA]
; CHECK: ; fixup A - offset: 0, value: .Ltmp0+0, kind: fixup_13_pcrel
@@ -17,3 +20,8 @@ foo:
; CHECK: rcall .Ltmp3+46 ; encoding: [A,0b1101AAAA]
; CHECK: ; fixup A - offset: 0, value: .Ltmp3+46, kind: fixup_13_pcrel
+; INST: rcall .+0
+; INST: rcall .+0
+; INST: rcall .+0
+; INST: rcall .+0
+; INST: rcall .-44
diff --git a/llvm/test/MC/AVR/inst-rjmp.s b/llvm/test/MC/AVR/inst-rjmp.s
index 22d9f2f8d9b2a..472d654ce3460 100644
--- a/llvm/test/MC/AVR/inst-rjmp.s
+++ b/llvm/test/MC/AVR/inst-rjmp.s
@@ -16,6 +16,7 @@ end:
rjmp .-6
x:
rjmp x
+ .short 0xc00f
; CHECK: rjmp .Ltmp0+2 ; encoding: [A,0b1100AAAA]
; CHECK: ; fixup A - offset: 0, value: .Ltmp0+2, kind: fixup_13_pcrel
@@ -45,3 +46,4 @@ x:
; INST: rjmp .+0
; INST: rjmp .+0
; INST: rjmp .+0
+; INST: rjmp .+30
More information about the llvm-commits
mailing list