1 //===- XCoreDisassembler.cpp - Disassembler for XCore -----------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 /// \brief This file is part of the XCore Disassembler.
13 //===----------------------------------------------------------------------===//
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"
26 typedef MCDisassembler::DecodeStatus DecodeStatus;
30 /// \brief A disassembler class for XCore.
31 class XCoreDisassembler : public MCDisassembler {
32 const MCRegisterInfo *RegInfo;
34 XCoreDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info) :
35 MCDisassembler(STI), RegInfo(Info) {}
37 /// \brief See MCDisassembler.
38 virtual DecodeStatus getInstruction(MCInst &instr,
40 const MemoryObject ®ion,
43 raw_ostream &cStream) const;
45 const MCRegisterInfo *getRegInfo() const { return RegInfo; }
49 static bool readInstruction16(const MemoryObject ®ion,
55 // We want to read exactly 2 Bytes of data.
56 if (region.readBytes(address, 2, Bytes, NULL) == -1) {
60 // Encoded as a little-endian 16-bit word in the stream.
61 insn = (Bytes[0] << 0) | (Bytes[1] << 8);
65 static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
66 const XCoreDisassembler *Dis = static_cast<const XCoreDisassembler*>(D);
67 return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo);
70 static DecodeStatus DecodeGRRegsRegisterClass(MCInst &Inst,
75 static DecodeStatus DecodeBitpOperand(MCInst &Inst, unsigned Val,
76 uint64_t Address, const void *Decoder);
78 static DecodeStatus Decode2RInstruction(MCInst &Inst,
83 static DecodeStatus DecodeR2RInstruction(MCInst &Inst,
88 static DecodeStatus Decode2RSrcDstInstruction(MCInst &Inst,
93 static DecodeStatus DecodeRUSInstruction(MCInst &Inst,
98 static DecodeStatus DecodeRUSBitpInstruction(MCInst &Inst,
101 const void *Decoder);
103 static DecodeStatus DecodeRUSSrcDstBitpInstruction(MCInst &Inst,
106 const void *Decoder);
108 #include "XCoreGenDisassemblerTables.inc"
110 static DecodeStatus DecodeGRRegsRegisterClass(MCInst &Inst,
116 return MCDisassembler::Fail;
117 unsigned Reg = getReg(Decoder, XCore::GRRegsRegClassID, RegNo);
118 Inst.addOperand(MCOperand::CreateReg(Reg));
119 return MCDisassembler::Success;
122 static DecodeStatus DecodeBitpOperand(MCInst &Inst, unsigned Val,
123 uint64_t Address, const void *Decoder) {
125 return MCDisassembler::Fail;
126 static unsigned Values[] = {
127 32 /*bpw*/, 1, 2, 3, 4, 5, 6, 7, 8, 16, 24, 32
129 Inst.addOperand(MCOperand::CreateImm(Values[Val]));
130 return MCDisassembler::Success;
134 Decode2OpInstruction(unsigned Insn, unsigned &Op1, unsigned &Op2) {
135 unsigned Combined = fieldFromInstruction(Insn, 6, 5) +
136 fieldFromInstruction(Insn, 5, 1) * 5 - 27;
138 return MCDisassembler::Fail;
140 unsigned Op1High = Combined % 3;
141 unsigned Op2High = Combined / 3;
142 Op1 = (Op1High << 2) | fieldFromInstruction(Insn, 2, 2);
143 Op2 = (Op2High << 2) | fieldFromInstruction(Insn, 0, 2);
144 return MCDisassembler::Success;
148 Decode2RInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
149 const void *Decoder) {
151 DecodeStatus S = Decode2OpInstruction(Insn, Op1, Op2);
152 if (S == MCDisassembler::Success) {
153 DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
154 DecodeGRRegsRegisterClass(Inst, Op2, Address, Decoder);
160 DecodeR2RInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
161 const void *Decoder) {
163 DecodeStatus S = Decode2OpInstruction(Insn, Op2, Op1);
164 if (S == MCDisassembler::Success) {
165 DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
166 DecodeGRRegsRegisterClass(Inst, Op2, Address, Decoder);
172 Decode2RSrcDstInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
173 const void *Decoder) {
175 DecodeStatus S = Decode2OpInstruction(Insn, Op1, Op2);
176 if (S == MCDisassembler::Success) {
177 DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
178 DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
179 DecodeGRRegsRegisterClass(Inst, Op2, Address, Decoder);
185 DecodeRUSInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
186 const void *Decoder) {
188 DecodeStatus S = Decode2OpInstruction(Insn, Op1, Op2);
189 if (S == MCDisassembler::Success) {
190 DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
191 Inst.addOperand(MCOperand::CreateImm(Op2));
197 DecodeRUSBitpInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
198 const void *Decoder) {
200 DecodeStatus S = Decode2OpInstruction(Insn, Op1, Op2);
201 if (S == MCDisassembler::Success) {
202 DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
203 DecodeBitpOperand(Inst, Op2, Address, Decoder);
209 DecodeRUSSrcDstBitpInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
210 const void *Decoder) {
212 DecodeStatus S = Decode2OpInstruction(Insn, Op1, Op2);
213 if (S == MCDisassembler::Success) {
214 DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
215 DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
216 DecodeBitpOperand(Inst, Op2, Address, Decoder);
221 MCDisassembler::DecodeStatus
222 XCoreDisassembler::getInstruction(MCInst &instr,
224 const MemoryObject &Region,
226 raw_ostream &vStream,
227 raw_ostream &cStream) const {
230 if (!readInstruction16(Region, Address, Size, low)) {
234 // Calling the auto-generated decoder function.
235 DecodeStatus Result = decodeInstruction(DecoderTable16, instr, low, Address,
237 if (Result != Fail) {
246 extern Target TheXCoreTarget;
249 static MCDisassembler *createXCoreDisassembler(const Target &T,
250 const MCSubtargetInfo &STI) {
251 return new XCoreDisassembler(STI, T.createMCRegInfo(""));
254 extern "C" void LLVMInitializeXCoreDisassembler() {
255 // Register the disassembler.
256 TargetRegistry::RegisterMCDisassembler(TheXCoreTarget,
257 createXCoreDisassembler);