1 //===- AVRDisassembler.cpp - Disassembler for AVR ---------------*- C++ -*-===// 2 // 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 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file is part of the AVR Disassembler. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "AVR.h" 14 #include "AVRRegisterInfo.h" 15 #include "AVRSubtarget.h" 16 #include "MCTargetDesc/AVRMCTargetDesc.h" 17 #include "TargetInfo/AVRTargetInfo.h" 18 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" 25 26 using namespace llvm; 27 28 #define DEBUG_TYPE "avr-disassembler" 29 30 typedef MCDisassembler::DecodeStatus DecodeStatus; 31 32 namespace { 33 34 /// A disassembler class for AVR. 35 class AVRDisassembler : public MCDisassembler { 36 public: 37 AVRDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) 38 : MCDisassembler(STI, Ctx) {} 39 virtual ~AVRDisassembler() {} 40 41 DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, 42 ArrayRef<uint8_t> Bytes, uint64_t Address, 43 raw_ostream &VStream, 44 raw_ostream &CStream) const override; 45 }; 46 } 47 48 static MCDisassembler *createAVRDisassembler(const Target &T, 49 const MCSubtargetInfo &STI, 50 MCContext &Ctx) { 51 return new AVRDisassembler(STI, Ctx); 52 } 53 54 55 extern "C" void LLVMInitializeAVRDisassembler() { 56 // Register the disassembler. 57 TargetRegistry::RegisterMCDisassembler(getTheAVRTarget(), 58 createAVRDisassembler); 59 } 60 61 static DecodeStatus DecodeGPR8RegisterClass(MCInst &Inst, unsigned RegNo, 62 uint64_t Address, const void *Decoder) { 63 return MCDisassembler::Success; 64 } 65 66 static DecodeStatus DecodeLD8RegisterClass(MCInst &Inst, unsigned RegNo, 67 uint64_t Address, const void *Decoder) { 68 return MCDisassembler::Success; 69 } 70 71 static DecodeStatus DecodePTRREGSRegisterClass(MCInst &Inst, unsigned RegNo, 72 uint64_t Address, const void *Decoder) { 73 return MCDisassembler::Success; 74 } 75 76 #include "AVRGenDisassemblerTables.inc" 77 78 static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address, 79 uint64_t &Size, uint32_t &Insn) { 80 if (Bytes.size() < 2) { 81 Size = 0; 82 return MCDisassembler::Fail; 83 } 84 85 Size = 2; 86 Insn = (Bytes[0] << 0) | (Bytes[1] << 8); 87 88 return MCDisassembler::Success; 89 } 90 91 static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address, 92 uint64_t &Size, uint32_t &Insn) { 93 94 if (Bytes.size() < 4) { 95 Size = 0; 96 return MCDisassembler::Fail; 97 } 98 99 Size = 4; 100 Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) | (Bytes[3] << 24); 101 102 return MCDisassembler::Success; 103 } 104 105 static const uint8_t *getDecoderTable(uint64_t Size) { 106 107 switch (Size) { 108 case 2: return DecoderTable16; 109 case 4: return DecoderTable32; 110 default: llvm_unreachable("instructions must be 16 or 32-bits"); 111 } 112 } 113 114 DecodeStatus AVRDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, 115 ArrayRef<uint8_t> Bytes, 116 uint64_t Address, 117 raw_ostream &VStream, 118 raw_ostream &CStream) const { 119 uint32_t Insn; 120 121 DecodeStatus Result; 122 123 // Try decode a 16-bit instruction. 124 { 125 Result = readInstruction16(Bytes, Address, Size, Insn); 126 127 if (Result == MCDisassembler::Fail) return MCDisassembler::Fail; 128 129 // Try to auto-decode a 16-bit instruction. 130 Result = decodeInstruction(getDecoderTable(Size), Instr, 131 Insn, Address, this, STI); 132 133 if (Result != MCDisassembler::Fail) 134 return Result; 135 } 136 137 // Try decode a 32-bit instruction. 138 { 139 Result = readInstruction32(Bytes, Address, Size, Insn); 140 141 if (Result == MCDisassembler::Fail) return MCDisassembler::Fail; 142 143 Result = decodeInstruction(getDecoderTable(Size), Instr, Insn, 144 Address, this, STI); 145 146 if (Result != MCDisassembler::Fail) { 147 return Result; 148 } 149 150 return MCDisassembler::Fail; 151 } 152 } 153 154 typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address, 155 const void *Decoder); 156 157