@@ -38,9 +38,7 @@ class XtensaDisassembler : public MCDisassembler {
38
38
XtensaDisassembler (const MCSubtargetInfo &STI, MCContext &Ctx, bool isLE)
39
39
: MCDisassembler(STI, Ctx), IsLittleEndian(isLE) {}
40
40
41
- bool hasDensity () const {
42
- return STI.hasFeature (Xtensa::FeatureDensity);
43
- }
41
+ bool hasDensity () const { return STI.hasFeature (Xtensa::FeatureDensity); }
44
42
45
43
DecodeStatus getInstruction (MCInst &Instr, uint64_t &Size ,
46
44
ArrayRef<uint8_t > Bytes, uint64_t Address,
@@ -99,8 +97,8 @@ static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch,
99
97
uint64_t InstSize, MCInst &MI,
100
98
const void *Decoder) {
101
99
const MCDisassembler *Dis = static_cast <const MCDisassembler *>(Decoder);
102
- return Dis->tryAddingSymbolicOperand (MI, Value, Address, isBranch, Offset, /* OpSize= */ 0 ,
103
- InstSize);
100
+ return Dis->tryAddingSymbolicOperand (MI, Value, Address, isBranch, Offset,
101
+ /* OpSize= */ 0 , InstSize);
104
102
}
105
103
106
104
static DecodeStatus decodeCallOperand (MCInst &Inst, uint64_t Imm,
@@ -190,6 +188,28 @@ static DecodeStatus decodeImm1_16Operand(MCInst &Inst, uint64_t Imm,
190
188
return MCDisassembler::Success;
191
189
}
192
190
191
+ static DecodeStatus decodeImm1n_15Operand (MCInst &Inst, uint64_t Imm,
192
+ int64_t Address,
193
+ const void *Decoder) {
194
+ assert (isUInt<4 >(Imm) && " Invalid immediate" );
195
+ if (!Imm)
196
+ Inst.addOperand (MCOperand::createImm (-1 ));
197
+ else
198
+ Inst.addOperand (MCOperand::createImm (Imm));
199
+ return MCDisassembler::Success;
200
+ }
201
+
202
+ static DecodeStatus decodeImm32n_95Operand (MCInst &Inst, uint64_t Imm,
203
+ int64_t Address,
204
+ const void *Decoder) {
205
+ assert (isUInt<7 >(Imm) && " Invalid immediate" );
206
+ if ((Imm & 0x60 ) == 0x60 )
207
+ Inst.addOperand (MCOperand::createImm ((~0x1f ) | Imm));
208
+ else
209
+ Inst.addOperand (MCOperand::createImm (Imm));
210
+ return MCDisassembler::Success;
211
+ }
212
+
193
213
static DecodeStatus decodeShimm1_31Operand (MCInst &Inst, uint64_t Imm,
194
214
int64_t Address,
195
215
const void *Decoder) {
@@ -243,9 +263,37 @@ static DecodeStatus decodeMem32Operand(MCInst &Inst, uint64_t Imm,
243
263
return MCDisassembler::Success;
244
264
}
245
265
266
+ static DecodeStatus decodeMem32nOperand (MCInst &Inst, uint64_t Imm,
267
+ int64_t Address, const void *Decoder) {
268
+ assert (isUInt<8 >(Imm) && " Invalid immediate" );
269
+ DecodeARRegisterClass (Inst, Imm & 0xf , Address, Decoder);
270
+ Inst.addOperand (MCOperand::createImm ((Imm >> 2 ) & 0x3c ));
271
+ return MCDisassembler::Success;
272
+ }
273
+
274
+ // / Read two bytes from the ArrayRef and return 16 bit data sorted
275
+ // / according to the given endianness.
276
+ static DecodeStatus readInstruction16 (ArrayRef<uint8_t > Bytes, uint64_t Address,
277
+ uint64_t &Size , uint64_t &Insn,
278
+ bool IsLittleEndian) {
279
+ // We want to read exactly 2 Bytes of data.
280
+ if (Bytes.size () < 2 ) {
281
+ Size = 0 ;
282
+ return MCDisassembler::Fail;
283
+ }
284
+
285
+ if (!IsLittleEndian) {
286
+ report_fatal_error (" Big-endian mode currently is not supported!" );
287
+ } else {
288
+ Insn = (Bytes[1 ] << 8 ) | Bytes[0 ];
289
+ }
290
+
291
+ return MCDisassembler::Success;
292
+ }
293
+
246
294
// / Read three bytes from the ArrayRef and return 24 bit data
247
295
static DecodeStatus readInstruction24 (ArrayRef<uint8_t > Bytes, uint64_t Address,
248
- uint64_t &Size , uint32_t &Insn,
296
+ uint64_t &Size , uint64_t &Insn,
249
297
bool IsLittleEndian) {
250
298
// We want to read exactly 3 Bytes of data.
251
299
if (Bytes.size () < 3 ) {
@@ -259,7 +307,6 @@ static DecodeStatus readInstruction24(ArrayRef<uint8_t> Bytes, uint64_t Address,
259
307
Insn = (Bytes[2 ] << 16 ) | (Bytes[1 ] << 8 ) | (Bytes[0 ] << 0 );
260
308
}
261
309
262
- Size = 3 ;
263
310
return MCDisassembler::Success;
264
311
}
265
312
@@ -269,13 +316,31 @@ DecodeStatus XtensaDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
269
316
ArrayRef<uint8_t > Bytes,
270
317
uint64_t Address,
271
318
raw_ostream &CS) const {
272
- uint32_t Insn;
319
+ uint64_t Insn;
273
320
DecodeStatus Result;
274
321
322
+ // Parse 16-bit instructions
323
+ if (hasDensity ()) {
324
+ Result = readInstruction16 (Bytes, Address, Size , Insn, IsLittleEndian);
325
+ if (Result == MCDisassembler::Fail)
326
+ return MCDisassembler::Fail;
327
+ LLVM_DEBUG (dbgs () << " Trying Xtensa 16-bit instruction table :\n " );
328
+ Result = decodeInstruction (DecoderTable16, MI, Insn, Address, this , STI);
329
+ if (Result != MCDisassembler::Fail) {
330
+ Size = 2 ;
331
+ return Result;
332
+ }
333
+ }
334
+
335
+ // Parse Core 24-bit instructions
275
336
Result = readInstruction24 (Bytes, Address, Size , Insn, IsLittleEndian);
276
337
if (Result == MCDisassembler::Fail)
277
338
return MCDisassembler::Fail;
278
339
LLVM_DEBUG (dbgs () << " Trying Xtensa 24-bit instruction table :\n " );
279
340
Result = decodeInstruction (DecoderTable24, MI, Insn, Address, this , STI);
341
+ if (Result != MCDisassembler::Fail) {
342
+ Size = 3 ;
343
+ return Result;
344
+ }
280
345
return Result;
281
346
}
0 commit comments