1249259Sdim//===- XCoreDisassembler.cpp - Disassembler for XCore -----------*- C++ -*-===//
2249259Sdim//
3249259Sdim//                     The LLVM Compiler Infrastructure
4249259Sdim//
5249259Sdim// This file is distributed under the University of Illinois Open Source
6249259Sdim// License. See LICENSE.TXT for details.
7249259Sdim//
8249259Sdim//===----------------------------------------------------------------------===//
9249259Sdim///
10249259Sdim/// \file
11249259Sdim/// \brief This file is part of the XCore Disassembler.
12249259Sdim///
13249259Sdim//===----------------------------------------------------------------------===//
14249259Sdim
15249259Sdim#include "XCore.h"
16249259Sdim#include "XCoreRegisterInfo.h"
17249259Sdim#include "llvm/MC/MCDisassembler.h"
18249259Sdim#include "llvm/MC/MCFixedLenDisassembler.h"
19249259Sdim#include "llvm/MC/MCInst.h"
20249259Sdim#include "llvm/MC/MCSubtargetInfo.h"
21249259Sdim#include "llvm/Support/MemoryObject.h"
22249259Sdim#include "llvm/Support/TargetRegistry.h"
23249259Sdim
24249259Sdimusing namespace llvm;
25249259Sdim
26249259Sdimtypedef MCDisassembler::DecodeStatus DecodeStatus;
27249259Sdim
28249259Sdimnamespace {
29249259Sdim
30249259Sdim/// \brief A disassembler class for XCore.
31249259Sdimclass XCoreDisassembler : public MCDisassembler {
32263508Sdim  OwningPtr<const MCRegisterInfo> RegInfo;
33249259Sdimpublic:
34249259Sdim  XCoreDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info) :
35249259Sdim    MCDisassembler(STI), RegInfo(Info) {}
36249259Sdim
37249259Sdim  /// \brief See MCDisassembler.
38249259Sdim  virtual DecodeStatus getInstruction(MCInst &instr,
39249259Sdim                                      uint64_t &size,
40249259Sdim                                      const MemoryObject &region,
41249259Sdim                                      uint64_t address,
42249259Sdim                                      raw_ostream &vStream,
43249259Sdim                                      raw_ostream &cStream) const;
44249259Sdim
45263508Sdim  const MCRegisterInfo *getRegInfo() const { return RegInfo.get(); }
46249259Sdim};
47249259Sdim}
48249259Sdim
49249259Sdimstatic bool readInstruction16(const MemoryObject &region,
50249259Sdim                              uint64_t address,
51249259Sdim                              uint64_t &size,
52249259Sdim                              uint16_t &insn) {
53249259Sdim  uint8_t Bytes[4];
54249259Sdim
55249259Sdim  // We want to read exactly 2 Bytes of data.
56263508Sdim  if (region.readBytes(address, 2, Bytes) == -1) {
57249259Sdim    size = 0;
58249259Sdim    return false;
59249259Sdim  }
60249259Sdim  // Encoded as a little-endian 16-bit word in the stream.
61249259Sdim  insn = (Bytes[0] <<  0) | (Bytes[1] <<  8);
62249259Sdim  return true;
63249259Sdim}
64249259Sdim
65249259Sdimstatic bool readInstruction32(const MemoryObject &region,
66249259Sdim                              uint64_t address,
67249259Sdim                              uint64_t &size,
68249259Sdim                              uint32_t &insn) {
69249259Sdim  uint8_t Bytes[4];
70249259Sdim
71249259Sdim  // We want to read exactly 4 Bytes of data.
72263508Sdim  if (region.readBytes(address, 4, Bytes) == -1) {
73249259Sdim    size = 0;
74249259Sdim    return false;
75249259Sdim  }
76249259Sdim  // Encoded as a little-endian 32-bit word in the stream.
77249259Sdim  insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
78249259Sdim         (Bytes[3] << 24);
79249259Sdim  return true;
80249259Sdim}
81249259Sdim
82249259Sdimstatic unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
83249259Sdim  const XCoreDisassembler *Dis = static_cast<const XCoreDisassembler*>(D);
84249259Sdim  return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo);
85249259Sdim}
86249259Sdim
87249259Sdimstatic DecodeStatus DecodeGRRegsRegisterClass(MCInst &Inst,
88249259Sdim                                              unsigned RegNo,
89249259Sdim                                              uint64_t Address,
90249259Sdim                                              const void *Decoder);
91249259Sdim
92249259Sdimstatic DecodeStatus DecodeRRegsRegisterClass(MCInst &Inst,
93249259Sdim                                             unsigned RegNo,
94249259Sdim                                             uint64_t Address,
95249259Sdim                                             const void *Decoder);
96249259Sdim
97249259Sdimstatic DecodeStatus DecodeBitpOperand(MCInst &Inst, unsigned Val,
98249259Sdim                                      uint64_t Address, const void *Decoder);
99249259Sdim
100251662Sdimstatic DecodeStatus DecodeNegImmOperand(MCInst &Inst, unsigned Val,
101251662Sdim                                        uint64_t Address, const void *Decoder);
102249259Sdim
103249259Sdimstatic DecodeStatus Decode2RInstruction(MCInst &Inst,
104249259Sdim                                        unsigned Insn,
105249259Sdim                                        uint64_t Address,
106249259Sdim                                        const void *Decoder);
107249259Sdim
108249259Sdimstatic DecodeStatus Decode2RImmInstruction(MCInst &Inst,
109249259Sdim                                           unsigned Insn,
110249259Sdim                                           uint64_t Address,
111249259Sdim                                           const void *Decoder);
112249259Sdim
113249259Sdimstatic DecodeStatus DecodeR2RInstruction(MCInst &Inst,
114249259Sdim                                         unsigned Insn,
115249259Sdim                                         uint64_t Address,
116249259Sdim                                         const void *Decoder);
117249259Sdim
118249259Sdimstatic DecodeStatus Decode2RSrcDstInstruction(MCInst &Inst,
119249259Sdim                                              unsigned Insn,
120249259Sdim                                              uint64_t Address,
121249259Sdim                                              const void *Decoder);
122249259Sdim
123249259Sdimstatic DecodeStatus DecodeRUSInstruction(MCInst &Inst,
124249259Sdim                                         unsigned Insn,
125249259Sdim                                         uint64_t Address,
126249259Sdim                                         const void *Decoder);
127249259Sdim
128249259Sdimstatic DecodeStatus DecodeRUSBitpInstruction(MCInst &Inst,
129249259Sdim                                             unsigned Insn,
130249259Sdim                                             uint64_t Address,
131249259Sdim                                             const void *Decoder);
132249259Sdim
133249259Sdimstatic DecodeStatus DecodeRUSSrcDstBitpInstruction(MCInst &Inst,
134249259Sdim                                                   unsigned Insn,
135249259Sdim                                                   uint64_t Address,
136249259Sdim                                                   const void *Decoder);
137249259Sdim
138249259Sdimstatic DecodeStatus DecodeL2RInstruction(MCInst &Inst,
139249259Sdim                                         unsigned Insn,
140249259Sdim                                         uint64_t Address,
141249259Sdim                                         const void *Decoder);
142249259Sdim
143249259Sdimstatic DecodeStatus DecodeLR2RInstruction(MCInst &Inst,
144249259Sdim                                          unsigned Insn,
145249259Sdim                                          uint64_t Address,
146249259Sdim                                          const void *Decoder);
147249259Sdim
148249259Sdimstatic DecodeStatus Decode3RInstruction(MCInst &Inst,
149249259Sdim                                        unsigned Insn,
150249259Sdim                                        uint64_t Address,
151249259Sdim                                        const void *Decoder);
152249259Sdim
153249259Sdimstatic DecodeStatus Decode3RImmInstruction(MCInst &Inst,
154249259Sdim                                           unsigned Insn,
155249259Sdim                                           uint64_t Address,
156249259Sdim                                           const void *Decoder);
157249259Sdim
158249259Sdimstatic DecodeStatus Decode2RUSInstruction(MCInst &Inst,
159249259Sdim                                          unsigned Insn,
160249259Sdim                                          uint64_t Address,
161249259Sdim                                          const void *Decoder);
162249259Sdim
163249259Sdimstatic DecodeStatus Decode2RUSBitpInstruction(MCInst &Inst,
164249259Sdim                                              unsigned Insn,
165249259Sdim                                              uint64_t Address,
166249259Sdim                                              const void *Decoder);
167249259Sdim
168249259Sdimstatic DecodeStatus DecodeL3RInstruction(MCInst &Inst,
169249259Sdim                                         unsigned Insn,
170249259Sdim                                         uint64_t Address,
171249259Sdim                                         const void *Decoder);
172249259Sdim
173249259Sdimstatic DecodeStatus DecodeL3RSrcDstInstruction(MCInst &Inst,
174249259Sdim                                               unsigned Insn,
175249259Sdim                                               uint64_t Address,
176249259Sdim                                               const void *Decoder);
177249259Sdim
178249259Sdimstatic DecodeStatus DecodeL2RUSInstruction(MCInst &Inst,
179249259Sdim                                           unsigned Insn,
180249259Sdim                                           uint64_t Address,
181249259Sdim                                           const void *Decoder);
182249259Sdim
183249259Sdimstatic DecodeStatus DecodeL2RUSBitpInstruction(MCInst &Inst,
184249259Sdim                                               unsigned Insn,
185249259Sdim                                               uint64_t Address,
186249259Sdim                                               const void *Decoder);
187249259Sdim
188249259Sdimstatic DecodeStatus DecodeL6RInstruction(MCInst &Inst,
189249259Sdim                                         unsigned Insn,
190249259Sdim                                         uint64_t Address,
191249259Sdim                                         const void *Decoder);
192249259Sdim
193249259Sdimstatic DecodeStatus DecodeL5RInstruction(MCInst &Inst,
194249259Sdim                                         unsigned Insn,
195249259Sdim                                         uint64_t Address,
196249259Sdim                                         const void *Decoder);
197249259Sdim
198249259Sdimstatic DecodeStatus DecodeL4RSrcDstInstruction(MCInst &Inst,
199249259Sdim                                               unsigned Insn,
200249259Sdim                                               uint64_t Address,
201249259Sdim                                               const void *Decoder);
202249259Sdim
203249259Sdimstatic DecodeStatus DecodeL4RSrcDstSrcDstInstruction(MCInst &Inst,
204249259Sdim                                                     unsigned Insn,
205249259Sdim                                                     uint64_t Address,
206249259Sdim                                                     const void *Decoder);
207249259Sdim
208249259Sdim#include "XCoreGenDisassemblerTables.inc"
209249259Sdim
210249259Sdimstatic DecodeStatus DecodeGRRegsRegisterClass(MCInst &Inst,
211249259Sdim                                              unsigned RegNo,
212249259Sdim                                              uint64_t Address,
213249259Sdim                                              const void *Decoder)
214249259Sdim{
215249259Sdim  if (RegNo > 11)
216249259Sdim    return MCDisassembler::Fail;
217249259Sdim  unsigned Reg = getReg(Decoder, XCore::GRRegsRegClassID, RegNo);
218249259Sdim  Inst.addOperand(MCOperand::CreateReg(Reg));
219249259Sdim  return MCDisassembler::Success;
220249259Sdim}
221249259Sdim
222249259Sdimstatic DecodeStatus DecodeRRegsRegisterClass(MCInst &Inst,
223249259Sdim                                             unsigned RegNo,
224249259Sdim                                             uint64_t Address,
225249259Sdim                                             const void *Decoder)
226249259Sdim{
227249259Sdim  if (RegNo > 15)
228249259Sdim    return MCDisassembler::Fail;
229249259Sdim  unsigned Reg = getReg(Decoder, XCore::RRegsRegClassID, RegNo);
230249259Sdim  Inst.addOperand(MCOperand::CreateReg(Reg));
231249259Sdim  return MCDisassembler::Success;
232249259Sdim}
233249259Sdim
234249259Sdimstatic DecodeStatus DecodeBitpOperand(MCInst &Inst, unsigned Val,
235249259Sdim                                      uint64_t Address, const void *Decoder) {
236249259Sdim  if (Val > 11)
237249259Sdim    return MCDisassembler::Fail;
238249259Sdim  static unsigned Values[] = {
239249259Sdim    32 /*bpw*/, 1, 2, 3, 4, 5, 6, 7, 8, 16, 24, 32
240249259Sdim  };
241249259Sdim  Inst.addOperand(MCOperand::CreateImm(Values[Val]));
242249259Sdim  return MCDisassembler::Success;
243249259Sdim}
244249259Sdim
245251662Sdimstatic DecodeStatus DecodeNegImmOperand(MCInst &Inst, unsigned Val,
246251662Sdim                                        uint64_t Address, const void *Decoder) {
247251662Sdim  Inst.addOperand(MCOperand::CreateImm(-(int64_t)Val));
248249259Sdim  return MCDisassembler::Success;
249249259Sdim}
250249259Sdim
251249259Sdimstatic DecodeStatus
252249259SdimDecode2OpInstruction(unsigned Insn, unsigned &Op1, unsigned &Op2) {
253249259Sdim  unsigned Combined = fieldFromInstruction(Insn, 6, 5);
254249259Sdim  if (Combined < 27)
255249259Sdim    return MCDisassembler::Fail;
256249259Sdim  if (fieldFromInstruction(Insn, 5, 1)) {
257249259Sdim    if (Combined == 31)
258249259Sdim      return MCDisassembler::Fail;
259249259Sdim    Combined += 5;
260249259Sdim  }
261249259Sdim  Combined -= 27;
262249259Sdim  unsigned Op1High = Combined % 3;
263249259Sdim  unsigned Op2High = Combined / 3;
264249259Sdim  Op1 = (Op1High << 2) | fieldFromInstruction(Insn, 2, 2);
265249259Sdim  Op2 = (Op2High << 2) | fieldFromInstruction(Insn, 0, 2);
266249259Sdim  return MCDisassembler::Success;
267249259Sdim}
268249259Sdim
269249259Sdimstatic DecodeStatus
270249259SdimDecode3OpInstruction(unsigned Insn, unsigned &Op1, unsigned &Op2,
271249259Sdim                     unsigned &Op3) {
272249259Sdim  unsigned Combined = fieldFromInstruction(Insn, 6, 5);
273249259Sdim  if (Combined >= 27)
274249259Sdim    return MCDisassembler::Fail;
275249259Sdim
276249259Sdim  unsigned Op1High = Combined % 3;
277249259Sdim  unsigned Op2High = (Combined / 3) % 3;
278249259Sdim  unsigned Op3High = Combined / 9;
279249259Sdim  Op1 = (Op1High << 2) | fieldFromInstruction(Insn, 4, 2);
280249259Sdim  Op2 = (Op2High << 2) | fieldFromInstruction(Insn, 2, 2);
281249259Sdim  Op3 = (Op3High << 2) | fieldFromInstruction(Insn, 0, 2);
282249259Sdim  return MCDisassembler::Success;
283249259Sdim}
284249259Sdim
285249259Sdimstatic DecodeStatus
286249259SdimDecode2OpInstructionFail(MCInst &Inst, unsigned Insn, uint64_t Address,
287249259Sdim                         const void *Decoder) {
288249259Sdim  // Try and decode as a 3R instruction.
289249259Sdim  unsigned Opcode = fieldFromInstruction(Insn, 11, 5);
290249259Sdim  switch (Opcode) {
291249259Sdim  case 0x0:
292249259Sdim    Inst.setOpcode(XCore::STW_2rus);
293249259Sdim    return Decode2RUSInstruction(Inst, Insn, Address, Decoder);
294249259Sdim  case 0x1:
295249259Sdim    Inst.setOpcode(XCore::LDW_2rus);
296249259Sdim    return Decode2RUSInstruction(Inst, Insn, Address, Decoder);
297249259Sdim  case 0x2:
298249259Sdim    Inst.setOpcode(XCore::ADD_3r);
299249259Sdim    return Decode3RInstruction(Inst, Insn, Address, Decoder);
300249259Sdim  case 0x3:
301249259Sdim    Inst.setOpcode(XCore::SUB_3r);
302249259Sdim    return Decode3RInstruction(Inst, Insn, Address, Decoder);
303249259Sdim  case 0x4:
304249259Sdim    Inst.setOpcode(XCore::SHL_3r);
305249259Sdim    return Decode3RInstruction(Inst, Insn, Address, Decoder);
306249259Sdim  case 0x5:
307249259Sdim    Inst.setOpcode(XCore::SHR_3r);
308249259Sdim    return Decode3RInstruction(Inst, Insn, Address, Decoder);
309249259Sdim  case 0x6:
310249259Sdim    Inst.setOpcode(XCore::EQ_3r);
311249259Sdim    return Decode3RInstruction(Inst, Insn, Address, Decoder);
312249259Sdim  case 0x7:
313249259Sdim    Inst.setOpcode(XCore::AND_3r);
314249259Sdim    return Decode3RInstruction(Inst, Insn, Address, Decoder);
315249259Sdim  case 0x8:
316249259Sdim    Inst.setOpcode(XCore::OR_3r);
317249259Sdim    return Decode3RInstruction(Inst, Insn, Address, Decoder);
318249259Sdim  case 0x9:
319249259Sdim    Inst.setOpcode(XCore::LDW_3r);
320249259Sdim    return Decode3RInstruction(Inst, Insn, Address, Decoder);
321249259Sdim  case 0x10:
322249259Sdim    Inst.setOpcode(XCore::LD16S_3r);
323249259Sdim    return Decode3RInstruction(Inst, Insn, Address, Decoder);
324249259Sdim  case 0x11:
325249259Sdim    Inst.setOpcode(XCore::LD8U_3r);
326249259Sdim    return Decode3RInstruction(Inst, Insn, Address, Decoder);
327249259Sdim  case 0x12:
328249259Sdim    Inst.setOpcode(XCore::ADD_2rus);
329249259Sdim    return Decode2RUSInstruction(Inst, Insn, Address, Decoder);
330249259Sdim  case 0x13:
331249259Sdim    Inst.setOpcode(XCore::SUB_2rus);
332249259Sdim    return Decode2RUSInstruction(Inst, Insn, Address, Decoder);
333249259Sdim  case 0x14:
334249259Sdim    Inst.setOpcode(XCore::SHL_2rus);
335249259Sdim    return Decode2RUSBitpInstruction(Inst, Insn, Address, Decoder);
336249259Sdim  case 0x15:
337249259Sdim    Inst.setOpcode(XCore::SHR_2rus);
338249259Sdim    return Decode2RUSBitpInstruction(Inst, Insn, Address, Decoder);
339249259Sdim  case 0x16:
340249259Sdim    Inst.setOpcode(XCore::EQ_2rus);
341249259Sdim    return Decode2RUSInstruction(Inst, Insn, Address, Decoder);
342249259Sdim  case 0x17:
343249259Sdim    Inst.setOpcode(XCore::TSETR_3r);
344249259Sdim    return Decode3RImmInstruction(Inst, Insn, Address, Decoder);
345249259Sdim  case 0x18:
346249259Sdim    Inst.setOpcode(XCore::LSS_3r);
347249259Sdim    return Decode3RInstruction(Inst, Insn, Address, Decoder);
348249259Sdim  case 0x19:
349249259Sdim    Inst.setOpcode(XCore::LSU_3r);
350249259Sdim    return Decode3RInstruction(Inst, Insn, Address, Decoder);
351249259Sdim  }
352249259Sdim  return MCDisassembler::Fail;
353249259Sdim}
354249259Sdim
355249259Sdimstatic DecodeStatus
356249259SdimDecode2RInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
357249259Sdim                    const void *Decoder) {
358249259Sdim  unsigned Op1, Op2;
359249259Sdim  DecodeStatus S = Decode2OpInstruction(Insn, Op1, Op2);
360249259Sdim  if (S != MCDisassembler::Success)
361249259Sdim    return Decode2OpInstructionFail(Inst, Insn, Address, Decoder);
362249259Sdim
363249259Sdim  DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
364249259Sdim  DecodeGRRegsRegisterClass(Inst, Op2, Address, Decoder);
365249259Sdim  return S;
366249259Sdim}
367249259Sdim
368249259Sdimstatic DecodeStatus
369249259SdimDecode2RImmInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
370249259Sdim                       const void *Decoder) {
371249259Sdim  unsigned Op1, Op2;
372249259Sdim  DecodeStatus S = Decode2OpInstruction(Insn, Op1, Op2);
373249259Sdim  if (S != MCDisassembler::Success)
374249259Sdim    return Decode2OpInstructionFail(Inst, Insn, Address, Decoder);
375249259Sdim
376249259Sdim  Inst.addOperand(MCOperand::CreateImm(Op1));
377249259Sdim  DecodeGRRegsRegisterClass(Inst, Op2, Address, Decoder);
378249259Sdim  return S;
379249259Sdim}
380249259Sdim
381249259Sdimstatic DecodeStatus
382249259SdimDecodeR2RInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
383249259Sdim                     const void *Decoder) {
384249259Sdim  unsigned Op1, Op2;
385249259Sdim  DecodeStatus S = Decode2OpInstruction(Insn, Op2, Op1);
386249259Sdim  if (S != MCDisassembler::Success)
387249259Sdim    return Decode2OpInstructionFail(Inst, Insn, Address, Decoder);
388249259Sdim
389249259Sdim  DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
390249259Sdim  DecodeGRRegsRegisterClass(Inst, Op2, Address, Decoder);
391249259Sdim  return S;
392249259Sdim}
393249259Sdim
394249259Sdimstatic DecodeStatus
395249259SdimDecode2RSrcDstInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
396249259Sdim                          const void *Decoder) {
397249259Sdim  unsigned Op1, Op2;
398249259Sdim  DecodeStatus S = Decode2OpInstruction(Insn, Op1, Op2);
399249259Sdim  if (S != MCDisassembler::Success)
400249259Sdim    return Decode2OpInstructionFail(Inst, Insn, Address, Decoder);
401249259Sdim
402249259Sdim  DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
403249259Sdim  DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
404249259Sdim  DecodeGRRegsRegisterClass(Inst, Op2, Address, Decoder);
405249259Sdim  return S;
406249259Sdim}
407249259Sdim
408249259Sdimstatic DecodeStatus
409249259SdimDecodeRUSInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
410249259Sdim                     const void *Decoder) {
411249259Sdim  unsigned Op1, Op2;
412249259Sdim  DecodeStatus S = Decode2OpInstruction(Insn, Op1, Op2);
413249259Sdim  if (S != MCDisassembler::Success)
414249259Sdim    return Decode2OpInstructionFail(Inst, Insn, Address, Decoder);
415249259Sdim
416249259Sdim  DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
417249259Sdim  Inst.addOperand(MCOperand::CreateImm(Op2));
418249259Sdim  return S;
419249259Sdim}
420249259Sdim
421249259Sdimstatic DecodeStatus
422249259SdimDecodeRUSBitpInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
423249259Sdim                         const void *Decoder) {
424249259Sdim  unsigned Op1, Op2;
425249259Sdim  DecodeStatus S = Decode2OpInstruction(Insn, Op1, Op2);
426249259Sdim  if (S != MCDisassembler::Success)
427249259Sdim    return Decode2OpInstructionFail(Inst, Insn, Address, Decoder);
428249259Sdim
429249259Sdim  DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
430249259Sdim  DecodeBitpOperand(Inst, Op2, Address, Decoder);
431249259Sdim  return S;
432249259Sdim}
433249259Sdim
434249259Sdimstatic DecodeStatus
435249259SdimDecodeRUSSrcDstBitpInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
436249259Sdim                               const void *Decoder) {
437249259Sdim  unsigned Op1, Op2;
438249259Sdim  DecodeStatus S = Decode2OpInstruction(Insn, Op1, Op2);
439249259Sdim  if (S != MCDisassembler::Success)
440249259Sdim    return Decode2OpInstructionFail(Inst, Insn, Address, Decoder);
441249259Sdim
442249259Sdim  DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
443249259Sdim  DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
444249259Sdim  DecodeBitpOperand(Inst, Op2, Address, Decoder);
445249259Sdim  return S;
446249259Sdim}
447249259Sdim
448249259Sdimstatic DecodeStatus
449249259SdimDecodeL2OpInstructionFail(MCInst &Inst, unsigned Insn, uint64_t Address,
450249259Sdim                          const void *Decoder) {
451249259Sdim  // Try and decode as a L3R / L2RUS instruction.
452249259Sdim  unsigned Opcode = fieldFromInstruction(Insn, 16, 4) |
453249259Sdim                    fieldFromInstruction(Insn, 27, 5) << 4;
454249259Sdim  switch (Opcode) {
455249259Sdim  case 0x0c:
456249259Sdim    Inst.setOpcode(XCore::STW_l3r);
457249259Sdim    return DecodeL3RInstruction(Inst, Insn, Address, Decoder);
458249259Sdim  case 0x1c:
459249259Sdim    Inst.setOpcode(XCore::XOR_l3r);
460249259Sdim    return DecodeL3RInstruction(Inst, Insn, Address, Decoder);
461249259Sdim  case 0x2c:
462249259Sdim    Inst.setOpcode(XCore::ASHR_l3r);
463249259Sdim    return DecodeL3RInstruction(Inst, Insn, Address, Decoder);
464249259Sdim  case 0x3c:
465249259Sdim    Inst.setOpcode(XCore::LDAWF_l3r);
466249259Sdim    return DecodeL3RInstruction(Inst, Insn, Address, Decoder);
467249259Sdim  case 0x4c:
468249259Sdim    Inst.setOpcode(XCore::LDAWB_l3r);
469249259Sdim    return DecodeL3RInstruction(Inst, Insn, Address, Decoder);
470249259Sdim  case 0x5c:
471249259Sdim    Inst.setOpcode(XCore::LDA16F_l3r);
472249259Sdim    return DecodeL3RInstruction(Inst, Insn, Address, Decoder);
473249259Sdim  case 0x6c:
474249259Sdim    Inst.setOpcode(XCore::LDA16B_l3r);
475249259Sdim    return DecodeL3RInstruction(Inst, Insn, Address, Decoder);
476249259Sdim  case 0x7c:
477249259Sdim    Inst.setOpcode(XCore::MUL_l3r);
478249259Sdim    return DecodeL3RInstruction(Inst, Insn, Address, Decoder);
479249259Sdim  case 0x8c:
480249259Sdim    Inst.setOpcode(XCore::DIVS_l3r);
481249259Sdim    return DecodeL3RInstruction(Inst, Insn, Address, Decoder);
482249259Sdim  case 0x9c:
483249259Sdim    Inst.setOpcode(XCore::DIVU_l3r);
484249259Sdim    return DecodeL3RInstruction(Inst, Insn, Address, Decoder);
485249259Sdim  case 0x10c:
486249259Sdim    Inst.setOpcode(XCore::ST16_l3r);
487249259Sdim    return DecodeL3RInstruction(Inst, Insn, Address, Decoder);
488249259Sdim  case 0x11c:
489249259Sdim    Inst.setOpcode(XCore::ST8_l3r);
490249259Sdim    return DecodeL3RInstruction(Inst, Insn, Address, Decoder);
491249259Sdim  case 0x12c:
492249259Sdim    Inst.setOpcode(XCore::ASHR_l2rus);
493249259Sdim    return DecodeL2RUSBitpInstruction(Inst, Insn, Address, Decoder);
494249259Sdim  case 0x12d:
495249259Sdim    Inst.setOpcode(XCore::OUTPW_l2rus);
496249259Sdim    return DecodeL2RUSBitpInstruction(Inst, Insn, Address, Decoder);
497249259Sdim  case 0x12e:
498249259Sdim    Inst.setOpcode(XCore::INPW_l2rus);
499249259Sdim    return DecodeL2RUSBitpInstruction(Inst, Insn, Address, Decoder);
500249259Sdim  case 0x13c:
501249259Sdim    Inst.setOpcode(XCore::LDAWF_l2rus);
502249259Sdim    return DecodeL2RUSInstruction(Inst, Insn, Address, Decoder);
503249259Sdim  case 0x14c:
504249259Sdim    Inst.setOpcode(XCore::LDAWB_l2rus);
505249259Sdim    return DecodeL2RUSInstruction(Inst, Insn, Address, Decoder);
506249259Sdim  case 0x15c:
507249259Sdim    Inst.setOpcode(XCore::CRC_l3r);
508249259Sdim    return DecodeL3RSrcDstInstruction(Inst, Insn, Address, Decoder);
509249259Sdim  case 0x18c:
510249259Sdim    Inst.setOpcode(XCore::REMS_l3r);
511249259Sdim    return DecodeL3RInstruction(Inst, Insn, Address, Decoder);
512249259Sdim  case 0x19c:
513249259Sdim    Inst.setOpcode(XCore::REMU_l3r);
514249259Sdim    return DecodeL3RInstruction(Inst, Insn, Address, Decoder);
515249259Sdim  }
516249259Sdim  return MCDisassembler::Fail;
517249259Sdim}
518249259Sdim
519249259Sdimstatic DecodeStatus
520249259SdimDecodeL2RInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
521249259Sdim                               const void *Decoder) {
522249259Sdim  unsigned Op1, Op2;
523249259Sdim  DecodeStatus S = Decode2OpInstruction(fieldFromInstruction(Insn, 0, 16),
524249259Sdim                                        Op1, Op2);
525249259Sdim  if (S != MCDisassembler::Success)
526249259Sdim    return DecodeL2OpInstructionFail(Inst, Insn, Address, Decoder);
527249259Sdim
528249259Sdim  DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
529249259Sdim  DecodeGRRegsRegisterClass(Inst, Op2, Address, Decoder);
530249259Sdim  return S;
531249259Sdim}
532249259Sdim
533249259Sdimstatic DecodeStatus
534249259SdimDecodeLR2RInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
535249259Sdim                               const void *Decoder) {
536249259Sdim  unsigned Op1, Op2;
537249259Sdim  DecodeStatus S = Decode2OpInstruction(fieldFromInstruction(Insn, 0, 16),
538249259Sdim                                        Op1, Op2);
539249259Sdim  if (S != MCDisassembler::Success)
540249259Sdim    return DecodeL2OpInstructionFail(Inst, Insn, Address, Decoder);
541249259Sdim
542249259Sdim  DecodeGRRegsRegisterClass(Inst, Op2, Address, Decoder);
543249259Sdim  DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
544249259Sdim  return S;
545249259Sdim}
546249259Sdim
547249259Sdimstatic DecodeStatus
548249259SdimDecode3RInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
549249259Sdim                    const void *Decoder) {
550249259Sdim  unsigned Op1, Op2, Op3;
551249259Sdim  DecodeStatus S = Decode3OpInstruction(Insn, Op1, Op2, Op3);
552249259Sdim  if (S == MCDisassembler::Success) {
553249259Sdim    DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
554249259Sdim    DecodeGRRegsRegisterClass(Inst, Op2, Address, Decoder);
555249259Sdim    DecodeGRRegsRegisterClass(Inst, Op3, Address, Decoder);
556249259Sdim  }
557249259Sdim  return S;
558249259Sdim}
559249259Sdim
560249259Sdimstatic DecodeStatus
561249259SdimDecode3RImmInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
562249259Sdim                       const void *Decoder) {
563249259Sdim  unsigned Op1, Op2, Op3;
564249259Sdim  DecodeStatus S = Decode3OpInstruction(Insn, Op1, Op2, Op3);
565249259Sdim  if (S == MCDisassembler::Success) {
566249259Sdim    Inst.addOperand(MCOperand::CreateImm(Op1));
567249259Sdim    DecodeGRRegsRegisterClass(Inst, Op2, Address, Decoder);
568249259Sdim    DecodeGRRegsRegisterClass(Inst, Op3, Address, Decoder);
569249259Sdim  }
570249259Sdim  return S;
571249259Sdim}
572249259Sdim
573249259Sdimstatic DecodeStatus
574249259SdimDecode2RUSInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
575249259Sdim                      const void *Decoder) {
576249259Sdim  unsigned Op1, Op2, Op3;
577249259Sdim  DecodeStatus S = Decode3OpInstruction(Insn, Op1, Op2, Op3);
578249259Sdim  if (S == MCDisassembler::Success) {
579249259Sdim    DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
580249259Sdim    DecodeGRRegsRegisterClass(Inst, Op2, Address, Decoder);
581249259Sdim    Inst.addOperand(MCOperand::CreateImm(Op3));
582249259Sdim  }
583249259Sdim  return S;
584249259Sdim}
585249259Sdim
586249259Sdimstatic DecodeStatus
587249259SdimDecode2RUSBitpInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
588249259Sdim                      const void *Decoder) {
589249259Sdim  unsigned Op1, Op2, Op3;
590249259Sdim  DecodeStatus S = Decode3OpInstruction(Insn, Op1, Op2, Op3);
591249259Sdim  if (S == MCDisassembler::Success) {
592249259Sdim    DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
593249259Sdim    DecodeGRRegsRegisterClass(Inst, Op2, Address, Decoder);
594249259Sdim    DecodeBitpOperand(Inst, Op3, Address, Decoder);
595249259Sdim  }
596249259Sdim  return S;
597249259Sdim}
598249259Sdim
599249259Sdimstatic DecodeStatus
600249259SdimDecodeL3RInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
601249259Sdim                     const void *Decoder) {
602249259Sdim  unsigned Op1, Op2, Op3;
603249259Sdim  DecodeStatus S =
604249259Sdim    Decode3OpInstruction(fieldFromInstruction(Insn, 0, 16), Op1, Op2, Op3);
605249259Sdim  if (S == MCDisassembler::Success) {
606249259Sdim    DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
607249259Sdim    DecodeGRRegsRegisterClass(Inst, Op2, Address, Decoder);
608249259Sdim    DecodeGRRegsRegisterClass(Inst, Op3, Address, Decoder);
609249259Sdim  }
610249259Sdim  return S;
611249259Sdim}
612249259Sdim
613249259Sdimstatic DecodeStatus
614249259SdimDecodeL3RSrcDstInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
615249259Sdim                           const void *Decoder) {
616249259Sdim  unsigned Op1, Op2, Op3;
617249259Sdim  DecodeStatus S =
618249259Sdim  Decode3OpInstruction(fieldFromInstruction(Insn, 0, 16), Op1, Op2, Op3);
619249259Sdim  if (S == MCDisassembler::Success) {
620249259Sdim    DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
621249259Sdim    DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
622249259Sdim    DecodeGRRegsRegisterClass(Inst, Op2, Address, Decoder);
623249259Sdim    DecodeGRRegsRegisterClass(Inst, Op3, Address, Decoder);
624249259Sdim  }
625249259Sdim  return S;
626249259Sdim}
627249259Sdim
628249259Sdimstatic DecodeStatus
629249259SdimDecodeL2RUSInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
630249259Sdim                       const void *Decoder) {
631249259Sdim  unsigned Op1, Op2, Op3;
632249259Sdim  DecodeStatus S =
633249259Sdim  Decode3OpInstruction(fieldFromInstruction(Insn, 0, 16), Op1, Op2, Op3);
634249259Sdim  if (S == MCDisassembler::Success) {
635249259Sdim    DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
636249259Sdim    DecodeGRRegsRegisterClass(Inst, Op2, Address, Decoder);
637249259Sdim    Inst.addOperand(MCOperand::CreateImm(Op3));
638249259Sdim  }
639249259Sdim  return S;
640249259Sdim}
641249259Sdim
642249259Sdimstatic DecodeStatus
643249259SdimDecodeL2RUSBitpInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
644249259Sdim                           const void *Decoder) {
645249259Sdim  unsigned Op1, Op2, Op3;
646249259Sdim  DecodeStatus S =
647249259Sdim  Decode3OpInstruction(fieldFromInstruction(Insn, 0, 16), Op1, Op2, Op3);
648249259Sdim  if (S == MCDisassembler::Success) {
649249259Sdim    DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
650249259Sdim    DecodeGRRegsRegisterClass(Inst, Op2, Address, Decoder);
651249259Sdim    DecodeBitpOperand(Inst, Op3, Address, Decoder);
652249259Sdim  }
653249259Sdim  return S;
654249259Sdim}
655249259Sdim
656249259Sdimstatic DecodeStatus
657249259SdimDecodeL6RInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
658249259Sdim                     const void *Decoder) {
659249259Sdim  unsigned Op1, Op2, Op3, Op4, Op5, Op6;
660249259Sdim  DecodeStatus S =
661249259Sdim    Decode3OpInstruction(fieldFromInstruction(Insn, 0, 16), Op1, Op2, Op3);
662249259Sdim  if (S != MCDisassembler::Success)
663249259Sdim    return S;
664249259Sdim  S = Decode3OpInstruction(fieldFromInstruction(Insn, 16, 16), Op4, Op5, Op6);
665249259Sdim  if (S != MCDisassembler::Success)
666249259Sdim    return S;
667249259Sdim  DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
668249259Sdim  DecodeGRRegsRegisterClass(Inst, Op4, Address, Decoder);
669249259Sdim  DecodeGRRegsRegisterClass(Inst, Op2, Address, Decoder);
670249259Sdim  DecodeGRRegsRegisterClass(Inst, Op3, Address, Decoder);
671249259Sdim  DecodeGRRegsRegisterClass(Inst, Op5, Address, Decoder);
672249259Sdim  DecodeGRRegsRegisterClass(Inst, Op6, Address, Decoder);
673249259Sdim  return S;
674249259Sdim}
675249259Sdim
676249259Sdimstatic DecodeStatus
677249259SdimDecodeL5RInstructionFail(MCInst &Inst, unsigned Insn, uint64_t Address,
678249259Sdim                     const void *Decoder) {
679249259Sdim  // Try and decode as a L6R instruction.
680249259Sdim  Inst.clear();
681249259Sdim  unsigned Opcode = fieldFromInstruction(Insn, 27, 5);
682249259Sdim  switch (Opcode) {
683249259Sdim  case 0x00:
684249259Sdim    Inst.setOpcode(XCore::LMUL_l6r);
685249259Sdim    return DecodeL6RInstruction(Inst, Insn, Address, Decoder);
686249259Sdim  }
687249259Sdim  return MCDisassembler::Fail;
688249259Sdim}
689249259Sdim
690249259Sdimstatic DecodeStatus
691249259SdimDecodeL5RInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
692249259Sdim                     const void *Decoder) {
693249259Sdim  unsigned Op1, Op2, Op3, Op4, Op5;
694249259Sdim  DecodeStatus S =
695249259Sdim    Decode3OpInstruction(fieldFromInstruction(Insn, 0, 16), Op1, Op2, Op3);
696249259Sdim  if (S != MCDisassembler::Success)
697249259Sdim    return DecodeL5RInstructionFail(Inst, Insn, Address, Decoder);
698249259Sdim  S = Decode2OpInstruction(fieldFromInstruction(Insn, 16, 16), Op4, Op5);
699249259Sdim  if (S != MCDisassembler::Success)
700249259Sdim    return DecodeL5RInstructionFail(Inst, Insn, Address, Decoder);
701249259Sdim
702249259Sdim  DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
703249259Sdim  DecodeGRRegsRegisterClass(Inst, Op4, Address, Decoder);
704249259Sdim  DecodeGRRegsRegisterClass(Inst, Op2, Address, Decoder);
705249259Sdim  DecodeGRRegsRegisterClass(Inst, Op3, Address, Decoder);
706249259Sdim  DecodeGRRegsRegisterClass(Inst, Op5, Address, Decoder);
707249259Sdim  return S;
708249259Sdim}
709249259Sdim
710249259Sdimstatic DecodeStatus
711249259SdimDecodeL4RSrcDstInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
712249259Sdim                           const void *Decoder) {
713249259Sdim  unsigned Op1, Op2, Op3;
714249259Sdim  unsigned Op4 = fieldFromInstruction(Insn, 16, 4);
715249259Sdim  DecodeStatus S =
716249259Sdim    Decode3OpInstruction(fieldFromInstruction(Insn, 0, 16), Op1, Op2, Op3);
717249259Sdim  if (S == MCDisassembler::Success) {
718249259Sdim    DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
719249259Sdim    S = DecodeGRRegsRegisterClass(Inst, Op4, Address, Decoder);
720249259Sdim  }
721249259Sdim  if (S == MCDisassembler::Success) {
722249259Sdim    DecodeGRRegsRegisterClass(Inst, Op4, Address, Decoder);
723249259Sdim    DecodeGRRegsRegisterClass(Inst, Op2, Address, Decoder);
724249259Sdim    DecodeGRRegsRegisterClass(Inst, Op3, Address, Decoder);
725249259Sdim  }
726249259Sdim  return S;
727249259Sdim}
728249259Sdim
729249259Sdimstatic DecodeStatus
730249259SdimDecodeL4RSrcDstSrcDstInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
731249259Sdim                                 const void *Decoder) {
732249259Sdim  unsigned Op1, Op2, Op3;
733249259Sdim  unsigned Op4 = fieldFromInstruction(Insn, 16, 4);
734249259Sdim  DecodeStatus S =
735249259Sdim  Decode3OpInstruction(fieldFromInstruction(Insn, 0, 16), Op1, Op2, Op3);
736249259Sdim  if (S == MCDisassembler::Success) {
737249259Sdim    DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
738249259Sdim    S = DecodeGRRegsRegisterClass(Inst, Op4, Address, Decoder);
739249259Sdim  }
740249259Sdim  if (S == MCDisassembler::Success) {
741249259Sdim    DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
742249259Sdim    DecodeGRRegsRegisterClass(Inst, Op4, Address, Decoder);
743249259Sdim    DecodeGRRegsRegisterClass(Inst, Op2, Address, Decoder);
744249259Sdim    DecodeGRRegsRegisterClass(Inst, Op3, Address, Decoder);
745249259Sdim  }
746249259Sdim  return S;
747249259Sdim}
748249259Sdim
749249259SdimMCDisassembler::DecodeStatus
750249259SdimXCoreDisassembler::getInstruction(MCInst &instr,
751249259Sdim                                  uint64_t &Size,
752249259Sdim                                  const MemoryObject &Region,
753249259Sdim                                  uint64_t Address,
754249259Sdim                                  raw_ostream &vStream,
755249259Sdim                                  raw_ostream &cStream) const {
756249259Sdim  uint16_t insn16;
757249259Sdim
758249259Sdim  if (!readInstruction16(Region, Address, Size, insn16)) {
759249259Sdim    return Fail;
760249259Sdim  }
761249259Sdim
762249259Sdim  // Calling the auto-generated decoder function.
763249259Sdim  DecodeStatus Result = decodeInstruction(DecoderTable16, instr, insn16,
764249259Sdim                                          Address, this, STI);
765249259Sdim  if (Result != Fail) {
766249259Sdim    Size = 2;
767249259Sdim    return Result;
768249259Sdim  }
769249259Sdim
770249259Sdim  uint32_t insn32;
771249259Sdim
772249259Sdim  if (!readInstruction32(Region, Address, Size, insn32)) {
773249259Sdim    return Fail;
774249259Sdim  }
775249259Sdim
776249259Sdim  // Calling the auto-generated decoder function.
777249259Sdim  Result = decodeInstruction(DecoderTable32, instr, insn32, Address, this, STI);
778249259Sdim  if (Result != Fail) {
779249259Sdim    Size = 4;
780249259Sdim    return Result;
781249259Sdim  }
782249259Sdim
783249259Sdim  return Fail;
784249259Sdim}
785249259Sdim
786249259Sdimnamespace llvm {
787249259Sdim  extern Target TheXCoreTarget;
788249259Sdim}
789249259Sdim
790249259Sdimstatic MCDisassembler *createXCoreDisassembler(const Target &T,
791249259Sdim                                               const MCSubtargetInfo &STI) {
792249259Sdim  return new XCoreDisassembler(STI, T.createMCRegInfo(""));
793249259Sdim}
794249259Sdim
795249259Sdimextern "C" void LLVMInitializeXCoreDisassembler() {
796249259Sdim  // Register the disassembler.
797249259Sdim  TargetRegistry::RegisterMCDisassembler(TheXCoreTarget,
798249259Sdim                                         createXCoreDisassembler);
799249259Sdim}
800