/// <summary>
        /// Decodes the specified instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="decoder">The instruction decoder, which holds the code stream.</param>
        public override void Decode(InstructionNode ctx, IInstructionDecoder decoder)
        {
            // Decode base classes first
            base.Decode(ctx, decoder);

            throw new NotImplementedException();
        }
        /// <summary>
        /// Decodes the specified instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="decoder">The instruction decoder, which holds the code stream.</param>
        public override void Decode(InstructionNode ctx, IInstructionDecoder decoder)
        {
            // Decode base classes first
            base.Decode(ctx, decoder);

            // Opcode specific handling
            int index;
            switch (opcode)
            {
                case OpCode.Ldloc:
                case OpCode.Ldloc_s: index = (int)decoder.Instruction.Operand; break;
                case OpCode.Ldloc_0: index = 0; break;
                case OpCode.Ldloc_1: index = 1; break;
                case OpCode.Ldloc_2: index = 2; break;
                case OpCode.Ldloc_3: index = 3; break;
                default: throw new InvalidMetadataException();
            }

            // Push the loaded value onto the evaluation stack
            var local = decoder.Compiler.LocalVariables[index];
            var result = AllocateVirtualRegisterOrStackSlot(decoder.Compiler, local.Type);

            ctx.Operand1 = local;
            ctx.Result = result;
        }
        /// <summary>
        /// Decodes the specified CIL instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="decoder">The instruction decoder, which holds the code stream.</param>
        /// <remarks>
        /// This method is used by instructions to retrieve immediate operands
        /// From the instruction stream.
        /// </remarks>
        public override void Decode(InstructionNode ctx, IInstructionDecoder decoder)
        {
            // Decode base classes first
            base.Decode(ctx, decoder);

            int index;

            // Opcode specific handling
            switch (opcode)
            {
                case OpCode.Ldarg:
                case OpCode.Ldarg_s: index = (int)decoder.Instruction.Operand; break;
                case OpCode.Ldarg_0: index = 0; break;
                case OpCode.Ldarg_1: index = 1; break;
                case OpCode.Ldarg_2: index = 2; break;
                case OpCode.Ldarg_3: index = 3; break;
                default: throw new System.NotImplementedException();
            }

            // Push the loaded value onto the evaluation stack
            var parameterOperand = decoder.Compiler.GetParameterOperand(index);
            var result = LoadInstruction.CreateResultOperand(decoder, parameterOperand.Type);

            ctx.Operand1 = parameterOperand;
            ctx.Result = result;
        }
 /// <summary>
 /// Gets the instruction modifier.
 /// </summary>
 /// <param name="node">The context.</param>
 /// <returns></returns>
 protected override string GetModifier(InstructionNode node)
 {
     switch (((node.Instruction) as CIL.BaseCILInstruction).OpCode)
     {
         case OpCode.Beq_s: return @"==";
         case OpCode.Beq: return @"==";
         case OpCode.Bge_s: return @">=";
         case OpCode.Bge: return @">=";
         case OpCode.Bge_un_s: return @">= unordered";
         case OpCode.Bge_un: return @">= unordered";
         case OpCode.Bgt_s: return @">";
         case OpCode.Bgt: return @">";
         case OpCode.Bgt_un_s: return @"> unordered";
         case OpCode.Bgt_un: return @"> unordered";
         case OpCode.Ble_s: return @"<=";
         case OpCode.Ble: return @"<=";
         case OpCode.Ble_un_s: return @"<= unordered";
         case OpCode.Ble_un: return @"<= unordered";
         case OpCode.Blt_s: return @"<";
         case OpCode.Blt: return @"<";
         case OpCode.Blt_un_s: return @"< unordered";
         case OpCode.Blt_un: return @"< unordered";
         case OpCode.Bne_un_s: return @"!= unordered";
         case OpCode.Bne_un: return @"!= unordered";
         default: throw new InvalidOperationException(@"Opcode not set.");
     }
 }
        /// <summary>
        /// Decodes the specified instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="decoder">The instruction decoder, which holds the code stream.</param>
        public override void Decode(InstructionNode ctx, IInstructionDecoder decoder)
        {
            // Decode base classes first
            base.Decode(ctx, decoder);

            // Push the address on the stack
            ctx.Result = decoder.Compiler.CreateVirtualRegister(decoder.TypeSystem.BuiltIn.U);
        }
        /// <summary>
        /// Decodes the specified instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="decoder">The instruction decoder, which holds the code stream.</param>
        public override void Decode(InstructionNode ctx, IInstructionDecoder decoder)
        {
            // Decode base classes first
            base.Decode(ctx, decoder);

            // FIXME: Validate operands & verify instruction
            ctx.Result = decoder.Compiler.CreateVirtualRegister(decoder.TypeSystem.BuiltIn.I4);
        }
        /// <summary>
        /// Decodes the specified instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="decoder">The instruction decoder, which holds the code stream.</param>
        public override void Decode(InstructionNode ctx, IInstructionDecoder decoder)
        {
            // Decode base classes first
            base.Decode(ctx, decoder);

            // Set the result
            ctx.Result = decoder.Compiler.CreateVirtualRegister(decoder.TypeSystem.BuiltIn.I4);
        }
        /// <summary>
        /// Decodes the specified instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="decoder">The instruction decoder, which holds the code stream.</param>
        public override void Decode(InstructionNode ctx, IInstructionDecoder decoder)
        {
            // Decode base classes first
            base.Decode(ctx, decoder);

            var type = (MosaType)decoder.Instruction.Operand;

            ctx.Result = decoder.Compiler.CreateVirtualRegister(type.ToManagedPointer());
        }
        /// <summary>
        /// Decodes the specified instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="decoder">The instruction decoder, which holds the code stream.</param>
        public override void Decode(InstructionNode ctx, IInstructionDecoder decoder)
        {
            // Decode base classes first
            base.Decode(ctx, decoder);

            var type = (MosaType)decoder.Instruction.Operand;

            throw new NotImplementCompilerException();
        }
        /// <summary>
        /// Decodes the specified instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="decoder">The instruction decoder, which holds the code stream.</param>
        public override void Decode(InstructionNode ctx, IInstructionDecoder decoder)
        {
            // Decode base classes first
            base.Decode(ctx, decoder);

            var block = decoder.GetBlock((int)decoder.Instruction.Operand);

            ctx.AddBranchTarget(block);
        }
 /// <summary>
 /// Emits the constant operands.
 /// </summary>
 /// <param name="node">The node.</param>
 protected void EmitFloatingPointConstants(InstructionNode node)
 {
     if (node.OperandCount > 0)
         node.Operand1 = EmitFloatingPointConstant(node.Operand1);
     if (node.OperandCount > 1)
         node.Operand2 = EmitFloatingPointConstant(node.Operand2);
     if (node.OperandCount > 2)
         node.Operand3 = EmitFloatingPointConstant(node.Operand3);
 }
        /// <summary>
        /// Decodes the specified instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="decoder">The instruction decoder, which holds the code stream.</param>
        public override void Decode(InstructionNode ctx, IInstructionDecoder decoder)
        {
            // Decode base classes first
            base.Decode(ctx, decoder);

            byte nocheck = (byte)decoder.Instruction.Operand;
            //FUTURE:
            //ctx.Other = nocheck;
        }
        /// <summary>
        /// Decodes the specified instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="decoder">The instruction decoder, which holds the code stream.</param>
        public override void Decode(InstructionNode ctx, IInstructionDecoder decoder)
        {
            // Decode base classes first
            base.Decode(ctx, decoder);

            var type = (MosaType)decoder.Instruction.Operand;
            ctx.Result = decoder.Compiler.CreateVirtualRegister(decoder.TypeSystem.BuiltIn.Object);
            ctx.MosaType = type;
        }
        /// <summary>
        /// Decodes the specified instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="decoder">The instruction decoder, which holds the code stream.</param>
        public override void Decode(InstructionNode ctx, IInstructionDecoder decoder)
        {
            // Decode base classes first
            base.Decode(ctx, decoder);

            var type = (MosaMethod)decoder.Instruction.Operand;

            //TODO
            throw new NotImplementedException();
        }
        /// <summary>
        /// Decodes the specified instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="decoder">The instruction decoder, which holds the code stream.</param>
        public override void Decode(InstructionNode ctx, IInstructionDecoder decoder)
        {
            // Decode base classes first
            base.Decode(ctx, decoder);

            var type = (MosaType)decoder.Instruction.Operand;

            ctx.Result = decoder.Compiler.AllocateVirtualRegisterOrStackSlot(type);
            ctx.ResultCount = 1;
        }
        /// <summary>
        /// Decodes the specified instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="decoder">The instruction decoder, which holds the code stream.</param>
        public override void Decode(InstructionNode ctx, IInstructionDecoder decoder)
        {
            // Decode base classes first
            base.Decode(ctx, decoder);

            // Retrieve the type reference
            var type = (MosaType)decoder.Instruction.Operand;

            ctx.MosaType = type;
        }
        private static bool CheckAssignmentForCompliance(InstructionNode allocation, InstructionNode assignment)
        {
            // Only direct assignment without any casts is compliant. We can't perform casts or anything alike here,
            // as that is hard to complete at this point of time.

            var allocationType = (allocation.InvokeMethod != null) ? allocation.InvokeMethod.DeclaringType : allocation.Result.Type.ElementType;
            var storageType = (allocation.Instruction is CIL.NewarrInstruction) ? assignment.Operand1.Type.ElementType : assignment.MosaField.DeclaringType;

            return ReferenceEquals(allocationType, storageType);
        }
        /// <summary>
        /// Decodes the specified instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="decoder">The instruction decoder, which holds the code stream.</param>
        public override void Decode(InstructionNode ctx, IInstructionDecoder decoder)
        {
            // Decode base classes first
            base.Decode(ctx, decoder);

            MosaType type = (elementType == null)
                ? type = (MosaType)decoder.Instruction.Operand
                : type = decoder.TypeSystem.GetTypeFromTypeCode(elementType.Value);

            ctx.Result = LoadInstruction.CreateResultOperand(decoder, type);
        }
        /// <summary>
        /// Decodes the specified instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="decoder">The instruction decoder, which holds the code stream.</param>
        public override void Decode(InstructionNode ctx, IInstructionDecoder decoder)
        {
            base.Decode(ctx, decoder);

            var field = (MosaField)decoder.Instruction.Operand;

            decoder.Compiler.Scheduler.TrackFieldReferenced(field);

            ctx.MosaField = field;
            ctx.Result = AllocateVirtualRegisterOrStackSlot(decoder.Compiler, field.FieldType.ToManagedPointer());
        }
        /// <summary>
        /// Decodes the specified instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="decoder">The instruction decoder, which holds the code stream.</param>
        public override void Decode(InstructionNode ctx, IInstructionDecoder decoder)
        {
            // Decode base classes first
            base.Decode(ctx, decoder);

            var field = (MosaField)decoder.Instruction.Operand;

            decoder.Compiler.Scheduler.TrackFieldReferenced(field);

            ctx.MosaField = field;
        }
        /// <summary>
        /// Decodes the specified instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="decoder">The instruction decoder, which holds the code stream.</param>
        public override void Decode(InstructionNode ctx, IInstructionDecoder decoder)
        {
            // Decode base classes first
            base.Decode(ctx, decoder);

            MosaType type = (elementType == null)
                ? type = (MosaType)decoder.Instruction.Operand
                : type = decoder.TypeSystem.GetTypeFromTypeCode(elementType.Value);

            ctx.Result = AllocateVirtualRegisterOrStackSlot(decoder.Compiler, type);
        }
        /// <summary>
        /// Decodes the specified instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="decoder">The instruction decoder, which holds the code stream.</param>
        public override void Decode(InstructionNode ctx, IInstructionDecoder decoder)
        {
            // Decode base classes first
            base.Decode(ctx, decoder);

            // Retrieve a type reference from the immediate argument
            // FIXME: Limit the token types
            var token = (MosaType)decoder.Instruction.Operand;

            throw new NotImplementedException();
        }
        /// <summary>
        /// Decodes the specified instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="decoder">The instruction decoder, which holds the code stream.</param>
        public override void Decode(InstructionNode ctx, IInstructionDecoder decoder)
        {
            // Decode base classes first
            base.Decode(ctx, decoder);

            // Opcode specific handling

            Operand local = decoder.Compiler.GetLocalOperand((int)decoder.Instruction.Operand);
            ctx.Operand1 = local;
            ctx.Result = decoder.Compiler.CreateVirtualRegister(local.Type.ToManagedPointer());
        }
        /// <summary>
        /// Decodes the specified instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="decoder">The instruction decoder, which holds the code stream.</param>
        public override void Decode(InstructionNode ctx, IInstructionDecoder decoder)
        {
            base.Decode(ctx, decoder);

            var field = (MosaField)decoder.Instruction.Operand;

            decoder.Compiler.Scheduler.TrackFieldReferenced(field);

            ctx.MosaField = field;
            ctx.Result = LoadInstruction.CreateResultOperand(decoder, field.FieldType.ToManagedPointer());
        }
        /// <summary>
        /// Decodes the specified instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="decoder">The instruction decoder, which holds the code stream.</param>
        public override void Decode(InstructionNode ctx, IInstructionDecoder decoder)
        {
            // Decode base classes first
            base.Decode(ctx, decoder);

            var field = (MosaField)decoder.Instruction.Operand;

            decoder.Compiler.Scheduler.TrackFieldReferenced(field);

            ctx.MosaField = field;
            ctx.Result = LoadInstruction.CreateResultOperand(decoder, field.FieldType);
        }
        /// <summary>
        /// Decodes the specified instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="decoder">The instruction decoder, which holds the code stream.</param>
        public override void Decode(InstructionNode ctx, IInstructionDecoder decoder)
        {
            // Decode the base first
            base.Decode(ctx, decoder);

            // The argument is the result
            ctx.Result = decoder.Compiler.Parameters[(int)decoder.Instruction.Operand];

            // FIXME: Do some type compatibility checks
            // See verification for this instruction and
            // verification types.
        }
        /// <summary>
        /// Decodes the specified instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="decoder">The instruction decoder, which holds the code stream.</param>
        public override void Decode(InstructionNode ctx, IInstructionDecoder decoder)
        {
            // Decode base classes first
            base.Decode(ctx, decoder);

            var method = (MosaMethod)decoder.Instruction.Operand;

            decoder.Compiler.Scheduler.TrackMethodInvoked(method);

            ctx.Result = decoder.Compiler.CreateVirtualRegister(decoder.TypeSystem.ToFnPtr(method.Signature));
            ctx.InvokeMethod = method;
        }
        /// <summary>
        /// Decodes the specified instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="decoder">The instruction decoder, which holds the code stream.</param>
        public override void Decode(InstructionNode ctx, IInstructionDecoder decoder)
        {
            // Decode base classes first
            base.Decode(ctx, decoder);

            // Opcode specific handling
            int index = (int)decoder.Instruction.Operand;

            var parameterOperand = decoder.Compiler.Parameters[index];
            ctx.Operand1 = parameterOperand;
            ctx.Result = decoder.Compiler.CreateVirtualRegister(parameterOperand.Type.ToManagedPointer());
        }
        public override void Decode(InstructionNode ctx, IInstructionDecoder decoder)
        {
            // Decode base classes first
            base.Decode(ctx, decoder);

            var type = (MosaType)decoder.Instruction.Operand;

            //Operand result = decoder.Compiler.CreateVirtualRegister(type);
            //ctx.Result = result;
            ctx.Result = LoadInstruction.CreateResultOperand(decoder, type);
            ctx.MosaType = type;
        }
        /// <summary>
        /// Decodes the specified instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="decoder">The instruction decoder, which holds the code stream.</param>
        public override void Decode(InstructionNode ctx, IInstructionDecoder decoder)
        {
            // Decode base classes first
            base.Decode(ctx, decoder);

            var field = (MosaField)decoder.Instruction.Operand;

            decoder.Compiler.Scheduler.TrackFieldReferenced(field);

            ctx.MosaField = field;
            ctx.Result = decoder.Compiler.CreateVirtualRegister(field.FieldType.ToManagedPointer());
        }
Exemple #31
0
 /// <summary>
 /// Emits the instruction.
 /// </summary>
 /// <param name="node">The node.</param>
 /// <param name="codeEmitter">The code emitter.</param>
 protected virtual void EmitInstruction(InstructionNode node, BaseCodeEmitter codeEmitter)
 {
     (node.Instruction as BasePlatformInstruction).Emit(node, codeEmitter);
 }
        private void Phi(InstructionNode node)
        {
            //if (Trace.Active) Trace.Log(node.ToString());

            var result = GetVariableState(node.Result);

            if (result.IsOverDefined)
            {
                return;
            }

            var sourceBlocks = node.PhiBlocks;
            var currentBlock = node.Block;

            //if (Trace.Active) Trace.Log("Loop: " + currentBlock.PreviousBlocks.Count.ToString());

            for (var index = 0; index < currentBlock.PreviousBlocks.Count; index++)
            {
                var predecessor = sourceBlocks[index];

                phiStatements.AddIfNew(predecessor, node);

                bool executable = blockStates[predecessor.Sequence];

                //if (Trace.Active) Trace.Log("# " + index.ToString() + ": " + predecessor.ToString() + " " + (executable ? "Yes" : "No"));

                if (!executable)
                {
                    continue;
                }

                if (result.IsOverDefined)
                {
                    continue;
                }

                var op = node.GetOperand(index);

                var operand = GetVariableState(op);

                //if (Trace.Active) Trace.Log("# " + index.ToString() + ": " + operand.ToString());

                CheckAndUpdateNullAssignment(result, operand);

                if (operand.IsOverDefined)
                {
                    UpdateToOverDefined(result);
                    continue;
                }
                else if (operand.IsSingleConstant)
                {
                    UpdateToConstant(result, operand.ConstantUnsignedLongInteger);
                    continue;
                }
                else if (operand.HasMultipleConstants)
                {
                    foreach (var c in operand.Constants)
                    {
                        UpdateToConstant(result, c);

                        if (result.IsOverDefined)
                        {
                            break;
                        }
                    }
                }
            }
        }
Exemple #33
0
        /// <summary>
        /// Simple copy propagation.
        /// </summary>
        /// <param name="node">The node.</param>
        protected void SimpleForwardCopyPropagation(InstructionNode node)
        {
            var result = node.Result;
            var source = node.Operand1;

            if (!result.IsVirtualRegister)
            {
                return;
            }

            if (!source.IsVirtualRegister)
            {
                return;
            }

            if (result.Definitions.Count != 1)
            {
                return;
            }

            if (source.Definitions.Count != 1)
            {
                return;
            }

            if (!source.IsResolvedConstant)
            {
                return;
            }

            if (node.StatusRegister == StatusRegister.Set)
            {
                return;
            }

            if (node.ConditionCode != ConditionCode.Always)
            {
                return;
            }

            Debug.Assert(result != source);

            changed = true;

            //ReplaceOperand(result, source);
            foreach (var useNode in result.Uses.ToArray())
            {
                for (int i = 0; i < useNode.OperandCount; i++)
                {
                    var operand = useNode.GetOperand(i);

                    if (result == operand)
                    {
                        trace?.Log("*** SimpleForwardCopyPropagation");
                        trace?.Log($"BEFORE:\t{useNode}");
                        useNode.SetOperand(i, source);
                        trace?.Log($"AFTER: \t{useNode}");
                    }
                }
            }

            Debug.Assert(result.Uses.Count == 0);

            trace?.Log($"REMOVED:\t{node}");
            node.Empty();
            IRInstructionRemovedCount.Increment();
        }
Exemple #34
0
 protected override void Emit(InstructionNode node, ARMv6CodeEmitter emitter)
 {
     EmitMultiplyInstruction(node, emitter);
 }
Exemple #35
0
 /// <summary>
 /// Emits the specified platform instruction.
 /// </summary>
 /// <param name="node">The node.</param>
 /// <param name="emitter">The emitter.</param>
 public override void Emit(InstructionNode node, BaseCodeEmitter emitter)
 {
     LeaAddress(node, emitter);
 }
        private bool ProcessInstruction(InstructionNode node)
        {
            //if (MainTrace.Active) MainTrace.Log(context.ToString());

            var instruction = node.Instruction;

            if (instruction == IRInstruction.MoveInt32 ||
                instruction == IRInstruction.MoveInt64)
            {
                Move(node);
            }
            else if (instruction == IRInstruction.NewObject ||
                     instruction == IRInstruction.NewArray ||
                     instruction == IRInstruction.NewString)
            {
                NewObject(node);
            }
            else if (instruction == IRInstruction.CallDynamic ||
                     instruction == IRInstruction.CallInterface ||
                     instruction == IRInstruction.CallDirect ||
                     instruction == IRInstruction.CallStatic ||
                     instruction == IRInstruction.CallVirtual ||
                     instruction == IRInstruction.IntrinsicMethodCall)
            {
                Call(node);
            }
            else if (instruction == IRInstruction.LoadInt32 ||
                     instruction == IRInstruction.LoadInt64

                     || instruction == IRInstruction.LoadSignExtend8x32 ||
                     instruction == IRInstruction.LoadSignExtend16x32 ||
                     instruction == IRInstruction.LoadSignExtend8x64 ||
                     instruction == IRInstruction.LoadSignExtend16x64 ||
                     instruction == IRInstruction.LoadSignExtend32x64

                     || instruction == IRInstruction.LoadZeroExtend8x32 ||
                     instruction == IRInstruction.LoadZeroExtend16x32 ||
                     instruction == IRInstruction.LoadZeroExtend8x64 ||
                     instruction == IRInstruction.LoadZeroExtend16x64 ||
                     instruction == IRInstruction.LoadZeroExtend32x64

                     || instruction == IRInstruction.LoadFloatR4 ||
                     instruction == IRInstruction.LoadFloatR8 ||
                     instruction == IRInstruction.LoadParamSignExtend8x32 ||
                     instruction == IRInstruction.LoadParamSignExtend16x32 ||
                     instruction == IRInstruction.LoadParamInt32 ||
                     instruction == IRInstruction.LoadParamInt64 ||
                     instruction == IRInstruction.LoadParamSignExtend8x64 ||
                     instruction == IRInstruction.LoadParamSignExtend16x64 ||
                     instruction == IRInstruction.LoadParamSignExtend32x64 ||
                     instruction == IRInstruction.LoadParamZeroExtend8x32 ||
                     instruction == IRInstruction.LoadParamZeroExtend16x32 ||
                     instruction == IRInstruction.LoadParamZeroExtend8x64 ||
                     instruction == IRInstruction.LoadParamZeroExtend16x64 ||
                     instruction == IRInstruction.LoadParamZeroExtend32x64 ||
                     instruction == IRInstruction.LoadParamFloatR4 ||
                     instruction == IRInstruction.LoadParamFloatR8)
            {
                Load(node);
            }
            else if (instruction == IRInstruction.Add32 ||
                     instruction == IRInstruction.Add64 ||
                     instruction == IRInstruction.Sub32 ||
                     instruction == IRInstruction.Sub64 ||
                     instruction == IRInstruction.MulSigned32 ||
                     instruction == IRInstruction.MulUnsigned32 ||
                     instruction == IRInstruction.MulSigned64 ||
                     instruction == IRInstruction.MulUnsigned64 ||
                     instruction == IRInstruction.DivSigned32 ||
                     instruction == IRInstruction.DivUnsigned32 ||
                     instruction == IRInstruction.RemSigned32 ||
                     instruction == IRInstruction.RemUnsigned32 ||
                     instruction == IRInstruction.DivSigned64 ||
                     instruction == IRInstruction.DivUnsigned64 ||
                     instruction == IRInstruction.RemSigned64 ||
                     instruction == IRInstruction.RemUnsigned64 ||
                     instruction == IRInstruction.ShiftLeft32 ||
                     instruction == IRInstruction.ShiftRight32 ||
                     instruction == IRInstruction.ShiftLeft64 ||
                     instruction == IRInstruction.ShiftRight64 ||
                     instruction == IRInstruction.ArithShiftRight32 ||
                     instruction == IRInstruction.ArithShiftRight64)
            {
                IntegerOperation(node);
            }
            else if (instruction == IRInstruction.CompareInt32x32 ||
                     instruction == IRInstruction.CompareInt64x32 ||
                     instruction == IRInstruction.CompareInt64x64)
            {
                CompareIntegerOperation(node);
            }
            else if (instruction == IRInstruction.Phi)
            {
                Phi(node);
            }
            else if (instruction == IRInstruction.Jmp)
            {
                Jmp(node);
            }
            else if (instruction == IRInstruction.CompareIntBranch32 ||
                     instruction == IRInstruction.CompareIntBranch64)
            {
                return(CompareIntegerBranch(node));
            }
            else if (instruction == IRInstruction.AddressOf)
            {
                AddressOf(node);
            }
            else if (instruction == IRInstruction.SignExtend8x32 ||
                     instruction == IRInstruction.SignExtend16x32 ||
                     instruction == IRInstruction.SignExtend8x64 ||
                     instruction == IRInstruction.SignExtend16x64 ||
                     instruction == IRInstruction.SignExtend32x64 ||
                     instruction == IRInstruction.ZeroExtend8x32 ||
                     instruction == IRInstruction.ZeroExtend16x32 ||
                     instruction == IRInstruction.ZeroExtend8x64 ||
                     instruction == IRInstruction.ZeroExtend16x64 ||
                     instruction == IRInstruction.ZeroExtend32x64)
            {
                Move(node);
            }
            else if (instruction == IRInstruction.Switch)
            {
                Switch(node);
            }
            else if (instruction == IRInstruction.FinallyStart)
            {
                FinallyStart(node);
            }
            else if (instruction == IRInstruction.SetReturn32 ||
                     instruction == IRInstruction.SetReturn64 ||
                     instruction == IRInstruction.SetReturnR4 ||
                     instruction == IRInstruction.SetReturnR8 ||
                     instruction == IRInstruction.SetReturnCompound)
            {
                // nothing
            }
            else
            {
                // for all other instructions
                Default(node);
            }

            return(true);
        }
Exemple #37
0
 /// <summary>
 /// Emits the specified platform instruction.
 /// </summary>
 /// <param name="node">The node.</param>
 /// <param name="emitter">The emitter.</param>
 protected override void Emit(InstructionNode node, MachineCodeEmitter emitter)
 {
     // TODO
 }
Exemple #38
0
 /// <summary>
 /// Emits the specified platform instruction.
 /// </summary>
 /// <param name="ctx">The context.</param>
 /// <param name="emitter">The emitter.</param>
 internal override void EmitLegacy(InstructionNode node, X86CodeEmitter emitter)
 {
     emitter.WriteByte(0xC3);
 }
Exemple #39
0
 public IEnumerable <StoreDynamicDataStateProvider> MatchLoadToStore(InstructionNode loadNode)
 {
     return(_StateProviders.Where(x => x.IsLoadNodeMatching(loadNode)));
 }
Exemple #40
0
 /// <summary>
 /// Emits the specified platform instruction.
 /// </summary>
 /// <param name="node">The node.</param>
 /// <param name="emitter">The emitter.</param>
 protected override void Emit(InstructionNode node, MachineCodeEmitter emitter)
 {
     emitter.WriteByte(0xCD);
     emitter.WriteByte((byte)node.Operand1.ConstantUnsignedInteger);
 }
Exemple #41
0
 public IndexedArgument(int argIndex, InstructionNode argument, CoupledIndexedArgList containingList)
 {
     ArgIndex       = argIndex;
     Argument       = argument;
     ContainingList = containingList;
 }
Exemple #42
0
 /// <summary>
 /// Emits the specified platform instruction.
 /// </summary>
 /// <param name="node">The node.</param>
 /// <param name="emitter">The emitter.</param>
 protected override void Emit(InstructionNode node, ARMv6CodeEmitter emitter)
 {
     // TODO
 }
        private bool CompareIntegerBranch(InstructionNode node)
        {
            var operand1 = GetVariableState(node.Operand1);
            var operand2 = GetVariableState(node.Operand2);

            var compareNull = NullComparisionCheck(node.ConditionCode, operand1, operand2);

            if (compareNull.HasValue)
            {
                if (compareNull.Value)
                {
                    Branch(node);
                }

                return(!compareNull.Value);
            }

            if (operand1.IsOverDefined || operand2.IsOverDefined)
            {
                Branch(node);
                return(true);
            }
            else if (operand1.IsSingleConstant && operand2.IsSingleConstant)
            {
                bool?compare = Compare(operand1.ConstantUnsignedLongInteger, operand2.ConstantUnsignedLongInteger, node.ConditionCode);

                if (!compare.HasValue)
                {
                    // assume it always branches
                    Branch(node);
                    return(true);
                }

                if (compare.Value)
                {
                    Branch(node);
                }

                return(!compare.Value);
            }
            else if (operand1.HasOnlyConstants && operand2.HasOnlyConstants)
            {
                bool?final = null;

                foreach (var c1 in operand1.Constants)
                {
                    foreach (var c2 in operand2.Constants)
                    {
                        bool?compare = Compare(c1, c2, node.ConditionCode);

                        if (!compare.HasValue)
                        {
                            Branch(node);
                            return(true);
                        }

                        if (!final.HasValue)
                        {
                            final = compare;
                            continue;
                        }
                        else if (final.Value == compare.Value)
                        {
                            continue;
                        }
                        else
                        {
                            Branch(node);
                            return(true);
                        }
                    }
                }

                if (final.Value)
                {
                    Branch(node);
                }

                return(!final.Value);
            }

            Branch(node);
            return(true);
        }
 private void AddInstruction(InstructionNode node)
 {
     instructionWorkList.Push(node);
 }
Exemple #45
0
 protected override void Emit(InstructionNode node, ARMv6CodeEmitter emitter)
 {
     EmitDataProcessingInstruction(node, emitter, Bits.b1010);
 }
 /// <summary>
 /// Decodes the specified instruction.
 /// </summary>
 /// <param name="ctx">The context.</param>
 /// <param name="decoder">The instruction decoder, which holds the code stream.</param>
 public virtual void Decode(InstructionNode ctx, IInstructionDecoder decoder)
 {
     ctx.SetInstruction(this, DefaultOperandCount, DefaultResultCount);
 }
Exemple #47
0
 public override void Verify(InstructionNode instructionWrapper)
 {
     instructionWrapper.DataFlowBackRelated.CheckNumberings();
 }
Exemple #48
0
        public override void Emit(InstructionNode node, BaseCodeEmitter emitter)
        {
            System.Diagnostics.Debug.Assert(node.ResultCount == 1);
            System.Diagnostics.Debug.Assert(node.OperandCount == 2);

            if ((node.Operand1.IsCPURegister && node.Operand1.Register.RegisterCode == 5) && node.Operand2.IsConstantZero)
            {
                emitter.OpcodeEncoder.AppendByte(0x8D);
                emitter.OpcodeEncoder.Append2Bits(0b01);
                emitter.OpcodeEncoder.Append3Bits(node.Result.Register.RegisterCode);
                emitter.OpcodeEncoder.Append3Bits(0b101);
                emitter.OpcodeEncoder.AppendByte(0x00);
                return;
            }

            if ((node.Operand1.IsCPURegister && node.Operand1.Register.RegisterCode == 4) && node.Operand2.IsConstantZero)
            {
                emitter.OpcodeEncoder.AppendByte(0x8D);
                emitter.OpcodeEncoder.Append2Bits(0b00);
                emitter.OpcodeEncoder.Append3Bits(node.Result.Register.RegisterCode);
                emitter.OpcodeEncoder.Append3Bits(0b100);
                emitter.OpcodeEncoder.Append2Bits(0b00);
                emitter.OpcodeEncoder.Append3Bits(0b100);
                emitter.OpcodeEncoder.Append3Bits(0b100);
                return;
            }

            if ((node.Operand1.IsCPURegister && node.Operand1.Register.RegisterCode == 4) && (node.Operand2.IsConstant && node.Operand2.ConstantSignedInteger >= -128 && node.Operand2.ConstantSignedInteger <= 127))
            {
                emitter.OpcodeEncoder.AppendByte(0x8D);
                emitter.OpcodeEncoder.Append2Bits(0b01);
                emitter.OpcodeEncoder.Append3Bits(node.Result.Register.RegisterCode);
                emitter.OpcodeEncoder.Append3Bits(0b100);
                emitter.OpcodeEncoder.Append2Bits(0b00);
                emitter.OpcodeEncoder.Append3Bits(0b100);
                emitter.OpcodeEncoder.Append3Bits(0b100);
                emitter.OpcodeEncoder.Append8BitImmediate(node.Operand2);
                return;
            }

            if ((node.Operand1.IsCPURegister && node.Operand1.Register.RegisterCode == 4) && node.Operand2.IsConstant)
            {
                emitter.OpcodeEncoder.AppendByte(0x8D);
                emitter.OpcodeEncoder.Append2Bits(0b10);
                emitter.OpcodeEncoder.Append3Bits(node.Result.Register.RegisterCode);
                emitter.OpcodeEncoder.Append3Bits(0b100);
                emitter.OpcodeEncoder.Append8BitImmediate(node.Operand2);
                return;
            }

            if (node.Operand1.IsCPURegister && node.Operand2.IsCPURegister)
            {
                emitter.OpcodeEncoder.AppendByte(0x8D);
                emitter.OpcodeEncoder.Append2Bits(0b00);
                emitter.OpcodeEncoder.Append3Bits(node.Result.Register.RegisterCode);
                emitter.OpcodeEncoder.Append3Bits(0b100);
                emitter.OpcodeEncoder.Append2Bits(0b00);
                emitter.OpcodeEncoder.Append3Bits(node.Operand2.Register.RegisterCode);
                emitter.OpcodeEncoder.Append3Bits(node.Operand1.Register.RegisterCode);
                return;
            }

            if (node.Operand1.IsCPURegister && node.Operand2.IsConstantZero)
            {
                emitter.OpcodeEncoder.AppendByte(0x8D);
                emitter.OpcodeEncoder.Append2Bits(0b00);
                emitter.OpcodeEncoder.Append3Bits(node.Result.Register.RegisterCode);
                emitter.OpcodeEncoder.Append3Bits(node.Operand1.Register.RegisterCode);
                return;
            }

            if (node.Operand1.IsCPURegister && (node.Operand2.IsConstant && node.Operand2.ConstantSignedInteger >= -128 && node.Operand2.ConstantSignedInteger <= 127))
            {
                emitter.OpcodeEncoder.AppendByte(0x8D);
                emitter.OpcodeEncoder.Append2Bits(0b01);
                emitter.OpcodeEncoder.Append3Bits(node.Result.Register.RegisterCode);
                emitter.OpcodeEncoder.Append3Bits(node.Operand1.Register.RegisterCode);
                emitter.OpcodeEncoder.Append8BitImmediate(node.Operand2);
                return;
            }

            if (node.Operand1.IsCPURegister && node.Operand2.IsConstant)
            {
                emitter.OpcodeEncoder.AppendByte(0x8D);
                emitter.OpcodeEncoder.Append2Bits(0b10);
                emitter.OpcodeEncoder.Append3Bits(node.Result.Register.RegisterCode);
                emitter.OpcodeEncoder.Append3Bits(node.Operand1.Register.RegisterCode);
                emitter.OpcodeEncoder.Append32BitImmediate(node.Operand2);
                return;
            }

            if (node.Operand1.IsConstant && node.Operand2.IsConstantZero)
            {
                emitter.OpcodeEncoder.AppendByte(0x8D);
                emitter.OpcodeEncoder.Append2Bits(0b00);
                emitter.OpcodeEncoder.Append3Bits(node.Result.Register.RegisterCode);
                emitter.OpcodeEncoder.Append3Bits(0b101);
                emitter.OpcodeEncoder.Append32BitImmediate(node.Operand1);
                return;
            }

            throw new Compiler.Common.Exceptions.CompilerException("Invalid Opcode");
        }
 /// <summary>
 /// Decodes the specified instruction.
 /// </summary>
 /// <param name="ctx">The context.</param>
 /// <param name="decoder">The instruction decoder, which holds the code stream.</param>
 public override void Decode(InstructionNode ctx, IInstructionDecoder decoder)
 {
     // Decode base classes first
     base.Decode(ctx, decoder);
 }
Exemple #50
0
 /// <summary>
 /// Emits the specified platform instruction.
 /// </summary>
 /// <param name="node">The node.</param>
 /// <param name="emitter">The emitter.</param>
 protected override void Emit(InstructionNode node, MachineCodeEmitter emitter)
 {
     emitter.Emit(opcode, node.Operand3, null);
 }
Exemple #51
0
        private Operand Map(Operand operand, Dictionary <Operand, Operand> map, InstructionNode callSiteNode)
        {
            if (operand == null)
            {
                return(null);
            }

            if (map.TryGetValue(operand, out Operand mappedOperand))
            {
                return(mappedOperand);
            }

            if (operand.IsSymbol)
            {
                if (operand.StringData != null)
                {
                    mappedOperand = Operand.CreateStringSymbol(operand.Name, operand.StringData, operand.Type.TypeSystem);
                }
                else if (operand.Method != null)
                {
                    mappedOperand = Operand.CreateSymbolFromMethod(operand.Method, operand.Type.TypeSystem);
                }
                else if (operand.Name != null)
                {
                    mappedOperand = Operand.CreateSymbol(operand.Type, operand.Name);
                }
            }
            else if (operand.IsParameter)
            {
                mappedOperand = callSiteNode.GetOperand(operand.Index + 1);
            }
            else if (operand.IsStackLocal)
            {
                mappedOperand = MethodCompiler.AddStackLocal(operand.Type, operand.IsPinned);
            }
            else if (operand.IsVirtualRegister)
            {
                mappedOperand = AllocateVirtualRegister(operand.Type);
            }
            else if (operand.IsStaticField)
            {
                mappedOperand = Operand.CreateStaticField(operand.Field, TypeSystem);
            }
            else if (operand.IsCPURegister)
            {
                mappedOperand = operand;
            }
            else if (operand.IsConstant)
            {
                mappedOperand = operand;
            }

            Debug.Assert(mappedOperand != null);

            if (operand.HasLongParent)
            {
                MethodCompiler.SplitLongOperand(mappedOperand);

                if (operand.IsLow)
                {
                    mappedOperand = mappedOperand.Low;
                }
                else if (operand.IsHigh)
                {
                    mappedOperand = mappedOperand.High;
                }
            }

            map.Add(operand, mappedOperand);

            return(mappedOperand);
        }
Exemple #52
0
 /// <summary>
 /// Emits the specified platform instruction.
 /// </summary>
 /// <param name="node">The node.</param>
 /// <param name="emitter">The emitter.</param>
 public override void Emit(InstructionNode node, BaseCodeEmitter emitter)
 {
     MovssRegToMemory(node, emitter);
 }
Exemple #53
0
        protected void Inline(InstructionNode callSiteNode, BasicBlocks blocks)
        {
            var mapBlocks = new Dictionary <BasicBlock, BasicBlock>(blocks.Count);
            var map       = new Dictionary <Operand, Operand>();

            var nextBlock = Split(callSiteNode);

            // create basic blocks
            foreach (var block in blocks)
            {
                var newBlock = CreateNewBlock();
                mapBlocks.Add(block, newBlock);
            }

            // copy instructions
            foreach (var block in blocks)
            {
                var newBlock = mapBlocks[block];

                for (var node = block.AfterFirst; !node.IsBlockEndInstruction; node = node.Next)
                {
                    if (node.IsEmpty)
                    {
                        continue;
                    }

                    if (node.Instruction == IRInstruction.Prologue)
                    {
                        continue;
                    }

                    if (node.Instruction == IRInstruction.Epilogue)
                    {
                        newBlock.BeforeLast.Insert(new InstructionNode(IRInstruction.Jmp, nextBlock));
                        continue;
                    }

                    if (node.Instruction == IRInstruction.SetReturn32 ||
                        node.Instruction == IRInstruction.SetReturn64 ||
                        node.Instruction == IRInstruction.SetReturnR4 ||
                        node.Instruction == IRInstruction.SetReturnR8 ||
                        node.Instruction == IRInstruction.SetReturnCompound)
                    {
                        if (callSiteNode.Result != null)
                        {
                            var newOperand = Map(node.Operand1, map, callSiteNode);

                            BaseInstruction moveInstruction = null;

                            if (node.Instruction == IRInstruction.SetReturn32)
                            {
                                moveInstruction = IRInstruction.MoveInt32;
                            }
                            else if (node.Instruction == IRInstruction.SetReturn64)
                            {
                                moveInstruction = IRInstruction.MoveInt64;
                            }
                            else if (node.Instruction == IRInstruction.SetReturnR4)
                            {
                                moveInstruction = IRInstruction.MoveFloatR4;
                            }
                            else if (node.Instruction == IRInstruction.SetReturnR8)
                            {
                                moveInstruction = IRInstruction.MoveFloatR8;
                            }
                            else if (node.Instruction == IRInstruction.SetReturnCompound)
                            {
                                moveInstruction = IRInstruction.MoveCompound;
                            }

                            Debug.Assert(moveInstruction != null);

                            var moveNode = new InstructionNode(moveInstruction, callSiteNode.Result, newOperand);

                            newBlock.BeforeLast.Insert(moveNode);
                        }

                        continue;
                    }

                    var newNode = new InstructionNode(node.Instruction, node.OperandCount, node.ResultCount)
                    {
                        ConditionCode = node.ConditionCode,
                        Label         = callSiteNode.Label
                    };

                    if (node.BranchTargets != null)
                    {
                        // copy targets
                        foreach (var target in node.BranchTargets)
                        {
                            newNode.AddBranchTarget(mapBlocks[target]);
                        }
                    }

                    // copy results
                    for (int i = 0; i < node.ResultCount; i++)
                    {
                        var op = node.GetResult(i);

                        var newOp = Map(op, map, callSiteNode);

                        newNode.SetResult(i, newOp);
                    }

                    // copy operands
                    for (int i = 0; i < node.OperandCount; i++)
                    {
                        var op = node.GetOperand(i);

                        var newOp = Map(op, map, callSiteNode);

                        newNode.SetOperand(i, newOp);
                    }

                    // copy other
                    if (node.MosaType != null)
                    {
                        newNode.MosaType = node.MosaType;
                    }
                    if (node.MosaField != null)
                    {
                        newNode.MosaField = node.MosaField;
                    }

                    UpdateParameterInstructions(newNode);

                    newBlock.BeforeLast.Insert(newNode);
                }
            }

            var prologue = mapBlocks[blocks.PrologueBlock];

            var callSiteOperands = callSiteNode.GetOperands();

            if (callSiteOperands.Count > 1)
            {
                var context = new Context(prologue);

                for (int i = 1; i < callSiteOperands.Count; i++)
                {
                    var operand = callSiteOperands[i];

                    if (!operand.IsVirtualRegister || operand.Low == null)
                    {
                        continue;
                    }

                    context.AppendInstruction(IRInstruction.GetLow64, operand.Low, operand);
                    context.AppendInstruction(IRInstruction.GetHigh64, operand.High, operand);
                }
            }

            callSiteNode.SetInstruction(IRInstruction.Jmp, prologue);
        }
Exemple #54
0
 /// <summary>
 /// Emits the specified platform instruction.
 /// </summary>
 /// <param name="node">The node.</param>
 /// <param name="emitter">The emitter.</param>
 public override void Emit(InstructionNode node, BaseCodeEmitter emitter)
 {
     MovsdMemoryToReg(node, emitter);
 }
Exemple #55
0
 /// <summary>
 /// Emits the specified platform instruction.
 /// </summary>
 /// <param name="node">The node.</param>
 /// <param name="emitter">The emitter.</param>
 protected override void Emit(InstructionNode node, MachineCodeEmitter emitter)
 {
     EmitDataProcessingInstruction(node, emitter, Bits.b1001);
 }
 private void Switch(InstructionNode node)
 {
     // no optimization attempted
     Branch(node);
 }
Exemple #57
0
        /// <summary>
        /// Emits the specified platform instruction.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <param name="emitter">The emitter.</param>
        protected override void Emit(InstructionNode node, MachineCodeEmitter emitter)
        {
            var opCode = ComputeOpCode(node.Size, node.Result, node.Operand1);

            emitter.Emit(opCode, node.Result, node.Operand1);
        }
        protected BasicBlocks CopyInstructions()
        {
            var newBasicBlocks = new BasicBlocks();
            var mapBlocks      = new Dictionary <BasicBlock, BasicBlock>(BasicBlocks.Count);
            var map            = new Dictionary <Operand, Operand>();

            foreach (var block in BasicBlocks)
            {
                var newBlock = newBasicBlocks.CreateBlock(block.Label);
                mapBlocks.Add(block, newBlock);
            }

            var newPrologueBlock = newBasicBlocks.GetByLabel(BasicBlock.PrologueLabel);

            foreach (var operand in MethodCompiler.Parameters)
            {
                if (operand.Definitions.Count > 0)
                {
                    var newOp = Map(operand, map);

                    var newOperand = Operand.CreateVirtualRegister(operand.Type, -operand.Index);

                    newPrologueBlock.BeforeLast.Insert(new InstructionNode(IRInstruction.Move, newOperand, newOp));

                    // redirect map from parameter to virtual register going forward
                    map.Remove(operand);
                    map.Add(operand, newOperand);
                }
            }

            foreach (var block in BasicBlocks)
            {
                var newBlock = newBasicBlocks.GetByLabel(block.Label);

                for (var node = block.First.Next; !node.IsBlockEndInstruction; node = node.Next)
                {
                    if (node.IsEmpty)
                    {
                        continue;
                    }

                    var newNode = new InstructionNode(node.Instruction, node.OperandCount, node.ResultCount);
                    newNode.Size          = node.Size;
                    newNode.ConditionCode = node.ConditionCode;

                    if (node.BranchTargets != null)
                    {
                        // copy targets
                        foreach (var target in node.BranchTargets)
                        {
                            newNode.AddBranchTarget(mapBlocks[target]);
                        }
                    }

                    // copy results
                    for (int i = 0; i < node.ResultCount; i++)
                    {
                        var op = node.GetResult(i);

                        var newOp = Map(op, map);

                        newNode.SetResult(i, newOp);
                    }

                    // copy operands
                    for (int i = 0; i < node.OperandCount; i++)
                    {
                        var op = node.GetOperand(i);

                        var newOp = Map(op, map);

                        newNode.SetOperand(i, newOp);
                    }

                    // copy other
                    if (node.MosaType != null)
                    {
                        newNode.MosaType = node.MosaType;
                    }
                    if (node.MosaField != null)
                    {
                        newNode.MosaField = node.MosaField;
                    }
                    if (node.InvokeMethod != null)
                    {
                        newNode.InvokeMethod = node.InvokeMethod;
                    }

                    newBlock.BeforeLast.Insert(newNode);
                }
            }

            var trace = CreateTraceLog("InlineMap");

            if (trace.Active)
            {
                foreach (var entry in map)
                {
                    trace.Log(entry.Value.ToString() + " from: " + entry.Key.ToString());
                }
            }

            return(newBasicBlocks);
        }
Exemple #59
0
 /// <summary>
 /// Emits the specified platform instruction.
 /// </summary>
 /// <param name="node">The node.</param>
 /// <param name="emitter">The emitter.</param>
 internal override void EmitLegacy(InstructionNode node, X86CodeEmitter emitter)
 {
     emitter.Emit(opcode, node.Operand2);
 }
Exemple #60
0
        public override void Emit(InstructionNode node, OpcodeEncoder opcodeEncoder)
        {
            System.Diagnostics.Debug.Assert(node.ResultCount == 1);
            System.Diagnostics.Debug.Assert(node.OperandCount == 2);

            if ((node.Operand1.IsCPURegister && node.Operand1.Register.RegisterCode == 5) && node.Operand2.IsConstantZero)
            {
                opcodeEncoder.SuppressByte(0x40);
                opcodeEncoder.Append4Bits(0b0100);
                opcodeEncoder.Append1Bit(0b0);
                opcodeEncoder.Append1Bit((node.Result.Register.RegisterCode >> 3) & 0x1);
                opcodeEncoder.Append1Bit(0b0);
                opcodeEncoder.Append1Bit(0b0);
                opcodeEncoder.Append8Bits(0x8B);
                opcodeEncoder.Append2Bits(0b01);
                opcodeEncoder.Append3Bits(node.Result.Register.RegisterCode);
                opcodeEncoder.Append3Bits(0b101);
                opcodeEncoder.Append8Bits(0x00);
                return;
            }

            if ((node.Operand1.IsCPURegister && node.Operand1.Register.RegisterCode == 5) && node.Operand2.IsCPURegister)
            {
                opcodeEncoder.SuppressByte(0x40);
                opcodeEncoder.Append4Bits(0b0100);
                opcodeEncoder.Append1Bit(0b0);
                opcodeEncoder.Append1Bit((node.Result.Register.RegisterCode >> 3) & 0x1);
                opcodeEncoder.Append1Bit((node.Operand2.Register.RegisterCode >> 3) & 0x1);
                opcodeEncoder.Append1Bit(0b0);
                opcodeEncoder.Append8Bits(0x8B);
                opcodeEncoder.Append2Bits(0b01);
                opcodeEncoder.Append3Bits(node.Result.Register.RegisterCode);
                opcodeEncoder.Append3Bits(0b100);
                opcodeEncoder.Append2Bits(0b00);
                opcodeEncoder.Append3Bits(node.Operand2.Register.RegisterCode);
                opcodeEncoder.Append3Bits(0b101);
                opcodeEncoder.Append8Bits(0x00);
                return;
            }

            if ((node.Operand1.IsCPURegister && node.Operand1.Register.RegisterCode == 4) && node.Operand2.IsConstantZero)
            {
                opcodeEncoder.SuppressByte(0x40);
                opcodeEncoder.Append4Bits(0b0100);
                opcodeEncoder.Append1Bit(0b0);
                opcodeEncoder.Append1Bit((node.Result.Register.RegisterCode >> 3) & 0x1);
                opcodeEncoder.Append1Bit(0b0);
                opcodeEncoder.Append1Bit(0b0);
                opcodeEncoder.Append8Bits(0x8B);
                opcodeEncoder.Append2Bits(0b00);
                opcodeEncoder.Append3Bits(node.Result.Register.RegisterCode);
                opcodeEncoder.Append3Bits(0b100);
                opcodeEncoder.Append2Bits(0b00);
                opcodeEncoder.Append3Bits(0b100);
                opcodeEncoder.Append3Bits(0b100);
                return;
            }

            if ((node.Operand1.IsCPURegister && node.Operand1.Register.RegisterCode == 4) && (node.Operand2.IsConstant && node.Operand2.ConstantSigned32 >= -128 && node.Operand2.ConstantSigned32 <= 127))
            {
                opcodeEncoder.SuppressByte(0x40);
                opcodeEncoder.Append4Bits(0b0100);
                opcodeEncoder.Append1Bit(0b0);
                opcodeEncoder.Append1Bit((node.Result.Register.RegisterCode >> 3) & 0x1);
                opcodeEncoder.Append1Bit(0b0);
                opcodeEncoder.Append1Bit(0b0);
                opcodeEncoder.Append8Bits(0x8B);
                opcodeEncoder.Append2Bits(0b01);
                opcodeEncoder.Append3Bits(node.Result.Register.RegisterCode);
                opcodeEncoder.Append3Bits(0b100);
                opcodeEncoder.Append2Bits(0b00);
                opcodeEncoder.Append3Bits(0b100);
                opcodeEncoder.Append3Bits(0b100);
                opcodeEncoder.Append8BitImmediate(node.Operand2);
                return;
            }

            if ((node.Operand1.IsCPURegister && node.Operand1.Register.RegisterCode == 4) && node.Operand2.IsConstant)
            {
                opcodeEncoder.SuppressByte(0x40);
                opcodeEncoder.Append4Bits(0b0100);
                opcodeEncoder.Append1Bit(0b0);
                opcodeEncoder.Append1Bit((node.Result.Register.RegisterCode >> 3) & 0x1);
                opcodeEncoder.Append1Bit(0b0);
                opcodeEncoder.Append1Bit(0b0);
                opcodeEncoder.Append8Bits(0x8B);
                opcodeEncoder.Append2Bits(0b10);
                opcodeEncoder.Append3Bits(node.Result.Register.RegisterCode);
                opcodeEncoder.Append3Bits(0b100);
                opcodeEncoder.Append8BitImmediate(node.Operand2);
                return;
            }

            if (node.Operand1.IsCPURegister && node.Operand2.IsCPURegister)
            {
                opcodeEncoder.SuppressByte(0x40);
                opcodeEncoder.Append4Bits(0b0100);
                opcodeEncoder.Append1Bit(0b0);
                opcodeEncoder.Append1Bit((node.Result.Register.RegisterCode >> 3) & 0x1);
                opcodeEncoder.Append1Bit((node.Operand1.Register.RegisterCode >> 3) & 0x1);
                opcodeEncoder.Append1Bit(0b0);
                opcodeEncoder.Append8Bits(0x8B);
                opcodeEncoder.Append2Bits(0b00);
                opcodeEncoder.Append3Bits(node.Result.Register.RegisterCode);
                opcodeEncoder.Append3Bits(0b100);
                opcodeEncoder.Append2Bits(0b00);
                opcodeEncoder.Append3Bits(node.Operand2.Register.RegisterCode);
                opcodeEncoder.Append3Bits(node.Operand1.Register.RegisterCode);
                return;
            }

            if (node.Operand1.IsCPURegister && node.Operand2.IsConstantZero)
            {
                opcodeEncoder.SuppressByte(0x40);
                opcodeEncoder.Append4Bits(0b0100);
                opcodeEncoder.Append1Bit(0b0);
                opcodeEncoder.Append1Bit((node.Result.Register.RegisterCode >> 3) & 0x1);
                opcodeEncoder.Append1Bit(0b0);
                opcodeEncoder.Append1Bit((node.Operand1.Register.RegisterCode >> 3) & 0x1);
                opcodeEncoder.Append8Bits(0x8B);
                opcodeEncoder.Append2Bits(0b00);
                opcodeEncoder.Append3Bits(node.Result.Register.RegisterCode);
                opcodeEncoder.Append3Bits(node.Operand1.Register.RegisterCode);
                return;
            }

            if (node.Operand1.IsCPURegister && (node.Operand2.IsConstant && node.Operand2.ConstantSigned32 >= -128 && node.Operand2.ConstantSigned32 <= 127))
            {
                opcodeEncoder.SuppressByte(0x40);
                opcodeEncoder.Append4Bits(0b0100);
                opcodeEncoder.Append1Bit(0b0);
                opcodeEncoder.Append1Bit((node.Result.Register.RegisterCode >> 3) & 0x1);
                opcodeEncoder.Append1Bit(0b0);
                opcodeEncoder.Append1Bit((node.Operand1.Register.RegisterCode >> 3) & 0x1);
                opcodeEncoder.Append8Bits(0x8B);
                opcodeEncoder.Append2Bits(0b01);
                opcodeEncoder.Append3Bits(node.Result.Register.RegisterCode);
                opcodeEncoder.Append3Bits(node.Operand1.Register.RegisterCode);
                opcodeEncoder.Append8BitImmediate(node.Operand2);
                return;
            }

            if (node.Operand1.IsCPURegister && node.Operand2.IsConstant)
            {
                opcodeEncoder.SuppressByte(0x40);
                opcodeEncoder.Append4Bits(0b0100);
                opcodeEncoder.Append1Bit(0b0);
                opcodeEncoder.Append1Bit((node.Result.Register.RegisterCode >> 3) & 0x1);
                opcodeEncoder.Append1Bit(0b0);
                opcodeEncoder.Append1Bit((node.Operand1.Register.RegisterCode >> 3) & 0x1);
                opcodeEncoder.Append8Bits(0x8B);
                opcodeEncoder.Append2Bits(0b10);
                opcodeEncoder.Append3Bits(node.Result.Register.RegisterCode);
                opcodeEncoder.Append3Bits(node.Operand1.Register.RegisterCode);
                opcodeEncoder.Append32BitImmediate(node.Operand2);
                return;
            }

            if (node.Operand1.IsConstant && node.Operand2.IsConstantZero)
            {
                opcodeEncoder.SuppressByte(0x40);
                opcodeEncoder.Append4Bits(0b0100);
                opcodeEncoder.Append1Bit(0b0);
                opcodeEncoder.Append1Bit((node.Result.Register.RegisterCode >> 3) & 0x1);
                opcodeEncoder.Append1Bit(0b0);
                opcodeEncoder.Append1Bit(0b0);
                opcodeEncoder.Append8Bits(0x8B);
                opcodeEncoder.Append2Bits(0b00);
                opcodeEncoder.Append3Bits(node.Result.Register.RegisterCode);
                opcodeEncoder.Append3Bits(0b101);
                opcodeEncoder.Append32BitImmediate(node.Operand1);
                return;
            }

            if (node.Operand1.IsConstant && node.Operand2.IsConstant)
            {
                opcodeEncoder.SuppressByte(0x40);
                opcodeEncoder.Append4Bits(0b0100);
                opcodeEncoder.Append1Bit(0b0);
                opcodeEncoder.Append1Bit((node.Result.Register.RegisterCode >> 3) & 0x1);
                opcodeEncoder.Append1Bit(0b0);
                opcodeEncoder.Append1Bit(0b0);
                opcodeEncoder.Append8Bits(0x8B);
                opcodeEncoder.Append2Bits(0b00);
                opcodeEncoder.Append3Bits(node.Result.Register.RegisterCode);
                opcodeEncoder.Append3Bits(0b101);
                opcodeEncoder.Append32BitImmediateWithOffset(node.Operand1, node.Operand2);
                return;
            }

            throw new Compiler.Common.Exceptions.CompilerException("Invalid Opcode");
        }