diff --git a/llvm/lib/Target/AVR/AVRInstrFormats.td b/llvm/lib/Target/AVR/AVRInstrFormats.td --- a/llvm/lib/Target/AVR/AVRInstrFormats.td +++ b/llvm/lib/Target/AVR/AVRInstrFormats.td @@ -256,6 +256,8 @@ 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 @@ 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 --- a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp +++ b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp @@ -116,6 +116,12 @@ 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 @@ 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 --- 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 @@ 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 @@ ; 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 @@ ; 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 --- 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 @@ 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 --- 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 @@ ; 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