1 //===- XCoreDisassembler.cpp - Disassembler for XCore -----------*- 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 /// \file 11 /// \brief This file is part of the XCore Disassembler. 12 /// 13 //===----------------------------------------------------------------------===// 14 15 #include "XCore.h" 16 #include "XCoreRegisterInfo.h" 17 #include "llvm/MC/MCDisassembler.h" 18 #include "llvm/MC/MCFixedLenDisassembler.h" 19 #include "llvm/MC/MCInst.h" 20 #include "llvm/MC/MCSubtargetInfo.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 /// \brief A disassembler class for XCore. 31 class XCoreDisassembler : public MCDisassembler { 32 const MCRegisterInfo *RegInfo; 33 public: 34 XCoreDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info) : 35 MCDisassembler(STI), RegInfo(Info) {} 36 37 /// \brief See MCDisassembler. 38 virtual DecodeStatus getInstruction(MCInst &instr, 39 uint64_t &size, 40 const MemoryObject ®ion, 41 uint64_t address, 42 raw_ostream &vStream, 43 raw_ostream &cStream) const; 44 45 const MCRegisterInfo *getRegInfo() const { return RegInfo; } 46 }; 47 } 48 49 static bool readInstruction16(const MemoryObject ®ion, 50 uint64_t address, 51 uint64_t &size, 52 uint16_t &insn) { 53 uint8_t Bytes[4]; 54 55 // We want to read exactly 2 Bytes of data. 56 if (region.readBytes(address, 2, Bytes, NULL) == -1) { 57 size = 0; 58 return false; 59 } 60 // Encoded as a little-endian 16-bit word in the stream. 61 insn = (Bytes[0] << 0) | (Bytes[1] << 8); 62 return true; 63 } 64 65 static bool readInstruction32(const MemoryObject ®ion, 66 uint64_t address, 67 uint64_t &size, 68 uint32_t &insn) { 69 uint8_t Bytes[4]; 70 71 // We want to read exactly 4 Bytes of data. 72 if (region.readBytes(address, 4, Bytes, NULL) == -1) { 73 size = 0; 74 return false; 75 } 76 // Encoded as a little-endian 32-bit word in the stream. 77 insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) | 78 (Bytes[3] << 24); 79 return true; 80 } 81 82 static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) { 83 const XCoreDisassembler *Dis = static_cast<const XCoreDisassembler*>(D); 84 return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo); 85 } 86 87 static DecodeStatus DecodeGRRegsRegisterClass(MCInst &Inst, 88 unsigned RegNo, 89 uint64_t Address, 90 const void *Decoder); 91 92 static DecodeStatus DecodeBitpOperand(MCInst &Inst, unsigned Val, 93 uint64_t Address, const void *Decoder); 94 95 static DecodeStatus Decode2RInstruction(MCInst &Inst, 96 unsigned Insn, 97 uint64_t Address, 98 const void *Decoder); 99 100 static DecodeStatus DecodeR2RInstruction(MCInst &Inst, 101 unsigned Insn, 102 uint64_t Address, 103 const void *Decoder); 104 105 static DecodeStatus Decode2RSrcDstInstruction(MCInst &Inst, 106 unsigned Insn, 107 uint64_t Address, 108 const void *Decoder); 109 110 static DecodeStatus DecodeRUSInstruction(MCInst &Inst, 111 unsigned Insn, 112 uint64_t Address, 113 const void *Decoder); 114 115 static DecodeStatus DecodeRUSBitpInstruction(MCInst &Inst, 116 unsigned Insn, 117 uint64_t Address, 118 const void *Decoder); 119 120 static DecodeStatus DecodeRUSSrcDstBitpInstruction(MCInst &Inst, 121 unsigned Insn, 122 uint64_t Address, 123 const void *Decoder); 124 125 static DecodeStatus DecodeL2RInstruction(MCInst &Inst, 126 unsigned Insn, 127 uint64_t Address, 128 const void *Decoder); 129 130 static DecodeStatus DecodeLR2RInstruction(MCInst &Inst, 131 unsigned Insn, 132 uint64_t Address, 133 const void *Decoder); 134 135 #include "XCoreGenDisassemblerTables.inc" 136 137 static DecodeStatus DecodeGRRegsRegisterClass(MCInst &Inst, 138 unsigned RegNo, 139 uint64_t Address, 140 const void *Decoder) 141 { 142 if (RegNo > 11) 143 return MCDisassembler::Fail; 144 unsigned Reg = getReg(Decoder, XCore::GRRegsRegClassID, RegNo); 145 Inst.addOperand(MCOperand::CreateReg(Reg)); 146 return MCDisassembler::Success; 147 } 148 149 static DecodeStatus DecodeBitpOperand(MCInst &Inst, unsigned Val, 150 uint64_t Address, const void *Decoder) { 151 if (Val > 11) 152 return MCDisassembler::Fail; 153 static unsigned Values[] = { 154 32 /*bpw*/, 1, 2, 3, 4, 5, 6, 7, 8, 16, 24, 32 155 }; 156 Inst.addOperand(MCOperand::CreateImm(Values[Val])); 157 return MCDisassembler::Success; 158 } 159 160 static DecodeStatus 161 Decode2OpInstruction(unsigned Insn, unsigned &Op1, unsigned &Op2) { 162 unsigned Combined = fieldFromInstruction(Insn, 6, 5) + 163 fieldFromInstruction(Insn, 5, 1) * 5 - 27; 164 if (Combined >= 9) 165 return MCDisassembler::Fail; 166 167 unsigned Op1High = Combined % 3; 168 unsigned Op2High = Combined / 3; 169 Op1 = (Op1High << 2) | fieldFromInstruction(Insn, 2, 2); 170 Op2 = (Op2High << 2) | fieldFromInstruction(Insn, 0, 2); 171 return MCDisassembler::Success; 172 } 173 174 static DecodeStatus 175 Decode2RInstruction(MCInst &Inst, unsigned Insn, uint64_t Address, 176 const void *Decoder) { 177 unsigned Op1, Op2; 178 DecodeStatus S = Decode2OpInstruction(Insn, Op1, Op2); 179 if (S == MCDisassembler::Success) { 180 DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder); 181 DecodeGRRegsRegisterClass(Inst, Op2, Address, Decoder); 182 } 183 return S; 184 } 185 186 static DecodeStatus 187 DecodeR2RInstruction(MCInst &Inst, unsigned Insn, uint64_t Address, 188 const void *Decoder) { 189 unsigned Op1, Op2; 190 DecodeStatus S = Decode2OpInstruction(Insn, Op2, Op1); 191 if (S == MCDisassembler::Success) { 192 DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder); 193 DecodeGRRegsRegisterClass(Inst, Op2, Address, Decoder); 194 } 195 return S; 196 } 197 198 static DecodeStatus 199 Decode2RSrcDstInstruction(MCInst &Inst, unsigned Insn, uint64_t Address, 200 const void *Decoder) { 201 unsigned Op1, Op2; 202 DecodeStatus S = Decode2OpInstruction(Insn, Op1, Op2); 203 if (S == MCDisassembler::Success) { 204 DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder); 205 DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder); 206 DecodeGRRegsRegisterClass(Inst, Op2, Address, Decoder); 207 } 208 return S; 209 } 210 211 static DecodeStatus 212 DecodeRUSInstruction(MCInst &Inst, unsigned Insn, uint64_t Address, 213 const void *Decoder) { 214 unsigned Op1, Op2; 215 DecodeStatus S = Decode2OpInstruction(Insn, Op1, Op2); 216 if (S == MCDisassembler::Success) { 217 DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder); 218 Inst.addOperand(MCOperand::CreateImm(Op2)); 219 } 220 return S; 221 } 222 223 static DecodeStatus 224 DecodeRUSBitpInstruction(MCInst &Inst, unsigned Insn, uint64_t Address, 225 const void *Decoder) { 226 unsigned Op1, Op2; 227 DecodeStatus S = Decode2OpInstruction(Insn, Op1, Op2); 228 if (S == MCDisassembler::Success) { 229 DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder); 230 DecodeBitpOperand(Inst, Op2, Address, Decoder); 231 } 232 return S; 233 } 234 235 static DecodeStatus 236 DecodeRUSSrcDstBitpInstruction(MCInst &Inst, unsigned Insn, uint64_t Address, 237 const void *Decoder) { 238 unsigned Op1, Op2; 239 DecodeStatus S = Decode2OpInstruction(Insn, Op1, Op2); 240 if (S == MCDisassembler::Success) { 241 DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder); 242 DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder); 243 DecodeBitpOperand(Inst, Op2, Address, Decoder); 244 } 245 return S; 246 } 247 248 static DecodeStatus 249 DecodeL2RInstruction(MCInst &Inst, unsigned Insn, uint64_t Address, 250 const void *Decoder) { 251 unsigned Op1, Op2; 252 DecodeStatus S = Decode2OpInstruction(fieldFromInstruction(Insn, 0, 16), 253 Op1, Op2); 254 if (S == MCDisassembler::Success) { 255 DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder); 256 DecodeGRRegsRegisterClass(Inst, Op2, Address, Decoder); 257 } 258 return S; 259 } 260 261 static DecodeStatus 262 DecodeLR2RInstruction(MCInst &Inst, unsigned Insn, uint64_t Address, 263 const void *Decoder) { 264 unsigned Op1, Op2; 265 DecodeStatus S = Decode2OpInstruction(fieldFromInstruction(Insn, 0, 16), 266 Op1, Op2); 267 if (S == MCDisassembler::Success) { 268 DecodeGRRegsRegisterClass(Inst, Op2, Address, Decoder); 269 DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder); 270 } 271 return S; 272 } 273 274 MCDisassembler::DecodeStatus 275 XCoreDisassembler::getInstruction(MCInst &instr, 276 uint64_t &Size, 277 const MemoryObject &Region, 278 uint64_t Address, 279 raw_ostream &vStream, 280 raw_ostream &cStream) const { 281 uint16_t insn16; 282 283 if (!readInstruction16(Region, Address, Size, insn16)) { 284 return Fail; 285 } 286 287 // Calling the auto-generated decoder function. 288 DecodeStatus Result = decodeInstruction(DecoderTable16, instr, insn16, 289 Address, this, STI); 290 if (Result != Fail) { 291 Size = 2; 292 return Result; 293 } 294 295 uint32_t insn32; 296 297 if (!readInstruction32(Region, Address, Size, insn32)) { 298 return Fail; 299 } 300 301 // Calling the auto-generated decoder function. 302 Result = decodeInstruction(DecoderTable32, instr, insn32, Address, this, STI); 303 if (Result != Fail) { 304 Size = 4; 305 return Result; 306 } 307 308 return Fail; 309 } 310 311 namespace llvm { 312 extern Target TheXCoreTarget; 313 } 314 315 static MCDisassembler *createXCoreDisassembler(const Target &T, 316 const MCSubtargetInfo &STI) { 317 return new XCoreDisassembler(STI, T.createMCRegInfo("")); 318 } 319 320 extern "C" void LLVMInitializeXCoreDisassembler() { 321 // Register the disassembler. 322 TargetRegistry::RegisterMCDisassembler(TheXCoreTarget, 323 createXCoreDisassembler); 324 } 325