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 @@ -272,6 +272,8 @@ let Inst{8} = f; let Inst{7-4} = rd{3-0}; let Inst{3-0} = rr{3-0}; + + let DecoderMethod = "decodeFMUL2RdRr"; } // Special encoding for the FMUL family of instructions. @@ -295,6 +297,8 @@ let Inst{6-4} = rd; let Inst{3} = f{0}; let Inst{2-0} = rr; + + let DecoderMethod = "decodeFFMULRdRr"; } 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 @@ -110,6 +110,12 @@ static DecodeStatus decodeFRd(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); +static DecodeStatus decodeFFMULRdRr(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); + +static DecodeStatus decodeFMUL2RdRr(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); + #include "AVRGenDisassemblerTables.inc" static DecodeStatus decodeFIOARr(MCInst &Inst, unsigned Insn, @@ -161,6 +167,28 @@ return MCDisassembler::Success; } +static DecodeStatus decodeFFMULRdRr(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + unsigned d = fieldFromInstruction(Insn, 4, 3) + 16; + unsigned r = fieldFromInstruction(Insn, 0, 3) + 16; + if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == MCDisassembler::Fail) + return MCDisassembler::Fail; + if (DecodeGPR8RegisterClass(Inst, r, Address, Decoder) == MCDisassembler::Fail) + return MCDisassembler::Fail; + return MCDisassembler::Success; +} + +static DecodeStatus decodeFMUL2RdRr(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + unsigned rd = fieldFromInstruction(Insn, 4, 4) + 16; + unsigned rr = fieldFromInstruction(Insn, 0, 4) + 16; + if (DecodeGPR8RegisterClass(Inst, rd, Address, Decoder) == MCDisassembler::Fail) + return MCDisassembler::Fail; + if (DecodeGPR8RegisterClass(Inst, rr, Address, Decoder) == MCDisassembler::Fail) + return MCDisassembler::Fail; + return MCDisassembler::Success; +} + static DecodeStatus readInstruction16(ArrayRef Bytes, uint64_t Address, uint64_t &Size, uint32_t &Insn) { if (Bytes.size() < 2) { diff --git a/llvm/test/MC/AVR/inst-fmul.s b/llvm/test/MC/AVR/inst-fmul.s --- a/llvm/test/MC/AVR/inst-fmul.s +++ b/llvm/test/MC/AVR/inst-fmul.s @@ -1,4 +1,5 @@ ; RUN: llvm-mc -triple avr -mattr=mul -show-encoding < %s | FileCheck %s +; RUN: llvm-mc -filetype=obj -triple avr -mattr=mul < %s | llvm-objdump -d --mattr=mul - | FileCheck -check-prefix=CHECK-INST %s foo: @@ -7,8 +8,19 @@ fmul r19, r17 fmul r21, r23 fmul r23, r23 + fmul r16, r16 + fmul r16, r23 ; CHECK: fmul r22, r16 ; encoding: [0x68,0x03] ; CHECK: fmul r19, r17 ; encoding: [0x39,0x03] ; CHECK: fmul r21, r23 ; encoding: [0x5f,0x03] ; CHECK: fmul r23, r23 ; encoding: [0x7f,0x03] +; CHECK: fmul r16, r16 ; encoding: [0x08,0x03] +; CHECK: fmul r16, r23 ; encoding: [0x0f,0x03] + +; CHECK-INST: fmul r22, r16 +; CHECK-INST: fmul r19, r17 +; CHECK-INST: fmul r21, r23 +; CHECK-INST: fmul r23, r23 +; CHECK-INST: fmul r16, r16 +; CHECK-INST: fmul r16, r23 diff --git a/llvm/test/MC/AVR/inst-fmuls.s b/llvm/test/MC/AVR/inst-fmuls.s --- a/llvm/test/MC/AVR/inst-fmuls.s +++ b/llvm/test/MC/AVR/inst-fmuls.s @@ -1,4 +1,5 @@ ; RUN: llvm-mc -triple avr -mattr=mul -show-encoding < %s | FileCheck %s +; RUN: llvm-mc -filetype=obj -triple avr -mattr=mul < %s | llvm-objdump -d --mattr=mul - | FileCheck -check-prefix=CHECK-INST %s foo: @@ -12,3 +13,8 @@ ; CHECK: fmuls r19, r17 ; encoding: [0xb1,0x03] ; CHECK: fmuls r21, r23 ; encoding: [0xd7,0x03] ; CHECK: fmuls r23, r23 ; encoding: [0xf7,0x03] + +; CHECK-INST: fmuls r22, r16 +; CHECK-INST: fmuls r19, r17 +; CHECK-INST: fmuls r21, r23 +; CHECK-INST: fmuls r23, r23 diff --git a/llvm/test/MC/AVR/inst-fmulsu.s b/llvm/test/MC/AVR/inst-fmulsu.s --- a/llvm/test/MC/AVR/inst-fmulsu.s +++ b/llvm/test/MC/AVR/inst-fmulsu.s @@ -1,4 +1,5 @@ ; RUN: llvm-mc -triple avr -mattr=mul -show-encoding < %s | FileCheck %s +; RUN: llvm-mc -filetype=obj -triple avr -mattr=mul < %s | llvm-objdump -d --mattr=mul - | FileCheck -check-prefix=CHECK-INST %s foo: @@ -12,3 +13,8 @@ ; CHECK: fmulsu r19, r17 ; encoding: [0xb9,0x03] ; CHECK: fmulsu r21, r23 ; encoding: [0xdf,0x03] ; CHECK: fmulsu r23, r23 ; encoding: [0xff,0x03] + +; CHECK-INST: fmulsu r22, r16 +; CHECK-INST: fmulsu r19, r17 +; CHECK-INST: fmulsu r21, r23 +; CHECK-INST: fmulsu r23, r23 diff --git a/llvm/test/MC/AVR/inst-muls.s b/llvm/test/MC/AVR/inst-muls.s --- a/llvm/test/MC/AVR/inst-muls.s +++ b/llvm/test/MC/AVR/inst-muls.s @@ -1,4 +1,5 @@ ; RUN: llvm-mc -triple avr -mattr=mul -show-encoding < %s | FileCheck %s +; RUN: llvm-mc -filetype=obj -triple avr -mattr=mul < %s | llvm-objdump -d --mattr=mul - | FileCheck -check-prefix=CHECK-INST %s foo: @@ -7,8 +8,19 @@ muls r19, r17 muls r28, r31 muls r31, r31 + muls r16, r16 + muls r16, r31 ; CHECK: muls r22, r16 ; encoding: [0x60,0x02] ; CHECK: muls r19, r17 ; encoding: [0x31,0x02] ; CHECK: muls r28, r31 ; encoding: [0xcf,0x02] ; CHECK: muls r31, r31 ; encoding: [0xff,0x02] +; CHECK: muls r16, r16 ; encoding: [0x00,0x02] +; CHECK: muls r16, r31 ; encoding: [0x0f,0x02] + +; CHECK-INST: muls r22, r16 +; CHECK-INST: muls r19, r17 +; CHECK-INST: muls r28, r31 +; CHECK-INST: muls r31, r31 +; CHECK-INST: muls r16, r16 +; CHECK-INST: muls r16, r31 diff --git a/llvm/test/MC/AVR/inst-mulsu.s b/llvm/test/MC/AVR/inst-mulsu.s --- a/llvm/test/MC/AVR/inst-mulsu.s +++ b/llvm/test/MC/AVR/inst-mulsu.s @@ -1,4 +1,5 @@ ; RUN: llvm-mc -triple avr -mattr=mul -show-encoding < %s | FileCheck %s +; RUN: llvm-mc -filetype=obj -triple avr -mattr=mul < %s | llvm-objdump -d --mattr=mul - | FileCheck -check-prefix=CHECK-INST %s foo: @@ -12,3 +13,8 @@ ; CHECK: mulsu r19, r17 ; encoding: [0x31,0x03] ; CHECK: mulsu r21, r23 ; encoding: [0x57,0x03] ; CHECK: mulsu r23, r23 ; encoding: [0x77,0x03] + +; CHECK-INST: mulsu r22, r16 +; CHECK-INST: mulsu r19, r17 +; CHECK-INST: mulsu r21, r23 +; CHECK-INST: mulsu r23, r23