Index: llvm/lib/Target/AVR/AVRInstrInfo.td =================================================================== --- llvm/lib/Target/AVR/AVRInstrInfo.td +++ llvm/lib/Target/AVR/AVRInstrInfo.td @@ -177,6 +177,7 @@ let PrintMethod = "printMemri"; let EncoderMethod = "encodeMemri"; + let DecoderMethod = "decodeMemri"; let ParserMatchClass = MemriAsmOperand; } Index: llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp =================================================================== --- llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp +++ llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp @@ -128,6 +128,9 @@ uint64_t Address, const MCDisassembler *Decoder); +static DecodeStatus decodeMemri(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 +252,23 @@ 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 readInstruction16(ArrayRef Bytes, uint64_t Address, uint64_t &Size, uint32_t &Insn) { if (Bytes.size() < 2) { Index: llvm/test/MC/AVR/inst-ldd.s =================================================================== --- llvm/test/MC/AVR/inst-ldd.s +++ 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,9 @@ ; CHECK: ldd r9, Z+foo ; encoding: [0x90'A',0x80'A'] ; CHECK: ; fixup A - offset: 0, value: +foo, kind: fixup_6 + + ldd r2, y+7 + ldd r3, z+9 + +; INST: ldd r2, Y+7 +; INST: ldd r3, Z+9 Index: llvm/test/MC/AVR/inst-std.s =================================================================== --- llvm/test/MC/AVR/inst-std.s +++ 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,8 @@ ; CHECK: std Y+foo, r9 ; encoding: [0x98'A',0x82'A'] ; CHECK: ; fixup A - offset: 0, value: +foo, kind: fixup_6 + std y+19, r2 + std z+37, r3 + +; INST: std Y+19, r2 +; INST: std Z+37, r3