예제 #1
0
        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);
        }
예제 #2
0
        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;
        }
예제 #3
0
        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;
        }
예제 #4
0
        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;
                }
            }
        }
예제 #5
0
        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);
        }
예제 #6
0
        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;
                }
            }
        }
예제 #7
0
        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;
        }
예제 #8
0
        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);
        }
예제 #9
0
 public ShaderDecodeEntry(ShaderDecodeFunc Func, int XBits)
 {
     this.Func  = Func;
     this.XBits = XBits;
 }
예제 #10
0
 public ShaderDecodeEntry(ShaderDecodeFunc func, int xBits)
 {
     Func  = func;
     XBits = xBits;
 }