public static ShaderIrBlock DecodeBasicBlock(int[] Code, int Offset, GalShaderType ShaderType) { ShaderIrBlock Block = new ShaderIrBlock(); while (Offset + 2 <= Code.Length) { uint Word0 = (uint)Code[Offset++]; uint Word1 = (uint)Code[Offset++]; long OpCode = Word0 | (long)Word1 << 32; ShaderDecodeFunc Decode = ShaderOpCodeTable.GetDecoder(OpCode); if (Decode == null) { continue; } Decode(Block, OpCode); if (Block.GetLastNode() is ShaderIrOp Op && IsFlowChange(Op.Inst)) { break; } } Block.RunOptimizationPasses(ShaderType); return(Block); }
private static void FillBlock(IGalMemory Memory, ShaderIrBlock Block, long Beginning) { long Position = Block.Position; do { //Ignore scheduling instructions, which are written every 32 bytes. if (((Position - Beginning) & 0x1f) == 0) { Position += 8; continue; } uint Word0 = (uint)Memory.ReadInt32(Position + 0); uint Word1 = (uint)Memory.ReadInt32(Position + 4); Position += 8; long OpCode = Word0 | (long)Word1 << 32; ShaderDecodeFunc Decode = ShaderOpCodeTable.GetDecoder(OpCode); if (AddDbgComments) { string DbgOpCode = $"0x{(Position - Beginning - 8):x16}: 0x{OpCode:x16} "; DbgOpCode += (Decode?.Method.Name ?? "???"); if (Decode == ShaderDecode.Bra) { int Offset = ((int)(OpCode >> 20) << 8) >> 8; long Target = Position + Offset; DbgOpCode += " (0x" + Target.ToString("x16") + ")"; } Block.AddNode(new ShaderIrCmnt(DbgOpCode)); } if (Decode == null) { continue; } Decode(Block, OpCode); }while (!IsFlowChange(Block.GetLastNode())); Block.EndPosition = Position; }
private static void FillBlock(IGalMemory memory, ShaderIrBlock block, long beginning) { int position = block.Position; do { //Ignore scheduling instructions, which are written every 32 bytes. if ((position & 0x1f) == 0) { position += 8; continue; } uint word0 = (uint)memory.ReadInt32(position + beginning + 0); uint word1 = (uint)memory.ReadInt32(position + beginning + 4); position += 8; long opCode = word0 | (long)word1 << 32; ShaderDecodeFunc decode = ShaderOpCodeTable.GetDecoder(opCode); if (AddDbgComments) { string dbgOpCode = $"0x{(position - 8):x16}: 0x{opCode:x16} "; dbgOpCode += (decode?.Method.Name ?? "???"); if (decode == ShaderDecode.Bra || decode == ShaderDecode.Ssy) { int offset = ((int)(opCode >> 20) << 8) >> 8; long target = position + offset; dbgOpCode += " (0x" + target.ToString("x16") + ")"; } block.AddNode(new ShaderIrCmnt(dbgOpCode)); } if (decode == null) { continue; } decode(block, opCode, position); }while (!IsFlowChange(block.GetLastNode())); block.EndPosition = position; }
private static void Set(string Encoding, ShaderDecodeFunc Func) { if (Encoding.Length != EncodingBits) { throw new ArgumentException(nameof(Encoding)); } int Bit = Encoding.Length - 1; int Value = 0; int XMask = 0; int XBits = 0; int[] XPos = new int[Encoding.Length]; for (int Index = 0; Index < Encoding.Length; Index++, Bit--) { char Chr = Encoding[Index]; if (Chr == '1') { Value |= 1 << Bit; } else if (Chr == 'x') { XMask |= 1 << Bit; XPos[XBits++] = Bit; } } XMask = ~XMask; ShaderDecodeEntry Entry = new ShaderDecodeEntry(Func, XBits); for (int Index = 0; Index < (1 << XBits); Index++) { Value &= XMask; for (int X = 0; X < XBits; X++) { Value |= ((Index >> X) & 1) << XPos[X]; } if (OpCodes[Value] == null || OpCodes[Value].XBits > XBits) { OpCodes[Value] = Entry; } } }
public static ShaderIrBlock DecodeBasicBlock(int[] Code, int Offset) { ShaderIrBlock Block = new ShaderIrBlock(); while (Offset + 2 <= Code.Length) { int InstPos = Offset * 4; Block.Position = InstPos; Block.MarkLabel(InstPos); //Ignore scheduling instructions, which are written every 32 bytes. if ((Offset & 7) == 0) { Offset += 2; continue; } uint Word0 = (uint)Code[Offset++]; uint Word1 = (uint)Code[Offset++]; long OpCode = Word0 | (long)Word1 << 32; ShaderDecodeFunc Decode = ShaderOpCodeTable.GetDecoder(OpCode); if (AddDbgComments) { string DbgOpCode = $"0x{InstPos:x8}: 0x{OpCode:x16} "; Block.AddNode(new ShaderIrCmnt(DbgOpCode + (Decode?.Method.Name ?? "???"))); } if (Decode == null) { continue; } Decode(Block, OpCode); if (Block.GetLastNode() is ShaderIrOp Op && Op.Inst == ShaderIrInst.Exit) { break; } } return(Block); }
private static void Set(string encoding, ShaderDecodeFunc func) { if (encoding.Length != EncodingBits) { throw new ArgumentException(nameof(encoding)); } int bit = encoding.Length - 1; int value = 0; int xMask = 0; int xBits = 0; int[] xPos = new int[encoding.Length]; for (int index = 0; index < encoding.Length; index++, bit--) { char chr = encoding[index]; if (chr == '1') { value |= 1 << bit; } else if (chr == 'x') { xMask |= 1 << bit; xPos[xBits++] = bit; } } xMask = ~xMask; ShaderDecodeEntry entry = new ShaderDecodeEntry(func, xBits); for (int index = 0; index < (1 << xBits); index++) { value &= xMask; for (int x = 0; x < xBits; x++) { value |= ((index >> x) & 1) << xPos[x]; } if (_opCodes[value] == null || _opCodes[value].XBits > xBits) { _opCodes[value] = entry; } } }
private static void FillBlock(byte[] Binary, ShaderIrBlock Block, long Beginning) { long Position = Block.Position; do { //Ignore scheduling instructions, which are written every 32 bytes. if (((Position - Beginning) & 0x1f) == 0) { Position += 8; continue; } long OpCode = BitConverter.ToInt64(Binary, (int)Position); Position += 8; ShaderDecodeFunc Decode = ShaderOpCodeTable.GetDecoder(OpCode); if (AddDbgComments) { string DbgOpCode = $"0x{(Position - Beginning - 8):x16}: 0x{OpCode:x16} "; DbgOpCode += (Decode?.Method.Name ?? "???"); if (Decode == ShaderDecode.Bra) { int Offset = ((int)(OpCode >> 20) << 8) >> 8; long Target = Position + Offset - Beginning; DbgOpCode += " (0x" + Target.ToString("x16") + ")"; } Block.AddNode(new ShaderIrCmnt(DbgOpCode)); } if (Decode == null) { continue; } Decode(Block, OpCode, Position); }while (!IsFlowChange(Block.GetLastNode())); Block.EndPosition = Position; }
public static ShaderIrBlock DecodeBasicBlock(int[] Code, int Offset) { ShaderIrBlock Block = new ShaderIrBlock(); while (Offset + 2 <= Code.Length) { //Ignore scheduling instructions, which are //written every 32 bytes. if ((Offset & 7) == 0) { Offset += 2; continue; } uint Word0 = (uint)Code[Offset++]; uint Word1 = (uint)Code[Offset++]; long OpCode = Word0 | (long)Word1 << 32; ShaderDecodeFunc Decode = ShaderOpCodeTable.GetDecoder(OpCode); if (Decode == null) { continue; } Decode(Block, OpCode); if (Block.GetLastNode() is ShaderIrOp Op && IsFlowChange(Op.Inst)) { break; } } return(Block); }
public ShaderDecodeEntry(ShaderDecodeFunc Func, int XBits) { this.Func = Func; this.XBits = XBits; }
public ShaderDecodeEntry(ShaderDecodeFunc func, int xBits) { Func = func; XBits = xBits; }