示例#1
0
 /// <summary>
 /// Emits the specified platform instruction.
 /// </summary>
 /// <param name="ctx">The context.</param>
 /// <param name="emitter">The emitter.</param>
 protected override void Emit(Context ctx, MachineCodeEmitter emitter)
 {
     if (ctx.Operand1 is ConstantOperand)
     {
         if (IsByte(ctx.Operand1))
             emitter.Emit(CONST8, ctx.Operand1, null);
         else if (IsShort(ctx.Operand1) || IsChar(ctx.Operand1))
             emitter.Emit(CONST16, ctx.Operand1, null);
         else if (IsInt(ctx.Operand1))
             emitter.Emit(CONST32, ctx.Operand1, null);
         return;
     }
     if (ctx.Operand1 is RegisterOperand)
     {
         if ((ctx.Operand1 as RegisterOperand).Register is SegmentRegister)
             switch (((ctx.Operand1 as RegisterOperand).Register as SegmentRegister).Segment)
             {
                 case SegmentRegister.SegmentType.CS: emitter.Emit(PUSH_CS, null, null); return;
                 case SegmentRegister.SegmentType.SS: emitter.Emit(PUSH_SS, null, null); return;
                 case SegmentRegister.SegmentType.DS: emitter.Emit(PUSH_DS, null, null); return;
                 case SegmentRegister.SegmentType.ES: emitter.Emit(PUSH_ES, null, null); return;
                 case SegmentRegister.SegmentType.FS: emitter.Emit(PUSH_FS, null, null); return;
                 case SegmentRegister.SegmentType.GS: emitter.Emit(PUSH_GS, null, null); return;
                 default: throw new InvalidOperationException(@"unable to emit opcode for segment register");
             }
     }
     emitter.Emit(PUSH, ctx.Operand1, null, null);
 }
示例#2
0
 /// <summary>
 /// Emits the specified platform instruction.
 /// </summary>
 /// <param name="ctx">The context.</param>
 /// <param name="emitter">The emitter.</param>
 protected override void Emit(Context ctx, MachineCodeEmitter emitter)
 {
     if (ctx.Result is RegisterOperand)
         emitter.WriteByte ((byte)(0x58 + (ctx.Result as RegisterOperand).Register.RegisterCode));
     else
         emitter.Emit (POP.Code, 0, ctx.Result, null);
 }
        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);
        }
示例#4
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="emitter"></param>
        protected override void Emit(Context ctx, MachineCodeEmitter emitter)
        {
            RegisterOperand rop = (RegisterOperand)ctx.Result;
            MemoryOperand mop = (MemoryOperand)ctx.Operand1;
            byte[] code;

            if (null != mop.Base)
            {
                code = new byte[] {
                    0x8d,
                    0x84,
                    (4 << 3)
                };
                code[1] |= (byte)((rop.Register.RegisterCode & 0x7));
                code[2] |= (byte)((mop.Base.RegisterCode & 0x7));
            }

            else
            {
                code = new byte[] { 0xb8 };
            }

            emitter.Write (code, 0, code.Length);
            emitter.EmitImmediate (mop);
        }
示例#5
0
 /// <summary>
 /// Emits the specified platform instruction.
 /// </summary>
 /// <param name="ctx">The context.</param>
 /// <param name="emitter">The emitter.</param>
 protected override void Emit(Context ctx, MachineCodeEmitter emitter)
 {
     if (ctx.Operand1 is RegisterOperand)
         emitter.Emit(JmpReg, ctx.Operand1);
     else
         emitter.EmitBranch(JMP, ctx.Branch.Targets[0]);
 }
        /// <summary>
        /// Emits the specified platform instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="emitter">The emitter.</param>
        protected override void Emit(Context ctx, MachineCodeEmitter emitter)
        {
            OpCode opcode;

            switch (ctx.ConditionCode)
            {
                case IR.ConditionCode.Equal: opcode = E; break;
                case IR.ConditionCode.LessThan: opcode = LT; break;
                case IR.ConditionCode.LessOrEqual: opcode = LE; break;
                case IR.ConditionCode.GreaterOrEqual: opcode = GE; break;
                case IR.ConditionCode.GreaterThan: opcode = GT; break;
                case IR.ConditionCode.NotEqual: opcode = NE; break;
                case IR.ConditionCode.UnsignedGreaterOrEqual: opcode = UGE; break;
                case IR.ConditionCode.UnsignedGreaterThan: opcode = UGT; break;
                case IR.ConditionCode.UnsignedLessOrEqual: opcode = ULE; break;
                case IR.ConditionCode.UnsignedLessThan: opcode = ULT; break;
                case IR.ConditionCode.Parity: opcode = P; break;
                case IR.ConditionCode.NoParity: opcode = NP; break;
                case IR.ConditionCode.NoCarry: opcode = NC; break;
                case IR.ConditionCode.Carry: opcode = C; break;
                case IR.ConditionCode.Zero: opcode = Z; break;
                case IR.ConditionCode.NoZero: opcode = NZ; break;
                default: throw new NotSupportedException();
            }

            emitter.Emit(opcode, ctx.Result, null);
        }
        /// <summary>
        /// Creates the ISR methods.
        /// </summary>
        /// <param name="compiler">The compiler.</param>
        private void CreateISRMethods(AssemblyCompiler compiler)
        {
            // Create Interrupt Service Routines (ISR)
            RuntimeMethod InterruptMethod = compiler.Assembly.EntryPoint; // TODO: replace with another entry point

            SigType I1 = new SigType(CilElementType.I1);
            SigType I4 = new SigType(CilElementType.I4);
            RegisterOperand eax = new RegisterOperand(I4, GeneralPurposeRegister.EAX);

            for (int i = 0; i <= 256; i++) {
                InstructionSet set = new InstructionSet(100);
                Context ctx = new Context(set, -1);

                ctx.SetInstruction(CPUx86.Instruction.CliInstruction);
                if ((i != 8) && (i < 10 || i > 14)) // For IRQ 8, 10, 11, 12, 13, 14 the cpu automatically pushed the error code
                    ctx.AppendInstruction(CPUx86.Instruction.PushInstruction, null, new ConstantOperand(I4, 0x0));
                ctx.AppendInstruction(CPUx86.Instruction.PushadInstruction);
                ctx.AppendInstruction(CPUx86.Instruction.PushInstruction, null, new ConstantOperand(I4, i));
                // TODO: Set method parameters
                ctx.AppendInstruction(CPUx86.Instruction.CallInstruction, InterruptMethod);
                ctx.AppendInstruction(CPUx86.Instruction.PopInstruction, eax);
                ctx.AppendInstruction(CPUx86.Instruction.PopadInstruction);
                ctx.AppendInstruction(CPUx86.Instruction.PopInstruction, eax);
                ctx.AppendInstruction(CPUx86.Instruction.StiInstruction);
                //ctx.AppendInstruction(CPUx86.Instruction.IRetdInstruction);

                CompilerGeneratedMethod method = LinkTimeCodeGenerator.Compile(compiler, @"InterruptISR" + i.ToString(), set);
            }
        }
 /// <summary>
 /// Performs stage specific processing on the compiler context.
 /// </summary>
 public virtual void Run()
 {
     for (int index = 0; index < BasicBlocks.Count; index++)
         for (Context ctx = new Context (InstructionSet, BasicBlocks[index]); !ctx.EndOfInstruction; ctx.GotoNext ())
             if (ctx.Instruction != null)
                 ctx.Clone ().Visit (this);
 }
        /// <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();
        }
示例#10
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="ctx"></param>
 /// <param name="emitter"></param>
 protected override void Emit(Context ctx, MachineCodeEmitter emitter)
 {
     emitter.Emit (new OpCode (new byte[] {
         0xf,
         0xa2
     }), null, null);
 }
        /// <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
        }
        /// <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);
        }
示例#13
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>
        /// <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);
        }
 /// <summary>
 /// Emits the specified platform instruction.
 /// </summary>
 /// <param name="ctx">The context.</param>
 /// <param name="emitter">The emitter.</param>
 protected override void Emit(Context ctx, MachineCodeEmitter emitter)
 {
     emitter.WriteByte(0xE8);
     emitter.WriteByte(0x00);
     emitter.WriteByte(0x00);
     emitter.WriteByte(0x00);
     emitter.WriteByte(0x00);
     emitter.Call(ctx.InvokeTarget);
 }
 /// <summary>
 /// Visitation function for <see cref="CIL.ICILVisitor.Add"/>.
 /// </summary>
 /// <param name="ctx">The context.</param>
 void CIL.ICILVisitor.Add(Context ctx)
 {
     if (ctx.Operand1.StackType == StackTypeCode.F) {
         HandleCommutativeOperation(ctx, CPUx86.Instruction.SseAddInstruction);
         ExtendToR8(ctx);
     }
     else
         HandleCommutativeOperation(ctx, CPUx86.Instruction.AddInstruction);
 }
示例#17
0
        /// <summary>
        /// Emits the specified platform instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="emitter">The emitter.</param>
        protected override void Emit(Context ctx, MachineCodeEmitter emitter)
        {
            switch (ctx.ConditionCode)
            {
                case IR.ConditionCode.Equal:
                    emitter.EmitBranch(JE, ctx.Branch.Targets[0]);
                    break;

                case IR.ConditionCode.GreaterOrEqual:
                    emitter.EmitBranch(JGE, ctx.Branch.Targets[0]);
                    break;

                case IR.ConditionCode.GreaterThan:
                    emitter.EmitBranch(JG, ctx.Branch.Targets[0]);
                    break;

                case IR.ConditionCode.LessOrEqual:
                    emitter.EmitBranch(JLE, ctx.Branch.Targets[0]);
                    break;

                case IR.ConditionCode.LessThan:
                    emitter.EmitBranch(JL, ctx.Branch.Targets[0]);
                    break;

                case IR.ConditionCode.NotEqual:
                    emitter.EmitBranch(JNE, ctx.Branch.Targets[0]);
                    break;

                case IR.ConditionCode.UnsignedGreaterOrEqual:
                    emitter.EmitBranch(JAE, ctx.Branch.Targets[0]);
                    break;

                case IR.ConditionCode.UnsignedGreaterThan:
                    emitter.EmitBranch(JA, ctx.Branch.Targets[0]);
                    break;

                case IR.ConditionCode.UnsignedLessOrEqual:
                    emitter.EmitBranch(JBE, ctx.Branch.Targets[0]);
                    break;

                case IR.ConditionCode.UnsignedLessThan:
                    emitter.EmitBranch(JB, ctx.Branch.Targets[0]);
                    break;

                case IR.ConditionCode.NotSigned:
                    emitter.EmitBranch(JNS, ctx.Branch.Targets[0]);
                    break;

                case IR.ConditionCode.Signed:
                    emitter.EmitBranch(JS, ctx.Branch.Targets[0]);
                    break;

                default:
                    throw new NotSupportedException();
            }
        }
示例#18
0
        /// <summary>
        /// Converts the given instruction from three address format to a two address format.
        /// </summary>
        /// <param name="ctx">The conversion context.</param>
        private static void ThreeTwoAddressConversion(Context ctx)
        {
            Operand result = ctx.Result;
            Operand op1 = ctx.Operand1;
            Operand op2 = ctx.Operand2;

            if (ctx.Instruction is IR.FloatingPointCompareInstruction)
                return;

            if (ctx.Instruction is CIL.MulInstruction)
            {
                if (!(op1 is ConstantOperand) && (op2 is ConstantOperand))
                {
                    Operand temp = op1;
                    op1 = op2;
                    op2 = temp;
                }
            }

            RegisterOperand eax = new RegisterOperand (op1.Type, op1.StackType == StackTypeCode.F ? (Register)SSE2Register.XMM0 : GeneralPurposeRegister.EAX);
            RegisterOperand storeOperand = new RegisterOperand (result.Type, result.StackType == StackTypeCode.F ? (Register)SSE2Register.XMM0 : GeneralPurposeRegister.EAX);

            ctx.Result = storeOperand;
            ctx.Operand1 = op2;
            ctx.Operand2 = null;
            ctx.OperandCount = 1;

            if (op1.StackType != StackTypeCode.F)
            {
                if (IsSigned (op1) && !(op1 is ConstantOperand))
                    ctx.InsertBefore ().SetInstruction (IR.Instruction.SignExtendedMoveInstruction, eax, op1);                else if (IsUnsigned (op1) && !(op1 is ConstantOperand))
                    ctx.InsertBefore ().SetInstruction (IR.Instruction.ZeroExtendedMoveInstruction, eax, op1);
                else
                    ctx.InsertBefore ().SetInstruction (CPUx86.Instruction.MovInstruction, eax, op1);
            }

            else
            {
                if (op1.Type.Type == CilElementType.R4)
                {
                    if (op1 is ConstantOperand)
                    {
                        Context before = ctx.InsertBefore ();
                        before.SetInstruction (CPUx86.Instruction.MovInstruction, eax, op1);
                        before.AppendInstruction (CPUx86.Instruction.Cvtss2sdInstruction, eax, eax);
                    }

                    else
                        ctx.InsertBefore ().SetInstruction (CPUx86.Instruction.Cvtss2sdInstruction, eax, op1);
                }

                else
                    ctx.InsertBefore ().SetInstruction (CPUx86.Instruction.MovInstruction, eax, op1);
            }
            ctx.AppendInstruction (CPUx86.Instruction.MovInstruction, result, eax);
        }
        private bool CheckAssignmentForCompliance(Context allocation, Context 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.

            RuntimeType allocationType = allocation.InvokeTarget.DeclaringType;
            RuntimeType storageType = assignment.RuntimeField.Type;

            return ReferenceEquals(allocationType, storageType);
        }
示例#20
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);
        }
示例#21
0
 /// <summary>
 /// Creates the operand.
 /// </summary>
 /// <param name="ctx">The CTX.</param>
 /// <returns></returns>
 public Operand CreateOperand(Context ctx)
 {
     /* HACK:
      * Position independent code on x86 requires EIP relative addressing, which
      * unfortunately isn't available. We try to work around this limitation by
      * storing the EIP of the first instruction on the stack, however this isn't
      * enough. So PIC with Literals doesn't work for now.
      */
     //return new LabelOperand(this.Type, GeneralPurposeRegister.EBP, -8, this.Label);
     return new LabelOperand (ctx.LiteralData.Type, null, 0, ctx.LiteralData.Label);
 }
示例#22
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);
        }
示例#23
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);
 }
示例#24
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="ctx"></param>
 /// <param name="emitter"></param>
 protected override void Emit(Context ctx, MachineCodeEmitter emitter)
 {
     OpCode opCode = ComputeOpCode(ctx.Result, ctx.Operand1, ctx.Operand2);
     if (ctx.Operand1 is ConstantOperand)
     {
         ConstantOperand op = ctx.Operand1 as ConstantOperand;
         op = new ConstantOperand(new Mosa.Runtime.Metadata.Signatures.SigType(CilElementType.U1), op.Value);
         emitter.Emit(opCode, ctx.Result, op);
     }
     else
         emitter.Emit(opCode, ctx.Operand1, null);
 }
示例#25
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);
        }
示例#26
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);
        }
示例#27
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);
        }
示例#28
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);
        }
示例#29
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);

            RegisterOperand ebp = new RegisterOperand(u4, GeneralPurposeRegister.EBP);
            RegisterOperand esp = new RegisterOperand(u4, GeneralPurposeRegister.ESP);
            RegisterOperand eax = new RegisterOperand(u4, GeneralPurposeRegister.EAX);
            RegisterOperand ebx = new RegisterOperand(u4, GeneralPurposeRegister.EBX);
            RegisterOperand ecx = new RegisterOperand(u4, GeneralPurposeRegister.ECX);
            RegisterOperand edx = new RegisterOperand(u4, GeneralPurposeRegister.EDX);
            RegisterOperand esi = new RegisterOperand(u4, GeneralPurposeRegister.ESI);
            RegisterOperand edi = new RegisterOperand(u4, GeneralPurposeRegister.EDI);

            context.SetInstruction(CPUx86.Instruction.PushInstruction, null, ebp);
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, ebp, esp);
            context.AppendInstruction(CPUx86.Instruction.PushInstruction, null, ebx);
            context.AppendInstruction(CPUx86.Instruction.PushInstruction, null, esi);
            context.AppendInstruction(CPUx86.Instruction.PushInstruction, null, edi);

            // Load register context
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, eax, new MemoryOperand(u4, GeneralPurposeRegister.ESP, new IntPtr(28)));
            // Load exception handler
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, ecx, new MemoryOperand(u4, GeneralPurposeRegister.ESP, new IntPtr(32)));
            // Save EBP
            context.AppendInstruction(CPUx86.Instruction.PushInstruction, null, ebp);

            // Restore register values
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, ebp, new MemoryOperand(u4, GeneralPurposeRegister.EAX, new IntPtr(24)));
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, ebx, new MemoryOperand(u4, GeneralPurposeRegister.EAX, new IntPtr(4)));
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, esi, new MemoryOperand(u4, GeneralPurposeRegister.EAX, new IntPtr(16)));
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, edi, new MemoryOperand(u4, GeneralPurposeRegister.EAX, new IntPtr(20)));

            // Align ESP
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, edx, esp);
            context.AppendInstruction(CPUx86.Instruction.AndInstruction, esp, new ConstantOperand(u4, 0xFFFFFFF0u));
            context.AppendInstruction(CPUx86.Instruction.SubInstruction, esp, new ConstantOperand(u4, 0x8u));

            // Save original ESP
            context.AppendInstruction(CPUx86.Instruction.PushInstruction, null, edx);
            // Call catch handler
            context.AppendInstruction(CPUx86.Instruction.CallInstruction, ecx);

            // Restore registers
            context.AppendInstruction(CPUx86.Instruction.PopInstruction, esp);
            context.AppendInstruction(CPUx86.Instruction.PopInstruction, ebp);
            context.AppendInstruction(CPUx86.Instruction.PopInstruction, esi);
            context.AppendInstruction(CPUx86.Instruction.PopInstruction, edi);
            context.AppendInstruction(CPUx86.Instruction.PopInstruction, ebx);
            context.AppendInstruction(CPUx86.Instruction.LeaveInstruction);
            context.AppendInstruction(CPUx86.Instruction.RetInstruction);
        }
        /// <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;
        }