[AVR] Implement disassembly support for I/O instructions
authorAyke van Laethem <aykevanlaethem@gmail.com>
Wed, 5 Feb 2020 14:04:47 +0000 (15:04 +0100)
committerAyke van Laethem <aykevanlaethem@gmail.com>
Wed, 10 Jun 2020 18:55:47 +0000 (20:55 +0200)
The in, out, and sbi/cbi family of instructions seem to require a custom
decoder. I'm not exactly sure why and would prefer to convince TableGen
to provide the correct decoders for these, but I can't seem to convince
it to do so. They simply disassemble without any operands.

Differential Revision: https://reviews.llvm.org/D74049

llvm/lib/Target/AVR/AVRInstrFormats.td
llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp
llvm/test/MC/AVR/inst-cbi.s
llvm/test/MC/AVR/inst-in.s
llvm/test/MC/AVR/inst-out.s
llvm/test/MC/AVR/inst-sbi.s
llvm/test/MC/AVR/inst-sbic.s
llvm/test/MC/AVR/inst-sbis.s

index ffa67b8..159c143 100644 (file)
@@ -332,6 +332,8 @@ class FIORdA<dag outs, dag ins, string asmstr, list<dag> pattern>
   let Inst{10-9} = A{5-4};
   let Inst{8-4} = d;
   let Inst{3-0} = A{3-0};
+
+  let DecoderMethod = "decodeFIORdA";
 }
 
 //===----------------------------------------------------------------------===//
@@ -350,6 +352,8 @@ class FIOARr<dag outs, dag ins, string asmstr, list<dag> pattern>
   let Inst{10-9} = A{5-4};
   let Inst{8-4} = r;
   let Inst{3-0} = A{3-0};
+
+  let DecoderMethod = "decodeFIOARr";
 }
 
 //===----------------------------------------------------------------------===//
@@ -374,6 +378,8 @@ class FIOBIT<bits<2> t, dag outs, dag ins, string asmstr, list<dag> pattern>
 
   let Inst{3} = A{0};
   let Inst{2-0} = b{2-0};
+
+  let DecoderMethod = "decodeFIOBIT";
 }
 
 //===----------------------------------------------------------------------===//
index 3e1fd45..a5c08c4 100644 (file)
@@ -95,8 +95,50 @@ static DecodeStatus DecodePTRREGSRegisterClass(MCInst &Inst, unsigned RegNo,
   return MCDisassembler::Success;
 }
 
+static DecodeStatus decodeFIOARr(MCInst &Inst, unsigned Insn,
+                                 uint64_t Address, const void *Decoder);
+
+static DecodeStatus decodeFIORdA(MCInst &Inst, unsigned Insn,
+                                 uint64_t Address, const void *Decoder);
+
+static DecodeStatus decodeFIOBIT(MCInst &Inst, unsigned Insn,
+                                 uint64_t Address, const void *Decoder);
+
 #include "AVRGenDisassemblerTables.inc"
 
+static DecodeStatus decodeFIOARr(MCInst &Inst, unsigned Insn,
+                                 uint64_t Address, const void *Decoder) {
+  unsigned addr = 0;
+  addr |= fieldFromInstruction(Insn, 0, 4);
+  addr |= fieldFromInstruction(Insn, 9, 2) << 4;
+  unsigned reg = fieldFromInstruction(Insn, 4, 5);
+  Inst.addOperand(MCOperand::createImm(addr));
+  if (DecodeGPR8RegisterClass(Inst, reg, Address, Decoder) == MCDisassembler::Fail)
+    return MCDisassembler::Fail;
+  return MCDisassembler::Success;
+}
+
+static DecodeStatus decodeFIORdA(MCInst &Inst, unsigned Insn,
+                                 uint64_t Address, const void *Decoder) {
+  unsigned addr = 0;
+  addr |= fieldFromInstruction(Insn, 0, 4);
+  addr |= fieldFromInstruction(Insn, 9, 2) << 4;
+  unsigned reg = fieldFromInstruction(Insn, 4, 5);
+  if (DecodeGPR8RegisterClass(Inst, reg, Address, Decoder) == MCDisassembler::Fail)
+    return MCDisassembler::Fail;
+  Inst.addOperand(MCOperand::createImm(addr));
+  return MCDisassembler::Success;
+}
+
+static DecodeStatus decodeFIOBIT(MCInst &Inst, unsigned Insn,
+                                 uint64_t Address, const void *Decoder) {
+  unsigned addr = fieldFromInstruction(Insn, 3, 5);
+  unsigned b = fieldFromInstruction(Insn, 0, 3);
+  Inst.addOperand(MCOperand::createImm(addr));
+  Inst.addOperand(MCOperand::createImm(b));
+  return MCDisassembler::Success;
+}
+
 static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
                                       uint64_t &Size, uint32_t &Insn) {
   if (Bytes.size() < 2) {
index 95c21ad..2e6dc9e 100644 (file)
@@ -1,20 +1,36 @@
 ; RUN: llvm-mc -triple avr -show-encoding < %s | FileCheck %s
+; RUN: llvm-mc -filetype=obj -triple avr < %s | llvm-objdump -d - | FileCheck -check-prefix=CHECK-INST %s
 
 
 foo:
 
   cbi 3, 5
   cbi 1, 1
-  cbi 0, 0
   cbi 7, 2
+  cbi 0, 0
+  cbi 31, 0
+  cbi 0, 7
+  cbi 31, 7
 
   cbi bar-2, 2
 
 ; CHECK: cbi 3, 5                  ; encoding: [0x1d,0x98]
 ; CHECK: cbi 1, 1                  ; encoding: [0x09,0x98]
-; CHECK: cbi 0, 0                  ; encoding: [0x00,0x98]
 ; CHECK: cbi 7, 2                  ; encoding: [0x3a,0x98]
+; CHECK: cbi 0, 0                  ; encoding: [0x00,0x98]
+; CHECK: cbi 31, 0                 ; encoding: [0xf8,0x98]
+; CHECK: cbi 0, 7                  ; encoding: [0x07,0x98]
+; CHECK: cbi 31, 7                 ; encoding: [0xff,0x98]
 
 ; CHECK: cbi bar-2, 2              ; encoding: [0bAAAAA010,0x98]
 ; CHECK:                           ;   fixup A - offset: 0, value: bar-2, kind: fixup_port5
 
+; CHECK-INST: cbi 3, 5
+; CHECK-INST: cbi 1, 1
+; CHECK-INST: cbi 7, 2
+; CHECK-INST: cbi 0, 0
+; CHECK-INST: cbi 31, 0
+; CHECK-INST: cbi 0, 7
+; CHECK-INST: cbi 31, 7
+
+; CHECK-INST: cbi 0, 2
index e0b02d0..ec381f2 100644 (file)
@@ -1,4 +1,5 @@
 ; RUN: llvm-mc -triple avr -show-encoding < %s | FileCheck %s
+; RUN: llvm-mc -filetype=obj -triple avr < %s | llvm-objdump -d - | FileCheck -check-prefix=CHECK-INST %s
 
 
 foo:
@@ -7,6 +8,9 @@ foo:
   in r9, 6
   in r5, 32
   in r0, 0
+  in r31, 0
+  in r0, 63
+  in r31, 63
 
   in r20, foo+1
 
@@ -14,7 +18,19 @@ foo:
 ; CHECK: in r9, 6                   ; encoding: [0x96,0xb0]
 ; CHECK: in r5, 32                  ; encoding: [0x50,0xb4]
 ; CHECK: in r0, 0                   ; encoding: [0x00,0xb0]
+; CHECK: in r31, 0                  ; encoding: [0xf0,0xb1]
+; CHECK: in r0, 63                  ; encoding: [0x0f,0xb6]
+; CHECK: in r31, 63                 ; encoding: [0xff,0xb7]
 
 ; CHECK: in r20, foo+1              ; encoding: [0x40'A',0xb1'A']
 ; CHECK:                            ;   fixup A - offset: 0, value: foo+1, kind: fixup_port6
 
+; CHECK-INST: in r2, 4
+; CHECK-INST: in r9, 6
+; CHECK-INST: in r5, 32
+; CHECK-INST: in r0, 0
+; CHECK-INST: in r31, 0
+; CHECK-INST: in r0, 63
+; CHECK-INST: in r31, 63
+
+; CHECK-INST: in r20, 0
index 0e2de55..28a9d33 100644 (file)
@@ -1,4 +1,5 @@
 ; RUN: llvm-mc -triple avr -show-encoding < %s | FileCheck %s
+; RUN: llvm-mc -filetype=obj -triple avr < %s | llvm-objdump -d - | FileCheck -check-prefix=CHECK-INST %s
 
 
 foo:
@@ -7,6 +8,9 @@ foo:
   out 6,  r9
   out 32, r5
   out 0,  r0
+  out 0,  r31
+  out 63, r0
+  out 63, r31
 
   out bar-8, r29
 
@@ -14,7 +18,19 @@ foo:
 ; CHECK: out 6,  r9                  ; encoding: [0x96,0xb8]
 ; CHECK: out 32, r5                  ; encoding: [0x50,0xbc]
 ; CHECK: out 0,  r0                  ; encoding: [0x00,0xb8]
+; CHECK: out 0,  r31                 ; encoding: [0xf0,0xb9]
+; CHECK: out 63, r0                  ; encoding: [0x0f,0xbe]
+; CHECK: out 63, r31                 ; encoding: [0xff,0xbf]
 
 ; CHECK: out bar-8, r29              ; encoding: [0xd0'A',0xb9'A']
 ; CHECK:                             ;   fixup A - offset: 0, value: bar-8, kind: fixup_port6
 
+; CHECK-INST: out 4,  r2
+; CHECK-INST: out 6,  r9
+; CHECK-INST: out 32, r5
+; CHECK-INST: out 0,  r0
+; CHECK-INST: out 0,  r31
+; CHECK-INST: out 63, r0
+; CHECK-INST: out 63, r31
+
+; CHECK-INST: out 0, r29
index f5381a7..bed8368 100644 (file)
@@ -1,20 +1,36 @@
 ; RUN: llvm-mc -triple avr -show-encoding < %s | FileCheck %s
+; RUN: llvm-mc -filetype=obj -triple avr < %s | llvm-objdump -d - | FileCheck -check-prefix=CHECK-INST %s
 
 
 foo:
 
   sbi 3, 5
   sbi 1, 1
-  sbi 0, 0
   sbi 7, 2
+  sbi 0, 0
+  sbi 0, 7
+  sbi 31, 0
+  sbi 31, 7
 
   sbi main, 0
 
 ; CHECK: sbi 3, 5                  ; encoding: [0x1d,0x9a]
 ; CHECK: sbi 1, 1                  ; encoding: [0x09,0x9a]
-; CHECK: sbi 0, 0                  ; encoding: [0x00,0x9a]
 ; CHECK: sbi 7, 2                  ; encoding: [0x3a,0x9a]
+; CHECK: sbi 0, 0                  ; encoding: [0x00,0x9a]
+; CHECK: sbi 0, 7                  ; encoding: [0x07,0x9a]
+; CHECK: sbi 31, 0                 ; encoding: [0xf8,0x9a]
+; CHECK: sbi 31, 7                 ; encoding: [0xff,0x9a]
 
 ; CHECK: sbi main, 0               ; encoding: [0bAAAAA000,0x9a]
 ; CHECK:                           ;   fixup A - offset: 0, value: main, kind: fixup_port5
 
+; CHECK-INST: sbi 3, 5
+; CHECK-INST: sbi 1, 1
+; CHECK-INST: sbi 7, 2
+; CHECK-INST: sbi 0, 0
+; CHECK-INST: sbi 0, 7
+; CHECK-INST: sbi 31, 0
+; CHECK-INST: sbi 31, 7
+
+; CHECK-INST: sbi 0, 0
index 81acf62..c52facd 100644 (file)
@@ -1,4 +1,5 @@
 ; RUN: llvm-mc -triple avr -show-encoding < %s | FileCheck %s
+; RUN: llvm-mc -filetype=obj -triple avr < %s | llvm-objdump -d - | FileCheck -check-prefix=CHECK-INST %s
 
 
 foo:
@@ -7,6 +8,9 @@ foo:
   sbic 6,  2
   sbic 16, 5
   sbic 0,  0
+  sbic 31, 0
+  sbic 0,  7
+  sbic 31, 7
 
   sbic foo+1, 1
 
@@ -14,6 +18,19 @@ foo:
 ; CHECK: sbic 6,  2                  ; encoding: [0x32,0x99]
 ; CHECK: sbic 16, 5                  ; encoding: [0x85,0x99]
 ; CHECK: sbic 0,  0                  ; encoding: [0x00,0x99]
+; CHECK: sbic 31, 0                  ; encoding: [0xf8,0x99]
+; CHECK: sbic 0,  7                  ; encoding: [0x07,0x99]
+; CHECK: sbic 31, 7                  ; encoding: [0xff,0x99]
 
 ; CHECK: sbic foo+1, 1               ; encoding: [0bAAAAA001,0x99]
 ; CHECK:                             ;   fixup A - offset: 0, value: foo+1, kind: fixup_port5
+
+; CHECK-INST: sbic 4,  3
+; CHECK-INST: sbic 6,  2
+; CHECK-INST: sbic 16, 5
+; CHECK-INST: sbic 0,  0
+; CHECK-INST: sbic 31, 0
+; CHECK-INST: sbic 0,  7
+; CHECK-INST: sbic 31, 7
+
+; CHECK-INST: sbic 0, 1
index c1b896c..4ea8ebf 100644 (file)
@@ -1,4 +1,5 @@
 ; RUN: llvm-mc -triple avr -show-encoding < %s | FileCheck %s
+; RUN: llvm-mc -filetype=obj -triple avr < %s | llvm-objdump -d - | FileCheck -check-prefix=CHECK-INST %s
 
 
 foo:
@@ -6,6 +7,9 @@ foo:
   sbis 6,  2
   sbis 16, 5
   sbis 0,  0
+  sbis 31, 0
+  sbis 0,  7
+  sbis 31, 7
 
   sbis FOO+4, 7
 
@@ -13,6 +17,19 @@ foo:
 ; CHECK: sbis 6,  2                  ; encoding: [0x32,0x9b]
 ; CHECK: sbis 16, 5                  ; encoding: [0x85,0x9b]
 ; CHECK: sbis 0,  0                  ; encoding: [0x00,0x9b]
+; CHECK: sbis 31, 0                  ; encoding: [0xf8,0x9b]
+; CHECK: sbis 0,  7                  ; encoding: [0x07,0x9b]
+; CHECK: sbis 31, 7                  ; encoding: [0xff,0x9b]
 
 ; CHECK: sbis FOO+4, 7               ; encoding: [0bAAAAA111,0x9b]
 ; CHECK:                             ;   fixup A - offset: 0, value: FOO+4, kind: fixup_port5
+
+; CHECK-INST: sbis 4,  3
+; CHECK-INST: sbis 6,  2
+; CHECK-INST: sbis 16, 5
+; CHECK-INST: sbis 0,  0
+; CHECK-INST: sbis 31, 0
+; CHECK-INST: sbis 0,  7
+; CHECK-INST: sbis 31, 7
+
+; CHECK-INST: sbis 0, 7