Add instruction encodings and disassembly for 1r instructions.
[oota-llvm.git] / lib / Target / XCore / Disassembler / XCoreDisassembler.cpp
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 // This file is part of the XCore Disassembler.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "XCore.h"
15 #include "XCoreRegisterInfo.h"
16 #include "llvm/MC/MCDisassembler.h"
17 #include "llvm/MC/MCFixedLenDisassembler.h"
18 #include "llvm/MC/MCInst.h"
19 #include "llvm/MC/MCSubtargetInfo.h"
20 #include "llvm/Support/MemoryObject.h"
21 #include "llvm/Support/TargetRegistry.h"
22
23 using namespace llvm;
24
25 typedef MCDisassembler::DecodeStatus DecodeStatus;
26
27 namespace {
28
29 /// XCoreDisassembler - a disasembler class for XCore.
30 class XCoreDisassembler : public MCDisassembler {
31   const MCRegisterInfo *RegInfo;
32 public:
33   /// Constructor     - Initializes the disassembler.
34   ///
35   XCoreDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info) :
36     MCDisassembler(STI), RegInfo(Info) {}
37
38   /// getInstruction - See MCDisassembler.
39   virtual DecodeStatus getInstruction(MCInst &instr,
40                                       uint64_t &size,
41                                       const MemoryObject &region,
42                                       uint64_t address,
43                                       raw_ostream &vStream,
44                                       raw_ostream &cStream) const;
45
46   const MCRegisterInfo *getRegInfo() const { return RegInfo; }
47 };
48 }
49
50 static bool readInstruction16(const MemoryObject &region,
51                               uint64_t address,
52                               uint64_t &size,
53                               uint16_t &insn) {
54   uint8_t Bytes[4];
55
56   // We want to read exactly 2 Bytes of data.
57   if (region.readBytes(address, 2, Bytes, NULL) == -1) {
58     size = 0;
59     return false;
60   }
61   // Encoded as a little-endian 16-bit word in the stream.
62   insn = (Bytes[0] <<  0) | (Bytes[1] <<  8);
63   return true;
64 }
65
66 static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
67   const XCoreDisassembler *Dis = static_cast<const XCoreDisassembler*>(D);
68   return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo);
69 }
70
71
72 static DecodeStatus DecodeGRRegsRegisterClass(MCInst &Inst,
73                                               unsigned RegNo,
74                                               uint64_t Address,
75                                               const void *Decoder);
76
77 #include "XCoreGenDisassemblerTables.inc"
78
79 static DecodeStatus DecodeGRRegsRegisterClass(MCInst &Inst,
80                                               unsigned RegNo,
81                                               uint64_t Address,
82                                               const void *Decoder)
83 {
84   if (RegNo > 11)
85     return MCDisassembler::Fail;
86   unsigned Reg = getReg(Decoder, XCore::GRRegsRegClassID, RegNo);
87   Inst.addOperand(MCOperand::CreateReg(Reg));
88   return MCDisassembler::Success;
89 }
90
91 MCDisassembler::DecodeStatus
92 XCoreDisassembler::getInstruction(MCInst &instr,
93                                   uint64_t &Size,
94                                   const MemoryObject &Region,
95                                   uint64_t Address,
96                                   raw_ostream &vStream,
97                                   raw_ostream &cStream) const {
98   uint16_t low;
99
100   if (!readInstruction16(Region, Address, Size, low)) {
101     return Fail;
102   }
103
104   // Calling the auto-generated decoder function.
105   DecodeStatus Result = decodeInstruction(DecoderTable16, instr, low, Address,
106                              this, STI);
107   if (Result != Fail) {
108     Size = 2;
109     return Result;
110   }
111
112   return Fail;
113 }
114
115 namespace llvm {
116   extern Target TheXCoreTarget;
117 }
118
119 static MCDisassembler *createXCoreDisassembler(const Target &T,
120                                                const MCSubtargetInfo &STI) {
121   return new XCoreDisassembler(STI, T.createMCRegInfo(""));
122 }
123
124 extern "C" void LLVMInitializeXCoreDisassembler() {
125   // Register the disassembler.
126   TargetRegistry::RegisterMCDisassembler(TheXCoreTarget,
127                                          createXCoreDisassembler);
128 }