Exemplo n.º 1
0
        /// <summary>
        /// Replaces the instrinsic call site
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="typeSystem">The type system.</param>
        public void ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem)
        {
            SigType I4 = new SigType(CilElementType.I4);
            RegisterOperand esp = new RegisterOperand(I4, GeneralPurposeRegister.ESP);

            context.SetInstruction(CPUx86.Instruction.MovInstruction, esp, context.Operand1);
            context.AppendInstruction(CPUx86.Instruction.PopadInstruction);
            context.AppendInstruction(CPUx86.Instruction.AddInstruction, esp, new ConstantOperand(I4, 0x08));
            context.AppendInstruction(CPUx86.Instruction.StiInstruction);
            context.AppendInstruction(CPUx86.Instruction.IRetdInstruction);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Replaces the instrinsic call site
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="typeSystem">The type system.</param>
        public void ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem)
        {
            Operand result = context.Result;
            SigType u4 = new SigType(CilElementType.U4);
            RegisterOperand eax = new RegisterOperand(u4, GeneralPurposeRegister.EAX);

            context.SetInstruction(CPUx86.Instruction.PopInstruction, eax);
            context.AppendInstruction(CPUx86.Instruction.AddInstruction, eax, new RegisterOperand(u4, GeneralPurposeRegister.ESP));
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, eax, new MemoryOperand(u4, GeneralPurposeRegister.EAX, new IntPtr(0)));
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, result, eax);
            context.AppendInstruction(CPUx86.Instruction.PushInstruction, null, eax);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Replaces the instrinsic call site
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="typeSystem">The type system.</param>
        public void ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem)
        {
            Operand result = context.Result;
            Operand operand1 = context.Operand1;

            RegisterOperand edx = new RegisterOperand(operand1.Type, GeneralPurposeRegister.EDX);
            RegisterOperand eax = new RegisterOperand(result.Type, GeneralPurposeRegister.EAX);

            context.SetInstruction(CPUx86.Instruction.MovInstruction, edx, operand1);
            context.AppendInstruction(CPUx86.Instruction.InInstruction, eax, edx);
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, result, eax);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Replaces the instrinsic call site
        /// </summary>
        /// <param name="context">The context.</param>
        public void ReplaceIntrinsicCall(Context context)
        {
            Operand operand1 = context.Operand1;
            Operand operand2 = context.Operand2;

            RegisterOperand edx = new RegisterOperand (operand1.Type, GeneralPurposeRegister.EDX);
            RegisterOperand eax = new RegisterOperand (operand2.Type, GeneralPurposeRegister.EAX);

            context.SetInstruction (CPUx86.Instruction.MovInstruction, edx, operand1);
            context.AppendInstruction (CPUx86.Instruction.MovInstruction, eax, operand2);
            context.AppendInstruction (CPUx86.Instruction.OutInstruction, null, edx, eax);
        }
Exemplo n.º 5
0
 /// <summary>
 /// Replaces the instrinsic call site
 /// </summary>
 /// <param name="context">The context.</param>
 public void ReplaceIntrinsicCall(Context context)
 {
     Operand result = context.Result;
     Operand operand = context.Operand1;
     RegisterOperand eax = new RegisterOperand(new Mosa.Runtime.Metadata.Signatures.SigType(Mosa.Runtime.Metadata.CilElementType.I4), GeneralPurposeRegister.EAX);
     RegisterOperand ecx = new RegisterOperand(new Mosa.Runtime.Metadata.Signatures.SigType(Mosa.Runtime.Metadata.CilElementType.I4), GeneralPurposeRegister.ECX);
     RegisterOperand reg = new RegisterOperand(new Mosa.Runtime.Metadata.Signatures.SigType(Mosa.Runtime.Metadata.CilElementType.I4), GeneralPurposeRegister.EBX);
     context.SetInstruction(CPUx86.Instruction.MovInstruction, eax, operand);
     context.AppendInstruction(CPUx86.Instruction.XorInstruction, ecx, ecx);
     context.AppendInstruction(CPUx86.Instruction.CpuIdEbxInstruction);
     context.AppendInstruction(CPUx86.Instruction.MovInstruction, result, reg);
 }
Exemplo n.º 6
0
        /// <summary>
        /// Replaces the instrinsic call site
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="typeSystem">The type system.</param>
        public void ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem)
        {
            Operand dest = context.Operand1;
            Operand value = context.Operand2;

            RegisterOperand edx = new RegisterOperand(dest.Type, GeneralPurposeRegister.EDX);
            RegisterOperand eax = new RegisterOperand(value.Type, GeneralPurposeRegister.EAX);
            MemoryOperand memory = new MemoryOperand(new SigType(context.InvokeTarget.Signature.Parameters[1].Type), GeneralPurposeRegister.EDX, new IntPtr(0));

            context.SetInstruction(CPUx86.Instruction.MovInstruction, edx, dest);
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, eax, value);
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, memory, eax);
        }
        /// <summary>
        /// Performs stage specific processing on the compiler context.
        /// </summary>
        public void Run()
        {
            // Create the prologue block
            Context ctx = new Context(InstructionSet, -1);
            // Add a jump instruction to the first block from the prologue
            ctx.AppendInstruction(IR.Instruction.JmpInstruction);
            //ctx.AppendInstruction(CIL.Instruction.Get(CIL.OpCode.Br));
            ctx.SetBranch(0);
            ctx.Label = -1;
            _prologue = CreateBlock(-1, ctx.Index);

            SplitIntoBlocks(0);

            // Create the epilogue block
            ctx = new Context(InstructionSet, -1);
            // Add null instruction, necessary to generate a block index
            ctx.AppendInstruction(null);
            ctx.Ignore = true;
            ctx.Label = Int32.MaxValue;
            _epilogue = CreateBlock(Int32.MaxValue, ctx.Index);

            // Link all the blocks together
            BuildBlockLinks(_prologue);

            // Link Exception Header Clauses
            LinkExceptionHeaderClauses();
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="TypeInitializerSchedulerStage"/> class.
        /// </summary>
        public TypeInitializerSchedulerStage()
        {
            InstructionSet = new InstructionSet(1024);
            _ctx = CreateContext(-1);

            _ctx.AppendInstruction(IR.Instruction.PrologueInstruction);
            _ctx.Other = 0; // stacksize
        }
Exemplo n.º 9
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>
        /// Replaces the instrinsic call site
        /// </summary>
        /// <param name="context">The context.</param>
        public void ReplaceIntrinsicCall(Context context)
        {
            Operand operand1 = context.Operand1;

            RegisterOperand imm = new RegisterOperand(new SigType(CilElementType.U4), GeneralPurposeRegister.EAX);

            context.SetInstruction(IR.Instruction.MoveInstruction, imm, operand1);
            context.AppendInstruction(IR.Instruction.MoveInstruction, new RegisterOperand(new SigType(CilElementType.U4), _control), imm);
        }
        /// <summary>
        /// Replaces the instrinsic call site
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="typeSystem">The type system.</param>
        public void ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem)
        {
            Operand result = context.Result;

            RegisterOperand imm = new RegisterOperand(new SigType(CilElementType.U4), GeneralPurposeRegister.EAX);

            context.SetInstruction(IR.Instruction.MoveInstruction, imm, new RegisterOperand(new SigType(CilElementType.U4), _control));
            context.AppendInstruction(IR.Instruction.MoveInstruction, result, imm);
        }
Exemplo n.º 12
0
        /// <summary>
        /// Replaces the instrinsic call site
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="typeSystem">The type system.</param>
        public void ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem)
        {
            Operand result = context.Result;

            RegisterOperand tmp = new RegisterOperand(new Mosa.Runtime.Metadata.Signatures.SigType(Mosa.Runtime.Metadata.CilElementType.Ptr), GeneralPurposeRegister.EDX);
            MemoryOperand operand = new MemoryOperand(context.Operand1.Type, GeneralPurposeRegister.EDX, new System.IntPtr(0));

            context.SetInstruction(CPUx86.Instruction.MovInstruction, tmp, context.Operand1);
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, result, operand);
        }
        /// <summary>
        /// Create an empty block.
        /// </summary>
        /// <param name="label">The label.</param>
        /// <returns></returns>
        protected Context CreateEmptyBlockContext(int label)
        {
            Context ctx = new Context(InstructionSet, -1);
            BasicBlock block = CreateBlock(BasicBlocks.Count + 0x10000000);
            ctx.BasicBlock = block;

            // Need a dummy instruction at the start of each block to establish a starting point of the block
            ctx.AppendInstruction(null);
            ctx.Label = label;
            block.Index = ctx.Index;
            ctx.Ignore = true;

            return ctx;
        }
Exemplo n.º 14
0
        /// <summary>
        /// Replaces the instrinsic call site
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="typeSystem">The type system.</param>
        public void ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem)
        {
            MemoryOperand operand = new MemoryOperand(new Mosa.Runtime.Metadata.Signatures.SigType(Mosa.Runtime.Metadata.CilElementType.Ptr), GeneralPurposeRegister.EAX, new System.IntPtr(0));
            context.SetInstruction(CPUx86.Instruction.MovInstruction, new RegisterOperand(new Mosa.Runtime.Metadata.Signatures.SigType(Mosa.Runtime.Metadata.CilElementType.Ptr), GeneralPurposeRegister.EAX), context.Operand1);
            context.AppendInstruction(CPUx86.Instruction.LgdtInstruction, null, operand);

            RegisterOperand ax = new RegisterOperand(new Mosa.Runtime.Metadata.Signatures.SigType(Mosa.Runtime.Metadata.CilElementType.I2), GeneralPurposeRegister.EAX);
            RegisterOperand ds = new RegisterOperand(new Mosa.Runtime.Metadata.Signatures.SigType(Mosa.Runtime.Metadata.CilElementType.I2), SegmentRegister.DS);
            RegisterOperand es = new RegisterOperand(new Mosa.Runtime.Metadata.Signatures.SigType(Mosa.Runtime.Metadata.CilElementType.I2), SegmentRegister.ES);
            RegisterOperand fs = new RegisterOperand(new Mosa.Runtime.Metadata.Signatures.SigType(Mosa.Runtime.Metadata.CilElementType.I2), SegmentRegister.FS);
            RegisterOperand gs = new RegisterOperand(new Mosa.Runtime.Metadata.Signatures.SigType(Mosa.Runtime.Metadata.CilElementType.I2), SegmentRegister.GS);
            RegisterOperand ss = new RegisterOperand(new Mosa.Runtime.Metadata.Signatures.SigType(Mosa.Runtime.Metadata.CilElementType.I2), SegmentRegister.SS);

            context.AppendInstruction(CPUx86.Instruction.MovInstruction, ax, new ConstantOperand(new Mosa.Runtime.Metadata.Signatures.SigType(Mosa.Runtime.Metadata.CilElementType.I4), (int)0x00000010));
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, ds, ax);
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, es, ax);
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, fs, ax);
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, gs, ax);
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, ss, ax);
            context.AppendInstruction(CPUx86.Instruction.FarJmpInstruction);
            context.AppendInstruction(CPUx86.Instruction.NopInstruction);
            context.Previous.SetBranch(context.Offset);
        }
Exemplo n.º 15
0
        /// <summary>
        /// Replaces the instrinsic call site
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="typeSystem">The type system.</param>
        public void ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem)
        {
            SigType u4 = new SigType(Runtime.Metadata.CilElementType.U4);

            // Retrieve register context
            context.SetInstruction(CPUx86.Instruction.MovInstruction, new RegisterOperand(u4, GeneralPurposeRegister.EAX), new MemoryOperand(u4, GeneralPurposeRegister.ESP, new IntPtr(28)));

            // Restore registers (Note: EAX and EDX are NOT restored!)
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, new RegisterOperand(u4, GeneralPurposeRegister.EDX), new MemoryOperand(u4, GeneralPurposeRegister.EAX, new IntPtr(28)));
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, new RegisterOperand(u4, GeneralPurposeRegister.EBX), new MemoryOperand(u4, GeneralPurposeRegister.EAX, new IntPtr(4)));
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, new RegisterOperand(u4, GeneralPurposeRegister.EDI), new MemoryOperand(u4, GeneralPurposeRegister.EAX, new IntPtr(20)));
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, new RegisterOperand(u4, GeneralPurposeRegister.ESI), new MemoryOperand(u4, GeneralPurposeRegister.EAX, new IntPtr(16)));
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, new RegisterOperand(u4, GeneralPurposeRegister.ESP), new MemoryOperand(u4, GeneralPurposeRegister.EAX, new IntPtr(32)));
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, new RegisterOperand(u4, GeneralPurposeRegister.EBP), new MemoryOperand(u4, GeneralPurposeRegister.EAX, new IntPtr(24)));

            // Jmp to EIP (stored in EDX)
            context.AppendInstruction(CPUx86.Instruction.JmpInstruction);
            context.SetOperand(0, new RegisterOperand(u4, GeneralPurposeRegister.EDX));
        }
Exemplo n.º 16
0
        /// <summary>
        /// Replaces the instrinsic call site
        /// </summary>
        /// <param name="context">The context.</param>
        public void ReplaceIntrinsicCall(Context context)
        {
            if (!(context.Operand1 is ConstantOperand))
                throw new InvalidOperationException();

            Operand result = context.Result;

            ControlRegister control;

            switch ((int)(context.Operand1 as ConstantOperand).Value) {
                case 0: control = ControlRegister.CR0; break;
                case 2: control = ControlRegister.CR2; break;
                case 3: control = ControlRegister.CR3; break;
                case 4: control = ControlRegister.CR4; break;
                default: throw new InvalidOperationException();
            }

            RegisterOperand imm = new RegisterOperand(new SigType(CilElementType.U4), GeneralPurposeRegister.EAX);

            context.SetInstruction(IR.Instruction.MoveInstruction, imm, new RegisterOperand(new SigType(CilElementType.U4), control));
            context.AppendInstruction(IR.Instruction.MoveInstruction, result, imm);
        }
        private void HandleMemoryToMemoryOperation(Context ctx, Operand register, bool useStack)
        {
            Operand destination = ctx.Result;
            Operand source = ctx.Operand1;

            Debug.Assert(destination is MemoryOperand && source is MemoryOperand);

            if (register == null)
                register = new RegisterOperand(destination.Type, GeneralPurposeRegister.EDX);

            ctx.Operand1 = register;

            Context before = ctx.InsertBefore();

            if (useStack) {
                before.SetInstruction(CPUx86.Instruction.PushInstruction, null, register);
                before.AppendInstruction(CPUx86.Instruction.MovInstruction, register, source);
            }
            else
                before.SetInstruction(CPUx86.Instruction.MovInstruction, register, source);

            if (useStack)
                ctx.AppendInstruction(CPUx86.Instruction.PopInstruction, register);
        }
        /// <summary>
        /// Expands the neg instruction for 64-bits.
        /// </summary>
        /// <param name="context">The context.</param>
        private void ExpandXor(Context context)
        {
            Operand op0H, op1H, op2H, op0L, op1L, op2L;
            SplitLongOperand(context.Result, out op0L, out op0H);
            SplitLongOperand(context.Operand1, out op1L, out op1H);
            SplitLongOperand(context.Operand2, out op2L, out op2H);

            context.SetInstruction(CPUx86.Instruction.MovInstruction, op0H, op1H);
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, op0L, op1L);
            context.AppendInstruction(CPUx86.Instruction.XorInstruction, op0H, op2H);
            context.AppendInstruction(CPUx86.Instruction.XorInstruction, op0L, op2L);
        }
        /// <summary>
        /// Expands the unsigned move instruction for 64-bits.
        /// </summary>
        /// <param name="context">The context.</param>
        private void ExpandUnsignedMove(Context context)
        {
            MemoryOperand op0 = context.Result as MemoryOperand;
            Operand op1 = context.Operand1;
            Debug.Assert(op0 != null, @"I8 not in a memory operand!");

            SigType U4 = new SigType(CilElementType.U4);
            Operand op0L, op0H, op1L, op1H;
            SplitLongOperand(op0, out op0L, out op0H);
            SplitLongOperand(op1, out op1L, out op1H);
            RegisterOperand eax = new RegisterOperand(U4, GeneralPurposeRegister.EAX);
            RegisterOperand edx = new RegisterOperand(U4, GeneralPurposeRegister.EDX);

            switch (op1.Type.Type)
            {
                case CilElementType.Boolean:
                    context.SetInstruction(IR.Instruction.ZeroExtendedMoveInstruction, op0L, op1L);
                    context.AppendInstruction(IR.Instruction.LogicalXorInstruction, op0H, op0H, op0H);
                    break;

                case CilElementType.U1:
                    context.SetInstruction(IR.Instruction.ZeroExtendedMoveInstruction, eax, op1L);
                    context.AppendInstruction(CPUx86.Instruction.CdqInstruction);
                    context.AppendInstruction(CPUx86.Instruction.MovInstruction, op0L, eax);
                    context.AppendInstruction(IR.Instruction.LogicalXorInstruction, op0H, op0H, op0H);
                    break;

                case CilElementType.U2: goto case CilElementType.U1;

                case CilElementType.I4:
                    context.SetInstruction(IR.Instruction.ZeroExtendedMoveInstruction, eax, op1L);
                    context.AppendInstruction(CPUx86.Instruction.XorInstruction, edx, edx);
                    context.AppendInstruction(CPUx86.Instruction.MovInstruction, op0L, eax);
                    context.AppendInstruction(CPUx86.Instruction.MovInstruction, op0H, edx);
                    break;
                case CilElementType.U4:
                    context.SetInstruction(IR.Instruction.ZeroExtendedMoveInstruction, eax, op1L);
                    context.AppendInstruction(CPUx86.Instruction.CdqInstruction);
                    context.AppendInstruction(CPUx86.Instruction.MovInstruction, op0L, eax);
                    context.AppendInstruction(CPUx86.Instruction.MovInstruction, op0H, edx);
                    break;

                case CilElementType.U8:
                    context.SetInstruction(IR.Instruction.ZeroExtendedMoveInstruction, op0L, op1L);
                    context.SetInstruction(IR.Instruction.ZeroExtendedMoveInstruction, op0H, op1H);
                    break;

                case CilElementType.R4:
                    throw new NotSupportedException();

                case CilElementType.R8:
                    throw new NotSupportedException();

                default:
                    throw new NotSupportedException();
            }
        }
        /// <summary>
        /// Expands the sub instruction for 64-bit operands.
        /// </summary>
        /// <param name="context">The context.</param>
        private void ExpandSub(Context context)
        {
            /* This function transforms the SUB into the following sequence of x86 instructions:
             *
             * mov eax, [op1]       ; Move lower 32-bits of the first operand into eax
             * sub eax, [op2]       ; Sub lower 32-bits of second operand to eax
             * mov [result], eax    ; Save the result into the lower 32-bits of the result operand
             * mov eax, [op1+4]     ; Move upper 32-bits of the first operand into eax
             * sbb eax, [op2+4]     ; Sub with borrow upper 32-bits of the second operand to eax
             * mov [result+4], eax  ; Save the result into the upper 32-bits of the result operand
             *
             */

            // This only works for memory operands (can't store I8/U8 in a register.)
            // This fails for constant operands right now, which need to be extracted into memory
            // with a literal/literal operand first - TODO
            RegisterOperand eaxH = new RegisterOperand(new SigType(CilElementType.I4), GeneralPurposeRegister.EAX);
            RegisterOperand eaxL = new RegisterOperand(new SigType(CilElementType.U4), GeneralPurposeRegister.EAX);

            Operand op1L, op1H, op2L, op2H, resL, resH;
            SplitLongOperand(context.Operand1, out op1L, out op1H);
            SplitLongOperand(context.Operand2, out op2L, out op2H);
            SplitLongOperand(context.Result, out resL, out resH);

            context.SetInstruction(CPUx86.Instruction.MovInstruction, eaxL, op1L);
            context.AppendInstruction(CPUx86.Instruction.SubInstruction, eaxL, op2L);
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, resL, eaxL);
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, eaxH, op1H);
            context.AppendInstruction(CPUx86.Instruction.SbbInstruction, eaxH, op2H);
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, resH, eaxH);
        }
        /// <summary>
        /// Expands the store instruction for 64-bits.
        /// </summary>
        /// <param name="context">The context.</param>
        private void ExpandStore(Context context)
        {
            MemoryOperand op0 = context.Result as MemoryOperand;
            Operand offsetOperand = context.Operand1;
            MemoryOperand op2 = context.Operand2 as MemoryOperand;
            Debug.Assert(op0 != null && op2 != null, @"Operands to I8 LoadInstruction are not MemoryOperand.");

            SigType I4 = new SigType(CilElementType.I4);
            SigType U4 = new SigType(CilElementType.U4);
            Operand op1L, op1H;
            SplitLongOperand(op2, out op1L, out op1H);
            RegisterOperand eax = new RegisterOperand(I4, GeneralPurposeRegister.EAX);
            RegisterOperand edx = new RegisterOperand(I4, GeneralPurposeRegister.EDX);

            context.SetInstruction(CPUx86.Instruction.MovInstruction, edx, op0);

            // Fortunately in 32-bit mode, we can't have 64-bit offsets, so this plain add should suffice.
            context.AppendInstruction(CPUx86.Instruction.AddInstruction, edx, offsetOperand);

            context.AppendInstruction(CPUx86.Instruction.MovInstruction, eax, op1L);
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, new MemoryOperand(U4, GeneralPurposeRegister.EDX, IntPtr.Zero), eax);
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, eax, op1H);
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, new MemoryOperand(I4, GeneralPurposeRegister.EDX, new IntPtr(4)), eax);
        }
        /// <summary>
        /// Expands the not instruction for 64-bits.
        /// </summary>
        /// <param name="context">The context.</param>
        private void ExpandNot(Context context)
        {
            Operand op0H, op1H, op0L, op1L;
            SplitLongOperand(context.Result, out op0L, out op0H);
            SplitLongOperand(context.Operand1, out op1L, out op1H);

            context.SetInstruction(IR.Instruction.LogicalNotInstruction, op0H, op1H);
            context.AppendInstruction(IR.Instruction.LogicalNotInstruction, op0L, op1L);
        }
 /// <summary>
 /// Inserts the move instruction to load or spill an operand.
 /// </summary>
 /// <param name="ctx">The context.</param>
 /// <param name="destination">The destination operand.</param>
 /// <param name="source">The source operand.</param>
 private void InsertMove(Context ctx, Operand destination, Operand source)
 {
     //LegacyInstruction move = _architecture.CreateInstruction(typeof(IR.MoveInstruction), destination, source);
     //block.Instructions.Insert(idx, move);
     ctx.AppendInstruction(IR.Instruction.MoveInstruction, destination, source);
 }
        /// <summary>
        /// Expands the binary comparison instruction for 64-bits.
        /// </summary>
        /// <param name="context">The context.</param>
        private void ExpandComparison(Context context)
        {
            Operand op0 = context.Result;
            Operand op1 = context.Operand1;
            Operand op2 = context.Operand2;

            Debug.Assert(op1 != null && op2 != null, @"IntegerCompareInstruction operand not memory!");
            Debug.Assert(op0 is MemoryOperand || op0 is RegisterOperand, @"IntegerCompareInstruction result not memory and not register!");

            SigType I4 = new SigType(CilElementType.I4);
            //UNUSED:
            //SigType U4 = new SigType(CilElementType.U4);

            Operand op1L, op1H, op2L, op2H;
            SplitLongOperand(op1, out op1L, out op1H);
            SplitLongOperand(op2, out op2L, out op2H);

            Context[] newBlocks = CreateEmptyBlockContexts(context.Label, 4);
            IR.ConditionCode conditionCode = context.ConditionCode;
            Context nextBlock = SplitContext(context, false);

            // Compare high dwords
            context.SetInstruction(CPUx86.Instruction.CmpInstruction, op1H, op2H);
            context.AppendInstruction(CPUx86.Instruction.BranchInstruction, IR.ConditionCode.Equal, newBlocks[1].BasicBlock);
            context.AppendInstruction(CPUx86.Instruction.JmpInstruction, newBlocks[0].BasicBlock);
            LinkBlocks(context, newBlocks[0], newBlocks[1]);

            // Branch if check already gave results
            newBlocks[0].SetInstruction(CPUx86.Instruction.BranchInstruction, conditionCode, newBlocks[2].BasicBlock);
            newBlocks[0].AppendInstruction(CPUx86.Instruction.JmpInstruction, newBlocks[3].BasicBlock);
            LinkBlocks(newBlocks[0], newBlocks[2], newBlocks[3]);

            // Compare low dwords
            newBlocks[1].SetInstruction(CPUx86.Instruction.CmpInstruction, op1L, op2L);
            // Set the unsigned result...
            newBlocks[1].AppendInstruction(CPUx86.Instruction.BranchInstruction, GetUnsignedConditionCode(conditionCode), newBlocks[2].BasicBlock);
            newBlocks[1].AppendInstruction(CPUx86.Instruction.JmpInstruction, newBlocks[3].BasicBlock);
            LinkBlocks(newBlocks[1], newBlocks[2], newBlocks[3]);

            // Success
            newBlocks[2].SetInstruction(CPUx86.Instruction.MovsxInstruction, op0, new ConstantOperand(I4, 1));
            newBlocks[2].AppendInstruction(CPUx86.Instruction.JmpInstruction, nextBlock.BasicBlock);
            LinkBlocks(newBlocks[2], nextBlock);

            // Failed
            newBlocks[3].SetInstruction(CPUx86.Instruction.MovsxInstruction, op0, new ConstantOperand(I4, 0));
            newBlocks[3].AppendInstruction(CPUx86.Instruction.JmpInstruction, nextBlock.BasicBlock);
            LinkBlocks(newBlocks[3], nextBlock);
        }
        /// <summary>
        /// Expands the and instruction for 64-bits.
        /// </summary>
        /// <param name="context">The context.</param>
        private void ExpandAnd(Context context)
        {
            Operand op0H, op1H, op2H, op0L, op1L, op2L;
            SplitLongOperand(context.Result, out op0L, out op0H);
            SplitLongOperand(context.Operand1, out op1L, out op1H);
            SplitLongOperand(context.Operand2, out op2L, out op2H);

            if (context.Result.StackType != StackTypeCode.Int64)
            {
                context.AppendInstruction(CPUx86.Instruction.MovInstruction, op0L, op1L);
                context.AppendInstruction(CPUx86.Instruction.AndInstruction, op0L, op2L);
            }
            else
            {
                context.SetInstruction(CPUx86.Instruction.MovInstruction, op0H, op1H);
                context.AppendInstruction(CPUx86.Instruction.MovInstruction, op0L, op1L);
                context.AppendInstruction(CPUx86.Instruction.AndInstruction, op0H, op2H);
                context.AppendInstruction(CPUx86.Instruction.AndInstruction, op0L, op2L);
            }
        }
Exemplo n.º 26
0
 private void ProcessSingleTypeTruncation(Context ctx, IInstruction instruction, uint mask, Operand destinationOperand, Operand sourceOperand)
 {
     if (sourceOperand.Type.Type == CilElementType.I8 || sourceOperand.Type.Type == CilElementType.U8)
     {
         ctx.SetInstruction (IR.Instruction.MoveInstruction, destinationOperand, sourceOperand);
         ctx.AppendInstruction (instruction, destinationOperand, sourceOperand, new ConstantOperand (new SigType (CilElementType.U4), mask));
     }
     else
         ctx.SetInstruction (instruction, destinationOperand, sourceOperand, new ConstantOperand (new SigType (CilElementType.U4), mask));
 }
        /// <summary>
        /// Creates the new temporary moves.
        /// </summary>
        /// <param name="ctx">The CTX.</param>
        /// <param name="block">The block.</param>
        /// <param name="stack">The stack.</param>
        private void CreateNewTemporaryMoves(Context ctx, BasicBlock block, Stack<Operand> stack)
        {
            Stack<Operand> nextStack = new Stack<Operand>();
            foreach (Operand operand in stack)
            {
                Operand temp = MethodCompiler.CreateTemporary(operand.Type);
                nextStack.Push(temp);
                _operandStack.Pop();
                ctx.AppendInstruction(IR.Instruction.MoveInstruction, temp, operand);
            }

            if (nextStack.Count > 0)
                foreach (BasicBlock nextBlock in block.NextBlocks)
                    nextBlock.InitialStack = GetCurrentStack(nextStack);
        }
        /// <summary>
        /// Links the temporary moves.
        /// </summary>
        /// <param name="ctx">The CTX.</param>
        /// <param name="block">The block.</param>
        /// <param name="nextBlock">The next block.</param>
        /// <param name="stack">The stack.</param>
        private void LinkTemporaryMoves(Context ctx, BasicBlock block, BasicBlock nextBlock, Stack<Operand> stack)
        {
            Stack<Operand> initialStack = GetCurrentStack(stack);
            Stack<Operand> nextInitialStack = GetCurrentStack(nextBlock.InitialStack);

            for (int i = 0; i < nextBlock.InitialStack.Count; ++i)
                ctx.AppendInstruction(IR.Instruction.MoveInstruction, nextInitialStack.Pop(), initialStack.Pop());

            if (nextBlock.InitialStack.Count > 0)
                foreach (BasicBlock nBlock in block.NextBlocks)
                    nBlock.InitialStack = GetCurrentStack(nextBlock.InitialStack);
        }
        /// <summary>
        /// Expands the load instruction for 64-bits.
        /// </summary>
        /// <param name="context">The context.</param>
        private void ExpandLoad(Context context)
        {
            Operand op0 = context.Result;
            Operand op1 = context.Operand1;
            Operand offsetOperand = context.Operand2;
            Debug.Assert(op0 != null && op1 != null, @"Operands to I8 LoadInstruction are not MemoryOperand.");

            SigType I4 = new SigType(CilElementType.I4);
            Operand op0L, op0H;
            SplitLongOperand(op0, out op0L, out op0H);

            RegisterOperand eax = new RegisterOperand(I4, GeneralPurposeRegister.EAX);
            RegisterOperand edx = new RegisterOperand(I4, GeneralPurposeRegister.EDX);

            context.SetInstruction(CPUx86.Instruction.MovInstruction, eax, op1);
            context.AppendInstruction(CPUx86.Instruction.AddInstruction, eax, offsetOperand);
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, edx, new MemoryOperand(op0L.Type, GeneralPurposeRegister.EAX, IntPtr.Zero));
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, op0L, edx);
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, edx, new MemoryOperand(op0H.Type, GeneralPurposeRegister.EAX, new IntPtr(4)));
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, op0H, edx);
        }
Exemplo n.º 30
0
 /// <summary>
 /// Inserts the move instruction to load or spill an operand.
 /// </summary>
 /// <param name="ctx">The context.</param>
 /// <param name="destination">The destination operand.</param>
 /// <param name="source">The source operand.</param>
 private void InsertMove(Context ctx, Operand destination, Operand source)
 {
     //LegacyInstruction move = _architecture.CreateInstruction(typeof(IR.MoveInstruction), destination, source);
     //block.Instructions.Insert(idx, move);
     ctx.AppendInstruction(IR.Instruction.MoveInstruction, destination, source);
 }
        /// <summary>
        /// Expands the move instruction for 64-bits.
        /// </summary>
        /// <param name="context">The context.</param>
        private void ExpandMove(Context context)
        {
            Operand op0L, op0H, op1L, op1H;

            if (context.Result.StackType == StackTypeCode.Int64)
            {
                SplitLongOperand(context.Result, out op0L, out op0H);
                SplitLongOperand(context.Operand1, out op1L, out op1H);

                context.SetInstruction(CPUx86.Instruction.MovInstruction, op0L, op1L);
                context.AppendInstruction(CPUx86.Instruction.MovInstruction, op0H, op1H);
            }
            else
            {
                SplitLongOperand(context.Operand1, out op1L, out op1H);
                context.SetInstruction(CPUx86.Instruction.MovInstruction, context.Result, op1L);
            }
        }