Beispiel #1
0
        private void WriteInstruction(InstructionToken instruction)
        {
            if (RemoveIndentInstruction(instruction))
            {
                Indent--;
            }
            if (instruction.Opcode != Opcode.Comment && instruction.Opcode != Opcode.End)
            {
                WriteIndent();
            }
            if (AddIndentInstruction(instruction))
            {
                Indent++;
            }
            switch (instruction.Opcode)
            {
            case Opcode.Abs:
                WriteLine("abs{0} {1}, {2}",
                          GetInstructionModifier(instruction),
                          GetDestinationName(instruction), GetSourceName(instruction, 1));
                break;

            case Opcode.Add:
                WriteLine("add{0} {1}, {2}, {3}",
                          GetInstructionModifier(instruction), GetDestinationName(instruction),
                          GetSourceName(instruction, 1), GetSourceName(instruction, 2));
                break;

            case Opcode.Cmp:
                WriteLine("cmp{0} {1}, {2}, {3}, {4}",
                          GetInstructionModifier(instruction), GetDestinationName(instruction),
                          GetSourceName(instruction, 1), GetSourceName(instruction, 2), GetSourceName(instruction, 3));
                break;

            case Opcode.Dcl:
                string dclInstruction = "dcl";
                var    registerType   = instruction.GetParamRegisterType(1);
                if (ShouldDeclareSemantics(instruction, registerType))
                {
                    dclInstruction += "_" + instruction.GetDeclSemantic().ToLower();
                }
                WriteLine("{0}{1} {2}", dclInstruction, GetInstructionModifier(instruction), GetDestinationName(instruction));
                break;

            case Opcode.Def:
            {
                string modifier          = GetInstructionModifier(instruction);
                string constRegisterName = instruction.GetParamRegisterName(0);
                string constValue0       = SingleToString(instruction.GetParamBytes(1));
                string constValue1       = SingleToString(instruction.GetParamBytes(2));
                string constValue2       = SingleToString(instruction.GetParamBytes(3));
                string constValue3       = SingleToString(instruction.GetParamBytes(4));
                WriteLine("def{0} {1}, {2}, {3}, {4}, {5}", modifier, constRegisterName, constValue0, constValue1, constValue2, constValue3);
            }
            break;

            case Opcode.DefI:
            {
                string constRegisterName = instruction.GetParamRegisterName(0);
                WriteLine("defi{0} {1}, {2}, {3}, {4}, {5}",
                          GetInstructionModifier(instruction), constRegisterName,
                          instruction.Data[1], instruction.Data[2], instruction.Data[3], instruction.Data[4]);
            }
            break;

            case Opcode.DP2Add:
                WriteLine("dp2add{0} {1}, {2}, {3}, {4}",
                          GetInstructionModifier(instruction), GetDestinationName(instruction),
                          GetSourceName(instruction, 1), GetSourceName(instruction, 2), GetSourceName(instruction, 3));
                break;

            case Opcode.Dp3:
                WriteLine("dp3{0} {1}, {2}, {3}",
                          GetInstructionModifier(instruction), GetDestinationName(instruction),
                          GetSourceName(instruction, 1), GetSourceName(instruction, 2));
                break;

            case Opcode.Dp4:
                WriteLine("dp4{0} {1}, {2}, {3}",
                          GetInstructionModifier(instruction), GetDestinationName(instruction),
                          GetSourceName(instruction, 1), GetSourceName(instruction, 2));
                break;

            case Opcode.Else:
                WriteLine("else");
                break;

            case Opcode.Endif:
                WriteLine("endif");
                break;

            case Opcode.Exp:
                WriteLine("exp{0} {1}, {2}",
                          GetInstructionModifier(instruction), GetDestinationName(instruction),
                          GetSourceName(instruction, 1));
                break;

            case Opcode.Frc:
                WriteLine("frc{0} {1}, {2}",
                          GetInstructionModifier(instruction), GetDestinationName(instruction), GetSourceName(instruction, 1));
                break;

            case Opcode.If:
                WriteLine("if {0}", GetSourceName(instruction, 0));
                break;

            case Opcode.IfC:
                WriteLine("if_{0} {1}, {2}",
                          ((IfComparison)instruction.Modifier).ToString().ToLower(),
                          GetSourceName(instruction, 0), GetSourceName(instruction, 1));
                break;

            case Opcode.Log:
                WriteLine("log{0} {1}, {2}",
                          GetInstructionModifier(instruction), GetDestinationName(instruction),
                          GetSourceName(instruction, 1));
                break;

            case Opcode.Lrp:
                WriteLine("lrp{0} {1}, {2}, {3}, {4}",
                          GetInstructionModifier(instruction), GetDestinationName(instruction),
                          GetSourceName(instruction, 1), GetSourceName(instruction, 2), GetSourceName(instruction, 3));
                break;

            case Opcode.Mad:
                WriteLine("mad{0} {1}, {2}, {3}, {4}",
                          GetInstructionModifier(instruction), GetDestinationName(instruction),
                          GetSourceName(instruction, 1), GetSourceName(instruction, 2), GetSourceName(instruction, 3));
                break;

            case Opcode.Max:
                WriteLine("max{0} {1}, {2}, {3}",
                          GetInstructionModifier(instruction), GetDestinationName(instruction),
                          GetSourceName(instruction, 1), GetSourceName(instruction, 2));
                break;

            case Opcode.Min:
                WriteLine("min{0} {1}, {2}, {3}",
                          GetInstructionModifier(instruction), GetDestinationName(instruction),
                          GetSourceName(instruction, 1), GetSourceName(instruction, 2));
                break;

            case Opcode.Mov:
                WriteLine("mov{0} {1}, {2}",
                          GetInstructionModifier(instruction), GetDestinationName(instruction), GetSourceName(instruction, 1));
                break;

            case Opcode.MovA:
                WriteLine("mova{0} {1}, {2}",
                          GetInstructionModifier(instruction), GetDestinationName(instruction), GetSourceName(instruction, 1));
                break;

            case Opcode.Mul:
                WriteLine("mul{0} {1}, {2}, {3}",
                          GetInstructionModifier(instruction), GetDestinationName(instruction),
                          GetSourceName(instruction, 1), GetSourceName(instruction, 2));
                break;

            case Opcode.Nop:
                WriteLine("nop");
                break;

            case Opcode.Nrm:
                WriteLine("nrm{0} {1}, {2}",
                          GetInstructionModifier(instruction), GetDestinationName(instruction), GetSourceName(instruction, 1));
                break;

            case Opcode.Pow:
                WriteLine("pow{0} {1}, {2}, {3}",
                          GetInstructionModifier(instruction), GetDestinationName(instruction),
                          GetSourceName(instruction, 1), GetSourceName(instruction, 2));
                break;

            case Opcode.Rcp:
                WriteLine("rcp{0} {1}, {2}",
                          GetInstructionModifier(instruction),
                          GetDestinationName(instruction), GetSourceName(instruction, 1));
                break;

            case Opcode.Rsq:
                WriteLine("rsq{0} {1}, {2}",
                          GetInstructionModifier(instruction), GetDestinationName(instruction), GetSourceName(instruction, 1));
                break;

            case Opcode.Sge:
                WriteLine("sge{0} {1}, {2}, {3}",
                          GetInstructionModifier(instruction), GetDestinationName(instruction),
                          GetSourceName(instruction, 1), GetSourceName(instruction, 2));
                break;

            case Opcode.Slt:
                WriteLine("slt{0} {1}, {2}, {3}",
                          GetInstructionModifier(instruction), GetDestinationName(instruction),
                          GetSourceName(instruction, 1), GetSourceName(instruction, 2));
                break;

            case Opcode.SinCos:
                if (shader.MajorVersion >= 3)
                {
                    WriteLine("sincos {0}, {1}", GetDestinationName(instruction),
                              GetSourceName(instruction, 1));
                }
                else
                {
                    WriteLine("sincos {0}, {1}, {2}, {3}", GetDestinationName(instruction),
                              GetSourceName(instruction, 1), GetSourceName(instruction, 2), GetSourceName(instruction, 3));
                }
                break;

            case Opcode.Sub:
                WriteLine("sub{0} {1}, {2}, {3}",
                          GetInstructionModifier(instruction), GetDestinationName(instruction),
                          GetSourceName(instruction, 1), GetSourceName(instruction, 2));
                break;

            case Opcode.Tex:
                if ((shader.MajorVersion == 1 && shader.MinorVersion >= 4) || (shader.MajorVersion > 1))
                {
                    WriteLine("texld {0}, {1}, {2}", GetDestinationName(instruction),
                              GetSourceName(instruction, 1), GetSourceName(instruction, 2));
                }
                else
                {
                    WriteLine("tex {0}", GetDestinationName(instruction));
                }
                break;

            case Opcode.TexLDL:
                WriteLine("texldl {0}, {1}, {2}", GetDestinationName(instruction),
                          GetSourceName(instruction, 1), GetSourceName(instruction, 2));
                break;

            case Opcode.TexKill:
                WriteLine("texkill {0}", GetDestinationName(instruction));
                break;

            case Opcode.Rep:
                WriteLine("rep {0}",
                          GetDestinationName(instruction));
                break;

            case Opcode.EndRep:
                WriteLine("endrep");
                break;

            case Opcode.DSX:
                WriteLine("dsx{0} {1}, {2}",
                          GetInstructionModifier(instruction), GetDestinationName(instruction), GetSourceName(instruction, 1));
                break;

            case Opcode.DSY:
                WriteLine("dsy{0} {1}, {2}",
                          GetInstructionModifier(instruction), GetDestinationName(instruction), GetSourceName(instruction, 1));
                break;

            case Opcode.TexLDD:
                WriteLine("texldd {0}, {1}, {2}, {3}, {4}", GetDestinationName(instruction), GetSourceName(instruction, 1),
                          GetSourceName(instruction, 2), GetSourceName(instruction, 3),
                          GetSourceName(instruction, 4));
                break;

            case Opcode.BreakC:
                WriteLine("break_{0} {1}, {2}",
                          ((IfComparison)instruction.Modifier).ToString().ToLower(),
                          GetSourceName(instruction, 0),
                          GetSourceName(instruction, 1));
                break;

            //TODO: Add tests for Loop, and Lit
            case Opcode.Loop:
                WriteLine("loop {0}, {1}",
                          GetSourceName(instruction, 0),
                          GetSourceName(instruction, 1));
                break;

            case Opcode.EndLoop:
                WriteLine("endloop");
                break;

            case Opcode.Lit:
                WriteLine("lit{0} {1}, {2}",
                          GetInstructionModifier(instruction), GetDestinationName(instruction),
                          GetSourceName(instruction, 1));
                break;

            case Opcode.ExpP:
                WriteLine("expp{0} {1}, {2}",
                          GetInstructionModifier(instruction), GetDestinationName(instruction),
                          GetSourceName(instruction, 1));
                break;

            case Opcode.LogP:
                WriteLine("logp{0} {1}, {2}",
                          GetInstructionModifier(instruction), GetDestinationName(instruction),
                          GetSourceName(instruction, 1));
                break;

            case Opcode.M4x4:
                WriteLine("m4x4{0} {1}, {2}, {3}",
                          GetInstructionModifier(instruction), GetDestinationName(instruction),
                          GetSourceName(instruction, 1), GetSourceName(instruction, 2));
                break;

            case Opcode.M4x3:
                WriteLine("m4x3{0} {1}, {2}, {3}",
                          GetInstructionModifier(instruction), GetDestinationName(instruction),
                          GetSourceName(instruction, 1), GetSourceName(instruction, 2));
                break;

            case Opcode.M3x3:
                WriteLine("m3x3{0} {1}, {2}, {3}",
                          GetInstructionModifier(instruction), GetDestinationName(instruction),
                          GetSourceName(instruction, 1), GetSourceName(instruction, 2));
                break;

            case Opcode.Call:
                WriteLine("call {0}",
                          GetSourceName(instruction, 0));
                break;

            case Opcode.Ret:
                WriteLine("ret");
                break;

            case Opcode.Label:
                WriteLine("label", GetSourceName(instruction, 0));
                break;

            case Opcode.Comment:
            case Opcode.End:
                break;

            default:
                WriteLine(instruction.Opcode.ToString());
                //WriteLine("// Warning - Not Implemented");
                throw new NotImplementedException($"Instruction not implemented {instruction.Opcode}");
            }
        }