Esempio n. 1
0
        protected override void Body()
        {
            Lines.AppendLine("using Mosa.Platform.x64.Instructions;");
            Lines.AppendLine();
            Lines.AppendLine("namespace Mosa.Platform.x64");
            Lines.AppendLine("{");
            Lines.AppendLine("\t/// <summary>");
            Lines.AppendLine("\t/// X64 Instructions");
            Lines.AppendLine("\t/// </summary>");
            Lines.AppendLine("\tpublic static class X64");
            Lines.AppendLine("\t{");

            foreach (var entry in Entries.Instructions)
            {
                Lines.AppendLine("\t\tpublic static readonly " + entry.Name + " " + entry.Name + " = new " + entry.Name + "();");
            }

            Lines.AppendLine("\t}");
            Lines.AppendLine("}");
        }
Esempio n. 2
0
        protected override void Body()
        {
            Lines.AppendLine("namespace Mosa.Compiler.Framework.IR");
            Lines.AppendLine("{");
            Lines.AppendLine("\t/// <summary>");
            Lines.AppendLine("\t/// IR Instructions");
            Lines.AppendLine("\t/// </summary>");
            Lines.AppendLine("\tpublic static class IRInstruction");
            Lines.AppendLine("\t{");

            var instructions = Entries.Instructions;

            foreach (var entry in instructions)
            {
                Lines.AppendLine("\t\tpublic static readonly " + entry.Name + " " + entry.Name + " = new " + entry.Name + "();");
            }

            Lines.AppendLine("\t}");
            Lines.AppendLine("}");
        }
Esempio n. 3
0
        private void EmitCondition(string condition, string encoding, bool end, int index = 0)
        {
            var tabs = "\t\t\t\t\t\t\t\t\t\t".Substring(0, index + 3);

            Lines.Append(tabs);

            Lines.AppendLine("if (" + condition + ")");

            Lines.Append(tabs);
            Lines.AppendLine("{");

            EmitBits(encoding, index + 1);

            if (end)
            {
                Lines.Append(tabs);
                Lines.AppendLine("\treturn;");
            }

            Lines.Append(tabs);
            Lines.AppendLine("}");
        }
        protected override void Body()
        {
            Lines.AppendLine("using Mosa.Compiler.Framework;");
            Lines.AppendLine("using System.Collections.Generic;");
            Lines.AppendLine();
            Lines.AppendLine("namespace Mosa.Platform.x64");
            Lines.AppendLine("{");
            Lines.AppendLine("\t/// <summary>");
            Lines.AppendLine("\t/// X64 Instruction Map");
            Lines.AppendLine("\t/// </summary>");
            Lines.AppendLine("\tpublic static class X64Instructions");
            Lines.AppendLine("\t{");
            Lines.AppendLine("\t\tpublic static readonly List<BaseInstruction> List = new List<BaseInstruction> {");

            foreach (var entry in Entries.Instructions)
            {
                Lines.AppendLine("\t\t\tX64." + entry.Name + ",");
            }

            Lines.AppendLine("\t\t};");
            Lines.AppendLine("\t}");
            Lines.AppendLine("}");
        }
Esempio n. 5
0
        private void EmitBits(string bits, int index = 0)
        {
            var steps = bits.Split('|');
            var tabs  = "\t\t\t\t\t\t\t\t\t\t".Substring(0, index + 3);

            foreach (var s in steps)
            {
                if (string.IsNullOrWhiteSpace(s))
                {
                    continue;
                }

                if (s.StartsWith("["))                 // ignore these
                {
                    continue;
                }

                if (s.StartsWith("0x") | s.StartsWith("x"))
                {
                    // hex
                    string hex = s.StartsWith("x") ? s.Substring(1) : s.Substring(2);

                    Lines.Append(tabs);

                    switch (hex.Length)
                    {
                    case 1:
                        Lines.AppendLine("emitter.OpcodeEncoder.AppendNibble(0x" + hex + ");");
                        break;

                    case 2:
                        Lines.AppendLine("emitter.OpcodeEncoder.AppendByte(0x" + hex + ");");
                        break;

                    case 3:
                        Lines.AppendLine("emitter.OpcodeEncoder.AppendByte(0x" + hex.Substring(0, 2) + ");");
                        Lines.Append(tabs);
                        Lines.AppendLine("emitter.OpcodeEncoder.AppendNibble(0x" + hex.Substring(1) + ");");
                        break;

                    case 4:
                        Lines.AppendLine("emitter.OpcodeEncoder.AppendShort(0x" + hex + ");");
                        break;

                    case 5:
                        Lines.AppendLine("emitter.OpcodeEncoder.AppendShort(0x" + hex.Substring(0, 4) + ");");
                        Lines.Append(tabs);
                        Lines.AppendLine("emitter.OpcodeEncoder.AppendNibble(0x" + hex.Substring(5) + ");");
                        break;

                    case 8:
                        Lines.AppendLine("emitter.OpcodeEncoder.Append32Bits(0x" + hex + ");");
                        break;

                    default: throw new Exception("ERROR!");
                    }
                }
                else if (s.StartsWith("0b") | s.StartsWith("b") | s.StartsWith("0") | s.StartsWith("1"))
                {
                    // binary
                    string binary = s;

                    if (binary.StartsWith("0b"))
                    {
                        binary = s.Substring(2);
                    }

                    if (binary.StartsWith("b"))
                    {
                        binary = s.Substring(1);
                    }

                    Lines.Append(tabs);

                    switch (binary.Length)
                    {
                    case 1:
                        Lines.AppendLine("emitter.OpcodeEncoder.AppendBit(0b" + binary + ");");
                        break;

                    case 2:
                        Lines.AppendLine("emitter.OpcodeEncoder.Append2Bits(0b" + binary + ");");
                        break;

                    case 3:
                        Lines.AppendLine("emitter.OpcodeEncoder.Append3Bits(0b" + binary + ");");
                        break;

                    case 4:
                        Lines.AppendLine("emitter.OpcodeEncoder.AppendNibble(0b" + binary + ");");
                        break;

                    case 5:
                        Lines.AppendLine("emitter.OpcodeEncoder.AppendNibble(0b" + binary.Substring(0, 4) + ");");
                        Lines.Append(tabs);
                        Lines.AppendLine("emitter.OpcodeEncoder.AppendBit(0b" + binary.Substring(4) + ");");
                        break;

                    case 6:
                        Lines.AppendLine("emitter.OpcodeEncoder.AppendNibble(0b" + binary.Substring(0, 4) + ");");
                        Lines.Append(tabs);
                        Lines.AppendLine("emitter.OpcodeEncoder.Append2Bits(0b" + binary.Substring(4) + ");");
                        break;

                    case 7:
                        Lines.AppendLine("emitter.OpcodeEncoder.AppendNibble(0b" + binary.Substring(0, 4) + ");");
                        Lines.Append(tabs);
                        Lines.AppendLine("emitter.OpcodeEncoder.Append3Bits(0b" + binary.Substring(4) + ");");
                        break;

                    case 8:
                        Lines.AppendLine("emitter.OpcodeEncoder.AppendNibble(0b" + binary.Substring(0, 4) + ");");
                        Lines.Append(tabs);
                        Lines.AppendLine("emitter.OpcodeEncoder.AppendNibble(0b" + binary.Substring(4) + ");");
                        break;

                    default: throw new Exception("ERROR!");
                    }
                }
                else
                {
                    var parts = s.Split(':');

                    var code     = string.Empty;
                    var postcode = string.Empty;

                    GetCodes(parts[0], ref code, ref postcode);

                    var operand  = (parts.Length > 1) ? GetOperand(parts[1]) : string.Empty;
                    var operand2 = (parts.Length > 2) ? GetOperand(parts[2]) : null;

                    Lines.Append(tabs);

                    if (operand2 == null)
                    {
                        Lines.AppendLine("emitter.OpcodeEncoder." + code + "(" + operand + postcode + ");");
                    }
                    else
                    {
                        Lines.AppendLine("emitter.OpcodeEncoder." + code + "(" + operand + postcode + ", " + operand2 + ");");
                    }
                }
            }
        }
Esempio n. 6
0
        protected override void Body(dynamic node = null)
        {
            int id = Identifiers.GetInstructionID();

            Lines.AppendLine("using Mosa.Compiler.Framework;");

            if (node.ResultType != null || node.ResultType2 != null)
            {
                Lines.AppendLine("using Mosa.Compiler.MosaTypeSystem;");
            }

            Lines.AppendLine();
            Lines.AppendLine("namespace Mosa.Platform." + Platform + ".Instructions");
            Lines.AppendLine("{");
            Lines.AppendLine("\t/// <summary>");
            Lines.Append("\t/// " + node.Name);

            if (!string.IsNullOrWhiteSpace(node.Description))
            {
                Lines.Append(" - " + node.Description);
            }

            Lines.AppendLine();
            Lines.AppendLine("\t/// </summary>");
            Lines.AppendLine("\t/// <seealso cref=\"Mosa.Platform." + Platform + "." + NormalizedPlatform + "Instruction\" />");
            Lines.AppendLine("\tpublic sealed class " + node.Name + " : " + NormalizedPlatform + "Instruction");
            Lines.AppendLine("\t{");
            Lines.AppendLine("\t\tpublic override int ID { get { return " + id.ToString() + "; } }");
            Lines.AppendLine();
            Lines.AppendLine("\t\tinternal " + node.Name + "()");
            Lines.AppendLine("\t\t\t: base(" + node.ResultCount + ", " + node.OperandCount + ")");
            Lines.AppendLine("\t\t{");
            Lines.AppendLine("\t\t}");

            var FlagsUsed      = node.FlagsUsed == null ? string.Empty : node.FlagsUsed.ToUpper();           // tested_f
            var FlagsSet       = node.FlagsSet == null ? string.Empty : node.FlagsSet.ToUpper();             // values_f (upper=set, lower=cleared)
            var FlagsCleared   = node.FlagsCleared == null ? string.Empty : node.FlagsCleared.ToUpper();     // above
            var FlagsModified  = node.FlagsModified == null ? string.Empty : node.FlagsModified.ToUpper();   // modif_f
            var FlagsUndefined = node.FlagsUndefined == null ? string.Empty : node.FlagsUndefined.ToUpper(); // undef_f

            if (node.AlternativeName != null)
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override string AlternativeName { get { return \"" + node.AlternativeName + "\"; } }");
            }

            if (node.FlowControl != null && node.FlowControl != "Next")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override FlowControl FlowControl { get { return FlowControl." + node.FlowControl + "; } }");
            }

            if (node.ResultType != null && node.ResultType != "")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override BuiltInType ResultType { get { return BuiltInType." + node.ResultType + "; } }");
            }

            if (node.ResultType2 != null && node.ResultType2 != "")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override BuiltInType ResultType2 { get { return BuiltInType." + node.ResultType2 + "; } }");
            }

            if (node.IgnoreDuringCodeGeneration != null && node.IgnoreDuringCodeGeneration == "true")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IgnoreDuringCodeGeneration { get { return true; } }");
            }

            if (node.IgnoreInstructionBasicBlockTargets != null && node.IgnoreInstructionBasicBlockTargets == "true")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IgnoreInstructionBasicBlockTargets { get { return true; } }");
            }

            if (node.VariableOperands != null && node.VariableOperands == "true")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool VariableOperands { get { return true; } }");
            }

            if (node.Commutative != null && node.Commutative == "true")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsCommutative { get { return true; } }");
            }

            if (node.MemoryWrite != null && node.MemoryWrite == "true")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsMemoryWrite { get { return true; } }");
            }

            if (node.MemoryRead != null && node.MemoryRead == "true")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsMemoryRead { get { return true; } }");
            }

            if (node.IOOperation != null && node.IOOperation == "true")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsIOOperation { get { return true; } }");
            }

            if (node.UnspecifiedSideEffect != null && node.UnspecifiedSideEffect == "true")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool HasUnspecifiedSideEffect { get { return true; } }");
            }

            if (node.ThreeTwoAddressConversion != null && node.ThreeTwoAddressConversion == "true")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool ThreeTwoAddressConversion { get { return true; } }");
            }

            if (FlagsUsed.Contains("Z"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsZeroFlagUsed { get { return true; } }");
            }

            if (FlagsSet.Contains("Z"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsZeroFlagSet { get { return true; } }");
            }

            if (FlagsCleared.Contains("Z"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsZeroFlagCleared { get { return true; } }");
            }

            if (FlagsModified.Contains("Z") || FlagsSet.Contains("Z") || FlagsCleared.Contains("Z"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsZeroFlagModified { get { return true; } }");
            }

            if (FlagsUndefined.Contains("Z"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsZeroFlagUnchanged { get { return true; } }");
            }

            if (FlagsUndefined.Contains("Z"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsZeroFlagUndefined { get { return true; } }");
            }

            if (FlagsUsed.Contains("C"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsCarryFlagUsed { get { return true; } }");
            }

            if (FlagsSet.Contains("C"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsCarryFlagSet { get { return true; } }");
            }

            if (FlagsCleared.Contains("C"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsCarryFlagCleared { get { return true; } }");
            }

            if (FlagsModified.Contains("C") || FlagsSet.Contains("C") || FlagsCleared.Contains("C"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsCarryFlagModified { get { return true; } }");
            }

            if (FlagsUndefined.Contains("C"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsCarryFlagUnchanged { get { return true; } }");
            }

            if (FlagsUndefined.Contains("C"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsCarryFlagUndefined { get { return true; } }");
            }

            if (FlagsUsed.Contains("S"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsSignFlagUsed { get { return true; } }");
            }

            if (FlagsSet.Contains("S"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsSignFlagSet { get { return true; } }");
            }

            if (FlagsCleared.Contains("S"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsSignFlagCleared { get { return true; } }");
            }

            if (FlagsModified.Contains("S") || FlagsSet.Contains("S") || FlagsCleared.Contains("S"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsSignFlagModified { get { return true; } }");
            }

            if (FlagsUndefined.Contains("S"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsSignFlagUnchanged { get { return true; } }");
            }

            if (FlagsUndefined.Contains("S"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsSignFlagUndefined { get { return true; } }");
            }

            if (FlagsUsed.Contains("O"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsOverflowFlagUsed { get { return true; } }");
            }

            if (FlagsSet.Contains("O"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsOverflowFlagSet { get { return true; } }");
            }

            if (FlagsCleared.Contains("O"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsOverflowFlagCleared { get { return true; } }");
            }

            if (FlagsModified.Contains("O") || FlagsSet.Contains("O") || FlagsCleared.Contains("O"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsOverflowFlagModified { get { return true; } }");
            }

            if (FlagsUndefined.Contains("O"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsOverflowFlagUnchanged { get { return true; } }");
            }

            if (FlagsUndefined.Contains("O"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsOverflowFlagUndefined { get { return true; } }");
            }

            if (FlagsUsed.Contains("P"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsParityFlagUsed { get { return true; } }");
            }

            if (FlagsSet.Contains("P"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsParityFlagSet { get { return true; } }");
            }

            if (FlagsCleared.Contains("P"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsParityFlagCleared { get { return true; } }");
            }

            if (FlagsModified.Contains("P") || FlagsSet.Contains("P") || FlagsCleared.Contains("P"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsParityFlagModified { get { return true; } }");
            }

            if (FlagsUndefined.Contains("P"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsParityFlagUnchanged { get { return true; } }");
            }

            if (FlagsUndefined.Contains("P"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsParityFlagUndefined { get { return true; } }");
            }

            if (node.LogicalOpposite != null)
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override BaseInstruction GetOpposite()");
                Lines.AppendLine("\t\t{");
                Lines.AppendLine("\t\t\treturn " + node.FamilyName + "." + node.LogicalOpposite + ";");
                Lines.AppendLine("\t\t}");
            }

            if (node.StaticEmitMethod != null)
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override void Emit(InstructionNode node, BaseCodeEmitter emitter)");
                Lines.AppendLine("\t\t{");

                if (node.VariableOperands == null || node.VariableOperands == "false")
                {
                    Lines.AppendLine("\t\t\tSystem.Diagnostics.Debug.Assert(node.ResultCount == DefaultResultCount);");
                    Lines.AppendLine("\t\t\tSystem.Diagnostics.Debug.Assert(node.OperandCount == DefaultOperandCount);");
                    Lines.AppendLine();
                }

                Lines.AppendLine("\t\t\t" + node.StaticEmitMethod.Replace("%", node.Name) + "(node, emitter);");
                Lines.AppendLine("\t\t}");
            }

            if (node.OpcodeEncoding != null)
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override void Emit(InstructionNode node, BaseCodeEmitter emitter)");
                Lines.AppendLine("\t\t{");
                if (node.VariableOperands == null || node.VariableOperands == "false")
                {
                    Lines.AppendLine("\t\t\tSystem.Diagnostics.Debug.Assert(node.ResultCount == " + node.ResultCount + ");");
                    Lines.AppendLine("\t\t\tSystem.Diagnostics.Debug.Assert(node.OperandCount == " + node.OperandCount + ");");

                    if (node.ThreeTwoAddressConversion != null && node.ThreeTwoAddressConversion == "true")
                    {
                        Lines.AppendLine("\t\t\tSystem.Diagnostics.Debug.Assert(node.Result.IsCPURegister);");
                        Lines.AppendLine("\t\t\tSystem.Diagnostics.Debug.Assert(node.Operand1.IsCPURegister);");
                        Lines.AppendLine("\t\t\tSystem.Diagnostics.Debug.Assert(node.Result.Register == node.Operand1.Register);");
                    }
                    Lines.AppendLine();
                }

                CreateEncoding(node);

                Lines.AppendLine("\t\t}");
            }

            Lines.AppendLine("\t}");
            Lines.AppendLine("}");
        }
 private void EmitCondition(string condition)
 {
     Lines.AppendLine($"\t\t\tif ({condition})");
     Lines.AppendLine($"\t\t\t\treturn false;");
     Lines.AppendLine("");
 }
 private void EmitConditionStatement(string path)
 {
     Lines.AppendLine($"\t\t\tvar condition = context.{path}ConditionCode;");
     Lines.AppendLine("");
 }
        private void ProcessResultInstructionTree(Transformation transform)
        {
            // Capture the result type
            Lines.AppendLine("\t\t\tvar result = context.Result;");
            Lines.AppendLine("");

            // Capture all the labeled operands into variables
            int labelCount      = 0;
            var labelToLabelNbr = new Dictionary <string, int>();

            foreach (var name in transform.LabelSet.Labels)
            {
                var label = transform.LabelSet.GetExpressionLabel(name);

                if (!label.IsInResult)
                {
                    continue;
                }

                labelCount++;

                var labelPosition    = label.Positions[0];
                var labelParent      = NodeNbrToNode[labelPosition.NodeNbr];
                var labelOperandName = GetOperandName(labelPosition.OperandIndex);
                var labelName        = $"context.{labelParent}{labelOperandName}";

                labelToLabelNbr.Add(label.Name, labelCount);

                Lines.AppendLine($"\t\t\tvar t{labelCount} = {labelName};");
            }
            if (labelCount != 0)
            {
                Lines.AppendLine("");
            }

            var postOrder = transform.GetPostorder(transform.ResultInstructionTree);

            // Create virtual register for each child instruction
            int virtualRegisterNbr          = 0;
            var nodeNbrToVirtualRegisterNbr = new Dictionary <int, int>();

            foreach (var node in postOrder)
            {
                if (node == transform.ResultInstructionTree)
                {
                    continue;
                }

                virtualRegisterNbr++;
                var resultType = DetermineResultType(node);

                nodeNbrToVirtualRegisterNbr.Add(node.NodeNbr, virtualRegisterNbr);

                Lines.AppendLine($"\t\t\tvar v{virtualRegisterNbr} = transformContext.AllocateVirtualRegister(transformContext.{resultType});");
            }
            if (virtualRegisterNbr != 0)
            {
                Lines.AppendLine();
            }

            // Create all the constants variables
            var operandList = transform.GetAllOperands(transform.ResultInstructionTree);
            int constantNbr = 0;
            var constantTextToConstantNbr = new Dictionary <string, int>();
            var constantToConstantNbr     = new Dictionary <Operand, int>();

            foreach (var operand in operandList)
            {
                string name = CreateConstantName(operand);

                if (name == null)
                {
                    continue;
                }

                if (constantTextToConstantNbr.TryGetValue(name, out int found))
                {
                    constantToConstantNbr.Add(operand, found);
                    Lines.AppendLine($"\t\t\tvar c{operand} = transformContext.CreateConstant({name});");
                    continue;
                }

                constantNbr++;
                constantTextToConstantNbr.Add(name, constantNbr);
                constantToConstantNbr.Add(operand, constantNbr);

                Lines.AppendLine($"\t\t\tvar c{constantNbr} = transformContext.CreateConstant({name});");
            }
            if (constantNbr != 0)
            {
                Lines.AppendLine("");
            }

            // Evaluate functions
            int methodNbr = 0;
            var methodToExpressionText = new Dictionary <string, int>();
            var methodToMethodNbr      = new Dictionary <Method, int>();

            foreach (var node in postOrder)
            {
                foreach (var operand in node.Operands)
                {
                    if (!operand.IsMethod)
                    {
                        continue;
                    }

                    string name = CreateExpression(operand.Method, labelToLabelNbr, constantToConstantNbr);

                    if (methodToExpressionText.TryGetValue(name, out int found))
                    {
                        methodToMethodNbr.Add(operand.Method, found);
                        continue;

                        //Lines.AppendLine($"\t\t\tvar e{found} = transformContext.CreateConstant({name});");
                        //continue;
                    }

                    methodNbr++;

                    methodToMethodNbr.Add(operand.Method, methodNbr);
                    methodToExpressionText.Add(name, methodNbr);

                    Lines.AppendLine($"\t\t\tvar e{methodNbr} = transformContext.CreateConstant({name});");
                }
            }
            if (methodNbr != 0)
            {
                Lines.AppendLine("");
            }

            // Create Instructions
            bool firstInstruction = true;

            foreach (var node in postOrder)
            {
                var sb = new StringBuilder();
                foreach (var operand in node.Operands)
                {
                    if (operand.IsLabel)
                    {
                        sb.Append($"t{labelToLabelNbr[operand.LabelName]}");
                    }
                    else if (operand.IsInteger)
                    {
                        sb.Append($"c{constantToConstantNbr[operand]}");
                    }
                    else if (operand.IsDouble)
                    {
                        sb.Append($"c{constantToConstantNbr[operand]}");
                    }
                    else if (operand.IsFloat)
                    {
                        sb.Append($"c{constantToConstantNbr[operand]}");
                    }
                    else if (operand.IsInstruction)
                    {
                        sb.Append($"v{nodeNbrToVirtualRegisterNbr[operand.InstructionNode.NodeNbr]}");
                    }
                    else if (operand.IsMethod)
                    {
                        var nbr = methodToMethodNbr[operand.Method];
                        sb.Append($"e{nbr}");
                    }

                    sb.Append(", ");
                }

                if (node.Operands.Count != 0)
                {
                    sb.Length -= 2;
                }

                var operands = sb.ToString();

                var operation = firstInstruction ? "Set" : "Append";

                var condition = GetConditionText(node.Condition);

                condition = condition != null ? $"ConditionCode.{condition}, " : string.Empty;

                if (!string.IsNullOrWhiteSpace(node.InstructionName))
                {
                    var instruction = node.InstructionName.Replace("IR.", "IRInstruction.");;
                    var result      = node == transform.ResultInstructionTree ? "result" : $"v{nodeNbrToVirtualRegisterNbr[node.NodeNbr]}";

                    Lines.AppendLine($"\t\t\tcontext.{operation}Instruction({instruction}, {condition}{result}, {operands});");
                }
                else
                {
                    Lines.AppendLine($"\t\t\tcontext.{operation}Instruction(GetMove(result), {condition}result, {operands});");
                }

                firstInstruction = false;
            }
        }
        protected override void Body(dynamic node = null)
        {
            int id = Identifiers.GetInstructionID();

            string bytes    = EncodeOpcodeBytes(node);
            string legacy   = EncodeLegacyOpcode(node);
            string reg      = EncodeLegacyOpecodeRegField(node);
            string operands = EncodeOperandsOrder(node);

            Lines.AppendLine("using Mosa.Compiler.Framework;");

            if (node.ResultType != null || node.ResultType2 != null)
            {
                Lines.AppendLine("using Mosa.Compiler.MosaTypeSystem;");
            }

            Lines.AppendLine();
            Lines.AppendLine("namespace Mosa.Platform.x86.Instructions");
            Lines.AppendLine("{");
            Lines.AppendLine("\t/// <summary>");
            Lines.Append("\t/// " + node.Name);

            if (!string.IsNullOrWhiteSpace(node.Description))
            {
                Lines.Append(" - " + node.Description);
            }

            Lines.AppendLine();
            Lines.AppendLine("\t/// </summary>");
            Lines.AppendLine("\t/// <seealso cref=\"Mosa.Platform.x86.X86Instruction\" />");
            Lines.AppendLine("\tpublic sealed class " + node.Name + " : X86Instruction");
            Lines.AppendLine("\t{");
            Lines.AppendLine("\t\tpublic override int ID { get { return " + id.ToString() + "; } }");
            Lines.AppendLine();
            Lines.AppendLine("\t\tinternal " + node.Name + "()");
            Lines.AppendLine("\t\t\t: base(" + node.ResultCount + ", " + node.OperandCount + ")");
            Lines.AppendLine("\t\t{");
            Lines.AppendLine("\t\t}");

            if (node.AlternativeName != null)
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override string AlternativeName { get { return \"" + node.AlternativeName + "\"; } }");
            }

            if (node.X86EmitBytes != null)
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic static readonly byte[] opcode = new byte[] { " + bytes + " };");
            }

            if (node.X86LegacyOpcode != null)
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic static readonly LegacyOpCode LegacyOpcode = new LegacyOpCode(new byte[] { " + legacy + " }" + reg + ");");
            }

            if (node.FlowControl != null && node.FlowControl != "Next")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override FlowControl FlowControl { get { return FlowControl." + node.FlowControl + "; } }");
            }

            if (node.ResultType != null && node.ResultType != "")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override BuiltInType ResultType { get { return BuiltInType." + node.ResultType + "; } }");
            }

            if (node.ResultType2 != null && node.ResultType2 != "")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override BuiltInType ResultType2 { get { return BuiltInType." + node.ResultType2 + "; } }");
            }

            if (node.IgnoreDuringCodeGeneration != null && node.IgnoreDuringCodeGeneration == "true")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IgnoreDuringCodeGeneration { get { return true; } }");
            }

            if (node.IgnoreInstructionBasicBlockTargets != null && node.IgnoreInstructionBasicBlockTargets == "true")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IgnoreInstructionBasicBlockTargets { get { return true; } }");
            }

            if (node.VariableOperands != null && node.VariableOperands == "true")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool VariableOperands { get { return true; } }");
            }

            if (node.Commutative != null && node.Commutative == "true")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsCommutative { get { return true; } }");
            }

            if (node.MemoryWrite != null && node.MemoryWrite == "true")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsMemoryWrite { get { return true; } }");
            }

            if (node.MemoryRead != null && node.MemoryRead == "true")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsMemoryRead { get { return true; } }");
            }

            if (node.IOOperation != null && node.IOOperation == "true")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsIOOperation { get { return true; } }");
            }

            if (node.UnspecifiedSideEffect != null && node.UnspecifiedSideEffect == "true")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool HasUnspecifiedSideEffect { get { return true; } }");
            }

            if (node.X86ThreeTwoAddressConversion != null && node.X86ThreeTwoAddressConversion == "true")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool ThreeTwoAddressConversion { get { return true; } }");
            }

            if (node.FlagsUsed != null && node.FlagsUsed.Contains("Z"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsZeroFlagUsed { get { return true; } }");
            }

            if (node.FlagsSet != null && node.FlagsSet.Contains("Z"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsZeroFlagSet { get { return true; } }");
            }

            if (node.FlagsCleared != null && node.FlagsCleared.Contains("Z"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsZeroFlagCleared { get { return true; } }");
            }

            if (node.FlagsModified != null && (node.FlagsModified.Contains("Z") || node.FlagsSet.Contains("Z") || node.FlagsCleared.Contains("Z")))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsZeroFlagModified { get { return true; } }");
            }

            if (node.FlagsUndefined != null && node.FlagsUndefined.Contains("Z"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsZeroFlagUnchanged { get { return true; } }");
            }

            if (node.FlagsUnchanged != null && node.FlagsUndefined.Contains("Z"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsZeroFlagUndefined { get { return true; } }");
            }

            if (node.FlagsUsed != null && node.FlagsUsed.Contains("C"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsCarryFlagUsed { get { return true; } }");
            }

            if (node.FlagsSet != null && node.FlagsSet.Contains("C"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsCarryFlagSet { get { return true; } }");
            }

            if (node.FlagsCleared != null && node.FlagsCleared.Contains("C"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsCarryFlagCleared { get { return true; } }");
            }

            if (node.FlagsModified != null && (node.FlagsModified.Contains("C") || node.FlagsSet.Contains("C") || node.FlagsCleared.Contains("C")))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsCarryFlagModified { get { return true; } }");
            }

            if (node.FlagsUndefined != null && node.FlagsUndefined.Contains("C"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsCarryFlagUnchanged { get { return true; } }");
            }

            if (node.FlagsUnchanged != null && node.FlagsUndefined.Contains("C"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsCarryFlagUndefined { get { return true; } }");
            }

            if (node.FlagsUsed != null && node.FlagsUsed.Contains("S"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsSignFlagUsed { get { return true; } }");
            }

            if (node.FlagsSet != null && node.FlagsSet.Contains("S"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsSignFlagSet { get { return true; } }");
            }

            if (node.FlagsCleared != null && node.FlagsCleared.Contains("S"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsSignFlagCleared { get { return true; } }");
            }

            if (node.FlagsModified != null && (node.FlagsModified.Contains("S") || node.FlagsSet.Contains("S") || node.FlagsCleared.Contains("S")))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsSignFlagModified { get { return true; } }");
            }

            if (node.FlagsUndefined != null && node.FlagsUndefined.Contains("S"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsSignFlagUnchanged { get { return true; } }");
            }

            if (node.FlagsUnchanged != null && node.FlagsUndefined.Contains("S"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsSignFlagUndefined { get { return true; } }");
            }

            if (node.FlagsUsed != null && node.FlagsUsed.Contains("O"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsOverflowFlagUsed { get { return true; } }");
            }

            if (node.FlagsSet != null && node.FlagsSet.Contains("O"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsOverflowFlagSet { get { return true; } }");
            }

            if (node.FlagsCleared != null && node.FlagsCleared.Contains("O"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsOverflowFlagCleared { get { return true; } }");
            }

            if (node.FlagsModified != null && (node.FlagsModified.Contains("O") || node.FlagsSet.Contains("O") || node.FlagsCleared.Contains("O")))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsOverflowFlagModified { get { return true; } }");
            }

            if (node.FlagsUndefined != null && node.FlagsUndefined.Contains("O"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsOverflowFlagUnchanged { get { return true; } }");
            }

            if (node.FlagsUnchanged != null && node.FlagsUndefined.Contains("O"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsOverflowFlagUndefined { get { return true; } }");
            }

            if (node.FlagsUsed != null && node.FlagsUsed.Contains("P"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsParityFlagUsed { get { return true; } }");
            }

            if (node.FlagsSet != null && node.FlagsSet.Contains("P"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsParityFlagSet { get { return true; } }");
            }

            if (node.FlagsCleared != null && node.FlagsCleared.Contains("P"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsParityFlagCleared { get { return true; } }");
            }

            if (node.FlagsModified != null && (node.FlagsModified.Contains("P") || node.FlagsSet.Contains("P") || node.FlagsCleared.Contains("P")))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsParityFlagModified { get { return true; } }");
            }

            if (node.FlagsUndefined != null && node.FlagsUndefined.Contains("P"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsParityFlagUnchanged { get { return true; } }");
            }

            if (node.FlagsUnchanged != null && node.FlagsUndefined.Contains("P"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsParityFlagUndefined { get { return true; } }");
            }

            if (node.LogicalOpposite != null)
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override BaseInstruction GetOpposite()");
                Lines.AppendLine("\t\t{");
                Lines.AppendLine("\t\t\treturn " + node.FamilyName + "." + node.LogicalOpposite + ";");
                Lines.AppendLine("\t\t}");
            }

            if (node.X86EmitBytes != null)
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override void Emit(InstructionNode node, BaseCodeEmitter emitter)");
                Lines.AppendLine("\t\t{");

                if (node.VariableOperands == null || node.VariableOperands == "false")
                {
                    Lines.AppendLine("\t\t\tSystem.Diagnostics.Debug.Assert(node.ResultCount == " + node.ResultCount + ");");
                    Lines.AppendLine("\t\t\tSystem.Diagnostics.Debug.Assert(node.OperandCount == " + node.OperandCount + ");");

                    if (node.X86EmitRelativeBranchTarget != null || node.X86EmitRelativeBranchTarget == "true")
                    {
                        Lines.AppendLine("\t\t\tSystem.Diagnostics.Debug.Assert(node.BranchTargets.Count >= 1);");
                        Lines.AppendLine("\t\t\tSystem.Diagnostics.Debug.Assert(node.BranchTargets[0] != null);");
                    }
                    Lines.AppendLine();
                }

                Lines.AppendLine("\t\t\temitter.Write(opcode);");

                if (node.X86EmitRelativeBranchTarget != null || node.X86EmitRelativeBranchTarget == "true")
                {
                    Lines.AppendLine("\t\t\t(emitter as X86CodeEmitter).EmitRelativeBranchTarget(node.BranchTargets[0].Label);");
                }

                Lines.AppendLine("\t\t}");
            }

            if (node.StaticEmitMethod != null)
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override void Emit(InstructionNode node, BaseCodeEmitter emitter)");
                Lines.AppendLine("\t\t{");

                if (node.VariableOperands == null || node.VariableOperands == "false")
                {
                    Lines.AppendLine("\t\t\tSystem.Diagnostics.Debug.Assert(node.ResultCount == DefaultResultCount);");
                    Lines.AppendLine("\t\t\tSystem.Diagnostics.Debug.Assert(node.OperandCount == DefaultOperandCount);");
                    Lines.AppendLine();
                }

                Lines.AppendLine("\t\t\t" + node.StaticEmitMethod.Replace("%", node.Name) + "(node, emitter);");
                Lines.AppendLine("\t\t}");
            }

            if (node.X86LegacyOpcodeOperandOrder != null && node.X86LegacyOpcode != null && node.StaticEmitMethod == null)
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tinternal override void EmitLegacy(InstructionNode node, X86CodeEmitter emitter)");
                Lines.AppendLine("\t\t{");
                if (node.VariableOperands == null || node.VariableOperands == "false")
                {
                    Lines.AppendLine("\t\t\tSystem.Diagnostics.Debug.Assert(node.ResultCount == " + node.ResultCount + ");");
                    Lines.AppendLine("\t\t\tSystem.Diagnostics.Debug.Assert(node.OperandCount == " + node.OperandCount + ");");

                    if (node.X86ThreeTwoAddressConversion == null || node.X86ThreeTwoAddressConversion == "true")
                    {
                        Lines.AppendLine("\t\t\tSystem.Diagnostics.Debug.Assert(node.Result.IsCPURegister);");
                        Lines.AppendLine("\t\t\tSystem.Diagnostics.Debug.Assert(node.Operand1.IsCPURegister);");
                        Lines.AppendLine("\t\t\tSystem.Diagnostics.Debug.Assert(node.Result.Register == node.Operand1.Register);");
                    }
                    Lines.AppendLine();
                }

                if (operands == null)
                {
                    Lines.AppendLine("\t\t\temitter.Emit(LegacyOpcode);");
                }
                else
                {
                    Lines.AppendLine("\t\t\temitter.Emit(LegacyOpcode, " + operands + ");");
                }
                Lines.AppendLine("\t\t}");
            }

            Lines.AppendLine("\t}");
            Lines.AppendLine("}");
        }
Esempio n. 11
0
        protected override void Body(dynamic node = null)
        {
            if (node.ResultType != null || node.ResultType2 != null)
            {
                Lines.AppendLine("using Mosa.Compiler.MosaTypeSystem;");
                Lines.AppendLine();
            }

            Lines.AppendLine("namespace Mosa.Compiler.Framework.IR");
            Lines.AppendLine("{");
            Lines.AppendLine("\t/// <summary>");
            Lines.Append($"\t/// {node.Name}");

            if (!string.IsNullOrWhiteSpace(node.Description))
            {
                Lines.Append($" - {node.Description}");
            }
            Lines.AppendLine();

            Lines.AppendLine("\t/// </summary>");
            Lines.AppendLine("\t/// <seealso cref=\"Mosa.Compiler.Framework.IR.BaseIRInstruction\" />");
            Lines.AppendLine($"\tpublic sealed class {node.Name} : BaseIRInstruction");
            Lines.AppendLine("\t{");
            Lines.AppendLine("\t\tpublic " + node.Name + "()");
            Lines.AppendLine($"\t\t\t: base({node.OperandCount}, {node.ResultCount})");
            Lines.AppendLine("\t\t{");
            Lines.AppendLine("\t\t}");

            if (node.FlowControl != null && node.FlowControl != "Next")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override FlowControl FlowControl { get { return FlowControl." + node.FlowControl + "; } }");
            }

            if (node.ResultType != null && node.ResultType != "")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override BuiltInType ResultType { get { return BuiltInType." + node.ResultType + "; } }");
            }

            if (node.ResultType2 != null && node.ResultType2 != "")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override BuiltInType ResultType2 { get { return BuiltInType." + node.ResultType2 + "; } }");
            }

            if (node.IgnoreDuringCodeGeneration != null && node.IgnoreDuringCodeGeneration == "true")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IgnoreDuringCodeGeneration { get { return true; } }");
            }

            if (node.IgnoreInstructionBasicBlockTargets != null && node.IgnoreInstructionBasicBlockTargets == "true")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IgnoreInstructionBasicBlockTargets { get { return true; } }");
            }

            if (node.VariableOperands != null && node.VariableOperands == "true")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool VariableOperands { get { return true; } }");
            }

            if (node.Commutative != null && node.Commutative == "true")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsCommutative { get { return true; } }");
            }

            if (node.MemoryWrite != null && node.MemoryWrite == "true")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsMemoryWrite { get { return true; } }");
            }

            if (node.MemoryRead != null && node.MemoryRead == "true")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsMemoryRead { get { return true; } }");
            }

            if (node.IOOperation != null && node.IOOperation == "true")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsIOOperation { get { return true; } }");
            }

            if (node.IRUnspecifiedSideEffect != null && node.IRUnspecifiedSideEffect == "true")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool HasIRUnspecifiedSideEffect { get { return true; } }");
            }

            if (node.ParameterLoad != null && node.ParameterLoad == "true")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsParameterLoad { get { return true; } }");
            }

            if (node.ParameterStore != null && node.ParameterStore == "true")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsParameterStore { get { return true; } }");
            }

            Lines.AppendLine("\t}");
            Lines.AppendLine("}");
        }
        protected override void Body(dynamic node = null)
        {
            int id = Identifiers.GetInstructionID();

            Lines.AppendLine("using Mosa.Compiler.Framework;");

            if (node.ResultType != null || node.ResultType2 != null)
            {
                Lines.AppendLine("using Mosa.Compiler.MosaTypeSystem;");
            }

            if (!string.IsNullOrWhiteSpace(node.ARMv6Opcode))
            {
                Lines.AppendLine("using Mosa.Compiler.Common;");
            }

            Lines.AppendLine();
            Lines.AppendLine("namespace Mosa.Platform.ARMv6.Instructions");
            Lines.AppendLine("{");
            Lines.AppendLine("\t/// <summary>");
            Lines.Append("\t/// " + node.Name);

            if (!string.IsNullOrWhiteSpace(node.Description))
            {
                Lines.Append(" - " + node.Description);
            }

            Lines.AppendLine();
            Lines.AppendLine("\t/// </summary>");
            Lines.AppendLine("\t/// <seealso cref=\"Mosa.Platform.ARMv6.ARMv6Instruction\" />");
            Lines.AppendLine("\tpublic sealed class " + node.Name + " : ARMv6Instruction");
            Lines.AppendLine("\t{");
            Lines.AppendLine("\t\tpublic override int ID { get { return " + id.ToString() + "; } }");
            Lines.AppendLine();
            Lines.AppendLine("\t\tinternal " + node.Name + "()");
            Lines.AppendLine("\t\t\t: base(" + node.ResultCount + ", " + node.OperandCount + ")");
            Lines.AppendLine("\t\t{");
            Lines.AppendLine("\t\t}");

            if (node.AlternativeName != null)
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override string AlternativeName { get { return \"" + node.AlternativeName + "\"; } }");
            }

            if (node.FlowControl != null && node.FlowControl != "Next")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override FlowControl FlowControl { get { return FlowControl." + node.FlowControl + "; } }");
            }

            if (node.ResultType != null && node.ResultType != "")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override BuiltInType ResultType { get { return BuiltInType." + node.ResultType + "; } }");
            }

            if (node.ResultType2 != null && node.ResultType2 != "")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override BuiltInType ResultType2 { get { return BuiltInType." + node.ResultType2 + "; } }");
            }

            if (node.IgnoreDuringCodeGeneration != null && node.IgnoreDuringCodeGeneration == "true")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IgnoreDuringCodeGeneration { get { return true; } }");
            }

            if (node.IgnoreInstructionBasicBlockTargets != null && node.IgnoreInstructionBasicBlockTargets == "true")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IgnoreInstructionBasicBlockTargets { get { return true; } }");
            }

            if (node.VariableOperands != null && node.VariableOperands == "true")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool VariableOperands { get { return true; } }");
            }

            if (node.Commutative != null && node.Commutative == "true")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsCommutative { get { return true; } }");
            }

            if (node.MemoryWrite != null && node.MemoryWrite == "true")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsMemoryWrite { get { return true; } }");
            }

            if (node.MemoryRead != null && node.MemoryRead == "true")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsMemoryRead { get { return true; } }");
            }

            if (node.IOOperation != null && node.IOOperation == "true")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsIOOperation { get { return true; } }");
            }

            if (node.UnspecifiedSideEffect != null && node.UnspecifiedSideEffect == "true")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool HasUnspecifiedSideEffect { get { return true; } }");
            }

            if (node.ARMv6ThreeTwoAddressConversion != null && node.ARMv6ThreeTwoAddressConversion == "true")
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool ThreeTwoAddressConversion { get { return true; } }");
            }

            if (node.FlagsUsed != null && node.FlagsUsed.Contains("Z"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsZeroFlagUsed { get { return true; } }");
            }

            if (node.FlagsSet != null && node.FlagsSet.Contains("Z"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsZeroFlagSet { get { return true; } }");
            }

            if (node.FlagsCleared != null && node.FlagsCleared.Contains("Z"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsZeroFlagCleared { get { return true; } }");
            }

            if (node.FlagsModified != null && (node.FlagsModified.Contains("Z") || node.FlagsSet.Contains("Z") || node.FlagsCleared.Contains("Z")))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsZeroFlagModified { get { return true; } }");
            }

            if (node.FlagsUndefined != null && node.FlagsUndefined.Contains("Z"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsZeroFlagUnchanged { get { return true; } }");
            }

            if (node.FlagsUnchanged != null && node.FlagsUndefined.Contains("Z"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsZeroFlagUndefined { get { return true; } }");
            }

            if (node.FlagsUsed != null && node.FlagsUsed.Contains("C"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsCarryFlagUsed { get { return true; } }");
            }

            if (node.FlagsSet != null && node.FlagsSet.Contains("C"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsCarryFlagSet { get { return true; } }");
            }

            if (node.FlagsCleared != null && node.FlagsCleared.Contains("C"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsCarryFlagCleared { get { return true; } }");
            }

            if (node.FlagsModified != null && (node.FlagsModified.Contains("C") || node.FlagsSet.Contains("C") || node.FlagsCleared.Contains("C")))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsCarryFlagModified { get { return true; } }");
            }

            if (node.FlagsUndefined != null && node.FlagsUndefined.Contains("C"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsCarryFlagUnchanged { get { return true; } }");
            }

            if (node.FlagsUnchanged != null && node.FlagsUndefined.Contains("C"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsCarryFlagUndefined { get { return true; } }");
            }

            if (node.FlagsUsed != null && node.FlagsUsed.Contains("S"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsSignFlagUsed { get { return true; } }");
            }

            if (node.FlagsSet != null && node.FlagsSet.Contains("S"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsSignFlagSet { get { return true; } }");
            }

            if (node.FlagsCleared != null && node.FlagsCleared.Contains("S"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsSignFlagCleared { get { return true; } }");
            }

            if (node.FlagsModified != null && (node.FlagsModified.Contains("S") || node.FlagsSet.Contains("S") || node.FlagsCleared.Contains("S")))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsSignFlagModified { get { return true; } }");
            }

            if (node.FlagsUndefined != null && node.FlagsUndefined.Contains("S"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsSignFlagUnchanged { get { return true; } }");
            }

            if (node.FlagsUnchanged != null && node.FlagsUndefined.Contains("S"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsSignFlagUndefined { get { return true; } }");
            }

            if (node.FlagsUsed != null && node.FlagsUsed.Contains("O"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsOverflowFlagUsed { get { return true; } }");
            }

            if (node.FlagsSet != null && node.FlagsSet.Contains("O"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsOverflowFlagSet { get { return true; } }");
            }

            if (node.FlagsCleared != null && node.FlagsCleared.Contains("O"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsOverflowFlagCleared { get { return true; } }");
            }

            if (node.FlagsModified != null && (node.FlagsModified.Contains("O") || node.FlagsSet.Contains("O") || node.FlagsCleared.Contains("O")))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsOverflowFlagModified { get { return true; } }");
            }

            if (node.FlagsUndefined != null && node.FlagsUndefined.Contains("O"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsOverflowFlagUnchanged { get { return true; } }");
            }

            if (node.FlagsUnchanged != null && node.FlagsUndefined.Contains("O"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsOverflowFlagUndefined { get { return true; } }");
            }

            if (node.FlagsUsed != null && node.FlagsUsed.Contains("P"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsParityFlagUsed { get { return true; } }");
            }

            if (node.FlagsSet != null && node.FlagsSet.Contains("P"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsParityFlagSet { get { return true; } }");
            }

            if (node.FlagsCleared != null && node.FlagsCleared.Contains("P"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsParityFlagCleared { get { return true; } }");
            }

            if (node.FlagsModified != null && (node.FlagsModified.Contains("P") || node.FlagsSet.Contains("P") || node.FlagsCleared.Contains("P")))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsParityFlagModified { get { return true; } }");
            }

            if (node.FlagsUndefined != null && node.FlagsUndefined.Contains("P"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsParityFlagUnchanged { get { return true; } }");
            }

            if (node.FlagsUnchanged != null && node.FlagsUndefined.Contains("P"))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override bool IsParityFlagUndefined { get { return true; } }");
            }

            if (node.LogicalOpposite != null)
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tpublic override BaseInstruction GetOpposite()");
                Lines.AppendLine("\t\t{");
                Lines.AppendLine("\t\t\treturn " + node.FamilyName + "." + node.LogicalOpposite + ";");
                Lines.AppendLine("\t\t}");
            }

            if (!string.IsNullOrWhiteSpace(node.ARMv6Emitter))
            {
                Lines.AppendLine();
                Lines.AppendLine("\t\tprotected override void Emit(InstructionNode node, ARMv6CodeEmitter emitter)");
                Lines.AppendLine("\t\t{");

                if (!string.IsNullOrWhiteSpace(node.ARMv6Opcode))
                {
                    Lines.AppendLine("\t\t\t" + node.ARMv6Emitter + "(node, emitter, Bits." + node.ARMv6Opcode + ");");
                }
                else
                {
                    Lines.AppendLine("\t\t\t" + node.ARMv6Emitter + "(node, emitter);");
                }

                Lines.AppendLine("\t\t}");
            }

            Lines.AppendLine("\t}");
            Lines.AppendLine("}");
        }