[AVR] Disassemble instructions with fixed Z operand
authorAyke van Laethem <aykevanlaethem@gmail.com>
Thu, 18 Jun 2020 12:41:17 +0000 (14:41 +0200)
committerAyke van Laethem <aykevanlaethem@gmail.com>
Tue, 23 Jun 2020 00:17:53 +0000 (02:17 +0200)
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

llvm/lib/Target/AVR/AVRInstrFormats.td
llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp
llvm/lib/Target/AVR/MCTargetDesc/AVRInstPrinter.cpp
llvm/test/MC/AVR/inst-elpm.s
llvm/test/MC/AVR/inst-lac.s
llvm/test/MC/AVR/inst-las.s
llvm/test/MC/AVR/inst-lat.s
llvm/test/MC/AVR/inst-lpm.s
llvm/test/MC/AVR/inst-spm.s
llvm/test/MC/AVR/inst-xch.s

index 78e1d5a..0fcc21a 100644 (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";
 }
 
 //===----------------------------------------------------------------------===//
index dc06379..73f3e09 100644 (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;
index 3283f74..815a309 100644 (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) ||
index 4f58cdb..ac67fdb 100644 (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+
index da17572..e20998c 100644 (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
index 3ee52f4..d8ff8d5 100644 (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
index e10a216..ae001c0 100644 (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
index a0bdda7..7ddacd4 100644 (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+
index dbcb98a..3e1b8dd 100644 (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+
index 05e512b..36d30e2 100644 (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