Skip to content

Commit

Permalink
[Xtensa] Add support for decoding from HIFI namespace
Browse files Browse the repository at this point in the history
  • Loading branch information
maciej-czekaj authored and andreisfr committed Dec 19, 2023
1 parent 2849b71 commit f258e0a
Showing 1 changed file with 48 additions and 4 deletions.
52 changes: 48 additions & 4 deletions llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ class XtensaDisassembler : public MCDisassembler {

bool hasESP32S3Ops() const {
return STI.getFeatureBits()[Xtensa::FeatureESP32S3Ops];

}

bool hasHIFI3() const {
return STI.getFeatureBits()[Xtensa::FeatureHIFI3];
}

DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
Expand Down Expand Up @@ -832,7 +837,7 @@ static DecodeStatus decodeMem32nOperand(MCInst &Inst, uint64_t Imm,
/// Read two bytes from the ArrayRef and return 16 bit data sorted
/// according to the given endianness.
static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
uint64_t &Size, uint32_t &Insn,
uint64_t &Size, uint64_t &Insn,
bool IsLittleEndian) {
// We want to read exactly 2 Bytes of data.
if (Bytes.size() < 2) {
Expand All @@ -851,7 +856,7 @@ static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,

/// Read three bytes from the ArrayRef and return 24 bit data
static DecodeStatus readInstruction24(ArrayRef<uint8_t> Bytes, uint64_t Address,
uint64_t &Size, uint32_t &Insn,
uint64_t &Size, uint64_t &Insn,
bool IsLittleEndian) {
// We want to read exactly 3 Bytes of data.
if (Bytes.size() < 3) {
Expand All @@ -870,7 +875,7 @@ static DecodeStatus readInstruction24(ArrayRef<uint8_t> Bytes, uint64_t Address,

/// Read three bytes from the ArrayRef and return 32 bit data
static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
uint64_t &Size, uint32_t &Insn,
uint64_t &Size, uint64_t &Insn,
bool IsLittleEndian) {
// We want to read exactly 4 Bytes of data.
if (Bytes.size() < 4) {
Expand All @@ -887,13 +892,37 @@ static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
return MCDisassembler::Success;
}

/// Read InstSize bytes from the ArrayRef and return 24 bit data
static DecodeStatus readInstructionN(ArrayRef<uint8_t> Bytes, uint64_t Address,
unsigned InstSize,
uint64_t &Size, uint64_t &Insn,
bool IsLittleEndian) {
// We want to read exactly 3 Bytes of data.
if (Bytes.size() < InstSize) {
Size = 0;
return MCDisassembler::Fail;
}

if (!IsLittleEndian) {
report_fatal_error("Big-endian mode currently is not supported!");
} else {
Insn = 0;
for (unsigned i = 0; i < InstSize; i++)
Insn |= (Bytes[i] << 8*i);
}

Size = InstSize;
return MCDisassembler::Success;
}


#include "XtensaGenDisassemblerTables.inc"

DecodeStatus XtensaDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
ArrayRef<uint8_t> Bytes,
uint64_t Address,
raw_ostream &CS) const {
uint32_t Insn;
uint64_t Insn;
DecodeStatus Result;

// Parse 16-bit instructions
Expand Down Expand Up @@ -946,5 +975,20 @@ DecodeStatus XtensaDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
}
}

if (hasHIFI3()) {
LLVM_DEBUG(dbgs() << "Trying Xtensa HIFI3 24-bit instruction table :\n");
Result = decodeInstruction(DecoderTableHIFI324, MI, Insn, Address, this, STI);
if(Result != MCDisassembler::Fail)
return Result;

Result = readInstructionN(Bytes, Address, 48, Size, Insn, IsLittleEndian);
if (Result == MCDisassembler::Fail)
return MCDisassembler::Fail;

LLVM_DEBUG(dbgs() << "Trying Xtensa HIFI3 48-bit instruction table :\n");
Result = decodeInstruction(DecoderTableHIFI348, MI, Insn, Address, this, STI);
if(Result != MCDisassembler::Fail)
return Result;
}
return Result;
}

0 comments on commit f258e0a

Please sign in to comment.