[AVR] Disassemble instructions with fixed Z operand

Some instructions have a fixed Z register and don't have an explicit
register operand. This can be worked around by simply printing the
operand directly if the particular register class is detected.

The LPM and ELPM instructions also needed a custom decoder, which is
also included in this patch.

Differential Revision: https://reviews.llvm.org/D82088
This commit is contained in:
Ayke van Laethem 2020-06-18 14:41:17 +02:00
parent ec9efb856c
commit 9f09c29f01
No known key found for this signature in database
GPG Key ID: E97FF5335DFDFDED
10 changed files with 70 additions and 1 deletions

View File

@ -237,6 +237,8 @@ class FLPMX<bit e, bit p, dag outs, dag ins, string asmstr, list<dag> pattern>
let Inst{3-2} = 0b01;
let Inst{1} = e;
let Inst{0} = p;
let DecoderMethod = "decodeFLPMX";
}
//===----------------------------------------------------------------------===//

View File

@ -110,6 +110,9 @@ static DecodeStatus decodeCallTarget(MCInst &Inst, unsigned Insn,
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 @@ static DecodeStatus decodeFRd(MCInst &Inst, unsigned Insn,
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;

View File

@ -100,6 +100,14 @@ const char *AVRInstPrinter::getPrettyRegisterName(unsigned RegNum,
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 @@ void AVRInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
}
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) ||

View File

@ -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 @@ foo:
; 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+

View File

@ -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 @@ foo:
; 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

View File

@ -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 @@ foo:
; 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

View File

@ -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 @@ foo:
; 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

View File

@ -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 @@ foo:
lpm r8, Z+
lpm r0, Z+
lpm r31, Z+
; CHECK: lpm ; encoding: [0xc8,0x95]
@ -18,3 +20,13 @@ foo:
; 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+

View File

@ -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 @@ foo:
; CHECK: spm ; encoding: [0xe8,0x95]
; CHECK: spm Z+ ; encoding: [0xf8,0x95]
; CHECK-INST: spm
; CHECK-INST: spm Z+

View File

@ -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 @@ foo:
; 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