1 //===- AVRDisassembler.cpp - Disassembler for AVR ---------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file is part of the AVR Disassembler. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "AVR.h" 15 #include "AVRRegisterInfo.h" 16 #include "AVRSubtarget.h" 17 #include "MCTargetDesc/AVRMCTargetDesc.h" 18 19 #include "llvm/MC/MCDisassembler/MCDisassembler.h" 20 #include "llvm/MC/MCFixedLenDisassembler.h" 21 #include "llvm/MC/MCInst.h" 22 #include "llvm/MC/MCContext.h" 23 #include "llvm/MC/MCAsmInfo.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 namespace llvm { 49 extern Target TheAVRTarget; 50 } 51 52 static MCDisassembler *createAVRDisassembler(const Target &T, 53 const MCSubtargetInfo &STI, 54 MCContext &Ctx) { 55 return new AVRDisassembler(STI, Ctx); 56 } 57 58 59 extern "C" void LLVMInitializeAVRDisassembler() { 60 // Register the disassembler. 61 TargetRegistry::RegisterMCDisassembler(TheAVRTarget, 62 createAVRDisassembler); 63 } 64 65 static DecodeStatus DecodeGPR8RegisterClass(MCInst &Inst, unsigned RegNo, 66 uint64_t Address, const void *Decoder) { 67 return MCDisassembler::Success; 68 } 69 70 static DecodeStatus DecodeLD8RegisterClass(MCInst &Inst, unsigned RegNo, 71 uint64_t Address, const void *Decoder) { 72 return MCDisassembler::Success; 73 } 74 75 static DecodeStatus DecodePTRREGSRegisterClass(MCInst &Inst, unsigned RegNo, 76 uint64_t Address, const void *Decoder) { 77 return MCDisassembler::Success; 78 } 79 80 #include "AVRGenDisassemblerTables.inc" 81 82 static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address, 83 uint64_t &Size, uint32_t &Insn) { 84 if (Bytes.size() < 2) { 85 Size = 0; 86 return MCDisassembler::Fail; 87 } 88 89 Size = 2; 90 Insn = (Bytes[0] << 0) | (Bytes[1] << 8); 91 92 return MCDisassembler::Success; 93 } 94 95 static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address, 96 uint64_t &Size, uint32_t &Insn) { 97 98 if (Bytes.size() < 4) { 99 Size = 0; 100 return MCDisassembler::Fail; 101 } 102 103 Size = 4; 104 Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) | (Bytes[3] << 24); 105 106 return MCDisassembler::Success; 107 } 108 109 static const uint8_t *getDecoderTable(uint64_t Size) { 110 111 switch (Size) { 112 case 2: return DecoderTable16; 113 case 4: return DecoderTable32; 114 default: llvm_unreachable("instructions must be 16 or 32-bits"); 115 } 116 } 117 118 DecodeStatus AVRDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, 119 ArrayRef<uint8_t> Bytes, 120 uint64_t Address, 121 raw_ostream &VStream, 122 raw_ostream &CStream) const { 123 uint32_t Insn; 124 125 DecodeStatus Result; 126 127 // Try decode a 16-bit instruction. 128 { 129 Result = readInstruction16(Bytes, Address, Size, Insn); 130 131 if (Result == MCDisassembler::Fail) return MCDisassembler::Fail; 132 133 // Try to auto-decode a 16-bit instruction. 134 Result = decodeInstruction(getDecoderTable(Size), Instr, 135 Insn, Address, this, STI); 136 137 if (Result != MCDisassembler::Fail) 138 return Result; 139 } 140 141 // Try decode a 32-bit instruction. 142 { 143 Result = readInstruction32(Bytes, Address, Size, Insn); 144 145 if (Result == MCDisassembler::Fail) return MCDisassembler::Fail; 146 147 Result = decodeInstruction(getDecoderTable(Size), Instr, Insn, 148 Address, this, STI); 149 150 if (Result != MCDisassembler::Fail) { 151 return Result; 152 } 153 154 return MCDisassembler::Fail; 155 } 156 } 157 158 typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address, 159 const void *Decoder); 160 161