diff --git a/llvm/lib/Target/AVR/AVRInstrFormats.td b/llvm/lib/Target/AVR/AVRInstrFormats.td --- a/llvm/lib/Target/AVR/AVRInstrFormats.td +++ b/llvm/lib/Target/AVR/AVRInstrFormats.td @@ -237,6 +237,8 @@ let Inst{3-2} = 0b01; let Inst{1} = e; let Inst{0} = p; + + let DecoderMethod = "decodeFLPMX"; } //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp --- a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp +++ b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp @@ -110,6 +110,9 @@ static DecodeStatus decodeFRd(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); +static DecodeStatus decodeFLPMX(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); + static DecodeStatus decodeFFMULRdRr(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); @@ -167,6 +170,14 @@ return MCDisassembler::Success; } +static DecodeStatus decodeFLPMX(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + if (decodeFRd(Inst, Insn, Address, Decoder) == MCDisassembler::Fail) + return MCDisassembler::Fail; + Inst.addOperand(MCOperand::createReg(AVR::R31R30)); + return MCDisassembler::Success; +} + static DecodeStatus decodeFFMULRdRr(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder) { unsigned d = fieldFromInstruction(Insn, 4, 3) + 16; diff --git a/llvm/lib/Target/AVR/MCTargetDesc/AVRInstPrinter.cpp b/llvm/lib/Target/AVR/MCTargetDesc/AVRInstPrinter.cpp --- a/llvm/lib/Target/AVR/MCTargetDesc/AVRInstPrinter.cpp +++ b/llvm/lib/Target/AVR/MCTargetDesc/AVRInstPrinter.cpp @@ -100,6 +100,14 @@ void AVRInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) { + const MCOperandInfo &MOI = this->MII.get(MI->getOpcode()).OpInfo[OpNo]; + if (MOI.RegClass == AVR::ZREGRegClassID) { + // Special case for the Z register, which sometimes doesn't have an operand + // in the MCInst. + O << "Z"; + return; + } + if (OpNo >= MI->size()) { // Not all operands are correctly disassembled at the moment. This means // that some machine instructions won't have all the necessary operands @@ -111,7 +119,6 @@ } const MCOperand &Op = MI->getOperand(OpNo); - const MCOperandInfo &MOI = this->MII.get(MI->getOpcode()).OpInfo[OpNo]; if (Op.isReg()) { bool isPtrReg = (MOI.RegClass == AVR::PTRREGSRegClassID) || diff --git a/llvm/test/MC/AVR/inst-elpm.s b/llvm/test/MC/AVR/inst-elpm.s --- a/llvm/test/MC/AVR/inst-elpm.s +++ b/llvm/test/MC/AVR/inst-elpm.s @@ -1,4 +1,5 @@ ; RUN: llvm-mc -triple avr -mattr=elpm,elpmx -show-encoding < %s | FileCheck %s +; RUN: llvm-mc -filetype=obj -triple avr -mattr=elpm,elpmx < %s | llvm-objdump -d --mattr=elpm,elpmx - | FileCheck -check-prefix=CHECK-INST %s foo: @@ -18,3 +19,11 @@ ; CHECK: elpm r8, Z+ ; encoding: [0x87,0x90] ; CHECK: elpm r0, Z+ ; encoding: [0x07,0x90] + +; CHECK-INST: elpm + +; CHECK-INST: elpm r3, Z +; CHECK-INST: elpm r23, Z + +; CHECK-INST: elpm r8, Z+ +; CHECK-INST: elpm r0, Z+ diff --git a/llvm/test/MC/AVR/inst-lac.s b/llvm/test/MC/AVR/inst-lac.s --- a/llvm/test/MC/AVR/inst-lac.s +++ b/llvm/test/MC/AVR/inst-lac.s @@ -1,4 +1,5 @@ ; RUN: llvm-mc -triple avr -mattr=rmw -show-encoding < %s | FileCheck %s +; RUN: llvm-mc -filetype=obj -triple avr -mattr=rmw < %s | llvm-objdump -d --mattr=rmw - | FileCheck -check-prefix=CHECK-INST %s foo: @@ -12,3 +13,8 @@ ; CHECK: lac Z, r0 ; encoding: [0x06,0x92] ; CHECK: lac Z, r31 ; encoding: [0xf6,0x93] ; CHECK: lac Z, r3 ; encoding: [0x36,0x92] + +; CHECK-INST: lac Z, r13 +; CHECK-INST: lac Z, r0 +; CHECK-INST: lac Z, r31 +; CHECK-INST: lac Z, r3 diff --git a/llvm/test/MC/AVR/inst-las.s b/llvm/test/MC/AVR/inst-las.s --- a/llvm/test/MC/AVR/inst-las.s +++ b/llvm/test/MC/AVR/inst-las.s @@ -1,4 +1,5 @@ ; RUN: llvm-mc -triple avr -mattr=rmw -show-encoding < %s | FileCheck %s +; RUN: llvm-mc -filetype=obj -triple avr -mattr=rmw < %s | llvm-objdump -d --mattr=rmw - | FileCheck -check-prefix=CHECK-INST %s foo: @@ -12,3 +13,8 @@ ; CHECK: las Z, r0 ; encoding: [0x05,0x92] ; CHECK: las Z, r31 ; encoding: [0xf5,0x93] ; CHECK: las Z, r3 ; encoding: [0x35,0x92] + +; CHECK-INST: las Z, r13 +; CHECK-INST: las Z, r0 +; CHECK-INST: las Z, r31 +; CHECK-INST: las Z, r3 diff --git a/llvm/test/MC/AVR/inst-lat.s b/llvm/test/MC/AVR/inst-lat.s --- a/llvm/test/MC/AVR/inst-lat.s +++ b/llvm/test/MC/AVR/inst-lat.s @@ -1,4 +1,5 @@ ; RUN: llvm-mc -triple avr -mattr=rmw -show-encoding < %s | FileCheck %s +; RUN: llvm-mc -filetype=obj -triple avr -mattr=rmw < %s | llvm-objdump -d --mattr=rmw - | FileCheck -check-prefix=CHECK-INST %s foo: @@ -12,3 +13,8 @@ ; CHECK: lat Z, r0 ; encoding: [0x07,0x92] ; CHECK: lat Z, r31 ; encoding: [0xf7,0x93] ; CHECK: lat Z, r3 ; encoding: [0x37,0x92] + +; CHECK-INST: lat Z, r13 +; CHECK-INST: lat Z, r0 +; CHECK-INST: lat Z, r31 +; CHECK-INST: lat Z, r3 diff --git a/llvm/test/MC/AVR/inst-lpm.s b/llvm/test/MC/AVR/inst-lpm.s --- a/llvm/test/MC/AVR/inst-lpm.s +++ b/llvm/test/MC/AVR/inst-lpm.s @@ -1,4 +1,5 @@ ; RUN: llvm-mc -triple avr -mattr=lpm,lpmx -show-encoding < %s | FileCheck %s +; RUN: llvm-mc -filetype=obj -triple avr -mattr=lpm,lpmx < %s | llvm-objdump -d --mattr=lpm,lpmx - | FileCheck -check-prefix=CHECK-INST %s foo: @@ -10,6 +11,7 @@ lpm r8, Z+ lpm r0, Z+ + lpm r31, Z+ ; CHECK: lpm ; encoding: [0xc8,0x95] @@ -18,3 +20,13 @@ ; CHECK: lpm r8, Z+ ; encoding: [0x85,0x90] ; CHECK: lpm r0, Z+ ; encoding: [0x05,0x90] +; CHECK: lpm r31, Z+ ; encoding: [0xf5,0x91] + +; CHECK-INST: lpm + +; CHECK-INST: lpm r3, Z +; CHECK-INST: lpm r23, Z + +; CHECK-INST: lpm r8, Z+ +; CHECK-INST: lpm r0, Z+ +; CHECK-INST: lpm r31, Z+ diff --git a/llvm/test/MC/AVR/inst-spm.s b/llvm/test/MC/AVR/inst-spm.s --- a/llvm/test/MC/AVR/inst-spm.s +++ b/llvm/test/MC/AVR/inst-spm.s @@ -1,4 +1,5 @@ ; RUN: llvm-mc -triple avr -mattr=spm,spmx -show-encoding < %s | FileCheck %s +; RUN: llvm-mc -filetype=obj -triple avr -mattr=spm,spmx < %s | llvm-objdump -d --mattr=spm,spmx - | FileCheck -check-prefix=CHECK-INST %s foo: @@ -8,3 +9,6 @@ ; CHECK: spm ; encoding: [0xe8,0x95] ; CHECK: spm Z+ ; encoding: [0xf8,0x95] + +; CHECK-INST: spm +; CHECK-INST: spm Z+ diff --git a/llvm/test/MC/AVR/inst-xch.s b/llvm/test/MC/AVR/inst-xch.s --- a/llvm/test/MC/AVR/inst-xch.s +++ b/llvm/test/MC/AVR/inst-xch.s @@ -1,4 +1,5 @@ ; RUN: llvm-mc -triple avr -mattr=rmw -show-encoding < %s | FileCheck %s +; RUN: llvm-mc -filetype=obj -triple avr -mattr=rmw < %s | llvm-objdump -d --mattr=rmw - | FileCheck -check-prefix=CHECK-INST %s foo: @@ -12,3 +13,8 @@ ; CHECK: xch Z, r0 ; encoding: [0x04,0x92] ; CHECK: xch Z, r31 ; encoding: [0xf4,0x93] ; CHECK: xch Z, r3 ; encoding: [0x34,0x92] + +; CHECK-INST: xch Z, r13 +; CHECK-INST: xch Z, r0 +; CHECK-INST: xch Z, r31 +; CHECK-INST: xch Z, r3