1 //===- SparcDisassembler.cpp - Disassembler for Sparc -----------*- 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 Sparc Disassembler. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #define DEBUG_TYPE "sparc-disassembler" 15 16 #include "Sparc.h" 17 #include "SparcRegisterInfo.h" 18 #include "SparcSubtarget.h" 19 #include "llvm/MC/MCDisassembler.h" 20 #include "llvm/MC/MCFixedLenDisassembler.h" 21 #include "llvm/Support/MemoryObject.h" 22 #include "llvm/Support/TargetRegistry.h" 23 24 using namespace llvm; 25 26 typedef MCDisassembler::DecodeStatus DecodeStatus; 27 28 namespace { 29 30 /// SparcDisassembler - a disassembler class for Sparc. 31 class SparcDisassembler : public MCDisassembler { 32 public: 33 /// Constructor - Initializes the disassembler. 34 /// 35 SparcDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info) : 36 MCDisassembler(STI), RegInfo(Info) 37 {} 38 virtual ~SparcDisassembler() {} 39 40 const MCRegisterInfo *getRegInfo() const { return RegInfo.get(); } 41 42 /// getInstruction - See MCDisassembler. 43 virtual DecodeStatus getInstruction(MCInst &instr, 44 uint64_t &size, 45 const MemoryObject ®ion, 46 uint64_t address, 47 raw_ostream &vStream, 48 raw_ostream &cStream) const; 49 private: 50 OwningPtr<const MCRegisterInfo> RegInfo; 51 }; 52 53 } 54 55 namespace llvm { 56 extern Target TheSparcTarget, TheSparcV9Target; 57 } 58 59 static MCDisassembler *createSparcDisassembler( 60 const Target &T, 61 const MCSubtargetInfo &STI) { 62 return new SparcDisassembler(STI, T.createMCRegInfo("")); 63 } 64 65 66 extern "C" void LLVMInitializeSparcDisassembler() { 67 // Register the disassembler. 68 TargetRegistry::RegisterMCDisassembler(TheSparcTarget, 69 createSparcDisassembler); 70 TargetRegistry::RegisterMCDisassembler(TheSparcV9Target, 71 createSparcDisassembler); 72 } 73 74 75 76 static const unsigned IntRegDecoderTable[] = { 77 SP::G0, SP::G1, SP::G2, SP::G3, 78 SP::G4, SP::G5, SP::G6, SP::G7, 79 SP::O0, SP::O1, SP::O2, SP::O3, 80 SP::O4, SP::O5, SP::O6, SP::O7, 81 SP::L0, SP::L1, SP::L2, SP::L3, 82 SP::L4, SP::L5, SP::L6, SP::L7, 83 SP::I0, SP::I1, SP::I2, SP::I3, 84 SP::I4, SP::I5, SP::I6, SP::I7 }; 85 86 static const unsigned FPRegDecoderTable[] = { 87 SP::F0, SP::F1, SP::F2, SP::F3, 88 SP::F4, SP::F5, SP::F6, SP::F7, 89 SP::F8, SP::F9, SP::F10, SP::F11, 90 SP::F12, SP::F13, SP::F14, SP::F15, 91 SP::F16, SP::F17, SP::F18, SP::F19, 92 SP::F20, SP::F21, SP::F22, SP::F23, 93 SP::F24, SP::F25, SP::F26, SP::F27, 94 SP::F28, SP::F29, SP::F30, SP::F31 }; 95 96 static const unsigned DFPRegDecoderTable[] = { 97 SP::D0, SP::D16, SP::D1, SP::D17, 98 SP::D2, SP::D18, SP::D3, SP::D19, 99 SP::D4, SP::D20, SP::D5, SP::D21, 100 SP::D6, SP::D22, SP::D7, SP::D23, 101 SP::D8, SP::D24, SP::D9, SP::D25, 102 SP::D10, SP::D26, SP::D11, SP::D27, 103 SP::D12, SP::D28, SP::D13, SP::D29, 104 SP::D14, SP::D30, SP::D15, SP::D31 }; 105 106 static const unsigned QFPRegDecoderTable[] = { 107 SP::Q0, SP::Q8, ~0U, ~0U, 108 SP::Q1, SP::Q9, ~0U, ~0U, 109 SP::Q2, SP::Q10, ~0U, ~0U, 110 SP::Q3, SP::Q11, ~0U, ~0U, 111 SP::Q4, SP::Q12, ~0U, ~0U, 112 SP::Q5, SP::Q13, ~0U, ~0U, 113 SP::Q6, SP::Q14, ~0U, ~0U, 114 SP::Q7, SP::Q15, ~0U, ~0U } ; 115 116 static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, 117 unsigned RegNo, 118 uint64_t Address, 119 const void *Decoder) { 120 if (RegNo > 31) 121 return MCDisassembler::Fail; 122 unsigned Reg = IntRegDecoderTable[RegNo]; 123 Inst.addOperand(MCOperand::CreateReg(Reg)); 124 return MCDisassembler::Success; 125 } 126 127 static DecodeStatus DecodeI64RegsRegisterClass(MCInst &Inst, 128 unsigned RegNo, 129 uint64_t Address, 130 const void *Decoder) { 131 if (RegNo > 31) 132 return MCDisassembler::Fail; 133 unsigned Reg = IntRegDecoderTable[RegNo]; 134 Inst.addOperand(MCOperand::CreateReg(Reg)); 135 return MCDisassembler::Success; 136 } 137 138 139 static DecodeStatus DecodeFPRegsRegisterClass(MCInst &Inst, 140 unsigned RegNo, 141 uint64_t Address, 142 const void *Decoder) { 143 if (RegNo > 31) 144 return MCDisassembler::Fail; 145 unsigned Reg = FPRegDecoderTable[RegNo]; 146 Inst.addOperand(MCOperand::CreateReg(Reg)); 147 return MCDisassembler::Success; 148 } 149 150 151 static DecodeStatus DecodeDFPRegsRegisterClass(MCInst &Inst, 152 unsigned RegNo, 153 uint64_t Address, 154 const void *Decoder) { 155 if (RegNo > 31) 156 return MCDisassembler::Fail; 157 unsigned Reg = DFPRegDecoderTable[RegNo]; 158 Inst.addOperand(MCOperand::CreateReg(Reg)); 159 return MCDisassembler::Success; 160 } 161 162 163 static DecodeStatus DecodeQFPRegsRegisterClass(MCInst &Inst, 164 unsigned RegNo, 165 uint64_t Address, 166 const void *Decoder) { 167 if (RegNo > 31) 168 return MCDisassembler::Fail; 169 170 unsigned Reg = QFPRegDecoderTable[RegNo]; 171 if (Reg == ~0U) 172 return MCDisassembler::Fail; 173 Inst.addOperand(MCOperand::CreateReg(Reg)); 174 return MCDisassembler::Success; 175 } 176 177 178 #include "SparcGenDisassemblerTables.inc" 179 180 /// readInstruction - read four bytes from the MemoryObject 181 /// and return 32 bit word. 182 static DecodeStatus readInstruction32(const MemoryObject ®ion, 183 uint64_t address, 184 uint64_t &size, 185 uint32_t &insn) { 186 uint8_t Bytes[4]; 187 188 // We want to read exactly 4 Bytes of data. 189 if (region.readBytes(address, 4, Bytes) == -1) { 190 size = 0; 191 return MCDisassembler::Fail; 192 } 193 194 // Encoded as a big-endian 32-bit word in the stream. 195 insn = (Bytes[3] << 0) | 196 (Bytes[2] << 8) | 197 (Bytes[1] << 16) | 198 (Bytes[0] << 24); 199 200 return MCDisassembler::Success; 201 } 202 203 204 DecodeStatus 205 SparcDisassembler::getInstruction(MCInst &instr, 206 uint64_t &Size, 207 const MemoryObject &Region, 208 uint64_t Address, 209 raw_ostream &vStream, 210 raw_ostream &cStream) const { 211 uint32_t Insn; 212 213 DecodeStatus Result = readInstruction32(Region, Address, Size, Insn); 214 if (Result == MCDisassembler::Fail) 215 return MCDisassembler::Fail; 216 217 218 // Calling the auto-generated decoder function. 219 Result = decodeInstruction(DecoderTableSparc32, instr, Insn, Address, 220 this, STI); 221 222 if (Result != MCDisassembler::Fail) { 223 Size = 4; 224 return Result; 225 } 226 227 return MCDisassembler::Fail; 228 } 229