[llvm] cef2739 - [MC][AVR] Implement decoding STD/LDD
Ben Shi via llvm-commits
llvm-commits at lists.llvm.org
Wed May 4 19:08:17 PDT 2022
Author: Ben Shi
Date: 2022-05-05T01:53:49Z
New Revision: cef2739d682e329e4bf3aebcb82bf516438e095b
URL: https://github.com/llvm/llvm-project/commit/cef2739d682e329e4bf3aebcb82bf516438e095b
DIFF: https://github.com/llvm/llvm-project/commit/cef2739d682e329e4bf3aebcb82bf516438e095b.diff
LOG: [MC][AVR] Implement decoding STD/LDD
Reviewed By: aykevl, dylanmckay
Differential Revision: https://reviews.llvm.org/D123442
Added:
Modified:
llvm/lib/Target/AVR/AVRInstrFormats.td
llvm/lib/Target/AVR/AVRInstrInfo.td
llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp
llvm/test/MC/AVR/inst-ldd.s
llvm/test/MC/AVR/inst-std.s
Removed:
################################################################################
diff --git a/llvm/lib/Target/AVR/AVRInstrFormats.td b/llvm/lib/Target/AVR/AVRInstrFormats.td
index 2bcbcdfbf925c..83c32c80dfb98 100644
--- a/llvm/lib/Target/AVR/AVRInstrFormats.td
+++ b/llvm/lib/Target/AVR/AVRInstrFormats.td
@@ -179,7 +179,8 @@ class FSTDLDD<bit type, dag outs, dag ins, string asmstr, list<dag> pattern>
// r = src/dst register
//
// Note that the bit labelled 'i' above does not follow a simple pattern,
-// so there exists a post encoder method to set it manually.
+// so there exists a post encoder method to set it manually. Also a specified
+// decoder method is needed.
//===---------------------------------------------------------------------===//
class FSTLD<bit type, bits<2> mode, dag outs, dag ins, string asmstr,
list<dag> pattern> : AVRInst16<outs, ins, asmstr, pattern> {
@@ -200,6 +201,7 @@ class FSTLD<bit type, bits<2> mode, dag outs, dag ins, string asmstr,
let Inst{3 - 2} = ptrreg{1 - 0};
let Inst{1 - 0} = mode{1 - 0};
+ let DecoderMethod = "decodeLoadStore";
let PostEncoderMethod = "loadStorePostEncoder";
}
diff --git a/llvm/lib/Target/AVR/AVRInstrInfo.td b/llvm/lib/Target/AVR/AVRInstrInfo.td
index 9b45b50ac98bd..b04c5978dd008 100644
--- a/llvm/lib/Target/AVR/AVRInstrInfo.td
+++ b/llvm/lib/Target/AVR/AVRInstrInfo.td
@@ -177,6 +177,7 @@ def memri : Operand<iPTR> {
let PrintMethod = "printMemri";
let EncoderMethod = "encodeMemri";
+ let DecoderMethod = "decodeMemri";
let ParserMatchClass = MemriAsmOperand;
}
diff --git a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp
index bc245d2306229..23554109680bb 100644
--- a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp
+++ b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp
@@ -128,6 +128,13 @@ static DecodeStatus decodeFMUL2RdRr(MCInst &Inst, unsigned Insn,
uint64_t Address,
const MCDisassembler *Decoder);
+static DecodeStatus decodeMemri(MCInst &Inst, unsigned Insn, uint64_t Address,
+ const MCDisassembler *Decoder);
+
+static DecodeStatus decodeLoadStore(MCInst &Inst, unsigned Insn,
+ uint64_t Address,
+ const MCDisassembler *Decoder);
+
#include "AVRGenDisassemblerTables.inc"
static DecodeStatus decodeFIOARr(MCInst &Inst, unsigned Insn, uint64_t Address,
@@ -249,6 +256,49 @@ static DecodeStatus decodeFMUL2RdRr(MCInst &Inst, unsigned Insn,
return MCDisassembler::Success;
}
+static DecodeStatus decodeMemri(MCInst &Inst, unsigned Insn, uint64_t Address,
+ const MCDisassembler *Decoder) {
+ // As in the EncoderMethod `AVRMCCodeEmitter::encodeMemri`, the memory
+ // address is encoded into 7-bit, in which bits 0-5 are the immediate offset,
+ // and the bit-6 is the pointer register bit (Z=0, Y=1).
+ if (Insn > 127)
+ return MCDisassembler::Fail;
+
+ // Append the base register operand.
+ Inst.addOperand(
+ MCOperand::createReg((Insn & 0x40) ? AVR::R29R28 : AVR::R31R30));
+ // Append the immediate offset operand.
+ Inst.addOperand(MCOperand::createImm(Insn & 0x3f));
+
+ return MCDisassembler::Success;
+}
+
+static DecodeStatus decodeLoadStore(MCInst &Inst, unsigned Insn,
+ uint64_t Address,
+ const MCDisassembler *Decoder) {
+ // Decode LDD/STD with offset less than 8.
+ if ((Insn & 0xf000) == 0x8000) {
+ unsigned RegVal = GPRDecoderTable[(Insn >> 4) & 0x1f];
+ unsigned RegBase = (Insn & 0x8) ? AVR::R29R28 : AVR::R31R30;
+ unsigned Offset = Insn & 7; // We need not consider offset > 7.
+ if ((Insn & 0x200) == 0) { // Decode LDD.
+ Inst.setOpcode(AVR::LDDRdPtrQ);
+ Inst.addOperand(MCOperand::createReg(RegVal));
+ Inst.addOperand(MCOperand::createReg(RegBase));
+ Inst.addOperand(MCOperand::createImm(Offset));
+ } else { // Decode STD.
+ Inst.setOpcode(AVR::STDPtrQRr);
+ Inst.addOperand(MCOperand::createReg(RegBase));
+ Inst.addOperand(MCOperand::createImm(Offset));
+ Inst.addOperand(MCOperand::createReg(RegVal));
+ }
+ return MCDisassembler::Success;
+ }
+
+ // TODO: Decode ST/LD with postinc/predec properly.
+ return MCDisassembler::Fail;
+}
+
static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
uint64_t &Size, uint32_t &Insn) {
if (Bytes.size() < 2) {
diff --git a/llvm/test/MC/AVR/inst-ldd.s b/llvm/test/MC/AVR/inst-ldd.s
index 974cd39665a15..66b2c04a68638 100644
--- a/llvm/test/MC/AVR/inst-ldd.s
+++ b/llvm/test/MC/AVR/inst-ldd.s
@@ -1,5 +1,6 @@
; RUN: llvm-mc -triple avr -mattr=sram -show-encoding < %s | FileCheck %s
-
+; RUN: llvm-mc -filetype=obj -triple avr -mattr=sram < %s \
+; RUN: | llvm-objdump -d --mattr=sram - | FileCheck --check-prefix=INST %s
foo:
ldd r2, Y+2
@@ -18,3 +19,8 @@ foo:
; CHECK: ldd r9, Z+foo ; encoding: [0x90'A',0x80'A']
; CHECK: ; fixup A - offset: 0, value: +foo, kind: fixup_6
+
+; INST: ldd r2, Y+2
+; INST: ldd r0, Y+0
+; INST: ldd r9, Z+12
+; INST: ldd r7, Z+30
diff --git a/llvm/test/MC/AVR/inst-std.s b/llvm/test/MC/AVR/inst-std.s
index 94ae3bd2eb68f..571d5f475f9d7 100644
--- a/llvm/test/MC/AVR/inst-std.s
+++ b/llvm/test/MC/AVR/inst-std.s
@@ -1,5 +1,6 @@
; RUN: llvm-mc -triple avr -mattr=sram -show-encoding < %s | FileCheck %s
-
+; RUN: llvm-mc -filetype=obj -triple avr -mattr=sram < %s \
+; RUN: | llvm-objdump -d --mattr=sram - | FileCheck --check-prefix=INST %s
foo:
@@ -20,3 +21,7 @@ foo:
; CHECK: std Y+foo, r9 ; encoding: [0x98'A',0x82'A']
; CHECK: ; fixup A - offset: 0, value: +foo, kind: fixup_6
+; INST: std Y+2, r2
+; INST: std Y+0, r0
+; INST: std Z+12, r9
+; INST: std Z+30, r7
More information about the llvm-commits
mailing list