Esempio n. 1
0
        private static void EmitFsetp(ShaderIrBlock Block, long OpCode, ShaderOper Oper)
        {
            bool Aa = ((OpCode >> 7) & 1) != 0;
            bool Np = ((OpCode >> 42) & 1) != 0;
            bool Na = ((OpCode >> 43) & 1) != 0;
            bool Ab = ((OpCode >> 44) & 1) != 0;

            ShaderIrNode OperA = GetOperGpr8(OpCode), OperB;

            switch (Oper)
            {
            case ShaderOper.CR:   OperB = GetOperCbuf34(OpCode); break;

            case ShaderOper.Immf: OperB = GetOperImmf19_20(OpCode); break;

            case ShaderOper.RR:   OperB = GetOperGpr20(OpCode); break;

            default: throw new ArgumentException(nameof(Oper));
            }

            ShaderIrInst CmpInst = GetCmp(OpCode);

            ShaderIrOp Op = new ShaderIrOp(CmpInst,
                                           GetAluAbsNeg(OperA, Aa, Na),
                                           GetAluAbs(OperB, Ab));

            ShaderIrOperPred P0Node = GetOperPred3(OpCode);
            ShaderIrOperPred P1Node = GetOperPred0(OpCode);
            ShaderIrOperPred P2Node = GetOperPred39(OpCode);

            Block.AddNode(GetPredNode(new ShaderIrAsg(P0Node, Op), OpCode));

            ShaderIrInst LopInst = GetBLop(OpCode);

            if (LopInst == ShaderIrInst.Band && P1Node.IsConst && P2Node.IsConst)
            {
                return;
            }

            ShaderIrNode P2NNode = P2Node;

            if (Np)
            {
                P2NNode = new ShaderIrOp(ShaderIrInst.Bnot, P2NNode);
            }

            Op = new ShaderIrOp(ShaderIrInst.Bnot, P0Node);

            Op = new ShaderIrOp(LopInst, Op, P2NNode);

            Block.AddNode(GetPredNode(new ShaderIrAsg(P1Node, Op), OpCode));

            Op = new ShaderIrOp(LopInst, P0Node, P2NNode);

            Block.AddNode(GetPredNode(new ShaderIrAsg(P0Node, Op), OpCode));
        }
Esempio n. 2
0
        public static ShaderIrNode GetPredNode(ShaderIrNode Node, long OpCode)
        {
            ShaderIrOperPred Pred = GetPredNode(OpCode);

            if (Pred.Index != ShaderIrOperPred.UnusedIndex)
            {
                Node = new ShaderIrCond(Pred, Node);
            }

            return(Node);
        }
Esempio n. 3
0
        public static void Psetp(ShaderIrBlock Block, long OpCode, int Position)
        {
            bool NegA = OpCode.Read(15);
            bool NegB = OpCode.Read(32);
            bool NegP = OpCode.Read(42);

            ShaderIrInst LopInst = OpCode.BLop24();

            ShaderIrNode OperA = OpCode.Pred12();
            ShaderIrNode OperB = OpCode.Pred29();

            if (NegA)
            {
                OperA = new ShaderIrOp(ShaderIrInst.Bnot, OperA);
            }

            if (NegB)
            {
                OperB = new ShaderIrOp(ShaderIrInst.Bnot, OperB);
            }

            ShaderIrOp Op = new ShaderIrOp(LopInst, OperA, OperB);

            ShaderIrOperPred P0Node = OpCode.Pred3();
            ShaderIrOperPred P1Node = OpCode.Pred0();
            ShaderIrOperPred P2Node = OpCode.Pred39();

            Block.AddNode(OpCode.PredNode(new ShaderIrAsg(P0Node, Op)));

            LopInst = OpCode.BLop45();

            if (LopInst == ShaderIrInst.Band && P1Node.IsConst && P2Node.IsConst)
            {
                return;
            }

            ShaderIrNode P2NNode = P2Node;

            if (NegP)
            {
                P2NNode = new ShaderIrOp(ShaderIrInst.Bnot, P2NNode);
            }

            Op = new ShaderIrOp(ShaderIrInst.Bnot, P0Node);

            Op = new ShaderIrOp(LopInst, Op, P2NNode);

            Block.AddNode(OpCode.PredNode(new ShaderIrAsg(P1Node, Op)));

            Op = new ShaderIrOp(LopInst, P0Node, P2NNode);

            Block.AddNode(OpCode.PredNode(new ShaderIrAsg(P0Node, Op)));
        }
Esempio n. 4
0
        public static void Psetp(ShaderIrBlock Block, long OpCode)
        {
            bool NegA = ((OpCode >> 15) & 1) != 0;
            bool NegB = ((OpCode >> 32) & 1) != 0;
            bool NegP = ((OpCode >> 42) & 1) != 0;

            ShaderIrInst LopInst = GetBLop24(OpCode);

            ShaderIrNode OperA = GetOperPred12(OpCode);
            ShaderIrNode OperB = GetOperPred29(OpCode);

            if (NegA)
            {
                OperA = new ShaderIrOp(ShaderIrInst.Bnot, OperA);
            }

            if (NegB)
            {
                OperB = new ShaderIrOp(ShaderIrInst.Bnot, OperB);
            }

            ShaderIrOp Op = new ShaderIrOp(LopInst, OperA, OperB);

            ShaderIrOperPred P0Node = GetOperPred3(OpCode);
            ShaderIrOperPred P1Node = GetOperPred0(OpCode);
            ShaderIrOperPred P2Node = GetOperPred39(OpCode);

            Block.AddNode(GetPredNode(new ShaderIrAsg(P0Node, Op), OpCode));

            LopInst = GetBLop45(OpCode);

            if (LopInst == ShaderIrInst.Band && P1Node.IsConst && P2Node.IsConst)
            {
                return;
            }

            ShaderIrNode P2NNode = P2Node;

            if (NegP)
            {
                P2NNode = new ShaderIrOp(ShaderIrInst.Bnot, P2NNode);
            }

            Op = new ShaderIrOp(ShaderIrInst.Bnot, P0Node);

            Op = new ShaderIrOp(LopInst, Op, P2NNode);

            Block.AddNode(GetPredNode(new ShaderIrAsg(P1Node, Op), OpCode));

            Op = new ShaderIrOp(LopInst, P0Node, P2NNode);

            Block.AddNode(GetPredNode(new ShaderIrAsg(P0Node, Op), OpCode));
        }
Esempio n. 5
0
        public static void Psetp(ShaderIrBlock block, long opCode, int position)
        {
            bool negA = opCode.Read(15);
            bool negB = opCode.Read(32);
            bool negP = opCode.Read(42);

            ShaderIrInst lopInst = opCode.BLop24();

            ShaderIrNode operA = opCode.Pred12();
            ShaderIrNode operB = opCode.Pred29();

            if (negA)
            {
                operA = new ShaderIrOp(ShaderIrInst.Bnot, operA);
            }

            if (negB)
            {
                operB = new ShaderIrOp(ShaderIrInst.Bnot, operB);
            }

            ShaderIrOp op = new ShaderIrOp(lopInst, operA, operB);

            ShaderIrOperPred p0Node = opCode.Pred3();
            ShaderIrOperPred p1Node = opCode.Pred0();
            ShaderIrOperPred p2Node = opCode.Pred39();

            block.AddNode(opCode.PredNode(new ShaderIrAsg(p0Node, op)));

            lopInst = opCode.BLop45();

            if (lopInst == ShaderIrInst.Band && p1Node.IsConst && p2Node.IsConst)
            {
                return;
            }

            ShaderIrNode p2NNode = p2Node;

            if (negP)
            {
                p2NNode = new ShaderIrOp(ShaderIrInst.Bnot, p2NNode);
            }

            op = new ShaderIrOp(ShaderIrInst.Bnot, p0Node);

            op = new ShaderIrOp(lopInst, op, p2NNode);

            block.AddNode(opCode.PredNode(new ShaderIrAsg(p1Node, op)));

            op = new ShaderIrOp(lopInst, p0Node, p2NNode);

            block.AddNode(opCode.PredNode(new ShaderIrAsg(p0Node, op)));
        }
Esempio n. 6
0
        private static void EmitFmnmx(ShaderIrBlock Block, long OpCode, ShaderOper Oper)
        {
            bool NegB = ((OpCode >> 45) & 1) != 0;
            bool AbsA = ((OpCode >> 46) & 1) != 0;
            bool NegA = ((OpCode >> 48) & 1) != 0;
            bool AbsB = ((OpCode >> 49) & 1) != 0;

            ShaderIrNode OperA = GetOperGpr8(OpCode), OperB;

            OperA = GetAluFabsFneg(OperA, AbsA, NegA);

            switch (Oper)
            {
            case ShaderOper.CR:   OperB = GetOperCbuf34(OpCode); break;

            case ShaderOper.Immf: OperB = GetOperImmf19_20(OpCode); break;

            case ShaderOper.RR:   OperB = GetOperGpr20(OpCode); break;

            default: throw new ArgumentException(nameof(Oper));
            }

            OperB = GetAluFabsFneg(OperB, AbsB, NegB);

            ShaderIrOperPred Pred = GetOperPred39(OpCode);

            ShaderIrOp Op;

            if (Pred.IsConst)
            {
                bool IsMax = ((OpCode >> 42) & 1) != 0;

                Op = new ShaderIrOp(IsMax
                    ? ShaderIrInst.Fmax
                    : ShaderIrInst.Fmin, OperA, OperB);

                Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperGpr0(OpCode), Op), OpCode));
            }
            else
            {
                ShaderIrNode PredN = GetOperPred39N(OpCode);

                ShaderIrOp OpMax = new ShaderIrOp(ShaderIrInst.Fmax, OperA, OperB);
                ShaderIrOp OpMin = new ShaderIrOp(ShaderIrInst.Fmin, OperA, OperB);

                ShaderIrAsg AsgMax = new ShaderIrAsg(GetOperGpr0(OpCode), OpMax);
                ShaderIrAsg AsgMin = new ShaderIrAsg(GetOperGpr0(OpCode), OpMin);

                Block.AddNode(GetPredNode(new ShaderIrCond(PredN, AsgMax, Not: true), OpCode));
                Block.AddNode(GetPredNode(new ShaderIrCond(PredN, AsgMin, Not: false), OpCode));
            }
        }
Esempio n. 7
0
        private static ShaderIrNode PredNode(this long OpCode, ShaderIrNode Node)
        {
            ShaderIrOperPred Pred = OpCode.PredNode();

            if (Pred.Index != ShaderIrOperPred.UnusedIndex)
            {
                bool Inv = OpCode.Read(19);

                Node = new ShaderIrCond(Pred, Node, Inv);
            }

            return(Node);
        }
Esempio n. 8
0
        private static ShaderIrNode PredNode(this long opCode, ShaderIrNode node)
        {
            ShaderIrOperPred pred = opCode.PredNode();

            if (pred.Index != ShaderIrOperPred.UnusedIndex)
            {
                bool inv = opCode.Read(19);

                node = new ShaderIrCond(pred, node, inv);
            }

            return(node);
        }
Esempio n. 9
0
        public static ShaderIrNode GetPredNode(ShaderIrNode Node, long OpCode)
        {
            ShaderIrOperPred Pred = GetPredNode(OpCode);

            if (Pred.Index != ShaderIrOperPred.UnusedIndex)
            {
                bool Inv = ((OpCode >> 19) & 1) != 0;

                Node = new ShaderIrCond(Pred, Node, Inv);
            }

            return(Node);
        }
Esempio n. 10
0
        private static void EmitSet(ShaderIrBlock Block, long OpCode, bool IsFloat, ShaderOper Oper)
        {
            bool NegA = OpCode.Read(43);
            bool AbsB = OpCode.Read(44);
            bool NegB = OpCode.Read(53);
            bool AbsA = OpCode.Read(54);

            bool BoolFloat = OpCode.Read(IsFloat ? 52 : 44);

            ShaderIrNode OperA = OpCode.Gpr8(), OperB;

            switch (Oper)
            {
            case ShaderOper.CR:   OperB = OpCode.Cbuf34();    break;

            case ShaderOper.Imm:  OperB = OpCode.Imm19_20();  break;

            case ShaderOper.Immf: OperB = OpCode.Immf19_20(); break;

            case ShaderOper.RR:   OperB = OpCode.Gpr20();     break;

            default: throw new ArgumentException(nameof(Oper));
            }

            ShaderIrInst CmpInst;

            if (IsFloat)
            {
                OperA = GetAluFabsFneg(OperA, AbsA, NegA);
                OperB = GetAluFabsFneg(OperB, AbsB, NegB);

                CmpInst = OpCode.CmpF();
            }
            else
            {
                CmpInst = OpCode.Cmp();
            }

            ShaderIrOp Op = new ShaderIrOp(CmpInst, OperA, OperB);

            ShaderIrInst LopInst = OpCode.BLop45();

            ShaderIrOperPred PNode = OpCode.Pred39();

            ShaderIrNode Imm0, Imm1;

            if (BoolFloat)
            {
                Imm0 = new ShaderIrOperImmf(0);
                Imm1 = new ShaderIrOperImmf(1);
            }
            else
            {
                Imm0 = new ShaderIrOperImm(0);
                Imm1 = new ShaderIrOperImm(-1);
            }

            ShaderIrNode Asg0 = new ShaderIrAsg(OpCode.Gpr0(), Imm0);
            ShaderIrNode Asg1 = new ShaderIrAsg(OpCode.Gpr0(), Imm1);

            if (LopInst != ShaderIrInst.Band || !PNode.IsConst)
            {
                ShaderIrOp Op2 = new ShaderIrOp(LopInst, Op, PNode);

                Asg0 = new ShaderIrCond(Op2, Asg0, Not: true);
                Asg1 = new ShaderIrCond(Op2, Asg1, Not: false);
            }
            else
            {
                Asg0 = new ShaderIrCond(Op, Asg0, Not: true);
                Asg1 = new ShaderIrCond(Op, Asg1, Not: false);
            }

            Block.AddNode(OpCode.PredNode(Asg0));
            Block.AddNode(OpCode.PredNode(Asg1));
        }
Esempio n. 11
0
        private static void EmitMnmx(ShaderIrBlock Block, long OpCode, bool IsFloat, ShaderOper Oper)
        {
            bool NegB = OpCode.Read(45);
            bool AbsA = OpCode.Read(46);
            bool NegA = OpCode.Read(48);
            bool AbsB = OpCode.Read(49);

            ShaderIrNode OperA = OpCode.Gpr8(), OperB;

            if (IsFloat)
            {
                OperA = GetAluFabsFneg(OperA, AbsA, NegA);
            }
            else
            {
                OperA = GetAluIabsIneg(OperA, AbsA, NegA);
            }

            switch (Oper)
            {
            case ShaderOper.CR:   OperB = OpCode.Cbuf34();    break;

            case ShaderOper.Imm:  OperB = OpCode.Imm19_20();  break;

            case ShaderOper.Immf: OperB = OpCode.Immf19_20(); break;

            case ShaderOper.RR:   OperB = OpCode.Gpr20();     break;

            default: throw new ArgumentException(nameof(Oper));
            }

            if (IsFloat)
            {
                OperB = GetAluFabsFneg(OperB, AbsB, NegB);
            }
            else
            {
                OperB = GetAluIabsIneg(OperB, AbsB, NegB);
            }

            ShaderIrOperPred Pred = OpCode.Pred39();

            ShaderIrOp Op;

            ShaderIrInst MaxInst = IsFloat ? ShaderIrInst.Fmax : ShaderIrInst.Max;
            ShaderIrInst MinInst = IsFloat ? ShaderIrInst.Fmin : ShaderIrInst.Min;

            if (Pred.IsConst)
            {
                bool IsMax = OpCode.Read(42);

                Op = new ShaderIrOp(IsMax
                    ? MaxInst
                    : MinInst, OperA, OperB);

                Block.AddNode(OpCode.PredNode(new ShaderIrAsg(OpCode.Gpr0(), Op)));
            }
            else
            {
                ShaderIrNode PredN = OpCode.Pred39N();

                ShaderIrOp OpMax = new ShaderIrOp(MaxInst, OperA, OperB);
                ShaderIrOp OpMin = new ShaderIrOp(MinInst, OperA, OperB);

                ShaderIrAsg AsgMax = new ShaderIrAsg(OpCode.Gpr0(), OpMax);
                ShaderIrAsg AsgMin = new ShaderIrAsg(OpCode.Gpr0(), OpMin);

                Block.AddNode(OpCode.PredNode(new ShaderIrCond(PredN, AsgMax, Not: true)));
                Block.AddNode(OpCode.PredNode(new ShaderIrCond(PredN, AsgMin, Not: false)));
            }
        }
Esempio n. 12
0
        private static void EmitSetp(ShaderIrBlock Block, long OpCode, bool IsFloat, ShaderOper Oper)
        {
            bool AbsA = OpCode.Read(7);
            bool NegP = OpCode.Read(42);
            bool NegA = OpCode.Read(43);
            bool AbsB = OpCode.Read(44);

            ShaderIrNode OperA = OpCode.Gpr8(), OperB;

            switch (Oper)
            {
            case ShaderOper.CR:   OperB = OpCode.Cbuf34();    break;

            case ShaderOper.Imm:  OperB = OpCode.Imm19_20();  break;

            case ShaderOper.Immf: OperB = OpCode.Immf19_20(); break;

            case ShaderOper.RR:   OperB = OpCode.Gpr20();     break;

            default: throw new ArgumentException(nameof(Oper));
            }

            ShaderIrInst CmpInst;

            if (IsFloat)
            {
                OperA = GetAluFabsFneg(OperA, AbsA, NegA);
                OperB = GetAluFabs(OperB, AbsB);

                CmpInst = OpCode.CmpF();
            }
            else
            {
                CmpInst = OpCode.Cmp();
            }

            ShaderIrOp Op = new ShaderIrOp(CmpInst, OperA, OperB);

            ShaderIrOperPred P0Node = OpCode.Pred3();
            ShaderIrOperPred P1Node = OpCode.Pred0();
            ShaderIrOperPred P2Node = OpCode.Pred39();

            Block.AddNode(OpCode.PredNode(new ShaderIrAsg(P0Node, Op)));

            ShaderIrInst LopInst = OpCode.BLop45();

            if (LopInst == ShaderIrInst.Band && P1Node.IsConst && P2Node.IsConst)
            {
                return;
            }

            ShaderIrNode P2NNode = P2Node;

            if (NegP)
            {
                P2NNode = new ShaderIrOp(ShaderIrInst.Bnot, P2NNode);
            }

            Op = new ShaderIrOp(ShaderIrInst.Bnot, P0Node);

            Op = new ShaderIrOp(LopInst, Op, P2NNode);

            Block.AddNode(OpCode.PredNode(new ShaderIrAsg(P1Node, Op)));

            Op = new ShaderIrOp(LopInst, P0Node, P2NNode);

            Block.AddNode(OpCode.PredNode(new ShaderIrAsg(P0Node, Op)));
        }
Esempio n. 13
0
        private static void EmitSet(ShaderIrBlock Block, long OpCode, bool IsFloat, ShaderOper Oper)
        {
            bool Na = ((OpCode >> 43) & 1) != 0;
            bool Ab = ((OpCode >> 44) & 1) != 0;
            bool Nb = ((OpCode >> 53) & 1) != 0;
            bool Aa = ((OpCode >> 54) & 1) != 0;

            ShaderIrNode OperA = GetOperGpr8(OpCode), OperB;

            switch (Oper)
            {
            case ShaderOper.CR:   OperB = GetOperCbuf34(OpCode); break;

            case ShaderOper.Imm:  OperB = GetOperImm19_20(OpCode); break;

            case ShaderOper.Immf: OperB = GetOperImmf19_20(OpCode); break;

            case ShaderOper.RR:   OperB = GetOperGpr20(OpCode); break;

            default: throw new ArgumentException(nameof(Oper));
            }

            ShaderIrInst CmpInst;

            if (IsFloat)
            {
                OperA = GetAluAbsNeg(OperA, Aa, Na);
                OperB = GetAluAbsNeg(OperB, Ab, Nb);

                CmpInst = GetCmpF(OpCode);
            }
            else
            {
                CmpInst = GetCmp(OpCode);
            }

            ShaderIrOp Op = new ShaderIrOp(CmpInst, OperA, OperB);

            ShaderIrInst LopInst = GetBLop(OpCode);

            ShaderIrOperPred PNode = GetOperPred39(OpCode);

            ShaderIrOperImmf Imm0 = new ShaderIrOperImmf(0);
            ShaderIrOperImmf Imm1 = new ShaderIrOperImmf(1);

            ShaderIrNode Asg0 = new ShaderIrAsg(GetOperGpr0(OpCode), Imm0);
            ShaderIrNode Asg1 = new ShaderIrAsg(GetOperGpr0(OpCode), Imm1);

            if (LopInst != ShaderIrInst.Band || !PNode.IsConst)
            {
                ShaderIrOp Op2 = new ShaderIrOp(LopInst, Op, PNode);

                Asg0 = new ShaderIrCond(Op2, Asg0, Not: true);
                Asg1 = new ShaderIrCond(Op2, Asg1, Not: false);
            }
            else
            {
                Asg0 = new ShaderIrCond(Op, Asg0, Not: true);
                Asg1 = new ShaderIrCond(Op, Asg1, Not: false);
            }

            Block.AddNode(GetPredNode(Asg0, OpCode));
            Block.AddNode(GetPredNode(Asg1, OpCode));
        }
Esempio n. 14
0
        private static void EmitSet(ShaderIrBlock block, long opCode, bool isFloat, ShaderOper oper)
        {
            bool negA = opCode.Read(43);
            bool absB = opCode.Read(44);
            bool negB = opCode.Read(53);
            bool absA = opCode.Read(54);

            bool boolFloat = opCode.Read(isFloat ? 52 : 44);

            ShaderIrNode operA = opCode.Gpr8(), operB;

            switch (oper)
            {
            case ShaderOper.Cr:   operB = opCode.Cbuf34();    break;

            case ShaderOper.Imm:  operB = opCode.Imm19_20();  break;

            case ShaderOper.Immf: operB = opCode.Immf19_20(); break;

            case ShaderOper.Rr:   operB = opCode.Gpr20();     break;

            default: throw new ArgumentException(nameof(oper));
            }

            ShaderIrInst cmpInst;

            if (isFloat)
            {
                operA = GetAluFabsFneg(operA, absA, negA);
                operB = GetAluFabsFneg(operB, absB, negB);

                cmpInst = opCode.CmpF();
            }
            else
            {
                cmpInst = opCode.Cmp();
            }

            ShaderIrOp op = new ShaderIrOp(cmpInst, operA, operB);

            ShaderIrInst lopInst = opCode.BLop45();

            ShaderIrOperPred pNode = opCode.Pred39();

            ShaderIrNode imm0, imm1;

            if (boolFloat)
            {
                imm0 = new ShaderIrOperImmf(0);
                imm1 = new ShaderIrOperImmf(1);
            }
            else
            {
                imm0 = new ShaderIrOperImm(0);
                imm1 = new ShaderIrOperImm(-1);
            }

            ShaderIrNode asg0 = new ShaderIrAsg(opCode.Gpr0(), imm0);
            ShaderIrNode asg1 = new ShaderIrAsg(opCode.Gpr0(), imm1);

            if (lopInst != ShaderIrInst.Band || !pNode.IsConst)
            {
                ShaderIrOp op2 = new ShaderIrOp(lopInst, op, pNode);

                asg0 = new ShaderIrCond(op2, asg0, not: true);
                asg1 = new ShaderIrCond(op2, asg1, not: false);
            }
            else
            {
                asg0 = new ShaderIrCond(op, asg0, not: true);
                asg1 = new ShaderIrCond(op, asg1, not: false);
            }

            block.AddNode(opCode.PredNode(asg0));
            block.AddNode(opCode.PredNode(asg1));
        }
Esempio n. 15
0
        private static void EmitMnmx(ShaderIrBlock block, long opCode, bool isFloat, ShaderOper oper)
        {
            bool negB = opCode.Read(45);
            bool absA = opCode.Read(46);
            bool negA = opCode.Read(48);
            bool absB = opCode.Read(49);

            ShaderIrNode operA = opCode.Gpr8(), operB;

            if (isFloat)
            {
                operA = GetAluFabsFneg(operA, absA, negA);
            }
            else
            {
                operA = GetAluIabsIneg(operA, absA, negA);
            }

            switch (oper)
            {
            case ShaderOper.Cr:   operB = opCode.Cbuf34();    break;

            case ShaderOper.Imm:  operB = opCode.Imm19_20();  break;

            case ShaderOper.Immf: operB = opCode.Immf19_20(); break;

            case ShaderOper.Rr:   operB = opCode.Gpr20();     break;

            default: throw new ArgumentException(nameof(oper));
            }

            if (isFloat)
            {
                operB = GetAluFabsFneg(operB, absB, negB);
            }
            else
            {
                operB = GetAluIabsIneg(operB, absB, negB);
            }

            ShaderIrOperPred pred = opCode.Pred39();

            ShaderIrOp op;

            ShaderIrInst maxInst = isFloat ? ShaderIrInst.Fmax : ShaderIrInst.Max;
            ShaderIrInst minInst = isFloat ? ShaderIrInst.Fmin : ShaderIrInst.Min;

            if (pred.IsConst)
            {
                bool isMax = opCode.Read(42);

                op = new ShaderIrOp(isMax
                    ? maxInst
                    : minInst, operA, operB);

                block.AddNode(opCode.PredNode(new ShaderIrAsg(opCode.Gpr0(), op)));
            }
            else
            {
                ShaderIrNode predN = opCode.Pred39N();

                ShaderIrOp opMax = new ShaderIrOp(maxInst, operA, operB);
                ShaderIrOp opMin = new ShaderIrOp(minInst, operA, operB);

                ShaderIrAsg asgMax = new ShaderIrAsg(opCode.Gpr0(), opMax);
                ShaderIrAsg asgMin = new ShaderIrAsg(opCode.Gpr0(), opMin);

                block.AddNode(opCode.PredNode(new ShaderIrCond(predN, asgMax, not: true)));
                block.AddNode(opCode.PredNode(new ShaderIrCond(predN, asgMin, not: false)));
            }
        }
Esempio n. 16
0
        private static void EmitSetp(ShaderIrBlock block, long opCode, bool isFloat, ShaderOper oper)
        {
            bool absA = opCode.Read(7);
            bool negP = opCode.Read(42);
            bool negA = opCode.Read(43);
            bool absB = opCode.Read(44);

            ShaderIrNode operA = opCode.Gpr8(), operB;

            switch (oper)
            {
            case ShaderOper.Cr:   operB = opCode.Cbuf34();    break;

            case ShaderOper.Imm:  operB = opCode.Imm19_20();  break;

            case ShaderOper.Immf: operB = opCode.Immf19_20(); break;

            case ShaderOper.Rr:   operB = opCode.Gpr20();     break;

            default: throw new ArgumentException(nameof(oper));
            }

            ShaderIrInst cmpInst;

            if (isFloat)
            {
                operA = GetAluFabsFneg(operA, absA, negA);
                operB = GetAluFabs(operB, absB);

                cmpInst = opCode.CmpF();
            }
            else
            {
                cmpInst = opCode.Cmp();
            }

            ShaderIrOp op = new ShaderIrOp(cmpInst, operA, operB);

            ShaderIrOperPred p0Node = opCode.Pred3();
            ShaderIrOperPred p1Node = opCode.Pred0();
            ShaderIrOperPred p2Node = opCode.Pred39();

            block.AddNode(opCode.PredNode(new ShaderIrAsg(p0Node, op)));

            ShaderIrInst lopInst = opCode.BLop45();

            if (lopInst == ShaderIrInst.Band && p1Node.IsConst && p2Node.IsConst)
            {
                return;
            }

            ShaderIrNode p2NNode = p2Node;

            if (negP)
            {
                p2NNode = new ShaderIrOp(ShaderIrInst.Bnot, p2NNode);
            }

            op = new ShaderIrOp(ShaderIrInst.Bnot, p0Node);

            op = new ShaderIrOp(lopInst, op, p2NNode);

            block.AddNode(opCode.PredNode(new ShaderIrAsg(p1Node, op)));

            op = new ShaderIrOp(lopInst, p0Node, p2NNode);

            block.AddNode(opCode.PredNode(new ShaderIrAsg(p0Node, op)));
        }