1 //===-- XtensaDisassembler.cpp - Disassembler for Xtensa ------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
6 // See https://llvm.org/LICENSE.txt for license information.
7 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 //
9 //===----------------------------------------------------------------------===//
10 //
11 // This file implements the XtensaDisassembler class.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "MCTargetDesc/XtensaMCTargetDesc.h"
16 #include "TargetInfo/XtensaTargetInfo.h"
17 #include "llvm/MC/MCContext.h"
18 #include "llvm/MC/MCDecoderOps.h"
19 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
20 #include "llvm/MC/MCInst.h"
21 #include "llvm/MC/MCRegisterInfo.h"
22 #include "llvm/MC/MCSubtargetInfo.h"
23 #include "llvm/MC/TargetRegistry.h"
24 #include "llvm/Support/Endian.h"
25
26 using namespace llvm;
27
28 #define DEBUG_TYPE "Xtensa-disassembler"
29
30 using DecodeStatus = MCDisassembler::DecodeStatus;
31
32 namespace {
33
34 class XtensaDisassembler : public MCDisassembler {
35 bool IsLittleEndian;
36
37 public:
XtensaDisassembler(const MCSubtargetInfo & STI,MCContext & Ctx,bool isLE)38 XtensaDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, bool isLE)
39 : MCDisassembler(STI, Ctx), IsLittleEndian(isLE) {}
40
hasDensity() const41 bool hasDensity() const { return STI.hasFeature(Xtensa::FeatureDensity); }
42
43 DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
44 ArrayRef<uint8_t> Bytes, uint64_t Address,
45 raw_ostream &CStream) const override;
46 };
47 } // end anonymous namespace
48
createXtensaDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)49 static MCDisassembler *createXtensaDisassembler(const Target &T,
50 const MCSubtargetInfo &STI,
51 MCContext &Ctx) {
52 return new XtensaDisassembler(STI, Ctx, true);
53 }
54
LLVMInitializeXtensaDisassembler()55 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXtensaDisassembler() {
56 TargetRegistry::RegisterMCDisassembler(getTheXtensaTarget(),
57 createXtensaDisassembler);
58 }
59
60 const MCPhysReg ARDecoderTable[] = {
61 Xtensa::A0, Xtensa::SP, Xtensa::A2, Xtensa::A3, Xtensa::A4, Xtensa::A5,
62 Xtensa::A6, Xtensa::A7, Xtensa::A8, Xtensa::A9, Xtensa::A10, Xtensa::A11,
63 Xtensa::A12, Xtensa::A13, Xtensa::A14, Xtensa::A15};
64
DecodeARRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)65 static DecodeStatus DecodeARRegisterClass(MCInst &Inst, uint64_t RegNo,
66 uint64_t Address,
67 const void *Decoder) {
68 if (RegNo >= std::size(ARDecoderTable))
69 return MCDisassembler::Fail;
70
71 MCPhysReg Reg = ARDecoderTable[RegNo];
72 Inst.addOperand(MCOperand::createReg(Reg));
73 return MCDisassembler::Success;
74 }
75
DecodeMRRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)76 static DecodeStatus DecodeMRRegisterClass(MCInst &Inst, uint64_t RegNo,
77 uint64_t Address,
78 const void *Decoder) {
79 if (RegNo > 3)
80 return MCDisassembler::Fail;
81
82 MCPhysReg Reg = Xtensa::M0 + RegNo;
83 Inst.addOperand(MCOperand::createReg(Reg));
84 return MCDisassembler::Success;
85 }
86
DecodeMR01RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)87 static DecodeStatus DecodeMR01RegisterClass(MCInst &Inst, uint64_t RegNo,
88 uint64_t Address,
89 const void *Decoder) {
90 if (RegNo > 1)
91 return MCDisassembler::Fail;
92
93 MCPhysReg Reg = Xtensa::M0 + RegNo;
94 Inst.addOperand(MCOperand::createReg(Reg));
95 return MCDisassembler::Success;
96 }
97
DecodeMR23RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)98 static DecodeStatus DecodeMR23RegisterClass(MCInst &Inst, uint64_t RegNo,
99 uint64_t Address,
100 const void *Decoder) {
101 if (RegNo > 1)
102 return MCDisassembler::Fail;
103
104 MCPhysReg Reg = Xtensa::M2 + RegNo;
105 Inst.addOperand(MCOperand::createReg(Reg));
106 return MCDisassembler::Success;
107 }
108
DecodeFPRRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)109 static DecodeStatus DecodeFPRRegisterClass(MCInst &Inst, uint64_t RegNo,
110 uint64_t Address,
111 const void *Decoder) {
112 if (RegNo > 15)
113 return MCDisassembler::Fail;
114
115 MCPhysReg Reg = Xtensa::F0 + RegNo;
116 Inst.addOperand(MCOperand::createReg(Reg));
117 return MCDisassembler::Success;
118 }
119
DecodeURRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)120 static DecodeStatus DecodeURRegisterClass(MCInst &Inst, uint64_t RegNo,
121 uint64_t Address,
122 const MCDisassembler *Decoder) {
123 if (RegNo > 255)
124 return MCDisassembler::Fail;
125
126 Xtensa::RegisterAccessType RAType = Inst.getOpcode() == Xtensa::WUR
127 ? Xtensa::REGISTER_WRITE
128 : Xtensa::REGISTER_READ;
129
130 const XtensaDisassembler *Dis =
131 static_cast<const XtensaDisassembler *>(Decoder);
132 const MCRegisterInfo *MRI = Dis->getContext().getRegisterInfo();
133 MCPhysReg Reg = Xtensa::getUserRegister(RegNo, *MRI);
134 if (!Xtensa::checkRegister(Reg, Decoder->getSubtargetInfo().getFeatureBits(),
135 RAType))
136 return MCDisassembler::Fail;
137
138 Inst.addOperand(MCOperand::createReg(Reg));
139 return MCDisassembler::Success;
140 }
141
142 struct DecodeRegister {
143 MCPhysReg Reg;
144 uint32_t RegNo;
145 };
146
147 const DecodeRegister SRDecoderTable[] = {
148 {Xtensa::LBEG, 0}, {Xtensa::LEND, 1},
149 {Xtensa::LCOUNT, 2}, {Xtensa::SAR, 3},
150 {Xtensa::BREG, 4}, {Xtensa::LITBASE, 5},
151 {Xtensa::ACCLO, 16}, {Xtensa::ACCHI, 17},
152 {Xtensa::M0, 32}, {Xtensa::M1, 33},
153 {Xtensa::M2, 34}, {Xtensa::M3, 35},
154 {Xtensa::WINDOWBASE, 72}, {Xtensa::WINDOWSTART, 73},
155 {Xtensa::IBREAKENABLE, 96}, {Xtensa::MEMCTL, 97},
156 {Xtensa::DDR, 104}, {Xtensa::IBREAKA0, 128},
157 {Xtensa::IBREAKA1, 129}, {Xtensa::DBREAKA0, 144},
158 {Xtensa::DBREAKA1, 145}, {Xtensa::DBREAKC0, 160},
159 {Xtensa::DBREAKC1, 161}, {Xtensa::CONFIGID0, 176},
160 {Xtensa::EPC1, 177}, {Xtensa::EPC2, 178},
161 {Xtensa::EPC3, 179}, {Xtensa::EPC4, 180},
162 {Xtensa::EPC5, 181}, {Xtensa::EPC6, 182},
163 {Xtensa::EPC7, 183}, {Xtensa::DEPC, 192},
164 {Xtensa::EPS2, 194}, {Xtensa::EPS3, 195},
165 {Xtensa::EPS4, 196}, {Xtensa::EPS5, 197},
166 {Xtensa::EPS6, 198}, {Xtensa::EPS7, 199},
167 {Xtensa::CONFIGID1, 208}, {Xtensa::EXCSAVE1, 209},
168 {Xtensa::EXCSAVE2, 210}, {Xtensa::EXCSAVE3, 211},
169 {Xtensa::EXCSAVE4, 212}, {Xtensa::EXCSAVE5, 213},
170 {Xtensa::EXCSAVE6, 214}, {Xtensa::EXCSAVE7, 215},
171 {Xtensa::CPENABLE, 224}, {Xtensa::INTERRUPT, 226},
172 {Xtensa::INTCLEAR, 227}, {Xtensa::INTENABLE, 228},
173 {Xtensa::PS, 230}, {Xtensa::VECBASE, 231},
174 {Xtensa::EXCCAUSE, 232}, {Xtensa::DEBUGCAUSE, 233},
175 {Xtensa::CCOUNT, 234}, {Xtensa::PRID, 235},
176 {Xtensa::ICOUNT, 236}, {Xtensa::ICOUNTLEVEL, 237},
177 {Xtensa::EXCVADDR, 238}, {Xtensa::CCOMPARE0, 240},
178 {Xtensa::CCOMPARE1, 241}, {Xtensa::CCOMPARE2, 242},
179 {Xtensa::MISC0, 244}, {Xtensa::MISC1, 245},
180 {Xtensa::MISC2, 246}, {Xtensa::MISC3, 247}};
181
DecodeSRRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)182 static DecodeStatus DecodeSRRegisterClass(MCInst &Inst, uint64_t RegNo,
183 uint64_t Address,
184 const MCDisassembler *Decoder) {
185 if (RegNo > 255)
186 return MCDisassembler::Fail;
187
188 Xtensa::RegisterAccessType RAType =
189 Inst.getOpcode() == Xtensa::WSR
190 ? Xtensa::REGISTER_WRITE
191 : (Inst.getOpcode() == Xtensa::RSR ? Xtensa::REGISTER_READ
192 : Xtensa::REGISTER_EXCHANGE);
193
194 for (unsigned i = 0; i < std::size(SRDecoderTable); i++) {
195 if (SRDecoderTable[i].RegNo == RegNo) {
196 MCPhysReg Reg = SRDecoderTable[i].Reg;
197
198 // Handle special case. The INTERRUPT/INTSET registers use the same
199 // encoding, but INTERRUPT used for read and INTSET for write.
200 if (Reg == Xtensa::INTERRUPT && RAType == Xtensa::REGISTER_WRITE) {
201 Reg = Xtensa::INTSET;
202 }
203
204 if (!Xtensa::checkRegister(
205 Reg, Decoder->getSubtargetInfo().getFeatureBits(), RAType))
206 return MCDisassembler::Fail;
207
208 Inst.addOperand(MCOperand::createReg(Reg));
209 return MCDisassembler::Success;
210 }
211 }
212
213 return MCDisassembler::Fail;
214 }
215
DecodeBRRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)216 static DecodeStatus DecodeBRRegisterClass(MCInst &Inst, uint64_t RegNo,
217 uint64_t Address,
218 const void *Decoder) {
219 if (RegNo > 15)
220 return MCDisassembler::Fail;
221
222 MCPhysReg Reg = Xtensa::B0 + RegNo;
223 Inst.addOperand(MCOperand::createReg(Reg));
224 return MCDisassembler::Success;
225 }
226
tryAddingSymbolicOperand(int64_t Value,bool isBranch,uint64_t Address,uint64_t Offset,uint64_t InstSize,MCInst & MI,const void * Decoder)227 static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch,
228 uint64_t Address, uint64_t Offset,
229 uint64_t InstSize, MCInst &MI,
230 const void *Decoder) {
231 const MCDisassembler *Dis = static_cast<const MCDisassembler *>(Decoder);
232 return Dis->tryAddingSymbolicOperand(MI, Value, Address, isBranch, Offset,
233 /*OpSize=*/0, InstSize);
234 }
235
decodeCallOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)236 static DecodeStatus decodeCallOperand(MCInst &Inst, uint64_t Imm,
237 int64_t Address, const void *Decoder) {
238 assert(isUInt<18>(Imm) && "Invalid immediate");
239 Inst.addOperand(
240 MCOperand::createImm(SignExtend64<20>(Imm << 2) + (Address & 0x3)));
241 return MCDisassembler::Success;
242 }
243
decodeJumpOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)244 static DecodeStatus decodeJumpOperand(MCInst &Inst, uint64_t Imm,
245 int64_t Address, const void *Decoder) {
246 assert(isUInt<18>(Imm) && "Invalid immediate");
247 Inst.addOperand(MCOperand::createImm(SignExtend64<18>(Imm)));
248 return MCDisassembler::Success;
249 }
250
decodeBranchOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)251 static DecodeStatus decodeBranchOperand(MCInst &Inst, uint64_t Imm,
252 int64_t Address, const void *Decoder) {
253 switch (Inst.getOpcode()) {
254 case Xtensa::BEQZ:
255 case Xtensa::BGEZ:
256 case Xtensa::BLTZ:
257 case Xtensa::BNEZ:
258 assert(isUInt<12>(Imm) && "Invalid immediate");
259 if (!tryAddingSymbolicOperand(SignExtend64<12>(Imm) + 4 + Address, true,
260 Address, 0, 3, Inst, Decoder))
261 Inst.addOperand(MCOperand::createImm(SignExtend64<12>(Imm)));
262 break;
263 default:
264 assert(isUInt<8>(Imm) && "Invalid immediate");
265 if (!tryAddingSymbolicOperand(SignExtend64<8>(Imm) + 4 + Address, true,
266 Address, 0, 3, Inst, Decoder))
267 Inst.addOperand(MCOperand::createImm(SignExtend64<8>(Imm)));
268 }
269 return MCDisassembler::Success;
270 }
271
decodeLoopOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)272 static DecodeStatus decodeLoopOperand(MCInst &Inst, uint64_t Imm,
273 int64_t Address, const void *Decoder) {
274
275 assert(isUInt<8>(Imm) && "Invalid immediate");
276 if (!tryAddingSymbolicOperand(Imm + 4 + Address, true, Address, 0, 3, Inst,
277 Decoder))
278 Inst.addOperand(MCOperand::createImm(Imm));
279 return MCDisassembler::Success;
280 }
281
decodeL32ROperand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)282 static DecodeStatus decodeL32ROperand(MCInst &Inst, uint64_t Imm,
283 int64_t Address, const void *Decoder) {
284
285 assert(isUInt<16>(Imm) && "Invalid immediate");
286 Inst.addOperand(MCOperand::createImm(
287 SignExtend64<17>((Imm << 2) + 0x40000 + (Address & 0x3))));
288 return MCDisassembler::Success;
289 }
290
decodeImm8Operand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)291 static DecodeStatus decodeImm8Operand(MCInst &Inst, uint64_t Imm,
292 int64_t Address, const void *Decoder) {
293 assert(isUInt<8>(Imm) && "Invalid immediate");
294 Inst.addOperand(MCOperand::createImm(SignExtend64<8>(Imm)));
295 return MCDisassembler::Success;
296 }
297
decodeImm8_sh8Operand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)298 static DecodeStatus decodeImm8_sh8Operand(MCInst &Inst, uint64_t Imm,
299 int64_t Address,
300 const void *Decoder) {
301 assert(isUInt<8>(Imm) && "Invalid immediate");
302 Inst.addOperand(MCOperand::createImm(SignExtend64<16>(Imm << 8)));
303 return MCDisassembler::Success;
304 }
305
decodeImm12Operand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)306 static DecodeStatus decodeImm12Operand(MCInst &Inst, uint64_t Imm,
307 int64_t Address, const void *Decoder) {
308 assert(isUInt<12>(Imm) && "Invalid immediate");
309 Inst.addOperand(MCOperand::createImm(SignExtend64<12>(Imm)));
310 return MCDisassembler::Success;
311 }
312
decodeUimm4Operand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)313 static DecodeStatus decodeUimm4Operand(MCInst &Inst, uint64_t Imm,
314 int64_t Address, const void *Decoder) {
315 assert(isUInt<4>(Imm) && "Invalid immediate");
316 Inst.addOperand(MCOperand::createImm(Imm));
317 return MCDisassembler::Success;
318 }
319
decodeUimm5Operand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)320 static DecodeStatus decodeUimm5Operand(MCInst &Inst, uint64_t Imm,
321 int64_t Address, const void *Decoder) {
322 assert(isUInt<5>(Imm) && "Invalid immediate");
323 Inst.addOperand(MCOperand::createImm(Imm));
324 return MCDisassembler::Success;
325 }
326
decodeImm1_16Operand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)327 static DecodeStatus decodeImm1_16Operand(MCInst &Inst, uint64_t Imm,
328 int64_t Address, const void *Decoder) {
329 assert(isUInt<4>(Imm) && "Invalid immediate");
330 Inst.addOperand(MCOperand::createImm(Imm + 1));
331 return MCDisassembler::Success;
332 }
333
decodeImm1n_15Operand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)334 static DecodeStatus decodeImm1n_15Operand(MCInst &Inst, uint64_t Imm,
335 int64_t Address,
336 const void *Decoder) {
337 assert(isUInt<4>(Imm) && "Invalid immediate");
338 if (!Imm)
339 Inst.addOperand(MCOperand::createImm(-1));
340 else
341 Inst.addOperand(MCOperand::createImm(Imm));
342 return MCDisassembler::Success;
343 }
344
decodeImm32n_95Operand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)345 static DecodeStatus decodeImm32n_95Operand(MCInst &Inst, uint64_t Imm,
346 int64_t Address,
347 const void *Decoder) {
348 assert(isUInt<7>(Imm) && "Invalid immediate");
349 if ((Imm & 0x60) == 0x60)
350 Inst.addOperand(MCOperand::createImm((~0x1f) | Imm));
351 else
352 Inst.addOperand(MCOperand::createImm(Imm));
353 return MCDisassembler::Success;
354 }
355
decodeImm8n_7Operand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)356 static DecodeStatus decodeImm8n_7Operand(MCInst &Inst, uint64_t Imm,
357 int64_t Address, const void *Decoder) {
358 assert(isUInt<4>(Imm) && "Invalid immediate");
359 Inst.addOperand(MCOperand::createImm(Imm > 7 ? Imm - 16 : Imm));
360 return MCDisassembler::Success;
361 }
362
decodeImm64n_4nOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)363 static DecodeStatus decodeImm64n_4nOperand(MCInst &Inst, uint64_t Imm,
364 int64_t Address,
365 const void *Decoder) {
366 assert(isUInt<6>(Imm) && ((Imm & 0x3) == 0) && "Invalid immediate");
367 Inst.addOperand(MCOperand::createImm((~0x3f) | (Imm)));
368 return MCDisassembler::Success;
369 }
370
decodeEntry_Imm12OpValue(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)371 static DecodeStatus decodeEntry_Imm12OpValue(MCInst &Inst, uint64_t Imm,
372 int64_t Address,
373 const void *Decoder) {
374 assert(isUInt<15>(Imm) && ((Imm & 0x7) == 0) && "Invalid immediate");
375 Inst.addOperand(MCOperand::createImm(Imm));
376 return MCDisassembler::Success;
377 }
378
decodeShimm1_31Operand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)379 static DecodeStatus decodeShimm1_31Operand(MCInst &Inst, uint64_t Imm,
380 int64_t Address,
381 const void *Decoder) {
382 assert(isUInt<5>(Imm) && "Invalid immediate");
383 Inst.addOperand(MCOperand::createImm(32 - Imm));
384 return MCDisassembler::Success;
385 }
386
387 static int64_t TableB4const[16] = {-1, 1, 2, 3, 4, 5, 6, 7,
388 8, 10, 12, 16, 32, 64, 128, 256};
decodeB4constOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)389 static DecodeStatus decodeB4constOperand(MCInst &Inst, uint64_t Imm,
390 int64_t Address, const void *Decoder) {
391 assert(isUInt<4>(Imm) && "Invalid immediate");
392
393 Inst.addOperand(MCOperand::createImm(TableB4const[Imm]));
394 return MCDisassembler::Success;
395 }
396
397 static int64_t TableB4constu[16] = {32768, 65536, 2, 3, 4, 5, 6, 7,
398 8, 10, 12, 16, 32, 64, 128, 256};
decodeB4constuOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)399 static DecodeStatus decodeB4constuOperand(MCInst &Inst, uint64_t Imm,
400 int64_t Address,
401 const void *Decoder) {
402 assert(isUInt<4>(Imm) && "Invalid immediate");
403
404 Inst.addOperand(MCOperand::createImm(TableB4constu[Imm]));
405 return MCDisassembler::Success;
406 }
407
decodeImm7_22Operand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)408 static DecodeStatus decodeImm7_22Operand(MCInst &Inst, uint64_t Imm,
409 int64_t Address, const void *Decoder) {
410 assert(isUInt<4>(Imm) && "Invalid immediate");
411 Inst.addOperand(MCOperand::createImm(Imm + 7));
412 return MCDisassembler::Success;
413 }
414
decodeMem8Operand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)415 static DecodeStatus decodeMem8Operand(MCInst &Inst, uint64_t Imm,
416 int64_t Address, const void *Decoder) {
417 assert(isUInt<12>(Imm) && "Invalid immediate");
418 DecodeARRegisterClass(Inst, Imm & 0xf, Address, Decoder);
419 Inst.addOperand(MCOperand::createImm((Imm >> 4) & 0xff));
420 return MCDisassembler::Success;
421 }
422
decodeMem16Operand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)423 static DecodeStatus decodeMem16Operand(MCInst &Inst, uint64_t Imm,
424 int64_t Address, const void *Decoder) {
425 assert(isUInt<12>(Imm) && "Invalid immediate");
426 DecodeARRegisterClass(Inst, Imm & 0xf, Address, Decoder);
427 Inst.addOperand(MCOperand::createImm((Imm >> 3) & 0x1fe));
428 return MCDisassembler::Success;
429 }
430
decodeMem32Operand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)431 static DecodeStatus decodeMem32Operand(MCInst &Inst, uint64_t Imm,
432 int64_t Address, const void *Decoder) {
433 assert(isUInt<12>(Imm) && "Invalid immediate");
434 DecodeARRegisterClass(Inst, Imm & 0xf, Address, Decoder);
435 Inst.addOperand(MCOperand::createImm((Imm >> 2) & 0x3fc));
436 return MCDisassembler::Success;
437 }
438
decodeMem32nOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)439 static DecodeStatus decodeMem32nOperand(MCInst &Inst, uint64_t Imm,
440 int64_t Address, const void *Decoder) {
441 assert(isUInt<8>(Imm) && "Invalid immediate");
442 DecodeARRegisterClass(Inst, Imm & 0xf, Address, Decoder);
443 Inst.addOperand(MCOperand::createImm((Imm >> 2) & 0x3c));
444 return MCDisassembler::Success;
445 }
446
447 /// Read two bytes from the ArrayRef and return 16 bit data sorted
448 /// according to the given endianness.
readInstruction16(ArrayRef<uint8_t> Bytes,uint64_t Address,uint64_t & Size,uint64_t & Insn,bool IsLittleEndian)449 static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
450 uint64_t &Size, uint64_t &Insn,
451 bool IsLittleEndian) {
452 // We want to read exactly 2 Bytes of data.
453 if (Bytes.size() < 2) {
454 Size = 0;
455 return MCDisassembler::Fail;
456 }
457
458 if (!IsLittleEndian) {
459 report_fatal_error("Big-endian mode currently is not supported!");
460 } else {
461 Insn = (Bytes[1] << 8) | Bytes[0];
462 }
463
464 return MCDisassembler::Success;
465 }
466
467 /// Read three bytes from the ArrayRef and return 24 bit data
readInstruction24(ArrayRef<uint8_t> Bytes,uint64_t Address,uint64_t & Size,uint64_t & Insn,bool IsLittleEndian)468 static DecodeStatus readInstruction24(ArrayRef<uint8_t> Bytes, uint64_t Address,
469 uint64_t &Size, uint64_t &Insn,
470 bool IsLittleEndian) {
471 // We want to read exactly 3 Bytes of data.
472 if (Bytes.size() < 3) {
473 Size = 0;
474 return MCDisassembler::Fail;
475 }
476
477 if (!IsLittleEndian) {
478 report_fatal_error("Big-endian mode currently is not supported!");
479 } else {
480 Insn = (Bytes[2] << 16) | (Bytes[1] << 8) | (Bytes[0] << 0);
481 }
482
483 return MCDisassembler::Success;
484 }
485
486 #include "XtensaGenDisassemblerTables.inc"
487
getInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CS) const488 DecodeStatus XtensaDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
489 ArrayRef<uint8_t> Bytes,
490 uint64_t Address,
491 raw_ostream &CS) const {
492 uint64_t Insn;
493 DecodeStatus Result;
494
495 // Parse 16-bit instructions
496 if (hasDensity()) {
497 Result = readInstruction16(Bytes, Address, Size, Insn, IsLittleEndian);
498 if (Result == MCDisassembler::Fail)
499 return MCDisassembler::Fail;
500 LLVM_DEBUG(dbgs() << "Trying Xtensa 16-bit instruction table :\n");
501 Result = decodeInstruction(DecoderTable16, MI, Insn, Address, this, STI);
502 if (Result != MCDisassembler::Fail) {
503 Size = 2;
504 return Result;
505 }
506 }
507
508 // Parse Core 24-bit instructions
509 Result = readInstruction24(Bytes, Address, Size, Insn, IsLittleEndian);
510 if (Result == MCDisassembler::Fail)
511 return MCDisassembler::Fail;
512 LLVM_DEBUG(dbgs() << "Trying Xtensa 24-bit instruction table :\n");
513 Result = decodeInstruction(DecoderTable24, MI, Insn, Address, this, STI);
514 if (Result != MCDisassembler::Fail) {
515 Size = 3;
516 return Result;
517 }
518 return Result;
519 }
520