mirror of
https://github.com/par274/sharpemu.git
synced 2026-07-31 23:19:44 +08:00
Shader cfg ssa (#707)
* [shader] add scalar control flow graph * [shader] add gen5 branch resolver * [shader] add scalar reaching definitions * [shader] add cfg and dataflow tests * [shader] guard descriptors from unresolved registers
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
// Copyright (C) 2026 SharpEmu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
using System;
|
||||
|
||||
namespace SharpEmu.ShaderCompiler.Ir;
|
||||
|
||||
public sealed class Gen5IrBranchResolver : IIrBranchResolver
|
||||
{
|
||||
public static Gen5IrBranchResolver Instance { get; } = new();
|
||||
|
||||
public bool IsBranch(Gen5ShaderInstruction instruction) =>
|
||||
IsUnconditionalBranch(instruction) ||
|
||||
IsConditional(instruction) ||
|
||||
IsTerminator(instruction);
|
||||
|
||||
public bool IsConditional(Gen5ShaderInstruction instruction) => instruction.Opcode switch
|
||||
{
|
||||
"SCbranchScc0" or
|
||||
"SCbranchScc1" or
|
||||
"SCbranchVccz" or
|
||||
"SCbranchVccnz" or
|
||||
"SCbranchExecz" or
|
||||
"SCbranchExecnz" or
|
||||
"SCbranchCdbgsys" or
|
||||
"SCbranchCdbguser" or
|
||||
"SCbranchCdbgsysOrUser" or
|
||||
"SCbranchCdbgsysAndUser" => true,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
public bool TryGetBranchTarget(Gen5ShaderInstruction instruction, out uint targetPc)
|
||||
{
|
||||
targetPc = 0;
|
||||
if (IsTerminator(instruction))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!IsUnconditionalBranch(instruction) && !IsConditional(instruction))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (instruction.Encoding != Gen5ShaderEncoding.Sopp || instruction.Words.Count == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var offset = unchecked((short)(instruction.Words[0] & 0xFFFF));
|
||||
var nextPc = (long)instruction.Pc + instruction.Words.Count * sizeof(uint);
|
||||
var target = nextPc + offset * sizeof(uint);
|
||||
if (target < 0 || target > uint.MaxValue)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
targetPc = (uint)target;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool IsUnconditionalBranch(Gen5ShaderInstruction instruction) =>
|
||||
string.Equals(instruction.Opcode, "SBranch", StringComparison.Ordinal);
|
||||
|
||||
public static bool IsTerminator(Gen5ShaderInstruction instruction) =>
|
||||
instruction.Opcode is "SEndpgm" or "SEndpgmSaved";
|
||||
}
|
||||
Reference in New Issue
Block a user