mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-12 04:35:56 +00:00
Merge 29836c9d2e
into 27cbd6647f
This commit is contained in:
commit
99f72c8760
3 changed files with 157 additions and 279 deletions
|
@ -16,76 +16,6 @@ T extract(T value, u32 lst, u32 fst) {
|
||||||
}
|
}
|
||||||
} // namespace bit
|
} // namespace bit
|
||||||
|
|
||||||
InstEncoding GetInstructionEncoding(u32 token) {
|
|
||||||
auto encoding = static_cast<InstEncoding>(token & (u32)EncodingMask::MASK_9bit);
|
|
||||||
switch (encoding) {
|
|
||||||
case InstEncoding::SOP1:
|
|
||||||
case InstEncoding::SOPP:
|
|
||||||
case InstEncoding::SOPC:
|
|
||||||
return encoding;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
encoding = static_cast<InstEncoding>(token & (u32)EncodingMask::MASK_7bit);
|
|
||||||
switch (encoding) {
|
|
||||||
case InstEncoding::VOP1:
|
|
||||||
case InstEncoding::VOPC:
|
|
||||||
return encoding;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
encoding = static_cast<InstEncoding>(token & (u32)EncodingMask::MASK_6bit);
|
|
||||||
switch (encoding) {
|
|
||||||
case InstEncoding::VOP3:
|
|
||||||
case InstEncoding::EXP:
|
|
||||||
case InstEncoding::VINTRP:
|
|
||||||
case InstEncoding::DS:
|
|
||||||
case InstEncoding::MUBUF:
|
|
||||||
case InstEncoding::MTBUF:
|
|
||||||
case InstEncoding::MIMG:
|
|
||||||
return encoding;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
encoding = static_cast<InstEncoding>(token & (u32)EncodingMask::MASK_5bit);
|
|
||||||
switch (encoding) {
|
|
||||||
case InstEncoding::SMRD:
|
|
||||||
return encoding;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
encoding = static_cast<InstEncoding>(token & (u32)EncodingMask::MASK_4bit);
|
|
||||||
switch (encoding) {
|
|
||||||
case InstEncoding::SOPK:
|
|
||||||
return encoding;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
encoding = static_cast<InstEncoding>(token & (u32)EncodingMask::MASK_2bit);
|
|
||||||
switch (encoding) {
|
|
||||||
case InstEncoding::SOP2:
|
|
||||||
return encoding;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
encoding = static_cast<InstEncoding>(token & (u32)EncodingMask::MASK_1bit);
|
|
||||||
switch (encoding) {
|
|
||||||
case InstEncoding::VOP2:
|
|
||||||
return encoding;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
UNREACHABLE();
|
|
||||||
return InstEncoding::ILLEGAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool HasAdditionalLiteral(InstEncoding encoding, Opcode opcode) {
|
bool HasAdditionalLiteral(InstEncoding encoding, Opcode opcode) {
|
||||||
switch (encoding) {
|
switch (encoding) {
|
||||||
case InstEncoding::SOPK: {
|
case InstEncoding::SOPK: {
|
||||||
|
@ -107,128 +37,153 @@ bool IsVop3BEncoding(Opcode opcode) {
|
||||||
opcode == Opcode::V_MAD_U64_U32 || opcode == Opcode::V_MAD_I64_I32;
|
opcode == Opcode::V_MAD_U64_U32 || opcode == Opcode::V_MAD_I64_I32;
|
||||||
}
|
}
|
||||||
|
|
||||||
GcnInst GcnDecodeContext::decodeInstruction(GcnCodeSlice& code) {
|
inline static InstEncoding castToken(u32 token, EncodingMask mask) {
|
||||||
const uint32_t token = code.at(0);
|
return static_cast<InstEncoding>(token & static_cast<u32>(mask));
|
||||||
|
}
|
||||||
|
|
||||||
InstEncoding encoding = GetInstructionEncoding(token);
|
GcnInst GcnDecodeContext::decodeInstruction(GcnCodeSlice& code) {
|
||||||
ASSERT_MSG(encoding != InstEncoding::ILLEGAL, "illegal encoding");
|
const u32 token = code.at(0);
|
||||||
uint32_t encodingLen = getEncodingLength(encoding);
|
|
||||||
|
|
||||||
// Clear the instruction
|
// Clear the instruction
|
||||||
m_instruction = GcnInst();
|
m_instruction = GcnInst();
|
||||||
|
|
||||||
// Decode
|
OpcodeMap opcodeMap;
|
||||||
if (encodingLen == sizeof(uint32_t)) {
|
bool is64bit = false;
|
||||||
decodeInstruction32(encoding, code);
|
|
||||||
|
m_instruction.encoding = castToken(token, EncodingMask::MASK_7bit);
|
||||||
|
switch (m_instruction.encoding) {
|
||||||
|
case InstEncoding::VOP1:
|
||||||
|
opcodeMap = OpcodeMap::OP_MAP_VOP1;
|
||||||
|
decodeInstructionVOP1(code.readu32());
|
||||||
|
break;
|
||||||
|
case InstEncoding::VOPC:
|
||||||
|
opcodeMap = OpcodeMap::OP_MAP_VOPC;
|
||||||
|
decodeInstructionVOPC(code.readu32());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
|
||||||
|
m_instruction.encoding = castToken(token, EncodingMask::MASK_1bit);
|
||||||
|
switch (m_instruction.encoding) {
|
||||||
|
case InstEncoding::VOP2:
|
||||||
|
opcodeMap = OpcodeMap::OP_MAP_VOP2;
|
||||||
|
decodeInstructionVOP2(code.readu32());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
|
||||||
|
m_instruction.encoding = castToken(token, EncodingMask::MASK_9bit);
|
||||||
|
switch (m_instruction.encoding) {
|
||||||
|
case InstEncoding::SOP1:
|
||||||
|
opcodeMap = OpcodeMap::OP_MAP_SOP1;
|
||||||
|
decodeInstructionSOP1(code.readu32());
|
||||||
|
break;
|
||||||
|
case InstEncoding::SOPP:
|
||||||
|
opcodeMap = OpcodeMap::OP_MAP_SOPP;
|
||||||
|
decodeInstructionSOPP(code.readu32());
|
||||||
|
break;
|
||||||
|
case InstEncoding::SOPC:
|
||||||
|
opcodeMap = OpcodeMap::OP_MAP_SOPC;
|
||||||
|
decodeInstructionSOPC(code.readu32());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
|
||||||
|
m_instruction.encoding = castToken(token, EncodingMask::MASK_6bit);
|
||||||
|
switch (m_instruction.encoding) {
|
||||||
|
case InstEncoding::VINTRP:
|
||||||
|
opcodeMap = OpcodeMap::OP_MAP_VINTRP;
|
||||||
|
decodeInstructionVINTRP(code.readu32());
|
||||||
|
break;
|
||||||
|
case InstEncoding::VOP3:
|
||||||
|
is64bit = true;
|
||||||
|
opcodeMap = OpcodeMap::OP_MAP_VOP3;
|
||||||
|
decodeInstructionVOP3(code.readu64()); // VOP3 is 64 bits instruction
|
||||||
|
break;
|
||||||
|
case InstEncoding::EXP:
|
||||||
|
is64bit = true;
|
||||||
|
opcodeMap = OpcodeMap::OP_MAP_EXP;
|
||||||
|
decodeInstructionEXP(code.readu64()); // EXP is 64 bits instruction
|
||||||
|
break;
|
||||||
|
case InstEncoding::DS:
|
||||||
|
is64bit = true;
|
||||||
|
opcodeMap = OpcodeMap::OP_MAP_DS;
|
||||||
|
decodeInstructionDS(code.readu64()); // DS is 64 bits instruction
|
||||||
|
break;
|
||||||
|
case InstEncoding::MUBUF:
|
||||||
|
is64bit = true;
|
||||||
|
opcodeMap = OpcodeMap::OP_MAP_MUBUF;
|
||||||
|
decodeInstructionMUBUF(code.readu64()); // MUBUF is 64 bits instruction
|
||||||
|
break;
|
||||||
|
case InstEncoding::MTBUF:
|
||||||
|
is64bit = true;
|
||||||
|
opcodeMap = OpcodeMap::OP_MAP_MTBUF;
|
||||||
|
decodeInstructionMTBUF(code.readu64()); // MTBUF is 64 bits instruction
|
||||||
|
break;
|
||||||
|
case InstEncoding::MIMG:
|
||||||
|
is64bit = true;
|
||||||
|
opcodeMap = OpcodeMap::OP_MAP_MIMG;
|
||||||
|
decodeInstructionMIMG(code.readu64()); // MIMG is 64 bits instruction
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
|
||||||
|
m_instruction.encoding = castToken(token, EncodingMask::MASK_5bit);
|
||||||
|
switch (m_instruction.encoding) {
|
||||||
|
case InstEncoding::SMRD:
|
||||||
|
opcodeMap = OpcodeMap::OP_MAP_SMRD;
|
||||||
|
decodeInstructionSMRD(code.readu32());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
|
||||||
|
m_instruction.encoding = castToken(token, EncodingMask::MASK_4bit);
|
||||||
|
switch (m_instruction.encoding) {
|
||||||
|
case InstEncoding::SOPK:
|
||||||
|
opcodeMap = OpcodeMap::OP_MAP_SOPK;
|
||||||
|
decodeInstructionSOPK(code.readu32());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
|
||||||
|
m_instruction.encoding = castToken(token, EncodingMask::MASK_2bit);
|
||||||
|
switch (m_instruction.encoding) {
|
||||||
|
case InstEncoding::SOP2:
|
||||||
|
opcodeMap = OpcodeMap::OP_MAP_SOP2;
|
||||||
|
decodeInstructionSOP2(code.readu32());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
|
||||||
|
UNREACHABLE();
|
||||||
|
ASSERT_MSG("illegal encoding");
|
||||||
|
|
||||||
|
} // switch mask_2bit
|
||||||
|
|
||||||
|
} // switch mask_4bit
|
||||||
|
|
||||||
|
} // switch mask_5bit
|
||||||
|
|
||||||
|
} // switch mask_6bit
|
||||||
|
|
||||||
|
} // switch mask_9bit
|
||||||
|
|
||||||
|
} // switch mask_1bit
|
||||||
|
|
||||||
|
} // switch mask_7bit
|
||||||
|
|
||||||
|
if (is64bit) {
|
||||||
|
// Update instruction meta info.
|
||||||
|
updateInstructionMeta(opcodeMap, sizeof(uint64_t));
|
||||||
} else {
|
} else {
|
||||||
decodeInstruction64(encoding, code);
|
// Update instruction meta info.
|
||||||
}
|
updateInstructionMeta(opcodeMap, sizeof(uint32_t));
|
||||||
|
// Detect literal constant. Only 32 bits instructions may have literal constant.
|
||||||
// Update instruction meta info.
|
// Note: Literal constant decode must be performed after meta info updated.
|
||||||
updateInstructionMeta(encoding);
|
decodeLiteralConstant(opcodeMap, code);
|
||||||
|
|
||||||
// Detect literal constant. Only 32 bits instructions may have literal constant.
|
|
||||||
// Note: Literal constant decode must be performed after meta info updated.
|
|
||||||
if (encodingLen == sizeof(u32)) {
|
|
||||||
decodeLiteralConstant(encoding, code);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
repairOperandType();
|
repairOperandType();
|
||||||
return m_instruction;
|
return m_instruction;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t GcnDecodeContext::getEncodingLength(InstEncoding encoding) {
|
uint32_t GcnDecodeContext::mapEncodingOp(OpcodeMap opcodeMap, Opcode opcode) {
|
||||||
uint32_t instLength = 0;
|
|
||||||
|
|
||||||
switch (encoding) {
|
|
||||||
case InstEncoding::SOP1:
|
|
||||||
case InstEncoding::SOPP:
|
|
||||||
case InstEncoding::SOPC:
|
|
||||||
case InstEncoding::SOPK:
|
|
||||||
case InstEncoding::SOP2:
|
|
||||||
case InstEncoding::VOP1:
|
|
||||||
case InstEncoding::VOPC:
|
|
||||||
case InstEncoding::VOP2:
|
|
||||||
case InstEncoding::SMRD:
|
|
||||||
case InstEncoding::VINTRP:
|
|
||||||
instLength = sizeof(uint32_t);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case InstEncoding::VOP3:
|
|
||||||
case InstEncoding::MUBUF:
|
|
||||||
case InstEncoding::MTBUF:
|
|
||||||
case InstEncoding::MIMG:
|
|
||||||
case InstEncoding::DS:
|
|
||||||
case InstEncoding::EXP:
|
|
||||||
instLength = sizeof(uint64_t);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return instLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t GcnDecodeContext::getOpMapOffset(InstEncoding encoding) {
|
|
||||||
uint32_t offset = 0;
|
|
||||||
switch (encoding) {
|
|
||||||
case InstEncoding::SOP1:
|
|
||||||
offset = (uint32_t)OpcodeMap::OP_MAP_SOP1;
|
|
||||||
break;
|
|
||||||
case InstEncoding::SOPP:
|
|
||||||
offset = (uint32_t)OpcodeMap::OP_MAP_SOPP;
|
|
||||||
break;
|
|
||||||
case InstEncoding::SOPC:
|
|
||||||
offset = (uint32_t)OpcodeMap::OP_MAP_SOPC;
|
|
||||||
break;
|
|
||||||
case InstEncoding::VOP1:
|
|
||||||
offset = (uint32_t)OpcodeMap::OP_MAP_VOP1;
|
|
||||||
break;
|
|
||||||
case InstEncoding::VOPC:
|
|
||||||
offset = (uint32_t)OpcodeMap::OP_MAP_VOPC;
|
|
||||||
break;
|
|
||||||
case InstEncoding::VOP3:
|
|
||||||
offset = (uint32_t)OpcodeMap::OP_MAP_VOP3;
|
|
||||||
break;
|
|
||||||
case InstEncoding::EXP:
|
|
||||||
offset = (uint32_t)OpcodeMap::OP_MAP_EXP;
|
|
||||||
break;
|
|
||||||
case InstEncoding::VINTRP:
|
|
||||||
offset = (uint32_t)OpcodeMap::OP_MAP_VINTRP;
|
|
||||||
break;
|
|
||||||
case InstEncoding::DS:
|
|
||||||
offset = (uint32_t)OpcodeMap::OP_MAP_DS;
|
|
||||||
break;
|
|
||||||
case InstEncoding::MUBUF:
|
|
||||||
offset = (uint32_t)OpcodeMap::OP_MAP_MUBUF;
|
|
||||||
break;
|
|
||||||
case InstEncoding::MTBUF:
|
|
||||||
offset = (uint32_t)OpcodeMap::OP_MAP_MTBUF;
|
|
||||||
break;
|
|
||||||
case InstEncoding::MIMG:
|
|
||||||
offset = (uint32_t)OpcodeMap::OP_MAP_MIMG;
|
|
||||||
break;
|
|
||||||
case InstEncoding::SMRD:
|
|
||||||
offset = (uint32_t)OpcodeMap::OP_MAP_SMRD;
|
|
||||||
break;
|
|
||||||
case InstEncoding::SOPK:
|
|
||||||
offset = (uint32_t)OpcodeMap::OP_MAP_SOPK;
|
|
||||||
break;
|
|
||||||
case InstEncoding::SOP2:
|
|
||||||
offset = (uint32_t)OpcodeMap::OP_MAP_SOP2;
|
|
||||||
break;
|
|
||||||
case InstEncoding::VOP2:
|
|
||||||
offset = (uint32_t)OpcodeMap::OP_MAP_VOP2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t GcnDecodeContext::mapEncodingOp(InstEncoding encoding, Opcode opcode) {
|
|
||||||
// Map from uniform opcode to encoding specific opcode.
|
// Map from uniform opcode to encoding specific opcode.
|
||||||
uint32_t encodingOp = 0;
|
uint32_t encodingOp = 0;
|
||||||
if (encoding == InstEncoding::VOP3) {
|
if (m_instruction.encoding == InstEncoding::VOP3) {
|
||||||
if (opcode >= Opcode::V_CMP_F_F32 && opcode <= Opcode::V_CMPX_T_U64) {
|
if (opcode >= Opcode::V_CMP_F_F32 && opcode <= Opcode::V_CMPX_T_U64) {
|
||||||
uint32_t op =
|
uint32_t op =
|
||||||
static_cast<uint32_t>(opcode) - static_cast<uint32_t>(OpcodeMap::OP_MAP_VOPC);
|
static_cast<uint32_t>(opcode) - static_cast<uint32_t>(OpcodeMap::OP_MAP_VOPC);
|
||||||
|
@ -246,28 +201,27 @@ uint32_t GcnDecodeContext::mapEncodingOp(InstEncoding encoding, Opcode opcode) {
|
||||||
static_cast<uint32_t>(opcode) - static_cast<uint32_t>(OpcodeMap::OP_MAP_VOP3);
|
static_cast<uint32_t>(opcode) - static_cast<uint32_t>(OpcodeMap::OP_MAP_VOP3);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
uint32_t mapOffset = getOpMapOffset(encoding);
|
uint32_t mapOffset = static_cast<uint32_t>(opcodeMap);
|
||||||
encodingOp = static_cast<uint32_t>(opcode) - mapOffset;
|
encodingOp = static_cast<uint32_t>(opcode) - mapOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
return encodingOp;
|
return encodingOp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GcnDecodeContext::updateInstructionMeta(InstEncoding encoding) {
|
void GcnDecodeContext::updateInstructionMeta(OpcodeMap opcodeMap, uint32_t encodingLength) {
|
||||||
uint32_t encodingOp = mapEncodingOp(encoding, m_instruction.opcode);
|
uint32_t encodingOp = mapEncodingOp(opcodeMap, m_instruction.opcode);
|
||||||
InstFormat instFormat = InstructionFormat(encoding, encodingOp);
|
InstFormat instFormat = InstructionFormat(m_instruction.encoding, encodingOp);
|
||||||
|
|
||||||
ASSERT_MSG(instFormat.src_type != ScalarType::Undefined &&
|
ASSERT_MSG(instFormat.src_type != ScalarType::Undefined &&
|
||||||
instFormat.dst_type != ScalarType::Undefined,
|
instFormat.dst_type != ScalarType::Undefined,
|
||||||
"Instruction format table incomplete for opcode {} ({}, encoding = 0x{:x})",
|
"Instruction format table incomplete for opcode {} ({}, encoding = 0x{:x})",
|
||||||
magic_enum::enum_name(m_instruction.opcode), u32(m_instruction.opcode),
|
magic_enum::enum_name(m_instruction.opcode), u32(m_instruction.opcode),
|
||||||
u32(encoding));
|
u32(m_instruction.encoding));
|
||||||
|
|
||||||
m_instruction.inst_class = instFormat.inst_class;
|
m_instruction.inst_class = instFormat.inst_class;
|
||||||
m_instruction.category = instFormat.inst_category;
|
m_instruction.category = instFormat.inst_category;
|
||||||
m_instruction.encoding = encoding;
|
|
||||||
m_instruction.src_count = instFormat.src_count;
|
m_instruction.src_count = instFormat.src_count;
|
||||||
m_instruction.length = getEncodingLength(encoding);
|
m_instruction.length = encodingLength;
|
||||||
|
|
||||||
// Update src operand scalar type.
|
// Update src operand scalar type.
|
||||||
auto setOperandType = [&instFormat](InstOperand& src) {
|
auto setOperandType = [&instFormat](InstOperand& src) {
|
||||||
|
@ -337,74 +291,10 @@ OperandField GcnDecodeContext::getOperandField(uint32_t code) {
|
||||||
return field;
|
return field;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GcnDecodeContext::decodeInstruction32(InstEncoding encoding, GcnCodeSlice& code) {
|
void GcnDecodeContext::decodeLiteralConstant(OpcodeMap opcodeMap, GcnCodeSlice& code) {
|
||||||
u32 hexInstruction = code.readu32();
|
if (HasAdditionalLiteral(m_instruction.encoding, m_instruction.opcode)) {
|
||||||
switch (encoding) {
|
u32 encoding_op = mapEncodingOp(opcodeMap, m_instruction.opcode);
|
||||||
case InstEncoding::SOP1:
|
InstFormat instFormat = InstructionFormat(m_instruction.encoding, encoding_op);
|
||||||
decodeInstructionSOP1(hexInstruction);
|
|
||||||
break;
|
|
||||||
case InstEncoding::SOPP:
|
|
||||||
decodeInstructionSOPP(hexInstruction);
|
|
||||||
break;
|
|
||||||
case InstEncoding::SOPC:
|
|
||||||
decodeInstructionSOPC(hexInstruction);
|
|
||||||
break;
|
|
||||||
case InstEncoding::SOPK:
|
|
||||||
decodeInstructionSOPK(hexInstruction);
|
|
||||||
break;
|
|
||||||
case InstEncoding::SOP2:
|
|
||||||
decodeInstructionSOP2(hexInstruction);
|
|
||||||
break;
|
|
||||||
case InstEncoding::VOP1:
|
|
||||||
decodeInstructionVOP1(hexInstruction);
|
|
||||||
break;
|
|
||||||
case InstEncoding::VOPC:
|
|
||||||
decodeInstructionVOPC(hexInstruction);
|
|
||||||
break;
|
|
||||||
case InstEncoding::VOP2:
|
|
||||||
decodeInstructionVOP2(hexInstruction);
|
|
||||||
break;
|
|
||||||
case InstEncoding::SMRD:
|
|
||||||
decodeInstructionSMRD(hexInstruction);
|
|
||||||
break;
|
|
||||||
case InstEncoding::VINTRP:
|
|
||||||
decodeInstructionVINTRP(hexInstruction);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GcnDecodeContext::decodeInstruction64(InstEncoding encoding, GcnCodeSlice& code) {
|
|
||||||
uint64_t hexInstruction = code.readu64();
|
|
||||||
switch (encoding) {
|
|
||||||
case InstEncoding::VOP3:
|
|
||||||
decodeInstructionVOP3(hexInstruction);
|
|
||||||
break;
|
|
||||||
case InstEncoding::MUBUF:
|
|
||||||
decodeInstructionMUBUF(hexInstruction);
|
|
||||||
break;
|
|
||||||
case InstEncoding::MTBUF:
|
|
||||||
decodeInstructionMTBUF(hexInstruction);
|
|
||||||
break;
|
|
||||||
case InstEncoding::MIMG:
|
|
||||||
decodeInstructionMIMG(hexInstruction);
|
|
||||||
break;
|
|
||||||
case InstEncoding::DS:
|
|
||||||
decodeInstructionDS(hexInstruction);
|
|
||||||
break;
|
|
||||||
case InstEncoding::EXP:
|
|
||||||
decodeInstructionEXP(hexInstruction);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GcnDecodeContext::decodeLiteralConstant(InstEncoding encoding, GcnCodeSlice& code) {
|
|
||||||
if (HasAdditionalLiteral(encoding, m_instruction.opcode)) {
|
|
||||||
u32 encoding_op = mapEncodingOp(encoding, m_instruction.opcode);
|
|
||||||
InstFormat instFormat = InstructionFormat(encoding, encoding_op);
|
|
||||||
m_instruction.src[m_instruction.src_count].field = OperandField::LiteralConst;
|
m_instruction.src[m_instruction.src_count].field = OperandField::LiteralConst;
|
||||||
m_instruction.src[m_instruction.src_count].type = instFormat.src_type;
|
m_instruction.src[m_instruction.src_count].type = instFormat.src_type;
|
||||||
m_instruction.src[m_instruction.src_count].code = code.readu32();
|
m_instruction.src[m_instruction.src_count].code = code.readu32();
|
||||||
|
|
|
@ -16,13 +16,7 @@ struct InstFormat {
|
||||||
ScalarType dst_type = ScalarType::Undefined;
|
ScalarType dst_type = ScalarType::Undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
InstEncoding GetInstructionEncoding(u32 token);
|
InstFormat InstructionFormat(InstEncoding encoding, uint32_t opcode);
|
||||||
|
|
||||||
u32 GetEncodingLength(InstEncoding encoding);
|
|
||||||
|
|
||||||
InstFormat InstructionFormat(InstEncoding encoding, u32 opcode);
|
|
||||||
|
|
||||||
Opcode DecodeOpcode(u32 token);
|
|
||||||
|
|
||||||
class GcnCodeSlice {
|
class GcnCodeSlice {
|
||||||
public:
|
public:
|
||||||
|
@ -58,30 +52,26 @@ public:
|
||||||
GcnInst decodeInstruction(GcnCodeSlice& code);
|
GcnInst decodeInstruction(GcnCodeSlice& code);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t getEncodingLength(InstEncoding encoding);
|
uint32_t mapEncodingOp(OpcodeMap opcodeMap, Opcode opcode);
|
||||||
uint32_t getOpMapOffset(InstEncoding encoding);
|
void updateInstructionMeta(OpcodeMap opcodeMap, uint32_t encodingLength);
|
||||||
uint32_t mapEncodingOp(InstEncoding encoding, Opcode opcode);
|
|
||||||
void updateInstructionMeta(InstEncoding encoding);
|
|
||||||
uint32_t getMimgModifier(Opcode opcode);
|
uint32_t getMimgModifier(Opcode opcode);
|
||||||
void repairOperandType();
|
void repairOperandType();
|
||||||
|
|
||||||
OperandField getOperandField(uint32_t code);
|
OperandField getOperandField(uint32_t code);
|
||||||
|
|
||||||
void decodeInstruction32(InstEncoding encoding, GcnCodeSlice& code);
|
void decodeLiteralConstant(OpcodeMap opcodeMap, GcnCodeSlice& code);
|
||||||
void decodeInstruction64(InstEncoding encoding, GcnCodeSlice& code);
|
|
||||||
void decodeLiteralConstant(InstEncoding encoding, GcnCodeSlice& code);
|
|
||||||
|
|
||||||
// 32 bits encodings
|
// 32 bits encodings
|
||||||
void decodeInstructionSOP1(uint32_t hexInstruction);
|
void decodeInstructionSOP1(u32 hexInstruction);
|
||||||
void decodeInstructionSOPP(uint32_t hexInstruction);
|
void decodeInstructionSOPP(u32 hexInstruction);
|
||||||
void decodeInstructionSOPC(uint32_t hexInstruction);
|
void decodeInstructionSOPC(u32 hexInstruction);
|
||||||
void decodeInstructionSOPK(uint32_t hexInstruction);
|
void decodeInstructionSOPK(u32 hexInstruction);
|
||||||
void decodeInstructionSOP2(uint32_t hexInstruction);
|
void decodeInstructionSOP2(u32 hexInstruction);
|
||||||
void decodeInstructionVOP1(uint32_t hexInstruction);
|
void decodeInstructionVOP1(u32 hexInstruction);
|
||||||
void decodeInstructionVOPC(uint32_t hexInstruction);
|
void decodeInstructionVOPC(u32 hexInstruction);
|
||||||
void decodeInstructionVOP2(uint32_t hexInstruction);
|
void decodeInstructionVOP2(u32 hexInstruction);
|
||||||
void decodeInstructionSMRD(uint32_t hexInstruction);
|
void decodeInstructionSMRD(u32 hexInstruction);
|
||||||
void decodeInstructionVINTRP(uint32_t hexInstruction);
|
void decodeInstructionVINTRP(u32 hexInstruction);
|
||||||
// 64 bits encodings
|
// 64 bits encodings
|
||||||
void decodeInstructionVOP3(uint64_t hexInstruction);
|
void decodeInstructionVOP3(uint64_t hexInstruction);
|
||||||
void decodeInstructionMUBUF(uint64_t hexInstruction);
|
void decodeInstructionMUBUF(uint64_t hexInstruction);
|
||||||
|
|
|
@ -2244,8 +2244,6 @@ enum class InstEncoding : u32 {
|
||||||
/// InstructionEncodingMask_1bit
|
/// InstructionEncodingMask_1bit
|
||||||
/// bits [31:31] - (0)
|
/// bits [31:31] - (0)
|
||||||
VOP2 = 0x00000000u << 31,
|
VOP2 = 0x00000000u << 31,
|
||||||
|
|
||||||
ILLEGAL
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class InstClass : u32 {
|
enum class InstClass : u32 {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue