* Copyright (c) Huawei Technologies Co., Ltd. 2026-2026. All rights reserved.
*/
#ifdef MS_DEBUGGER
#include "AscendDisassembler950.h"
#include "llvm/MC/MCInstrDesc.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include <vector>
using namespace std;
using namespace lldb_private;
namespace {
struct Inst {
uint32_t mask;
uint32_t value;
uint32_t byte_size{4};
};
const vector<Inst> &GetBranchInsts() {
static vector<Inst> insts = {
{0xFFE20000, 0x40020000},
{0xFFE20000, 0x40000000},
{0xFFFE0000, 0x40220000},
{0xFFFE0000, 0x40200000},
{0xFFFE0000, 0x40240000},
{0xF8030000, 0x48000000},
{0xF8030000, 0x48010000},
{0xF8030000, 0x48020000},
{0xF8030000, 0x48030000},
{0x3FFE0001, 0x01260000, 8},
{0x3FFE0001, 0x01A60000, 8},
{0xC000013F, 0xC0000013},
{0xC000013F, 0xC0000113},
{0xC000003F, 0xC0000034},
{0xC000003F, 0xC0000014},
{0xC000003F, 0xC0000039},
};
return insts;
}
const vector<Inst> &GetCallInsts() {
static vector<Inst> insts = {
{0xFFFE0000, 0x40400000},
{0xFFFE0000, 0x40420000},
{0xFFFE0000, 0x40440000},
{0x3FFE0001, 0x02260000, 8},
{0x3FFE0001, 0x05260001, 16},
{0x3FFE0001, 0x07260000, 8},
};
return insts;
}
const vector<Inst> &GetRetInsts() {
static vector<Inst> insts = {
{0xFFE1F000, 0x4061F000},
{0xFFE00000, 0x41200000},
{0xFFE00000, 0x41600000},
{0xFFE00000, 0x41800000},
{0x3FFE003D, 0x0626001C, 8},
{0x3FFE0001, 0x06A60000, 8},
{0xC000003F, 0xC0000017},
};
return insts;
}
uint32_t GetBit(const uint8_t *opcode_data, const size_t opcode_data_len) {
if (opcode_data_len < 4) {
return 0;
}
uint32_t data_s = (static_cast<uint32_t>(opcode_data[3]) << 24 |
static_cast<uint32_t>(opcode_data[2]) << 16 |
static_cast<uint32_t>(opcode_data[1]) << 8 |
static_cast<uint32_t>(opcode_data[0]));
return data_s;
}
int GetInstSize(const uint32_t encoding, const vector<Inst> &insts) {
for (const auto &inst : insts) {
if ((encoding & inst.mask) == inst.value) {
return inst.byte_size;
}
}
return 0;
}
}
void AscendDisassembler950::GetInstruction(const uint8_t *opcode_data,
const size_t opcode_data_len,
uint64_t &flags,
const InterruptPosType pos_type,
uint64_t &inst_size) {
Log *log = GetLog(LLDBLog::Process);
uint32_t encoding = GetBit(opcode_data, opcode_data_len);
inst_size = 4;
if (pos_type == InterruptPosType::VEC_INTERRUPT_SIMT) {
inst_size = 8;
}
int sz = 0;
sz = GetInstSize(encoding, GetBranchInsts());
if (sz > 0) {
flags |= 1ULL << (uint32_t)llvm::MCID::Branch;
inst_size = sz;
}
sz = GetInstSize(encoding, GetCallInsts());
if (sz > 0) {
flags |= 1ULL << (uint32_t)llvm::MCID::Call;
inst_size = sz;
}
sz = GetInstSize(encoding, GetRetInsts());
if (sz > 0) {
flags |= 1ULL << (uint32_t)llvm::MCID::Return;
inst_size = sz;
}
LLDB_LOG(log,
"opcode_data_len={0}, encoding={1:x}, inst_size={2}, flags={3:x}",
opcode_data_len, encoding, inst_size, flags);
}
#endif