@@ -38,9 +38,7 @@ class XtensaDisassembler : public MCDisassembler {
3838 XtensaDisassembler (const MCSubtargetInfo &STI, MCContext &Ctx, bool isLE)
3939 : MCDisassembler(STI, Ctx), IsLittleEndian(isLE) {}
4040
41- bool hasDensity () const {
42- return STI.hasFeature (Xtensa::FeatureDensity);
43- }
41+ bool hasDensity () const { return STI.hasFeature (Xtensa::FeatureDensity); }
4442
4543 DecodeStatus getInstruction (MCInst &Instr, uint64_t &Size,
4644 ArrayRef<uint8_t > Bytes, uint64_t Address,
@@ -99,8 +97,8 @@ static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch,
9997 uint64_t InstSize, MCInst &MI,
10098 const void *Decoder) {
10199 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);
104102}
105103
106104static DecodeStatus decodeCallOperand (MCInst &Inst, uint64_t Imm,
@@ -190,6 +188,28 @@ static DecodeStatus decodeImm1_16Operand(MCInst &Inst, uint64_t Imm,
190188 return MCDisassembler::Success;
191189}
192190
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+
193213static DecodeStatus decodeShimm1_31Operand (MCInst &Inst, uint64_t Imm,
194214 int64_t Address,
195215 const void *Decoder) {
@@ -243,9 +263,37 @@ static DecodeStatus decodeMem32Operand(MCInst &Inst, uint64_t Imm,
243263 return MCDisassembler::Success;
244264}
245265
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+ llvm_unreachable (" Big-endian mode currently is not supported!" );
287+ } else {
288+ Insn = (Bytes[1 ] << 8 ) | Bytes[0 ];
289+ }
290+
291+ return MCDisassembler::Success;
292+ }
293+
246294// / Read three bytes from the ArrayRef and return 24 bit data
247295static DecodeStatus readInstruction24 (ArrayRef<uint8_t > Bytes, uint64_t Address,
248- uint64_t &Size, uint32_t &Insn,
296+ uint64_t &Size, uint64_t &Insn,
249297 bool IsLittleEndian) {
250298 // We want to read exactly 3 Bytes of data.
251299 if (Bytes.size () < 3 ) {
@@ -259,7 +307,6 @@ static DecodeStatus readInstruction24(ArrayRef<uint8_t> Bytes, uint64_t Address,
259307 Insn = (Bytes[2 ] << 16 ) | (Bytes[1 ] << 8 ) | (Bytes[0 ] << 0 );
260308 }
261309
262- Size = 3 ;
263310 return MCDisassembler::Success;
264311}
265312
@@ -269,13 +316,31 @@ DecodeStatus XtensaDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
269316 ArrayRef<uint8_t > Bytes,
270317 uint64_t Address,
271318 raw_ostream &CS) const {
272- uint32_t Insn;
319+ uint64_t Insn;
273320 DecodeStatus Result;
274321
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
275336 Result = readInstruction24 (Bytes, Address, Size, Insn, IsLittleEndian);
276337 if (Result == MCDisassembler::Fail)
277338 return MCDisassembler::Fail;
278339 LLVM_DEBUG (dbgs () << " Trying Xtensa 24-bit instruction table :\n " );
279340 Result = decodeInstruction (DecoderTable24, MI, Insn, Address, this , STI);
341+ if (Result != MCDisassembler::Fail) {
342+ Size = 3 ;
343+ return Result;
344+ }
280345 return Result;
281346}
0 commit comments