[llvm] 15bf42d - [AVR] Implement disassembly of 32-bit instructions

Ayke van Laethem via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 18 02:27:18 PDT 2020


Author: Ayke van Laethem
Date: 2020-06-18T11:26:58+02:00
New Revision: 15bf42d503b9c388135308d37e1d153a05b33699

URL: https://github.com/llvm/llvm-project/commit/15bf42d503b9c388135308d37e1d153a05b33699
DIFF: https://github.com/llvm/llvm-project/commit/15bf42d503b9c388135308d37e1d153a05b33699.diff

LOG: [AVR] Implement disassembly of 32-bit instructions

This needed two fixes:

  * 32-bit instructions were read in the wrong order. The machine code
    swaps the two 16-bit instruction words, which wasn't undone when
    decoding instructions.
  * Jump and call instructions don't encode the lowest address bit,
    which is always zero. Therefore, the address needed to be shifted by
    one to fix that.

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

Added: 
    

Modified: 
    llvm/lib/Target/AVR/AVRInstrInfo.td
    llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp
    llvm/test/MC/AVR/inst-call.s
    llvm/test/MC/AVR/inst-jmp.s
    llvm/test/MC/AVR/inst-lds.s
    llvm/test/MC/AVR/inst-sts.s

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AVR/AVRInstrInfo.td b/llvm/lib/Target/AVR/AVRInstrInfo.td
index e64f465fac7d..b66eb792a2b7 100644
--- a/llvm/lib/Target/AVR/AVRInstrInfo.td
+++ b/llvm/lib/Target/AVR/AVRInstrInfo.td
@@ -193,6 +193,7 @@ def brtarget_13 : Operand<OtherVT>
 def call_target : Operand<iPTR>
 {
     let EncoderMethod = "encodeCallTarget";
+    let DecoderMethod = "decodeCallTarget";
 }
 
 // A 16-bit address (which can lead to an R_AVR_16 relocation).

diff  --git a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp
index a5c08c41e403..093e6a45e225 100644
--- a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp
+++ b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp
@@ -104,6 +104,9 @@ static DecodeStatus decodeFIORdA(MCInst &Inst, unsigned Insn,
 static DecodeStatus decodeFIOBIT(MCInst &Inst, unsigned Insn,
                                  uint64_t Address, const void *Decoder);
 
+static DecodeStatus decodeCallTarget(MCInst &Inst, unsigned Insn,
+                                     uint64_t Address, const void *Decoder);
+
 #include "AVRGenDisassemblerTables.inc"
 
 static DecodeStatus decodeFIOARr(MCInst &Inst, unsigned Insn,
@@ -139,6 +142,14 @@ static DecodeStatus decodeFIOBIT(MCInst &Inst, unsigned Insn,
   return MCDisassembler::Success;
 }
 
+static DecodeStatus decodeCallTarget(MCInst &Inst, unsigned Field,
+                                     uint64_t Address, const void *Decoder) {
+  // Call targets need to be shifted left by one so this needs a custom
+  // decoder.
+  Inst.addOperand(MCOperand::createImm(Field << 1));
+  return MCDisassembler::Success;
+}
+
 static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
                                       uint64_t &Size, uint32_t &Insn) {
   if (Bytes.size() < 2) {
@@ -161,7 +172,7 @@ static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
   }
 
   Size = 4;
-  Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) | (Bytes[3] << 24);
+  Insn = (Bytes[0] << 16) | (Bytes[1] << 24) | (Bytes[2] << 0) | (Bytes[3] << 8);
 
   return MCDisassembler::Success;
 }

diff  --git a/llvm/test/MC/AVR/inst-call.s b/llvm/test/MC/AVR/inst-call.s
index 312c8fffe970..9f3d0eb2e781 100644
--- a/llvm/test/MC/AVR/inst-call.s
+++ b/llvm/test/MC/AVR/inst-call.s
@@ -1,4 +1,5 @@
 ; RUN: llvm-mc -triple avr -mattr=jmpcall -show-encoding < %s | FileCheck %s
+; RUN: llvm-mc -filetype=obj -triple avr -mattr=jmpcall < %s | llvm-objdump -dr --mattr=jmpcall - | FileCheck -check-prefix=CHECK-INST %s
 
 
 foo:
@@ -12,3 +13,9 @@ foo:
 ; CHECK: call -124                  ; encoding: [0xff,0x95,0xc2,0xff]
 ; CHECK: call -12                   ; encoding: [0xff,0x95,0xfa,0xff]
 ; CHECK: call  0                    ; encoding: [0x0e,0x94,0x00,0x00]
+
+
+; CHECK-INST: call 4096
+; CHECK-INST: call 8388484
+; CHECK-INST: call 8388596
+; CHECK-INST: call 0

diff  --git a/llvm/test/MC/AVR/inst-jmp.s b/llvm/test/MC/AVR/inst-jmp.s
index 664f8c81cef6..369181caae0a 100644
--- a/llvm/test/MC/AVR/inst-jmp.s
+++ b/llvm/test/MC/AVR/inst-jmp.s
@@ -1,4 +1,5 @@
 ; RUN: llvm-mc -triple avr -mattr=jmpcall -show-encoding < %s | FileCheck %s
+; RUN: llvm-mc -filetype=obj -triple avr -mattr=jmpcall < %s | llvm-objdump -dr --mattr=jmpcall - | FileCheck -check-prefix=CHECK-INST %s
 
 
 foo:
@@ -10,6 +11,10 @@ foo:
 
   jmp foo+1
 
+  jmp   0x03fffe ; Inst{16-0}  or k{16-0}
+  jmp   0x7c0000 ; Inst{24-20} or k{21-17}
+  jmp   0x7ffffe ; all bits set
+
 ; CHECK: jmp  200                  ; encoding: [0x0c,0x94,0x64,0x00]
 ; CHECK: jmp -12                   ; encoding: [0xfd,0x95,0xfa,0xff]
 ; CHECK: jmp  80                   ; encoding: [0x0c,0x94,0x28,0x00]
@@ -17,3 +22,18 @@ foo:
 
 ; CHECK: jmp foo+1                 ; encoding: [0x0c'A',0x94'A',0b00AAAAAA,0x00]
 ; CHECK:                           ;   fixup A - offset: 0, value: foo+1, kind: fixup_call
+
+; CHECK: jmp 262142                ; encoding: [0x0d,0x94,0xff,0xff]
+; CHECK: jmp 8126464               ; encoding: [0xfc,0x95,0x00,0x00]
+; CHECK: jmp 8388606               ; encoding: [0xfd,0x95,0xff,0xff]
+
+
+; CHECK-INST: jmp 200
+; CHECK-INST: jmp 8388596
+; CHECK-INST: jmp 80
+; CHECK-INST: jmp 0
+; CHECK-INST: jmp 0
+; CHECK-INST:     R_AVR_CALL .text+0x1
+; CHECK-INST: jmp 262142
+; CHECK-INST: jmp 8126464
+; CHECK-INST: jmp 8388606

diff  --git a/llvm/test/MC/AVR/inst-lds.s b/llvm/test/MC/AVR/inst-lds.s
index e8151a32b860..2936b246004b 100644
--- a/llvm/test/MC/AVR/inst-lds.s
+++ b/llvm/test/MC/AVR/inst-lds.s
@@ -1,4 +1,5 @@
 ; RUN: llvm-mc -triple avr -mattr=sram -show-encoding < %s | FileCheck %s
+; RUN: llvm-mc -filetype=obj -triple avr -mattr=sram < %s | llvm-objdump -dr --mattr=sram - | FileCheck -check-prefix=CHECK-INST %s
 
 
 foo:
@@ -14,3 +15,11 @@ foo:
 ; CHECK: lds r27, 92                  ; encoding: [0xb0,0x91,0x5c,0x00]
 ; CHECK: lds r4, SYMBOL+12            ; encoding: [0x40,0x90,A,A]
 ; CHECK:                              ;   fixup A - offset: 2, value: SYMBOL+12, kind: fixup_16
+
+
+; CHECK-INST: lds r16, 241
+; CHECK-INST: lds r29, 190
+; CHECK-INST: lds r22, 172
+; CHECK-INST: lds r27, 92
+; CHECK-INST: lds r4,  0
+; CHECK-INST:     R_AVR_16 SYMBOL+0xc

diff  --git a/llvm/test/MC/AVR/inst-sts.s b/llvm/test/MC/AVR/inst-sts.s
index 0f5af7da6f3a..d2cc1fc4c98a 100644
--- a/llvm/test/MC/AVR/inst-sts.s
+++ b/llvm/test/MC/AVR/inst-sts.s
@@ -1,4 +1,5 @@
 ; RUN: llvm-mc -triple avr -mattr=sram -show-encoding < %s | FileCheck %s
+; RUN: llvm-mc -filetype=obj -triple avr -mattr=sram < %s | llvm-objdump -dr --mattr=sram - | FileCheck -check-prefix=CHECK-INST %s
 
 
 foo:
@@ -12,3 +13,8 @@ foo:
 ; CHECK:  sts SYMBOL+1, r25           ; encoding: [0x90,0x93,A,A]
 ; CHECK:                              ;   fixup A - offset: 2, value: SYMBOL+1, kind: fixup_16
 
+
+; CHECK-INST: sts 3, r5
+; CHECK-INST: sts 255, r7
+; CHECK-INST: sts 0, r25
+; CHECK-INST:     R_AVR_16 SYMBOL+0x1


        


More information about the llvm-commits mailing list