xref: /llvm-project/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp (revision d064d3fc2cf8841963151f428988475aab09ff56)
171199af1SAndrei Safronov //===-- XtensaDisassembler.cpp - Disassembler for Xtensa ------------------===//
271199af1SAndrei Safronov //
371199af1SAndrei Safronov //                     The LLVM Compiler Infrastructure
471199af1SAndrei Safronov //
571199af1SAndrei Safronov // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
671199af1SAndrei Safronov // See https://llvm.org/LICENSE.txt for license information.
771199af1SAndrei Safronov // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
871199af1SAndrei Safronov //
971199af1SAndrei Safronov //===----------------------------------------------------------------------===//
1071199af1SAndrei Safronov //
1171199af1SAndrei Safronov // This file implements the XtensaDisassembler class.
1271199af1SAndrei Safronov //
1371199af1SAndrei Safronov //===----------------------------------------------------------------------===//
1471199af1SAndrei Safronov 
1571199af1SAndrei Safronov #include "MCTargetDesc/XtensaMCTargetDesc.h"
1671199af1SAndrei Safronov #include "TargetInfo/XtensaTargetInfo.h"
1771199af1SAndrei Safronov #include "llvm/MC/MCContext.h"
1871199af1SAndrei Safronov #include "llvm/MC/MCDecoderOps.h"
1971199af1SAndrei Safronov #include "llvm/MC/MCDisassembler/MCDisassembler.h"
2071199af1SAndrei Safronov #include "llvm/MC/MCInst.h"
2171199af1SAndrei Safronov #include "llvm/MC/MCRegisterInfo.h"
2271199af1SAndrei Safronov #include "llvm/MC/MCSubtargetInfo.h"
2371199af1SAndrei Safronov #include "llvm/MC/TargetRegistry.h"
2471199af1SAndrei Safronov #include "llvm/Support/Endian.h"
2571199af1SAndrei Safronov 
2671199af1SAndrei Safronov using namespace llvm;
2771199af1SAndrei Safronov 
2871199af1SAndrei Safronov #define DEBUG_TYPE "Xtensa-disassembler"
2971199af1SAndrei Safronov 
3071199af1SAndrei Safronov using DecodeStatus = MCDisassembler::DecodeStatus;
3171199af1SAndrei Safronov 
3271199af1SAndrei Safronov namespace {
3371199af1SAndrei Safronov 
3471199af1SAndrei Safronov class XtensaDisassembler : public MCDisassembler {
3571199af1SAndrei Safronov   bool IsLittleEndian;
3671199af1SAndrei Safronov 
3771199af1SAndrei Safronov public:
3871199af1SAndrei Safronov   XtensaDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, bool isLE)
3971199af1SAndrei Safronov       : MCDisassembler(STI, Ctx), IsLittleEndian(isLE) {}
4071199af1SAndrei Safronov 
41c6967efeSAndrei Safronov   bool hasDensity() const { return STI.hasFeature(Xtensa::FeatureDensity); }
4271199af1SAndrei Safronov 
4371199af1SAndrei Safronov   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
4471199af1SAndrei Safronov                               ArrayRef<uint8_t> Bytes, uint64_t Address,
4571199af1SAndrei Safronov                               raw_ostream &CStream) const override;
4671199af1SAndrei Safronov };
4771199af1SAndrei Safronov } // end anonymous namespace
4871199af1SAndrei Safronov 
4971199af1SAndrei Safronov static MCDisassembler *createXtensaDisassembler(const Target &T,
5071199af1SAndrei Safronov                                                 const MCSubtargetInfo &STI,
5171199af1SAndrei Safronov                                                 MCContext &Ctx) {
5271199af1SAndrei Safronov   return new XtensaDisassembler(STI, Ctx, true);
5371199af1SAndrei Safronov }
5471199af1SAndrei Safronov 
5571199af1SAndrei Safronov extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXtensaDisassembler() {
5671199af1SAndrei Safronov   TargetRegistry::RegisterMCDisassembler(getTheXtensaTarget(),
5771199af1SAndrei Safronov                                          createXtensaDisassembler);
5871199af1SAndrei Safronov }
5971199af1SAndrei Safronov 
6071199af1SAndrei Safronov static const unsigned ARDecoderTable[] = {
6171199af1SAndrei Safronov     Xtensa::A0,  Xtensa::SP,  Xtensa::A2,  Xtensa::A3, Xtensa::A4,  Xtensa::A5,
6271199af1SAndrei Safronov     Xtensa::A6,  Xtensa::A7,  Xtensa::A8,  Xtensa::A9, Xtensa::A10, Xtensa::A11,
6371199af1SAndrei Safronov     Xtensa::A12, Xtensa::A13, Xtensa::A14, Xtensa::A15};
6471199af1SAndrei Safronov 
6571199af1SAndrei Safronov static DecodeStatus DecodeARRegisterClass(MCInst &Inst, uint64_t RegNo,
6671199af1SAndrei Safronov                                           uint64_t Address,
6771199af1SAndrei Safronov                                           const void *Decoder) {
6871199af1SAndrei Safronov   if (RegNo >= std::size(ARDecoderTable))
6971199af1SAndrei Safronov     return MCDisassembler::Fail;
7071199af1SAndrei Safronov 
7171199af1SAndrei Safronov   unsigned Reg = ARDecoderTable[RegNo];
7271199af1SAndrei Safronov   Inst.addOperand(MCOperand::createReg(Reg));
7371199af1SAndrei Safronov   return MCDisassembler::Success;
7471199af1SAndrei Safronov }
7571199af1SAndrei Safronov 
76*d064d3fcSSylvestre Ledru static const unsigned SRDecoderTable[] = {Xtensa::SAR, 3};
7771199af1SAndrei Safronov 
7871199af1SAndrei Safronov static DecodeStatus DecodeSRRegisterClass(MCInst &Inst, uint64_t RegNo,
7971199af1SAndrei Safronov                                           uint64_t Address,
80*d064d3fcSSylvestre Ledru                                           const void *Decoder) {
8171199af1SAndrei Safronov   if (RegNo > 255)
8271199af1SAndrei Safronov     return MCDisassembler::Fail;
8371199af1SAndrei Safronov 
8471199af1SAndrei Safronov   for (unsigned i = 0; i < std::size(SRDecoderTable); i += 2) {
8571199af1SAndrei Safronov     if (SRDecoderTable[i + 1] == RegNo) {
8671199af1SAndrei Safronov       unsigned Reg = SRDecoderTable[i];
8771199af1SAndrei Safronov       Inst.addOperand(MCOperand::createReg(Reg));
8871199af1SAndrei Safronov       return MCDisassembler::Success;
8971199af1SAndrei Safronov     }
9071199af1SAndrei Safronov   }
9171199af1SAndrei Safronov 
9271199af1SAndrei Safronov   return MCDisassembler::Fail;
9371199af1SAndrei Safronov }
9471199af1SAndrei Safronov 
95ff25800dSAndrei Safronov static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch,
96ff25800dSAndrei Safronov                                      uint64_t Address, uint64_t Offset,
97ff25800dSAndrei Safronov                                      uint64_t InstSize, MCInst &MI,
98ff25800dSAndrei Safronov                                      const void *Decoder) {
99ff25800dSAndrei Safronov   const MCDisassembler *Dis = static_cast<const MCDisassembler *>(Decoder);
100c6967efeSAndrei Safronov   return Dis->tryAddingSymbolicOperand(MI, Value, Address, isBranch, Offset,
101c6967efeSAndrei Safronov                                        /*OpSize=*/0, InstSize);
102ff25800dSAndrei Safronov }
103ff25800dSAndrei Safronov 
104ff25800dSAndrei Safronov static DecodeStatus decodeCallOperand(MCInst &Inst, uint64_t Imm,
105ff25800dSAndrei Safronov                                       int64_t Address, const void *Decoder) {
106ff25800dSAndrei Safronov   assert(isUInt<18>(Imm) && "Invalid immediate");
107ff25800dSAndrei Safronov   Inst.addOperand(MCOperand::createImm(SignExtend64<20>(Imm << 2)));
108ff25800dSAndrei Safronov   return MCDisassembler::Success;
109ff25800dSAndrei Safronov }
110ff25800dSAndrei Safronov 
111ff25800dSAndrei Safronov static DecodeStatus decodeJumpOperand(MCInst &Inst, uint64_t Imm,
112ff25800dSAndrei Safronov                                       int64_t Address, const void *Decoder) {
113ff25800dSAndrei Safronov   assert(isUInt<18>(Imm) && "Invalid immediate");
114ff25800dSAndrei Safronov   Inst.addOperand(MCOperand::createImm(SignExtend64<18>(Imm)));
115ff25800dSAndrei Safronov   return MCDisassembler::Success;
116ff25800dSAndrei Safronov }
117ff25800dSAndrei Safronov 
118ff25800dSAndrei Safronov static DecodeStatus decodeBranchOperand(MCInst &Inst, uint64_t Imm,
119ff25800dSAndrei Safronov                                         int64_t Address, const void *Decoder) {
120ff25800dSAndrei Safronov   switch (Inst.getOpcode()) {
121ff25800dSAndrei Safronov   case Xtensa::BEQZ:
122ff25800dSAndrei Safronov   case Xtensa::BGEZ:
123ff25800dSAndrei Safronov   case Xtensa::BLTZ:
124ff25800dSAndrei Safronov   case Xtensa::BNEZ:
125ff25800dSAndrei Safronov     assert(isUInt<12>(Imm) && "Invalid immediate");
126ff25800dSAndrei Safronov     if (!tryAddingSymbolicOperand(SignExtend64<12>(Imm) + 4 + Address, true,
127ff25800dSAndrei Safronov                                   Address, 0, 3, Inst, Decoder))
128ff25800dSAndrei Safronov       Inst.addOperand(MCOperand::createImm(SignExtend64<12>(Imm)));
129ff25800dSAndrei Safronov     break;
130ff25800dSAndrei Safronov   default:
131ff25800dSAndrei Safronov     assert(isUInt<8>(Imm) && "Invalid immediate");
132ff25800dSAndrei Safronov     if (!tryAddingSymbolicOperand(SignExtend64<8>(Imm) + 4 + Address, true,
133ff25800dSAndrei Safronov                                   Address, 0, 3, Inst, Decoder))
134ff25800dSAndrei Safronov       Inst.addOperand(MCOperand::createImm(SignExtend64<8>(Imm)));
135ff25800dSAndrei Safronov   }
136ff25800dSAndrei Safronov   return MCDisassembler::Success;
137ff25800dSAndrei Safronov }
138ff25800dSAndrei Safronov 
139ff25800dSAndrei Safronov static DecodeStatus decodeL32ROperand(MCInst &Inst, uint64_t Imm,
140ff25800dSAndrei Safronov                                       int64_t Address, const void *Decoder) {
141ff25800dSAndrei Safronov 
142ff25800dSAndrei Safronov   assert(isUInt<16>(Imm) && "Invalid immediate");
143ff25800dSAndrei Safronov   Inst.addOperand(MCOperand::createImm(
144ff25800dSAndrei Safronov       SignExtend64<17>((Imm << 2) + 0x40000 + (Address & 0x3))));
145ff25800dSAndrei Safronov   return MCDisassembler::Success;
146ff25800dSAndrei Safronov }
147ff25800dSAndrei Safronov 
14871199af1SAndrei Safronov static DecodeStatus decodeImm8Operand(MCInst &Inst, uint64_t Imm,
14971199af1SAndrei Safronov                                       int64_t Address, const void *Decoder) {
15071199af1SAndrei Safronov   assert(isUInt<8>(Imm) && "Invalid immediate");
15171199af1SAndrei Safronov   Inst.addOperand(MCOperand::createImm(SignExtend64<8>(Imm)));
15271199af1SAndrei Safronov   return MCDisassembler::Success;
15371199af1SAndrei Safronov }
15471199af1SAndrei Safronov 
15571199af1SAndrei Safronov static DecodeStatus decodeImm8_sh8Operand(MCInst &Inst, uint64_t Imm,
15671199af1SAndrei Safronov                                           int64_t Address,
15771199af1SAndrei Safronov                                           const void *Decoder) {
15871199af1SAndrei Safronov   assert(isUInt<8>(Imm) && "Invalid immediate");
15971199af1SAndrei Safronov   Inst.addOperand(MCOperand::createImm(SignExtend64<16>(Imm << 8)));
16071199af1SAndrei Safronov   return MCDisassembler::Success;
16171199af1SAndrei Safronov }
16271199af1SAndrei Safronov 
16371199af1SAndrei Safronov static DecodeStatus decodeImm12Operand(MCInst &Inst, uint64_t Imm,
16471199af1SAndrei Safronov                                        int64_t Address, const void *Decoder) {
16571199af1SAndrei Safronov   assert(isUInt<12>(Imm) && "Invalid immediate");
16671199af1SAndrei Safronov   Inst.addOperand(MCOperand::createImm(SignExtend64<12>(Imm)));
16771199af1SAndrei Safronov   return MCDisassembler::Success;
16871199af1SAndrei Safronov }
16971199af1SAndrei Safronov 
17071199af1SAndrei Safronov static DecodeStatus decodeUimm4Operand(MCInst &Inst, uint64_t Imm,
17171199af1SAndrei Safronov                                        int64_t Address, const void *Decoder) {
17271199af1SAndrei Safronov   assert(isUInt<4>(Imm) && "Invalid immediate");
17371199af1SAndrei Safronov   Inst.addOperand(MCOperand::createImm(Imm));
17471199af1SAndrei Safronov   return MCDisassembler::Success;
17571199af1SAndrei Safronov }
17671199af1SAndrei Safronov 
17771199af1SAndrei Safronov static DecodeStatus decodeUimm5Operand(MCInst &Inst, uint64_t Imm,
17871199af1SAndrei Safronov                                        int64_t Address, const void *Decoder) {
17971199af1SAndrei Safronov   assert(isUInt<5>(Imm) && "Invalid immediate");
18071199af1SAndrei Safronov   Inst.addOperand(MCOperand::createImm(Imm));
18171199af1SAndrei Safronov   return MCDisassembler::Success;
18271199af1SAndrei Safronov }
18371199af1SAndrei Safronov 
18471199af1SAndrei Safronov static DecodeStatus decodeImm1_16Operand(MCInst &Inst, uint64_t Imm,
18571199af1SAndrei Safronov                                          int64_t Address, const void *Decoder) {
18671199af1SAndrei Safronov   assert(isUInt<4>(Imm) && "Invalid immediate");
18771199af1SAndrei Safronov   Inst.addOperand(MCOperand::createImm(Imm + 1));
18871199af1SAndrei Safronov   return MCDisassembler::Success;
18971199af1SAndrei Safronov }
19071199af1SAndrei Safronov 
191c6967efeSAndrei Safronov static DecodeStatus decodeImm1n_15Operand(MCInst &Inst, uint64_t Imm,
192c6967efeSAndrei Safronov                                           int64_t Address,
193c6967efeSAndrei Safronov                                           const void *Decoder) {
194c6967efeSAndrei Safronov   assert(isUInt<4>(Imm) && "Invalid immediate");
195c6967efeSAndrei Safronov   if (!Imm)
196c6967efeSAndrei Safronov     Inst.addOperand(MCOperand::createImm(-1));
197c6967efeSAndrei Safronov   else
198c6967efeSAndrei Safronov     Inst.addOperand(MCOperand::createImm(Imm));
199c6967efeSAndrei Safronov   return MCDisassembler::Success;
200c6967efeSAndrei Safronov }
201c6967efeSAndrei Safronov 
202c6967efeSAndrei Safronov static DecodeStatus decodeImm32n_95Operand(MCInst &Inst, uint64_t Imm,
203c6967efeSAndrei Safronov                                            int64_t Address,
204c6967efeSAndrei Safronov                                            const void *Decoder) {
205c6967efeSAndrei Safronov   assert(isUInt<7>(Imm) && "Invalid immediate");
206c6967efeSAndrei Safronov   if ((Imm & 0x60) == 0x60)
207c6967efeSAndrei Safronov     Inst.addOperand(MCOperand::createImm((~0x1f) | Imm));
208c6967efeSAndrei Safronov   else
209c6967efeSAndrei Safronov     Inst.addOperand(MCOperand::createImm(Imm));
210c6967efeSAndrei Safronov   return MCDisassembler::Success;
211c6967efeSAndrei Safronov }
212c6967efeSAndrei Safronov 
21371199af1SAndrei Safronov static DecodeStatus decodeShimm1_31Operand(MCInst &Inst, uint64_t Imm,
21471199af1SAndrei Safronov                                            int64_t Address,
21571199af1SAndrei Safronov                                            const void *Decoder) {
21671199af1SAndrei Safronov   assert(isUInt<5>(Imm) && "Invalid immediate");
21771199af1SAndrei Safronov   Inst.addOperand(MCOperand::createImm(32 - Imm));
21871199af1SAndrei Safronov   return MCDisassembler::Success;
21971199af1SAndrei Safronov }
22071199af1SAndrei Safronov 
221ff25800dSAndrei Safronov static int64_t TableB4const[16] = {-1, 1,  2,  3,  4,  5,  6,   7,
222ff25800dSAndrei Safronov                                    8,  10, 12, 16, 32, 64, 128, 256};
223ff25800dSAndrei Safronov static DecodeStatus decodeB4constOperand(MCInst &Inst, uint64_t Imm,
224ff25800dSAndrei Safronov                                          int64_t Address, const void *Decoder) {
225ff25800dSAndrei Safronov   assert(isUInt<4>(Imm) && "Invalid immediate");
226ff25800dSAndrei Safronov 
227ff25800dSAndrei Safronov   Inst.addOperand(MCOperand::createImm(TableB4const[Imm]));
228ff25800dSAndrei Safronov   return MCDisassembler::Success;
229ff25800dSAndrei Safronov }
230ff25800dSAndrei Safronov 
231ff25800dSAndrei Safronov static int64_t TableB4constu[16] = {32768, 65536, 2,  3,  4,  5,  6,   7,
232ff25800dSAndrei Safronov                                     8,     10,    12, 16, 32, 64, 128, 256};
233ff25800dSAndrei Safronov static DecodeStatus decodeB4constuOperand(MCInst &Inst, uint64_t Imm,
234ff25800dSAndrei Safronov                                           int64_t Address,
235ff25800dSAndrei Safronov                                           const void *Decoder) {
236ff25800dSAndrei Safronov   assert(isUInt<4>(Imm) && "Invalid immediate");
237ff25800dSAndrei Safronov 
238ff25800dSAndrei Safronov   Inst.addOperand(MCOperand::createImm(TableB4constu[Imm]));
239ff25800dSAndrei Safronov   return MCDisassembler::Success;
240ff25800dSAndrei Safronov }
241ff25800dSAndrei Safronov 
24271199af1SAndrei Safronov static DecodeStatus decodeMem8Operand(MCInst &Inst, uint64_t Imm,
24371199af1SAndrei Safronov                                       int64_t Address, const void *Decoder) {
24471199af1SAndrei Safronov   assert(isUInt<12>(Imm) && "Invalid immediate");
24571199af1SAndrei Safronov   DecodeARRegisterClass(Inst, Imm & 0xf, Address, Decoder);
24671199af1SAndrei Safronov   Inst.addOperand(MCOperand::createImm((Imm >> 4) & 0xff));
24771199af1SAndrei Safronov   return MCDisassembler::Success;
24871199af1SAndrei Safronov }
24971199af1SAndrei Safronov 
25071199af1SAndrei Safronov static DecodeStatus decodeMem16Operand(MCInst &Inst, uint64_t Imm,
25171199af1SAndrei Safronov                                        int64_t Address, const void *Decoder) {
25271199af1SAndrei Safronov   assert(isUInt<12>(Imm) && "Invalid immediate");
25371199af1SAndrei Safronov   DecodeARRegisterClass(Inst, Imm & 0xf, Address, Decoder);
25471199af1SAndrei Safronov   Inst.addOperand(MCOperand::createImm((Imm >> 3) & 0x1fe));
25571199af1SAndrei Safronov   return MCDisassembler::Success;
25671199af1SAndrei Safronov }
25771199af1SAndrei Safronov 
25871199af1SAndrei Safronov static DecodeStatus decodeMem32Operand(MCInst &Inst, uint64_t Imm,
25971199af1SAndrei Safronov                                        int64_t Address, const void *Decoder) {
26071199af1SAndrei Safronov   assert(isUInt<12>(Imm) && "Invalid immediate");
26171199af1SAndrei Safronov   DecodeARRegisterClass(Inst, Imm & 0xf, Address, Decoder);
26271199af1SAndrei Safronov   Inst.addOperand(MCOperand::createImm((Imm >> 2) & 0x3fc));
26371199af1SAndrei Safronov   return MCDisassembler::Success;
26471199af1SAndrei Safronov }
26571199af1SAndrei Safronov 
266c6967efeSAndrei Safronov static DecodeStatus decodeMem32nOperand(MCInst &Inst, uint64_t Imm,
267c6967efeSAndrei Safronov                                         int64_t Address, const void *Decoder) {
268c6967efeSAndrei Safronov   assert(isUInt<8>(Imm) && "Invalid immediate");
269c6967efeSAndrei Safronov   DecodeARRegisterClass(Inst, Imm & 0xf, Address, Decoder);
270c6967efeSAndrei Safronov   Inst.addOperand(MCOperand::createImm((Imm >> 2) & 0x3c));
271c6967efeSAndrei Safronov   return MCDisassembler::Success;
272c6967efeSAndrei Safronov }
273c6967efeSAndrei Safronov 
274c6967efeSAndrei Safronov /// Read two bytes from the ArrayRef and return 16 bit data sorted
275c6967efeSAndrei Safronov /// according to the given endianness.
276c6967efeSAndrei Safronov static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
277c6967efeSAndrei Safronov                                       uint64_t &Size, uint64_t &Insn,
278c6967efeSAndrei Safronov                                       bool IsLittleEndian) {
279c6967efeSAndrei Safronov   // We want to read exactly 2 Bytes of data.
280c6967efeSAndrei Safronov   if (Bytes.size() < 2) {
281c6967efeSAndrei Safronov     Size = 0;
282c6967efeSAndrei Safronov     return MCDisassembler::Fail;
283c6967efeSAndrei Safronov   }
284c6967efeSAndrei Safronov 
285c6967efeSAndrei Safronov   if (!IsLittleEndian) {
286c6967efeSAndrei Safronov     report_fatal_error("Big-endian mode currently is not supported!");
287c6967efeSAndrei Safronov   } else {
288c6967efeSAndrei Safronov     Insn = (Bytes[1] << 8) | Bytes[0];
289c6967efeSAndrei Safronov   }
290c6967efeSAndrei Safronov 
291c6967efeSAndrei Safronov   return MCDisassembler::Success;
292c6967efeSAndrei Safronov }
293c6967efeSAndrei Safronov 
29471199af1SAndrei Safronov /// Read three bytes from the ArrayRef and return 24 bit data
29571199af1SAndrei Safronov static DecodeStatus readInstruction24(ArrayRef<uint8_t> Bytes, uint64_t Address,
296c6967efeSAndrei Safronov                                       uint64_t &Size, uint64_t &Insn,
29771199af1SAndrei Safronov                                       bool IsLittleEndian) {
29871199af1SAndrei Safronov   // We want to read exactly 3 Bytes of data.
29971199af1SAndrei Safronov   if (Bytes.size() < 3) {
30071199af1SAndrei Safronov     Size = 0;
30171199af1SAndrei Safronov     return MCDisassembler::Fail;
30271199af1SAndrei Safronov   }
30371199af1SAndrei Safronov 
30471199af1SAndrei Safronov   if (!IsLittleEndian) {
30571199af1SAndrei Safronov     report_fatal_error("Big-endian mode currently is not supported!");
30671199af1SAndrei Safronov   } else {
30771199af1SAndrei Safronov     Insn = (Bytes[2] << 16) | (Bytes[1] << 8) | (Bytes[0] << 0);
30871199af1SAndrei Safronov   }
30971199af1SAndrei Safronov 
31071199af1SAndrei Safronov   return MCDisassembler::Success;
31171199af1SAndrei Safronov }
31271199af1SAndrei Safronov 
31371199af1SAndrei Safronov #include "XtensaGenDisassemblerTables.inc"
31471199af1SAndrei Safronov 
31571199af1SAndrei Safronov DecodeStatus XtensaDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
31671199af1SAndrei Safronov                                                 ArrayRef<uint8_t> Bytes,
31771199af1SAndrei Safronov                                                 uint64_t Address,
31871199af1SAndrei Safronov                                                 raw_ostream &CS) const {
319c6967efeSAndrei Safronov   uint64_t Insn;
32071199af1SAndrei Safronov   DecodeStatus Result;
32171199af1SAndrei Safronov 
322c6967efeSAndrei Safronov   // Parse 16-bit instructions
323c6967efeSAndrei Safronov   if (hasDensity()) {
324c6967efeSAndrei Safronov     Result = readInstruction16(Bytes, Address, Size, Insn, IsLittleEndian);
325c6967efeSAndrei Safronov     if (Result == MCDisassembler::Fail)
326c6967efeSAndrei Safronov       return MCDisassembler::Fail;
327c6967efeSAndrei Safronov     LLVM_DEBUG(dbgs() << "Trying Xtensa 16-bit instruction table :\n");
328c6967efeSAndrei Safronov     Result = decodeInstruction(DecoderTable16, MI, Insn, Address, this, STI);
329c6967efeSAndrei Safronov     if (Result != MCDisassembler::Fail) {
330c6967efeSAndrei Safronov       Size = 2;
331c6967efeSAndrei Safronov       return Result;
332c6967efeSAndrei Safronov     }
333c6967efeSAndrei Safronov   }
334c6967efeSAndrei Safronov 
335c6967efeSAndrei Safronov   // Parse Core 24-bit instructions
33671199af1SAndrei Safronov   Result = readInstruction24(Bytes, Address, Size, Insn, IsLittleEndian);
33771199af1SAndrei Safronov   if (Result == MCDisassembler::Fail)
33871199af1SAndrei Safronov     return MCDisassembler::Fail;
33971199af1SAndrei Safronov   LLVM_DEBUG(dbgs() << "Trying Xtensa 24-bit instruction table :\n");
34071199af1SAndrei Safronov   Result = decodeInstruction(DecoderTable24, MI, Insn, Address, this, STI);
341c6967efeSAndrei Safronov   if (Result != MCDisassembler::Fail) {
342c6967efeSAndrei Safronov     Size = 3;
343c6967efeSAndrei Safronov     return Result;
344c6967efeSAndrei Safronov   }
34571199af1SAndrei Safronov   return Result;
34671199af1SAndrei Safronov }
347