Example #1
0
 /// <summary>
 /// Visitation function for <see cref="IR.IIRVisitor.AddressOfInstruction"/> instruction.
 /// </summary>
 /// <param name="ctx">The context.</param>
 void IR.IIRVisitor.AddressOfInstruction(Context ctx)
 {
     Operand opRes = ctx.Result;
     RegisterOperand eax = new RegisterOperand (opRes.Type, GeneralPurposeRegister.EAX);
     ctx.Result = eax;
     ctx.ReplaceInstructionOnly (CPUx86.Instruction.LeaInstruction);
     //            ctx.Ignore = true;
     ctx.AppendInstruction (CPUx86.Instruction.MovInstruction, opRes, eax);
 }
 /// <summary>
 /// Visitation function for <see cref="ICILVisitor.Switch"/>.
 /// </summary>
 /// <param name="ctx">The context.</param>
 public void Switch(Context ctx)
 {
     ctx.ReplaceInstructionOnly(Instruction.SwitchInstruction);
 }
 /// <summary>
 /// Visitation function for <see cref="ICILVisitor.Ret"/>.
 /// </summary>
 /// <param name="ctx">The context.</param>
 void ICILVisitor.Ret(Context ctx)
 {
     ctx.ReplaceInstructionOnly (IR.Instruction.ReturnInstruction);
 }
 /// <summary>
 /// Visitation function for <see cref="ICILVisitor.Ldarga"/>.
 /// </summary>
 /// <param name="ctx">The context.</param>
 void ICILVisitor.Ldarga(Context ctx)
 {
     ctx.ReplaceInstructionOnly (IR.Instruction.AddressOfInstruction);
     //ctx.SetInstruction(IR.Instruction.AddressOfInstruction, ctx.Result, ctx.Operand1);
 }
        /// <summary>
        /// Expands the given invoke instruction to perform the method call.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <returns>
        /// A single instruction or an array of instructions, which appropriately represent the method call.
        /// </returns>
        public void MakeCall(Context ctx, ISignatureContext context, IMetadataProvider metadata)
        {
            /*
             * Calling convention is right-to-left, pushed on the stack. Return value in EAX for integral
             * types 4 bytes or less, XMM0 for floating point and EAX:EDX for 64-bit. If this is a method
             * of a type, the this argument is moved to ECX right before the call.
             *
             */

            Operand invokeTarget = ctx.Operand1;
            Operand result = ctx.Result;
            Stack<Operand> operands = this.BuildOperandStack(ctx);

            ctx.ReplaceInstructionOnly(CPUx86.Instruction.NopInstruction);
            ctx.OperandCount = 0;
            ctx.Result = null;

            int stackSize = this.ReserveStackSizeForCall(ctx, metadata, context, operands);
            if (stackSize != 0)
            {
                this.PushOperands(context, ctx, operands, stackSize, metadata);
            }

            ctx.AppendInstruction(CPUx86.Instruction.CallInstruction, null, invokeTarget);

            if (stackSize != 0)
            {
                this.FreeStackAfterCall(ctx, stackSize);
            }

            this.CleanupReturnValue(ctx, result);
        }
 /// <summary>
 /// Visitation function for <see cref="CIL.ICILVisitor.Branch"/>.
 /// </summary>
 /// <param name="ctx">The context.</param>
 void CIL.ICILVisitor.Branch(Context ctx)
 {
     ctx.ReplaceInstructionOnly(CPUx86.Instruction.JmpInstruction);
 }
Example #7
0
 /// <summary>
 /// Visitation function for <see cref="IR.IIRVisitor.BranchInstruction"/> instructions.
 /// </summary>
 /// <param name="context">The context.</param>
 void IR.IIRVisitor.BranchInstruction(Context context)
 {
     context.ReplaceInstructionOnly (CPUx86.Instruction.BranchInstruction);
 }
Example #8
0
 /// <summary>
 /// Special handling for shift operations, which require the shift amount in the ECX or as a constant register.
 /// </summary>
 /// <param name="ctx">The transformation context.</param>
 /// <param name="instruction">The instruction to transform.</param>
 private void HandleShiftOperation(Context ctx, IInstruction instruction)
 {
     EmitOperandConstants (ctx);
     ctx.ReplaceInstructionOnly (instruction);
 }
 /// <summary>
 /// Visitation function for DivUInstruction.
 /// </summary>
 /// <param name="context">The context.</param>
 void IR.IIRVisitor.DivUInstruction(Context context)
 {
     context.ReplaceInstructionOnly(CPUx86.Instruction.UDivInstruction);
 }
 /// <summary>
 /// Special handling for commutative operations.
 /// </summary>
 /// <param name="context">The transformation context.</param>
 /// <param name="instruction">The instruction.</param>
 /// <remarks>
 /// Commutative operations are reordered by moving the constant to the second operand,
 /// which allows the instruction selection in the code generator to use a instruction
 /// format with an immediate operand.
 /// </remarks>
 private void HandleCommutativeOperation(Context context, IInstruction instruction)
 {
     EmitOperandConstants(context);
     context.ReplaceInstructionOnly(instruction);
 }
 /// <summary>
 /// Visitation function for <see cref="ICILVisitor.Ldloca"/>.
 /// </summary>
 /// <param name="ctx">The context.</param>
 public void Ldloca(Context ctx)
 {
     ctx.ReplaceInstructionOnly(Instruction.AddressOfInstruction);
 }
 /// <summary>
 /// Visitation function for <see cref="ICILVisitor.Branch"/>.
 /// </summary>
 /// <param name="ctx">The context.</param>
 public void Branch(Context ctx)
 {
     ctx.ReplaceInstructionOnly(Instruction.JmpInstruction);
 }
        /// <summary>
        /// Replaces the instruction with an internal call.
        /// </summary>
        /// <param name="ctx">The transformation context.</param>
        /// <param name="internalCallTarget">The internal call target.</param>
        private void ReplaceWithInternalCall(Context ctx, VmCall internalCallTarget)
        {
            RuntimeType rt = RuntimeBase.Instance.TypeLoader.GetType(@"Mosa.Runtime.RuntimeBase");
            RuntimeMethod callTarget = FindMethod(rt, internalCallTarget.ToString());

            ctx.ReplaceInstructionOnly(IR.Instruction.CallInstruction);
            ctx.SetOperand(0, SymbolOperand.FromMethod(callTarget));
        }
        /// <summary>
        /// Replaces the IL load instruction by an appropriate IR move instruction or removes it entirely, if
        /// it is a native size.
        /// </summary>
        /// <param name="context">Provides the transformation context.</param>
        private void ProcessLoadInstruction(Context context)
        {
            IInstruction extension = null;
            SigType extendedType = null;
            Operand source = context.Operand1;
            Operand destination = context.Result;

            // Is this a sign or zero-extending move?
            if (source != null)
            {
                if (IsSignExtending(source))
                {
                    extension = Instruction.SignExtendedMoveInstruction;
                    extendedType = BuiltInSigType.Int32;
                }
                else if (IsZeroExtending(source))
                {
                    extension = Instruction.ZeroExtendedMoveInstruction;
                    extendedType = BuiltInSigType.UInt32;
                }
            }

            if (extension != null)
            {
                Operand temp = this.MethodCompiler.CreateTemporary(extendedType);
                destination.Replace(temp, context.InstructionSet);
                context.SetInstruction(extension, temp, source);
            }
            else
            {
                context.ReplaceInstructionOnly(Instruction.MoveInstruction);
            }
        }
 private static void Replace(Context context, IIRInstruction floatingPointInstruction, IIRInstruction signedInstruction, IIRInstruction unsignedInstruction)
 {
     if (IsFloatingPoint(context))
     {
         context.ReplaceInstructionOnly(floatingPointInstruction);
     }
     else if (IsUnsigned(context))
     {
         context.ReplaceInstructionOnly(unsignedInstruction);
     }
     else
     {
         context.ReplaceInstructionOnly(signedInstruction);
     }
 }
Example #16
0
 /// <summary>
 /// Visitation function for <see cref="IR.IIRVisitor.UDivInstruction"/> instruction.
 /// </summary>
 /// <param name="ctx">The context.</param>
 void IR.IIRVisitor.UDivInstruction(Context ctx)
 {
     ctx.ReplaceInstructionOnly (CPUx86.Instruction.UDivInstruction);
 }
Example #17
0
        /// <summary>
        /// Visitation function for <see cref="IR.IIRVisitor.ZeroExtendedMoveInstruction"/> instructions.
        /// </summary>
        /// <param name="ctx">The context.</param>
        void IR.IIRVisitor.ZeroExtendedMoveInstruction(Context ctx)
        {
            switch (ctx.Operand1.Type.Type) {
                case CilElementType.I1:
                    ctx.ReplaceInstructionOnly (CPUx86.Instruction.MovzxInstruction);
                    break;
                case CilElementType.I2:
                    goto case CilElementType.I1;
                case CilElementType.I4:
                    goto case CilElementType.I1;
                case CilElementType.I8:
                    throw new NotSupportedException ();
                case CilElementType.U1:
                    goto case CilElementType.I1;
                case CilElementType.U2:
                    goto case CilElementType.I1;
                case CilElementType.U4:
                    goto case CilElementType.I1;
                case CilElementType.U8:
                    goto case CilElementType.I8;
                case CilElementType.Char:
                    goto case CilElementType.I2;
                default:
                    throw new NotSupportedException ();
            }

            if ((ctx.Result is RegisterOperand))
                return;

            Operand result = ctx.Result;
            Operand source = ctx.Operand1;
            RegisterOperand ebx = new RegisterOperand (result.Type, GeneralPurposeRegister.EBX);
            ctx.Result = ebx;

            ctx.AppendInstruction (CPUx86.Instruction.MovInstruction, result, ebx);
        }
 /// <summary>
 /// Visitation function for LogicalOrInstruction.
 /// </summary>
 /// <param name="context">The context.</param>
 void IR.IIRVisitor.LogicalOrInstruction(Context context)
 {
     context.ReplaceInstructionOnly(CPUx86.Instruction.OrInstruction);
 }
        /// <summary>
        /// Visitation function for MoveInstruction.
        /// </summary>
        /// <param name="context">The context.</param>
        void IR.IIRVisitor.MoveInstruction(Context context)
        {
            Operand result = context.Result;
            Operand operand = context.Operand1;
            context.Operand1 = EmitConstant(context.Operand1);

            if (context.Result.StackType == StackTypeCode.F)
            {
                Debug.Assert(context.Operand1.StackType == StackTypeCode.F, @"Move can't convert to floating point type.");
                if (context.Result.Type.Type == context.Operand1.Type.Type)
                {
                    if (context.Result.Type.Type == CilElementType.R4)
                        MoveFloatingPoint(context, CPUx86.Instruction.MovssInstruction);
                    else if (context.Result.Type.Type == CilElementType.R8)
                        MoveFloatingPoint(context, CPUx86.Instruction.MovsdInstruction);
                }
                else if (context.Result.Type.Type == CilElementType.R8)
                {
                    context.SetInstruction(CPUx86.Instruction.Cvtss2sdInstruction, context.Result, context.Operand1, context.Operand2);
                }
                else if (context.Result.Type.Type == CilElementType.R4)
                {
                    context.SetInstruction(CPUx86.Instruction.Cvtsd2ssInstruction, context.Result, context.Operand1, context.Operand2);
                }
            }
            else
            {
                if (context.Result is MemoryOperand && context.Operand1 is MemoryOperand)
                {
                    RegisterOperand load = new RegisterOperand(new SigType(CilElementType.I), GeneralPurposeRegister.EDX);
                    RegisterOperand store = new RegisterOperand(operand.Type, GeneralPurposeRegister.EDX);

                    if (!Is32Bit(operand) && IsSigned(operand))
                        context.SetInstruction(CPUx86.Instruction.MovsxInstruction, load, operand);
                    else if (!Is32Bit(operand) && IsUnsigned(operand))
                        context.SetInstruction(CPUx86.Instruction.MovzxInstruction, load, operand);
                    else
                        context.SetInstruction(CPUx86.Instruction.MovInstruction, load, operand);

                    context.AppendInstruction(CPUx86.Instruction.MovInstruction, result, store);
                }
                else
                    context.ReplaceInstructionOnly(CPUx86.Instruction.MovInstruction);
            }
        }
        /// <summary>
        /// Visitation function for SignExtendedMoveInstruction"/> instructions.
        /// </summary>
        /// <param name="context">The context.</param>
        void IR.IIRVisitor.SignExtendedMoveInstruction(Context context)
        {
            Operand offset = context.Operand2;
            if (offset != null)
            {
                RegisterOperand eax = new RegisterOperand(BuiltInSigType.Int32, GeneralPurposeRegister.EAX);
                Operand destination = context.Result;
                MemoryOperand source = (MemoryOperand)context.Operand1;
                SigType elementType = GetElementType(source.Type);
                ConstantOperand constantOffset = offset as ConstantOperand;
                IntPtr offsetPtr = IntPtr.Zero;

                context.SetInstruction(CPUx86.Instruction.MovInstruction, eax, source);
                if (constantOffset != null)
                {
                    offsetPtr = new IntPtr(Convert.ToInt64(constantOffset.Value));
                }
                else
                {
                    context.AppendInstruction(CPUx86.Instruction.AddInstruction, eax, offset);
                }

                context.AppendInstruction(CPUx86.Instruction.MovsxInstruction, destination, new MemoryOperand(elementType, GeneralPurposeRegister.EAX, offsetPtr));
            }
            else
            {
                context.ReplaceInstructionOnly(CPUx86.Instruction.MovsxInstruction);
            }
        }
 /// <summary>
 /// Visitation function for <see cref="CPUx86.IX86Visitor.Movzx"/> instructions.
 /// </summary>
 /// <param name="context">The context.</param>
 void CPUx86.IX86Visitor.Movzx(Context context)
 {
     if (Is32Bit(context.Operand1))
         context.ReplaceInstructionOnly(CPUx86.Instruction.MovInstruction);
     else {
         Operand result = context.Result;
         if (!(result is RegisterOperand)) {
             RegisterOperand ecx = new RegisterOperand(context.Result.Type, GeneralPurposeRegister.ECX);
             context.SetInstruction(CPUx86.Instruction.MovsxInstruction, ecx, context.Operand1);
             context.AppendInstruction(CPUx86.Instruction.MovInstruction, result, ecx);
         }
     }
 }
Example #22
0
 /// <summary>
 /// Visitation function for <see cref="IR.IIRVisitor.FloatingPointToIntegerConversionInstruction"/> instructions.
 /// </summary>
 /// <param name="context">The context.</param>
 void IR.IIRVisitor.FloatingPointToIntegerConversionInstruction(Context context)
 {
     Operand source = context.Operand1;
     Operand destination = context.Result;
     switch (destination.Type.Type) {
         case CilElementType.I1:
             goto case CilElementType.I4;
         case CilElementType.I2:
             goto case CilElementType.I4;
         case CilElementType.I4:
             if (source.Type.Type == CilElementType.R8)
                 context.ReplaceInstructionOnly (CPUx86.Instruction.Cvttsd2siInstruction);
             else
                 context.ReplaceInstructionOnly (CPUx86.Instruction.Cvttss2siInstruction);
             break;
         case CilElementType.I8:
             throw new NotSupportedException ();
         case CilElementType.U1:
             goto case CilElementType.U4;
         case CilElementType.U2:
             goto case CilElementType.U4;
         case CilElementType.U4:
             throw new NotSupportedException ();
         case CilElementType.U8:
             throw new NotSupportedException ();
         case CilElementType.I:
             goto case CilElementType.I4;
         case CilElementType.U:
             goto case CilElementType.U4;
     }
 }
 /// <summary>
 /// Handles the non commutative operation.
 /// </summary>
 /// <param name="ctx">The context.</param>
 /// <param name="instruction">The instruction.</param>
 private void HandleNonCommutativeOperation(Context ctx, IInstruction instruction)
 {
     EmitResultConstants(ctx);
     EmitOperandConstants(ctx);
     ctx.ReplaceInstructionOnly(instruction);
 }
Example #24
0
 /// <summary>
 /// Visitation function for <see cref="IR.IIRVisitor.LogicalXorInstruction"/> instruction.
 /// </summary>
 /// <param name="ctx">The context.</param>
 void IR.IIRVisitor.LogicalXorInstruction(Context ctx)
 {
     ctx.ReplaceInstructionOnly (CPUx86.Instruction.XorInstruction);
 }
        /// <summary>
        /// Replaces the instruction with an internal call.
        /// </summary>
        /// <param name="ctx">The transformation context.</param>
        /// <param name="internalCallTarget">The internal call target.</param>
        private void ReplaceWithInternalCall(Context ctx, object internalCallTarget)
        {
            RuntimeType rt = RuntimeBase.Instance.TypeLoader.GetType ("Mosa.Runtime.RuntimeBase");
            RuntimeMethod callTarget = FindMethod (rt, internalCallTarget.ToString ());

            ctx.ReplaceInstructionOnly (IR.Instruction.CallInstruction);
            ctx.InvokeTarget = callTarget;
        }
Example #26
0
        /// <summary>
        /// Visitation function for <see cref="IR.IIRVisitor.MoveInstruction"/> instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        void IR.IIRVisitor.MoveInstruction(Context ctx)
        {
            Operand result = ctx.Result;
            Operand operand = ctx.Operand1;
            ctx.Operand1 = EmitConstant (ctx.Operand1);
            if (ctx.Result.Type.Type == CilElementType.R4)
                MoveFloatingPoint (ctx, CPUx86.Instruction.MovssInstruction);
            else if (ctx.Result.Type.Type == CilElementType.R8)
                MoveFloatingPoint (ctx, CPUx86.Instruction.MovsdInstruction);
            else
            {
                if (ctx.Result is MemoryOperand && ctx.Operand1 is MemoryOperand)
                {
                    RegisterOperand load = new RegisterOperand (new SigType (CilElementType.I), GeneralPurposeRegister.ECX);
                    RegisterOperand store = new RegisterOperand (operand.Type, GeneralPurposeRegister.ECX);

                    if (!Is32Bit (operand) && IsSigned (operand))
                        ctx.SetInstruction (CPUx86.Instruction.MovsxInstruction, load, operand);
                    else if (!Is32Bit (operand) && IsUnsigned (operand))
                        ctx.SetInstruction (CPUx86.Instruction.MovzxInstruction, load, operand);
                    else
                        ctx.SetInstruction (CPUx86.Instruction.MovInstruction, load, operand);

                    ctx.AppendInstruction (CPUx86.Instruction.MovInstruction, result, store);
                }

                else

                    ctx.ReplaceInstructionOnly (CPUx86.Instruction.MovInstruction);
            }
        }
 /// <summary>
 /// Visitation function for <see cref="ICILVisitor.Nop"/>.
 /// </summary>
 /// <param name="ctx">The context.</param>
 void ICILVisitor.Nop(Context ctx)
 {
     ctx.ReplaceInstructionOnly (IR.Instruction.NopInstruction);
 }
Example #28
0
 /// <summary>
 /// Visitation function for <see cref="IR.IIRVisitor.SignExtendedMoveInstruction"/> instructions.
 /// </summary>
 /// <param name="ctx">The context.</param>
 void IR.IIRVisitor.SignExtendedMoveInstruction(Context ctx)
 {
     ctx.ReplaceInstructionOnly (CPUx86.Instruction.MovsxInstruction);
 }
        private void PerformStaticAllocationOf(Context allocation, Context assignment)
        {
            RuntimeType allocatedType = allocation.InvokeTarget.DeclaringType;

            // Allocate a linker symbol to refer to for this allocation. Use the destination field name as the linker symbol name.
            string symbolName = assignment.RuntimeField.ToString() + @"<<$cctor";
            using (var stream = this.linker.Allocate(symbolName, SectionKind.BSS, allocatedType.Size, 4))
            {
                // FIXME: Do we have to initialize this?
                string methodTableSymbol = this.GetMethodTableForType(allocatedType);
                if (methodTableSymbol != null)
                {
                    this.linker.Link(LinkType.AbsoluteAddress | LinkType.I4, symbolName, 0, 0, methodTableSymbol, IntPtr.Zero);
                }
            }

            // Issue a load request before the newobj and before the assignment.
            Operand symbol1 = this.InsertLoadBeforeInstruction(allocation, symbolName, assignment.RuntimeField.SignatureType);
            allocation.Operand1 = symbol1;

            Operand symbol2 = this.InsertLoadBeforeInstruction(assignment, symbolName, assignment.RuntimeField.SignatureType);
            assignment.Operand1 = symbol2;

            // Change the newobj to a call and increase the operand count to include the this ptr.
            allocation.OperandCount++;
            allocation.ResultCount = 0;
            allocation.ReplaceInstructionOnly(Instruction.Get(OpCode.Call));
        }
 /// <summary>
 /// Visitation function for Ldarga instruction.
 /// </summary>
 /// <param name="context">The context.</param>
 public void Ldarga(Context context)
 {
     context.ReplaceInstructionOnly(IR.Instruction.AddressOfInstruction);
 }