diff --git a/llvm/lib/Target/AVR/AVRInstrInfo.td b/llvm/lib/Target/AVR/AVRInstrInfo.td --- a/llvm/lib/Target/AVR/AVRInstrInfo.td +++ b/llvm/lib/Target/AVR/AVRInstrInfo.td @@ -193,6 +193,7 @@ def call_target : Operand { 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 --- a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp +++ b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp @@ -104,6 +104,9 @@ 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 @@ 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 Bytes, uint64_t Address, uint64_t &Size, uint32_t &Insn) { if (Bytes.size() < 2) { @@ -161,7 +172,7 @@ } 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 --- 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 @@ ; 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 --- 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 @@ 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 @@ ; 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 --- 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 @@ ; 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 --- 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 @@ ; 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