shader: Implement BRX

This commit is contained in:
FernandoS27 2021-03-27 22:30:24 +01:00 committed by ameerj
parent 39a379632e
commit 34aba9627a
21 changed files with 437 additions and 48 deletions

View file

@ -48,8 +48,12 @@ struct GotoVariable : FlagTag {
u32 index;
};
struct IndirectBranchVariable {
auto operator<=>(const IndirectBranchVariable&) const noexcept = default;
};
using Variant = std::variant<IR::Reg, IR::Pred, ZeroFlagTag, SignFlagTag, CarryFlagTag,
OverflowFlagTag, GotoVariable>;
OverflowFlagTag, GotoVariable, IndirectBranchVariable>;
using ValueMap = boost::container::flat_map<IR::Block*, IR::Value, std::less<IR::Block*>>;
struct DefTable {
@ -65,6 +69,10 @@ struct DefTable {
return goto_vars[goto_variable.index];
}
[[nodiscard]] ValueMap& operator[](IndirectBranchVariable) {
return indirect_branch_var;
}
[[nodiscard]] ValueMap& operator[](ZeroFlagTag) noexcept {
return zero_flag;
}
@ -84,6 +92,7 @@ struct DefTable {
std::array<ValueMap, IR::NUM_USER_REGS> regs;
std::array<ValueMap, IR::NUM_USER_PREDS> preds;
boost::container::flat_map<u32, ValueMap> goto_vars;
ValueMap indirect_branch_var;
ValueMap zero_flag;
ValueMap sign_flag;
ValueMap carry_flag;
@ -102,6 +111,10 @@ IR::Opcode UndefOpcode(const FlagTag&) noexcept {
return IR::Opcode::UndefU1;
}
IR::Opcode UndefOpcode(IndirectBranchVariable) noexcept {
return IR::Opcode::UndefU32;
}
[[nodiscard]] bool IsPhi(const IR::Inst& inst) noexcept {
return inst.Opcode() == IR::Opcode::Phi;
}
@ -219,6 +232,9 @@ void VisitInst(Pass& pass, IR::Block* block, IR::Inst& inst) {
case IR::Opcode::SetGotoVariable:
pass.WriteVariable(GotoVariable{inst.Arg(0).U32()}, block, inst.Arg(1));
break;
case IR::Opcode::SetIndirectBranchVariable:
pass.WriteVariable(IndirectBranchVariable{}, block, inst.Arg(0));
break;
case IR::Opcode::SetZFlag:
pass.WriteVariable(ZeroFlagTag{}, block, inst.Arg(0));
break;
@ -244,6 +260,9 @@ void VisitInst(Pass& pass, IR::Block* block, IR::Inst& inst) {
case IR::Opcode::GetGotoVariable:
inst.ReplaceUsesWith(pass.ReadVariable(GotoVariable{inst.Arg(0).U32()}, block));
break;
case IR::Opcode::GetIndirectBranchVariable:
inst.ReplaceUsesWith(pass.ReadVariable(IndirectBranchVariable{}, block));
break;
case IR::Opcode::GetZFlag:
inst.ReplaceUsesWith(pass.ReadVariable(ZeroFlagTag{}, block));
break;