1 //===- AVRDisassembler.cpp - Disassembler for AVR ---------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file is part of the AVR Disassembler.
11 //===----------------------------------------------------------------------===//
14 #include "AVRRegisterInfo.h"
15 #include "AVRSubtarget.h"
16 #include "MCTargetDesc/AVRMCTargetDesc.h"
17 #include "TargetInfo/AVRTargetInfo.h"
19 #include "llvm/MC/MCAsmInfo.h"
20 #include "llvm/MC/MCContext.h"
21 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
22 #include "llvm/MC/MCFixedLenDisassembler.h"
23 #include "llvm/MC/MCInst.h"
24 #include "llvm/Support/TargetRegistry.h"
28 #define DEBUG_TYPE "avr-disassembler"
30 typedef MCDisassembler::DecodeStatus DecodeStatus
;
34 /// A disassembler class for AVR.
35 class AVRDisassembler
: public MCDisassembler
{
37 AVRDisassembler(const MCSubtargetInfo
&STI
, MCContext
&Ctx
)
38 : MCDisassembler(STI
, Ctx
) {}
39 virtual ~AVRDisassembler() {}
41 DecodeStatus
getInstruction(MCInst
&Instr
, uint64_t &Size
,
42 ArrayRef
<uint8_t> Bytes
, uint64_t Address
,
44 raw_ostream
&CStream
) const override
;
48 static MCDisassembler
*createAVRDisassembler(const Target
&T
,
49 const MCSubtargetInfo
&STI
,
51 return new AVRDisassembler(STI
, Ctx
);
55 extern "C" void LLVMInitializeAVRDisassembler() {
56 // Register the disassembler.
57 TargetRegistry::RegisterMCDisassembler(getTheAVRTarget(),
58 createAVRDisassembler
);
61 static DecodeStatus
DecodeGPR8RegisterClass(MCInst
&Inst
, unsigned RegNo
,
62 uint64_t Address
, const void *Decoder
) {
63 return MCDisassembler::Success
;
66 static DecodeStatus
DecodeLD8RegisterClass(MCInst
&Inst
, unsigned RegNo
,
67 uint64_t Address
, const void *Decoder
) {
68 return MCDisassembler::Success
;
71 static DecodeStatus
DecodePTRREGSRegisterClass(MCInst
&Inst
, unsigned RegNo
,
72 uint64_t Address
, const void *Decoder
) {
73 return MCDisassembler::Success
;
76 #include "AVRGenDisassemblerTables.inc"
78 static DecodeStatus
readInstruction16(ArrayRef
<uint8_t> Bytes
, uint64_t Address
,
79 uint64_t &Size
, uint32_t &Insn
) {
80 if (Bytes
.size() < 2) {
82 return MCDisassembler::Fail
;
86 Insn
= (Bytes
[0] << 0) | (Bytes
[1] << 8);
88 return MCDisassembler::Success
;
91 static DecodeStatus
readInstruction32(ArrayRef
<uint8_t> Bytes
, uint64_t Address
,
92 uint64_t &Size
, uint32_t &Insn
) {
94 if (Bytes
.size() < 4) {
96 return MCDisassembler::Fail
;
100 Insn
= (Bytes
[0] << 0) | (Bytes
[1] << 8) | (Bytes
[2] << 16) | (Bytes
[3] << 24);
102 return MCDisassembler::Success
;
105 static const uint8_t *getDecoderTable(uint64_t Size
) {
108 case 2: return DecoderTable16
;
109 case 4: return DecoderTable32
;
110 default: llvm_unreachable("instructions must be 16 or 32-bits");
114 DecodeStatus
AVRDisassembler::getInstruction(MCInst
&Instr
, uint64_t &Size
,
115 ArrayRef
<uint8_t> Bytes
,
117 raw_ostream
&VStream
,
118 raw_ostream
&CStream
) const {
123 // Try decode a 16-bit instruction.
125 Result
= readInstruction16(Bytes
, Address
, Size
, Insn
);
127 if (Result
== MCDisassembler::Fail
) return MCDisassembler::Fail
;
129 // Try to auto-decode a 16-bit instruction.
130 Result
= decodeInstruction(getDecoderTable(Size
), Instr
,
131 Insn
, Address
, this, STI
);
133 if (Result
!= MCDisassembler::Fail
)
137 // Try decode a 32-bit instruction.
139 Result
= readInstruction32(Bytes
, Address
, Size
, Insn
);
141 if (Result
== MCDisassembler::Fail
) return MCDisassembler::Fail
;
143 Result
= decodeInstruction(getDecoderTable(Size
), Instr
, Insn
,
146 if (Result
!= MCDisassembler::Fail
) {
150 return MCDisassembler::Fail
;
154 typedef DecodeStatus (*DecodeFunc
)(MCInst
&MI
, unsigned insn
, uint64_t Address
,
155 const void *Decoder
);