From eac4a601548566fb311b0b596dbaee893507cfb8 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Thu, 18 Jun 2020 15:26:23 +0200 Subject: [PATCH] [AVR] Disassemble double register instructions Add disassembly support for the movw, adiw, and sbiw instructions. I had previously committed test cases for the adiw and sbiw instructions, but had accidentally made them not runnable so they were skipped all this time. Oops. This patch fixes that by adding support for disassembling those instructions. Differential Revision: https://reviews.llvm.org/D82093 --- llvm/lib/Target/AVR/AVRInstrFormats.td | 4 +++ .../Target/AVR/Disassembler/AVRDisassembler.cpp | 31 ++++++++++++++++++++++ llvm/test/MC/AVR/inst-adiw.s | 18 ++++++++++--- llvm/test/MC/AVR/inst-movw.s | 18 +++++++++++++ llvm/test/MC/AVR/inst-sbiw.s | 11 ++++---- 5 files changed, 73 insertions(+), 9 deletions(-) diff --git a/llvm/lib/Target/AVR/AVRInstrFormats.td b/llvm/lib/Target/AVR/AVRInstrFormats.td index 0fcc21a..6eb4907 100644 --- a/llvm/lib/Target/AVR/AVRInstrFormats.td +++ b/llvm/lib/Target/AVR/AVRInstrFormats.td @@ -256,6 +256,8 @@ class FMOVWRdRr pattern> let Inst{15-8} = 0b00000001; let Inst{7-4} = d{4-1}; let Inst{3-0} = r{4-1}; + + let DecoderMethod = "decodeFMOVWRdRr"; } //===----------------------------------------------------------------------===// @@ -322,6 +324,8 @@ class FWRdK pattern> let Inst{7-6} = k{5-4}; let Inst{5-4} = dst{2-1}; let Inst{3-0} = k{3-0}; + + let DecoderMethod = "decodeFWRdK"; } //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp index 73f3e09..8e7251a 100644 --- a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp +++ b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp @@ -116,6 +116,12 @@ static DecodeStatus decodeFLPMX(MCInst &Inst, unsigned Insn, static DecodeStatus decodeFFMULRdRr(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); +static DecodeStatus decodeFMOVWRdRr(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); + +static DecodeStatus decodeFWRdK(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); + static DecodeStatus decodeFMUL2RdRr(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); @@ -189,6 +195,31 @@ static DecodeStatus decodeFFMULRdRr(MCInst &Inst, unsigned Insn, return MCDisassembler::Success; } +static DecodeStatus decodeFMOVWRdRr(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + unsigned r = fieldFromInstruction(Insn, 4, 4) * 2; + unsigned d = fieldFromInstruction(Insn, 0, 4) * 2; + if (DecodeGPR8RegisterClass(Inst, r, Address, Decoder) == MCDisassembler::Fail) + return MCDisassembler::Fail; + if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == MCDisassembler::Fail) + return MCDisassembler::Fail; + return MCDisassembler::Success; +} + +static DecodeStatus decodeFWRdK(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + unsigned d = fieldFromInstruction(Insn, 4, 2) * 2 + 24; // starts at r24:r25 + unsigned k = 0; + k |= fieldFromInstruction(Insn, 0, 4); + k |= fieldFromInstruction(Insn, 6, 2) << 4; + if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == MCDisassembler::Fail) + return MCDisassembler::Fail; + if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == MCDisassembler::Fail) + return MCDisassembler::Fail; + Inst.addOperand(MCOperand::createImm(k)); + return MCDisassembler::Success; +} + static DecodeStatus decodeFMUL2RdRr(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder) { unsigned rd = fieldFromInstruction(Insn, 4, 4) + 16; diff --git a/llvm/test/MC/AVR/inst-adiw.s b/llvm/test/MC/AVR/inst-adiw.s index 4de394d..067bde9 100644 --- a/llvm/test/MC/AVR/inst-adiw.s +++ b/llvm/test/MC/AVR/inst-adiw.s @@ -1,5 +1,5 @@ ; RUN: llvm-mc -triple avr -mattr=addsubiw -show-encoding < %s | FileCheck %s -; RUNx: llvm-mc -filetype=obj -triple avr -mattr=addsubiw < %s | llvm-objdump -d --mattr=addsubiw - | FileCheck --check-prefix=CHECK-INST %s +; RUN: llvm-mc -filetype=obj -triple avr -mattr=addsubiw < %s | llvm-objdump -dr --mattr=addsubiw - | FileCheck --check-prefix=CHECK-INST %s foo: @@ -10,8 +10,11 @@ foo: adiw r28, 17 adiw r28, 0 - adiw r30, 63 adiw r30, 3 + adiw r30, 63 + adiw r24, 63 + adiw r24, 0 + adiw r30, 0 adiw r24, SYMBOL @@ -21,8 +24,11 @@ foo: ; CHECK: adiw r28, 17 ; encoding: [0x61,0x96] ; CHECK: adiw r28, 0 ; encoding: [0x20,0x96] -; CHECK: adiw r30, 63 ; encoding: [0xff,0x96] ; CHECK: adiw r30, 3 ; encoding: [0x33,0x96] +; CHECK: adiw r30, 63 ; encoding: [0xff,0x96] +; CHECK: adiw r24, 63 ; encoding: [0xcf,0x96] +; CHECK: adiw r24, 0 ; encoding: [0x00,0x96] +; CHECK: adiw r30, 0 ; encoding: [0x30,0x96] ; CHECK: adiw r24, SYMBOL ; encoding: [0b00AAAAAA,0x96] ; fixup A - offset: 0, value: SYMBOL, kind: fixup_6_adiw @@ -33,7 +39,11 @@ foo: ; CHECK-INST: adiw r28, 17 ; CHECK-INST: adiw r28, 0 -; CHECK-INST: adiw r30, 63 ; CHECK-INST: adiw r30, 3 +; CHECK-INST: adiw r30, 63 +; CHECK-INST: adiw r24, 63 +; CHECK-INST: adiw r24, 0 +; CHECK-INST: adiw r30, 0 ; CHECK-INST: adiw r24, 0 +; CHECK-INST: R_AVR_6_ADIW SYMBOL diff --git a/llvm/test/MC/AVR/inst-movw.s b/llvm/test/MC/AVR/inst-movw.s index 6d63bca..b93b530 100644 --- a/llvm/test/MC/AVR/inst-movw.s +++ b/llvm/test/MC/AVR/inst-movw.s @@ -1,4 +1,5 @@ ; RUN: llvm-mc -triple avr -mattr=movw -show-encoding < %s | FileCheck %s +; RUN: llvm-mc -filetype=obj -triple avr -mattr=movw < %s | llvm-objdump -d --mattr=movw - | FileCheck -check-prefix=CHECK-INST %s foo: @@ -7,8 +8,25 @@ foo: movw r12, r16 movw r20, r22 movw r8, r12 + movw r0, r0 + movw r0, r30 + movw r30, r30 + movw r30, r0 ; CHECK: movw r10, r8 ; encoding: [0x54,0x01] ; CHECK: movw r12, r16 ; encoding: [0x68,0x01] ; CHECK: movw r20, r22 ; encoding: [0xab,0x01] ; CHECK: movw r8, r12 ; encoding: [0x46,0x01] +; CHECK: movw r0, r0 ; encoding: [0x00,0x01] +; CHECK: movw r0, r30 ; encoding: [0x0f,0x01] +; CHECK: movw r30, r30 ; encoding: [0xff,0x01] +; CHECK: movw r30, r0 ; encoding: [0xf0,0x01] + +; CHECK-INST: movw r10, r8 +; CHECK-INST: movw r12, r16 +; CHECK-INST: movw r20, r22 +; CHECK-INST: movw r8, r12 +; CHECK-INST: movw r0, r0 +; CHECK-INST: movw r0, r30 +; CHECK-INST: movw r30, r30 +; CHECK-INST: movw r30, r0 diff --git a/llvm/test/MC/AVR/inst-sbiw.s b/llvm/test/MC/AVR/inst-sbiw.s index cb02428..109d1fc 100644 --- a/llvm/test/MC/AVR/inst-sbiw.s +++ b/llvm/test/MC/AVR/inst-sbiw.s @@ -1,5 +1,5 @@ ; RUN: llvm-mc -triple avr -mattr=addsubiw -show-encoding < %s | FileCheck %s -; RUNx: llvm-mc -filetype=obj -triple avr -mattr=addsubiw < %s | llvm-objdump -d --mattr=addsubiw - | FileCheck --check-prefix=CHECK-INST %s +; RUN: llvm-mc -filetype=obj -triple avr -mattr=addsubiw < %s | llvm-objdump -dr --mattr=addsubiw - | FileCheck --check-prefix=CHECK-INST %s foo: @@ -34,15 +34,16 @@ foo: ; fixup A - offset: 0, value: SYMBOL-1, kind: fixup_6_adiw ; CHECK-INST: sbiw r26, 54 -; CHECK-INST: sbiw X, 63 +; CHECK-INST: sbiw r26, 63 -; CHECK-INST: sbiw 28, 52 +; CHECK-INST: sbiw r28, 52 ; CHECK-INST: sbiw r28, 0 ; CHECK-INST: sbiw r30, 63 -; CHECK-INST: sbiw Z, 47 +; CHECK-INST: sbiw r30, 47 ; CHECK-INST: sbiw r24, 1 ; CHECK-INST: sbiw r24, 2 -; CHECK-INST: sbiw r24, SYMBOL-1 +; CHECK-INST: sbiw r24, 0 +; CHECK-INST: R_AVR_6_ADIW SYMBOL-0x1 -- 2.7.4