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