mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 02:47:02 +02:00
shader: share direct and conditional branch classification
This commit is contained in:
@@ -130,20 +130,6 @@ uint32_t EmbeddedFetchDstSize(const Decoder::Instruction& inst) {
|
||||
return inst.opcode == Decoder::Opcode::V_MAD_U64_U32 ? 2u : DecodedDstSize(inst);
|
||||
}
|
||||
|
||||
bool EmbeddedFetchHasBranch(Decoder::Opcode opcode) {
|
||||
switch (opcode) {
|
||||
case Decoder::Opcode::S_SETPC_B64:
|
||||
case Decoder::Opcode::S_BRANCH:
|
||||
case Decoder::Opcode::S_CBRANCH_SCC0:
|
||||
case Decoder::Opcode::S_CBRANCH_SCC1:
|
||||
case Decoder::Opcode::S_CBRANCH_VCCZ:
|
||||
case Decoder::Opcode::S_CBRANCH_VCCNZ:
|
||||
case Decoder::Opcode::S_CBRANCH_EXECZ:
|
||||
case Decoder::Opcode::S_CBRANCH_EXECNZ: return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
void ClearEmbeddedFetchSgprs(std::array<EmbeddedFetchSgprInfo, 108>& sgprs,
|
||||
const Decoder::Operand& dst, uint32_t size) {
|
||||
if (!IsDecodedSgpr(dst)) {
|
||||
@@ -242,7 +228,10 @@ EmbeddedFetchData DetectEmbeddedVertexFetch(const Decoder::Program& decoded
|
||||
EmbeddedFetchVectorLanes vector_lanes;
|
||||
const bool track_vector_lanes =
|
||||
std::none_of(decoded.instructions.begin(), decoded.instructions.end(),
|
||||
[](const auto& inst) { return EmbeddedFetchHasBranch(inst.opcode); });
|
||||
[](const auto& inst) {
|
||||
return Decoder::IsDirectBranch(inst.opcode) ||
|
||||
inst.opcode == Decoder::Opcode::S_SETPC_B64;
|
||||
});
|
||||
|
||||
if (attrib_reg >= 0 && attrib_reg < static_cast<int>(sgprs.size())) {
|
||||
sgprs[attrib_reg].type = EmbeddedFetchValueType::AttribTable;
|
||||
|
||||
@@ -52,26 +52,6 @@ uint32_t ProgramEndPc(const Decoder::Program& program) {
|
||||
return InstructionEndPc(program.instructions.back());
|
||||
}
|
||||
|
||||
bool IsUnconditionalBranch(Opcode opcode) {
|
||||
return opcode == Opcode::S_BRANCH;
|
||||
}
|
||||
|
||||
bool IsConditionalBranch(Opcode opcode) {
|
||||
switch (opcode) {
|
||||
case Opcode::S_CBRANCH_SCC0:
|
||||
case Opcode::S_CBRANCH_SCC1:
|
||||
case Opcode::S_CBRANCH_VCCZ:
|
||||
case Opcode::S_CBRANCH_VCCNZ:
|
||||
case Opcode::S_CBRANCH_EXECZ:
|
||||
case Opcode::S_CBRANCH_EXECNZ: return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsBranch(Opcode opcode) {
|
||||
return IsUnconditionalBranch(opcode) || IsConditionalBranch(opcode);
|
||||
}
|
||||
|
||||
BranchCondition ConditionForOpcode(Opcode opcode) {
|
||||
switch (opcode) {
|
||||
case Opcode::S_BRANCH: return BranchCondition::Always;
|
||||
@@ -1925,7 +1905,7 @@ Graph BuildGraph(const Decoder::Program& program) {
|
||||
for (uint32_t i = 0; i < program.instructions.size(); i++) {
|
||||
const auto& inst = program.instructions[i];
|
||||
const auto next_pc = InstructionEndPc(inst);
|
||||
if (IsBranch(inst.opcode)) {
|
||||
if (Decoder::IsDirectBranch(inst.opcode)) {
|
||||
if (!IsValidTarget(inst.branch_target, instruction_pcs, first_pc, end_pc)) {
|
||||
ExitBuildFailure(graph, FailureKind::InvalidBranchTarget, UINT32_MAX,
|
||||
fmt::format("branch at pc 0x{:08x} targets invalid pc 0x{:08x}",
|
||||
@@ -2032,11 +2012,11 @@ Graph BuildGraph(const Decoder::Program& program) {
|
||||
block.terminator.condition = BranchCondition::Always;
|
||||
block.terminator.true_block = pc_to_block.at(target_info.target);
|
||||
}
|
||||
} else if (IsUnconditionalBranch(last.opcode)) {
|
||||
} else if (last.opcode == Opcode::S_BRANCH) {
|
||||
block.terminator.kind = TerminatorKind::Branch;
|
||||
block.terminator.condition = BranchCondition::Always;
|
||||
block.terminator.true_block = pc_to_block.at(last.branch_target);
|
||||
} else if (IsConditionalBranch(last.opcode)) {
|
||||
} else if (Decoder::IsConditionalBranch(last.opcode)) {
|
||||
block.terminator.kind = TerminatorKind::ConditionalBranch;
|
||||
block.terminator.condition = ConditionForOpcode(last.opcode);
|
||||
block.terminator.true_block = pc_to_block.at(last.branch_target);
|
||||
|
||||
@@ -25,19 +25,6 @@ bool HasLiteral(const Instruction& inst) {
|
||||
inst.src3.kind == OperandKind::LiteralConstant;
|
||||
}
|
||||
|
||||
bool IsControlFlowBranch(Opcode opcode) {
|
||||
switch (opcode) {
|
||||
case Opcode::S_BRANCH:
|
||||
case Opcode::S_CBRANCH_SCC0:
|
||||
case Opcode::S_CBRANCH_SCC1:
|
||||
case Opcode::S_CBRANCH_VCCZ:
|
||||
case Opcode::S_CBRANCH_VCCNZ:
|
||||
case Opcode::S_CBRANCH_EXECZ:
|
||||
case Opcode::S_CBRANCH_EXECNZ: return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
void ApplyLiteral(Operand& operand, uint32_t literal) {
|
||||
if (operand.kind == OperandKind::LiteralConstant) {
|
||||
operand.value = literal;
|
||||
@@ -198,6 +185,22 @@ std::string FormatExp(const Instruction& inst) {
|
||||
|
||||
} // namespace
|
||||
|
||||
bool IsConditionalBranch(Opcode opcode) {
|
||||
switch (opcode) {
|
||||
case Opcode::S_CBRANCH_SCC0:
|
||||
case Opcode::S_CBRANCH_SCC1:
|
||||
case Opcode::S_CBRANCH_VCCZ:
|
||||
case Opcode::S_CBRANCH_VCCNZ:
|
||||
case Opcode::S_CBRANCH_EXECZ:
|
||||
case Opcode::S_CBRANCH_EXECNZ: return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsDirectBranch(Opcode opcode) {
|
||||
return opcode == Opcode::S_BRANCH || IsConditionalBranch(opcode);
|
||||
}
|
||||
|
||||
const char* ImageDimensionToString(ImageDimension dimension) {
|
||||
switch (dimension) {
|
||||
case ImageDimension::Dim1D: return "1d";
|
||||
@@ -389,7 +392,7 @@ void DecodeProgram(std::span<const uint32_t> code, Program& program) {
|
||||
const auto& inst = program.instructions.back();
|
||||
word_index += inst.word_count;
|
||||
|
||||
if (IsControlFlowBranch(inst.opcode)) {
|
||||
if (IsDirectBranch(inst.opcode)) {
|
||||
const auto target_index = inst.branch_target / sizeof(uint32_t);
|
||||
if (branch_targets.empty()) {
|
||||
branch_targets.resize(code.size());
|
||||
|
||||
@@ -717,6 +717,8 @@ Family GetInstructionFamily(uint32_t word);
|
||||
// The output object must be freshly initialized.
|
||||
void DecodeInstruction(std::span<const uint32_t> code, uint32_t word_index, Instruction& inst);
|
||||
void DecodeProgram(std::span<const uint32_t> code, Program& program);
|
||||
bool IsConditionalBranch(Opcode opcode);
|
||||
bool IsDirectBranch(Opcode opcode);
|
||||
|
||||
void DecodeScalarSource(uint32_t code, uint32_t pc, Operand& operand);
|
||||
void DecodeScalarDestination(uint32_t code, uint32_t pc, Operand& operand);
|
||||
|
||||
Reference in New Issue
Block a user