示例#1
0
        static void ReplaceOpcodeDest(ref OpCodes.OpCodeR op, short dst)
        {
            switch (op.Code)
            {
            case OpCodes.OpCodeREnum.Move:
            case OpCodeREnum.Ldc_I4_0:
            case OpCodeREnum.Ldc_I4_1:
            case OpCodeREnum.Ldc_I4_2:
            case OpCodeREnum.Ldc_I4_3:
            case OpCodeREnum.Ldc_I4_4:
            case OpCodeREnum.Ldc_I4_5:
            case OpCodeREnum.Ldc_I4_6:
            case OpCodeREnum.Ldc_I4_7:
            case OpCodeREnum.Ldc_I4_8:
            case OpCodeREnum.Ldc_I4_M1:
            case OpCodeREnum.Ldnull:
            case OpCodeREnum.Ldc_I4:
            case OpCodeREnum.Ldc_I4_S:
            case OpCodeREnum.Ldc_I8:
            case OpCodeREnum.Ldc_R4:
            case OpCodeREnum.Ldc_R8:
            case OpCodeREnum.Ldstr:
            case OpCodeREnum.Add:
            case OpCodeREnum.Add_Ovf:
            case OpCodeREnum.Add_Ovf_Un:
            case OpCodeREnum.Sub:
            case OpCodeREnum.Sub_Ovf:
            case OpCodeREnum.Sub_Ovf_Un:
            case OpCodeREnum.Mul:
            case OpCodeREnum.Mul_Ovf:
            case OpCodeREnum.Mul_Ovf_Un:
            case OpCodeREnum.Div:
            case OpCodeREnum.Div_Un:
            case OpCodeREnum.Rem:
            case OpCodeREnum.Rem_Un:
            case OpCodeREnum.Xor:
            case OpCodeREnum.And:
            case OpCodeREnum.Or:
            case OpCodeREnum.Shl:
            case OpCodeREnum.Shr:
            case OpCodeREnum.Shr_Un:
            case OpCodeREnum.Clt:
            case OpCodeREnum.Clt_Un:
            case OpCodeREnum.Cgt:
            case OpCodeREnum.Cgt_Un:
            case OpCodeREnum.Ceq:
            case OpCodeREnum.Conv_I:
            case OpCodeREnum.Conv_I1:
            case OpCodeREnum.Conv_I2:
            case OpCodeREnum.Conv_I4:
            case OpCodeREnum.Conv_I8:
            case OpCodeREnum.Conv_Ovf_I:
            case OpCodeREnum.Conv_Ovf_I1:
            case OpCodeREnum.Conv_Ovf_I1_Un:
            case OpCodeREnum.Conv_Ovf_I2:
            case OpCodeREnum.Conv_Ovf_I2_Un:
            case OpCodeREnum.Conv_Ovf_I4:
            case OpCodeREnum.Conv_Ovf_I4_Un:
            case OpCodeREnum.Conv_Ovf_I8:
            case OpCodeREnum.Conv_Ovf_I8_Un:
            case OpCodeREnum.Conv_Ovf_I_Un:
            case OpCodeREnum.Conv_Ovf_U:
            case OpCodeREnum.Conv_Ovf_U1:
            case OpCodeREnum.Conv_Ovf_U1_Un:
            case OpCodeREnum.Conv_Ovf_U2:
            case OpCodeREnum.Conv_Ovf_U2_Un:
            case OpCodeREnum.Conv_Ovf_U4:
            case OpCodeREnum.Conv_Ovf_U4_Un:
            case OpCodeREnum.Conv_Ovf_U8:
            case OpCodeREnum.Conv_Ovf_U8_Un:
            case OpCodeREnum.Conv_Ovf_U_Un:
            case OpCodeREnum.Conv_R4:
            case OpCodeREnum.Conv_R8:
            case OpCodeREnum.Conv_R_Un:
            case OpCodeREnum.Conv_U:
            case OpCodeREnum.Conv_U1:
            case OpCodeREnum.Conv_U2:
            case OpCodeREnum.Conv_U4:
            case OpCodeREnum.Conv_U8:
            case OpCodeREnum.Not:
            case OpCodeREnum.Neg:
            case OpCodeREnum.Box:
            case OpCodeREnum.Unbox:
            case OpCodeREnum.Unbox_Any:
            case OpCodeREnum.Call:
            case OpCodeREnum.Callvirt:
            case OpCodeREnum.Newobj:
            case OpCodeREnum.Ldind_I:
            case OpCodeREnum.Ldind_I1:
            case OpCodeREnum.Ldind_I2:
            case OpCodeREnum.Ldind_I4:
            case OpCodeREnum.Ldind_I8:
            case OpCodeREnum.Ldind_R4:
            case OpCodeREnum.Ldind_R8:
            case OpCodeREnum.Ldind_U1:
            case OpCodeREnum.Ldind_U2:
            case OpCodeREnum.Ldind_U4:
            case OpCodeREnum.Ldind_Ref:
            case OpCodeREnum.Ldobj:
            case OpCodeREnum.Ldloca:
            case OpCodeREnum.Ldloca_S:
            case OpCodeREnum.Ldarg_S:
            case OpCodeREnum.Ldarga:
            case OpCodeREnum.Ldarga_S:
            case OpCodeREnum.Ldlen:
            case OpCodeREnum.Newarr:
            case OpCodeREnum.Ldfld:
            case OpCodeREnum.Ldflda:
            case OpCodeREnum.Ldsfld:
            case OpCodeREnum.Ldsflda:
            case OpCodeREnum.Ldtoken:
            case OpCodeREnum.Ldftn:
            case OpCodeREnum.Ldvirtftn:
            case OpCodeREnum.Isinst:
            case OpCodeREnum.Ldelem_I1:
            case OpCodeREnum.Ldelem_U1:
            case OpCodeREnum.Ldelem_I2:
            case OpCodeREnum.Ldelem_U2:
            case OpCodeREnum.Ldelem_I4:
            case OpCodeREnum.Ldelem_U4:
            case OpCodeREnum.Ldelem_I8:
            case OpCodeREnum.Ldelem_R4:
            case OpCodeREnum.Ldelem_R8:
            case OpCodeREnum.Ldelem_Any:
            case OpCodeREnum.Ldelem_Ref:
            case OpCodeREnum.Ldelema:
                op.Register1 = dst;
                break;

            case OpCodeREnum.Br_S:
            case OpCodeREnum.Br:
            case OpCodeREnum.Brtrue:
            case OpCodeREnum.Brtrue_S:
            case OpCodeREnum.Brfalse:
            case OpCodeREnum.Brfalse_S:
            case OpCodeREnum.Switch:
            case OpCodeREnum.Blt:
            case OpCodeREnum.Blt_S:
            case OpCodeREnum.Blt_Un:
            case OpCodeREnum.Blt_Un_S:
            case OpCodeREnum.Ble:
            case OpCodeREnum.Ble_S:
            case OpCodeREnum.Ble_Un:
            case OpCodeREnum.Ble_Un_S:
            case OpCodeREnum.Bgt:
            case OpCodeREnum.Bgt_S:
            case OpCodeREnum.Bgt_Un:
            case OpCodeREnum.Bgt_Un_S:
            case OpCodeREnum.Bge:
            case OpCodeREnum.Bge_S:
            case OpCodeREnum.Bge_Un:
            case OpCodeREnum.Bge_Un_S:
            case OpCodeREnum.Beq:
            case OpCodeREnum.Beq_S:
            case OpCodeREnum.Bne_Un:
            case OpCodeREnum.Bne_Un_S:
            case OpCodeREnum.Nop:
            case OpCodeREnum.Ret:
            case OpCodeREnum.Push:
            case OpCodeREnum.Constrained:
                break;

            default:
                throw new NotImplementedException();
            }
        }
示例#2
0
        static void ReplaceOpcodeSource(ref OpCodes.OpCodeR op, int idx, short src)
        {
            switch (op.Code)
            {
            case OpCodes.OpCodeREnum.Move:
            case OpCodeREnum.Conv_I:
            case OpCodeREnum.Conv_I1:
            case OpCodeREnum.Conv_I2:
            case OpCodeREnum.Conv_I4:
            case OpCodeREnum.Conv_I8:
            case OpCodeREnum.Conv_Ovf_I:
            case OpCodeREnum.Conv_Ovf_I1:
            case OpCodeREnum.Conv_Ovf_I1_Un:
            case OpCodeREnum.Conv_Ovf_I2:
            case OpCodeREnum.Conv_Ovf_I2_Un:
            case OpCodeREnum.Conv_Ovf_I4:
            case OpCodeREnum.Conv_Ovf_I4_Un:
            case OpCodeREnum.Conv_Ovf_I8:
            case OpCodeREnum.Conv_Ovf_I8_Un:
            case OpCodeREnum.Conv_Ovf_I_Un:
            case OpCodeREnum.Conv_Ovf_U:
            case OpCodeREnum.Conv_Ovf_U1:
            case OpCodeREnum.Conv_Ovf_U1_Un:
            case OpCodeREnum.Conv_Ovf_U2:
            case OpCodeREnum.Conv_Ovf_U2_Un:
            case OpCodeREnum.Conv_Ovf_U4:
            case OpCodeREnum.Conv_Ovf_U4_Un:
            case OpCodeREnum.Conv_Ovf_U8:
            case OpCodeREnum.Conv_Ovf_U8_Un:
            case OpCodeREnum.Conv_Ovf_U_Un:
            case OpCodeREnum.Conv_R4:
            case OpCodeREnum.Conv_R8:
            case OpCodeREnum.Conv_R_Un:
            case OpCodeREnum.Conv_U:
            case OpCodeREnum.Conv_U1:
            case OpCodeREnum.Conv_U2:
            case OpCodeREnum.Conv_U4:
            case OpCodeREnum.Conv_U8:
            case OpCodeREnum.Not:
            case OpCodeREnum.Neg:
            case OpCodeREnum.Box:
            case OpCodeREnum.Unbox:
            case OpCodeREnum.Unbox_Any:
            case OpCodeREnum.Ldind_I:
            case OpCodeREnum.Ldind_I1:
            case OpCodeREnum.Ldind_I2:
            case OpCodeREnum.Ldind_I4:
            case OpCodeREnum.Ldind_I8:
            case OpCodeREnum.Ldind_R4:
            case OpCodeREnum.Ldind_R8:
            case OpCodeREnum.Ldind_U1:
            case OpCodeREnum.Ldind_U2:
            case OpCodeREnum.Ldind_U4:
            case OpCodeREnum.Ldind_Ref:
            case OpCodeREnum.Ldobj:
            case OpCodeREnum.Ldloca:
            case OpCodeREnum.Ldloca_S:
            case OpCodeREnum.Ldarg_S:
            case OpCodeREnum.Ldarga:
            case OpCodeREnum.Ldarga_S:
            case OpCodeREnum.Ldlen:
            case OpCodeREnum.Newarr:
            case OpCodeREnum.Ldfld:
            case OpCodeREnum.Ldflda:
            case OpCodeREnum.Ldvirtftn:
            case OpCodeREnum.Isinst:
                op.Register2 = src;
                break;

            case OpCodeREnum.Stind_I:
            case OpCodeREnum.Stind_I1:
            case OpCodeREnum.Stind_I2:
            case OpCodeREnum.Stind_I4:
            case OpCodeREnum.Stind_I8:
            case OpCodeREnum.Stind_R4:
            case OpCodeREnum.Stind_R8:
            case OpCodeREnum.Stind_Ref:
            case OpCodeREnum.Stobj:
            case OpCodeREnum.Stfld:
                switch (idx)
                {
                case 0:
                    op.Register1 = src;
                    break;

                case 1:
                    op.Register2 = src;
                    break;

                default:
                    throw new NotSupportedException();
                }
                break;

            case OpCodeREnum.Add:
            case OpCodeREnum.Add_Ovf:
            case OpCodeREnum.Add_Ovf_Un:
            case OpCodeREnum.Sub:
            case OpCodeREnum.Sub_Ovf:
            case OpCodeREnum.Sub_Ovf_Un:
            case OpCodeREnum.Mul:
            case OpCodeREnum.Mul_Ovf:
            case OpCodeREnum.Mul_Ovf_Un:
            case OpCodeREnum.Div:
            case OpCodeREnum.Div_Un:
            case OpCodeREnum.Rem:
            case OpCodeREnum.Rem_Un:
            case OpCodeREnum.Xor:
            case OpCodeREnum.And:
            case OpCodeREnum.Or:
            case OpCodeREnum.Shl:
            case OpCodeREnum.Shr:
            case OpCodeREnum.Shr_Un:
            case OpCodeREnum.Clt:
            case OpCodeREnum.Clt_Un:
            case OpCodeREnum.Cgt:
            case OpCodeREnum.Cgt_Un:
            case OpCodeREnum.Ceq:
            case OpCodeREnum.Ldelem_I1:
            case OpCodeREnum.Ldelem_U1:
            case OpCodeREnum.Ldelem_I2:
            case OpCodeREnum.Ldelem_U2:
            case OpCodeREnum.Ldelem_I4:
            case OpCodeREnum.Ldelem_U4:
            case OpCodeREnum.Ldelem_I8:
            case OpCodeREnum.Ldelem_R4:
            case OpCodeREnum.Ldelem_R8:
            case OpCodeREnum.Ldelem_Any:
            case OpCodeREnum.Ldelem_Ref:
            case OpCodeREnum.Ldelema:
                switch (idx)
                {
                case 0:
                    op.Register2 = src;
                    break;

                case 1:
                    op.Register3 = src;
                    break;

                default:
                    throw new NotSupportedException();
                }
                break;

            case OpCodeREnum.Stelem_I:
            case OpCodeREnum.Stelem_I1:
            case OpCodeREnum.Stelem_I2:
            case OpCodeREnum.Stelem_I4:
            case OpCodeREnum.Stelem_I8:
            case OpCodeREnum.Stelem_R4:
            case OpCodeREnum.Stelem_R8:
            case OpCodeREnum.Stelem_Ref:
            case OpCodeREnum.Stelem_Any:
                switch (idx)
                {
                case 0:
                    op.Register1 = src;
                    break;

                case 1:
                    op.Register2 = src;
                    break;

                case 2:
                    op.Register3 = src;
                    break;

                default:
                    throw new NotSupportedException();
                }
                break;

            case OpCodeREnum.Call:
            case OpCodeREnum.Callvirt:
            case OpCodeREnum.Newobj:

                switch (idx)
                {
                case 0:
                    op.Register2 = src;
                    break;

                case 1:
                    op.Register3 = src;
                    break;

                case 2:
                    op.Register4 = src;
                    break;

                default:
                    throw new NotSupportedException();
                }
                break;

            case OpCodeREnum.Brtrue:
            case OpCodeREnum.Brtrue_S:
            case OpCodeREnum.Brfalse:
            case OpCodeREnum.Brfalse_S:
            case OpCodeREnum.Switch:
            case OpCodeREnum.Push:
            case OpCodeREnum.Throw:
            case OpCodeREnum.Stsfld:
            case OpCodeREnum.Initobj:
                op.Register1 = src;
                break;

            case OpCodeREnum.Blt:
            case OpCodeREnum.Blt_S:
            case OpCodeREnum.Blt_Un:
            case OpCodeREnum.Blt_Un_S:
            case OpCodeREnum.Ble:
            case OpCodeREnum.Ble_S:
            case OpCodeREnum.Ble_Un:
            case OpCodeREnum.Ble_Un_S:
            case OpCodeREnum.Bgt:
            case OpCodeREnum.Bgt_S:
            case OpCodeREnum.Bgt_Un:
            case OpCodeREnum.Bgt_Un_S:
            case OpCodeREnum.Bge:
            case OpCodeREnum.Bge_S:
            case OpCodeREnum.Bge_Un:
            case OpCodeREnum.Bge_Un_S:
            case OpCodeREnum.Beq:
            case OpCodeREnum.Beq_S:
            case OpCodeREnum.Bne_Un:
            case OpCodeREnum.Bne_Un_S:
                switch (idx)
                {
                case 0:
                    op.Register1 = src;
                    break;

                case 1:
                    op.Register2 = src;
                    break;

                default:
                    throw new NotSupportedException();
                }
                break;

            case OpCodeREnum.Ret:
                op.Register1 = src;
                break;

            default:
                throw new NotImplementedException();
            }
        }
示例#3
0
        void Translate(CodeBasicBlock block, Instruction ins, short locVarRegStart, ref short baseRegIdx)
        {
            List <OpCodeR> lst   = block.FinalInstructions;
            OpCodeR        op    = new OpCodeR();
            var            code  = ins.OpCode;
            var            token = ins.Operand;

            op.Code = (OpCodeREnum)code.Code;
            bool hasRet;

            switch (code.Code)
            {
            case Code.Br_S:
            case Code.Br:
                op.Operand = entryMapping[(Mono.Cecil.Cil.Instruction)token];
                break;

            case Code.Brtrue:
            case Code.Brtrue_S:
            case Code.Brfalse:
            case Code.Brfalse_S:
                op.Register1 = --baseRegIdx;
                op.Operand   = entryMapping[(Mono.Cecil.Cil.Instruction)token];
                break;

            case Code.Switch:
                op.Register1 = --baseRegIdx;
                PrepareJumpTable(token);
                op.Operand = token.GetHashCode();
                break;

            case Code.Blt:
            case Code.Blt_S:
            case Code.Blt_Un:
            case Code.Blt_Un_S:
            case Code.Ble:
            case Code.Ble_S:
            case Code.Ble_Un:
            case Code.Ble_Un_S:
            case Code.Bgt:
            case Code.Bgt_S:
            case Code.Bgt_Un:
            case Code.Bgt_Un_S:
            case Code.Bge:
            case Code.Bge_S:
            case Code.Bge_Un:
            case Code.Bge_Un_S:
            case Code.Beq:
            case Code.Beq_S:
            case Code.Bne_Un:
            case Code.Bne_Un_S:
                op.Register1 = (short)(baseRegIdx - 2);
                op.Register2 = (short)(baseRegIdx - 1);
                baseRegIdx  -= 2;
                op.Operand   = entryMapping[(Mono.Cecil.Cil.Instruction)token];
                break;

            case Code.Ldc_I4_0:
            case Code.Ldc_I4_1:
            case Code.Ldc_I4_2:
            case Code.Ldc_I4_3:
            case Code.Ldc_I4_4:
            case Code.Ldc_I4_5:
            case Code.Ldc_I4_6:
            case Code.Ldc_I4_7:
            case Code.Ldc_I4_8:
            case Code.Ldc_I4_M1:
            case Code.Ldnull:
                op.Register1 = baseRegIdx++;
                break;

            case Code.Ldc_I4:
                op.Register1 = baseRegIdx++;
                op.Operand   = (int)token;
                break;

            case Code.Ldc_I4_S:
                op.Register1 = baseRegIdx++;
                op.Operand   = (sbyte)token;
                break;

            case Code.Ldc_I8:
                op.Register1   = baseRegIdx++;
                op.OperandLong = (long)token;
                break;

            case Code.Ldc_R4:
                op.Register1    = baseRegIdx++;
                op.OperandFloat = (float)token;
                break;

            case Code.Ldc_R8:
                op.Register1     = baseRegIdx++;
                op.OperandDouble = (double)token;
                break;

            case Code.Ldstr:
                op.Register1   = baseRegIdx++;
                op.OperandLong = appdomain.CacheString(token);
                break;

            case Code.Newobj:
            {
                bool     canInline, isILMethod;
                ILMethod toInline;
                IMethod  m;
                var      pCnt    = InitializeFunctionParam(ref op, token, out hasRet, out canInline, out m, out toInline, out isILMethod);
                int      pushCnt = Math.Max(pCnt - CallRegisterParamCount, 0);
                for (int i = pCnt; i > pCnt - pushCnt; i--)
                {
                    OpCodes.OpCodeR op2 = new OpCodes.OpCodeR();
                    op2.Code      = OpCodes.OpCodeREnum.Push;
                    op2.Register1 = (short)(baseRegIdx - i);
                    lst.Add(op2);
                }
                if (pushCnt < pCnt)
                {
                    switch (pCnt - pushCnt)
                    {
                    case 1:
                        op.Register2 = (short)(baseRegIdx - 1);
                        break;

                    case 2:
                        op.Register3 = (short)(baseRegIdx - 1);
                        op.Register2 = (short)(baseRegIdx - 2);
                        break;

                    case 3:
                        op.Register4 = (short)(baseRegIdx - 1);
                        op.Register3 = (short)(baseRegIdx - 2);
                        op.Register2 = (short)(baseRegIdx - 3);
                        break;
                    }
                }
                baseRegIdx  -= (short)pCnt;
                op.Register1 = baseRegIdx++;
            }
            break;

            case Code.Call:
            case Code.Callvirt:
            {
                bool     canInline, isILMethod;
                ILMethod toInline;
                IMethod  m;
                var      pCnt           = InitializeFunctionParam(ref op, token, out hasRet, out canInline, out m, out toInline, out isILMethod);
                bool     hasConstrained = false;
                int      constrainIdx   = -1;
                if (lst.Count > 0)
                {
                    constrainIdx   = lst.Count - 1;
                    hasConstrained = lst[constrainIdx].Code == OpCodeREnum.Constrained;
                }
                bool needInline = canInline && !hasConstrained;
                if (needInline)
                {
                    if (toInline.BodyRegister.Length > Optimizer.MaximalInlineInstructionCount / 2)
                    {
                        needInline = false;
                    }
                }
                if (!needInline)
                {
                    if (code.Code == Code.Callvirt && m is ILMethod)
                    {
                        ILMethod ilm = (ILMethod)m;
                        if (!ilm.Definition.IsAbstract && !ilm.Definition.IsVirtual && !ilm.DeclearingType.IsInterface)
                        {
                            op.Code = OpCodeREnum.Call;
                        }
                    }
                    int pushCnt = hasConstrained ? pCnt : Math.Max(pCnt - CallRegisterParamCount, 0);
                    for (int i = pCnt; i > pCnt - pushCnt; i--)
                    {
                        OpCodes.OpCodeR op2 = new OpCodes.OpCodeR();
                        op2.Code      = OpCodes.OpCodeREnum.Push;
                        op2.Operand   = isILMethod ? 1 : 0;
                        op2.Register1 = (short)(baseRegIdx - i);
                        lst.Add(op2);
                    }
                    if (pushCnt < pCnt)
                    {
                        switch (pCnt - pushCnt)
                        {
                        case 1:
                            op.Register2 = (short)(baseRegIdx - 1);
                            break;

                        case 2:
                            op.Register3 = (short)(baseRegIdx - 1);
                            op.Register2 = (short)(baseRegIdx - 2);
                            break;

                        case 3:
                            op.Register4 = (short)(baseRegIdx - 1);
                            op.Register3 = (short)(baseRegIdx - 2);
                            op.Register2 = (short)(baseRegIdx - 3);
                            break;
                        }
                    }
                    if (hasConstrained)
                    {
                        op.Operand4 = 1;
                        var old = lst[constrainIdx];
                        lst.RemoveAt(constrainIdx);
                        old.Operand2 = op.Operand2;
                        var symbol = block.InstructionMapping[constrainIdx];
                        block.InstructionMapping.Remove(constrainIdx);
                        block.InstructionMapping.Add(lst.Count, symbol);
                        lst.Add(old);
                    }
                    baseRegIdx -= (short)pCnt;

                    if (hasRet)
                    {
                        op.Register1 = baseRegIdx++;
                    }
                    else
                    {
                        op.Register1 = -1;
                    }
                }
                else
                {
                    baseRegIdx -= (short)pCnt;
                    RegisterVMSymbolLink link = null;
#if DEBUG && !DISABLE_ILRUNTIME_DEBUG
                    link = new RegisterVMSymbolLink();
                    link.BaseRegisterIndex = baseRegIdx;
                    link.Value.Instruction = ins;
                    link.Value.Method      = method;
#endif
#if DEBUG && !NO_PROFILER
                    if (System.Threading.Thread.CurrentThread.ManagedThreadId == method.AppDomain.UnityMainThreadID)

#if UNITY_5_5_OR_NEWER
                    { UnityEngine.Profiling.Profiler.BeginSample("JITCompiler.InlineMethod"); }
#else
                    { UnityEngine.Profiler.BeginSample("JITCompiler.InlineMethod"); }
#endif
#endif
                    Optimizer.InlineMethod(block, toInline, link, ref jumptables, baseRegIdx, hasRet);
#if DEBUG && !NO_PROFILER
                    if (System.Threading.Thread.CurrentThread.ManagedThreadId == method.AppDomain.UnityMainThreadID)
#if UNITY_5_5_OR_NEWER
                    { UnityEngine.Profiling.Profiler.EndSample(); }
#else
                    { UnityEngine.Profiler.EndSample(); }
#endif
#endif
                    if (hasRet)
                    {
                        baseRegIdx++;
                    }
                    return;
                }
            }
            break;

            case Code.Ldsfld:
            case Code.Ldsflda:
                op.Register1   = baseRegIdx++;
                op.OperandLong = appdomain.GetStaticFieldIndex(token, declaringType, method);
                break;

            case Code.Stsfld:
                op.Register1   = --baseRegIdx;
                op.OperandLong = appdomain.GetStaticFieldIndex(token, declaringType, method);
                break;

            case Code.Initobj:
                op.Register1 = --baseRegIdx;
                op.Operand   = method.GetTypeTokenHashCode(token);
                break;

            case Code.Ret:
                if (hasReturn)
                {
                    op.Register1 = --baseRegIdx;
                }
                break;

            case Code.Throw:
                op.Register1 = --baseRegIdx;
                break;

            case Code.Add:
            case Code.Add_Ovf:
            case Code.Add_Ovf_Un:
            case Code.Sub:
            case Code.Sub_Ovf:
            case Code.Sub_Ovf_Un:
            case Code.Mul:
            case Code.Mul_Ovf:
            case Code.Mul_Ovf_Un:
            case Code.Div:
            case Code.Div_Un:
            case Code.Rem:
            case Code.Rem_Un:
            case Code.Shr:
            case Code.Shr_Un:
            case Code.Shl:
            case Code.Xor:
            case Code.Or:
            case Code.And:
            case Code.Clt:
            case Code.Clt_Un:
            case Code.Cgt:
            case Code.Cgt_Un:
            case Code.Ceq:
            case Code.Ldelema:
            case Code.Ldelem_I1:
            case Code.Ldelem_U1:
            case Code.Ldelem_I2:
            case Code.Ldelem_U2:
            case Code.Ldelem_I4:
            case Code.Ldelem_U4:
            case Code.Ldelem_I8:
            case Code.Ldelem_R4:
            case Code.Ldelem_R8:
            case Code.Ldelem_Any:
            case Code.Ldelem_Ref:
                op.Register1 = (short)(baseRegIdx - 2);     //explicit use dest register for optimization
                op.Register2 = (short)(baseRegIdx - 2);
                op.Register3 = (short)(baseRegIdx - 1);
                baseRegIdx--;
                break;

            case Code.Nop:
            case Code.Castclass:
            case Code.Readonly:
            case Code.Volatile:
            case Code.Endfinally:
                break;

            case Code.Leave:
            case Code.Leave_S:
                break;

            case Code.Stloc_0:
                op.Code      = OpCodes.OpCodeREnum.Move;
                op.Register1 = locVarRegStart;
                op.Register2 = --baseRegIdx;
                break;

            case Code.Stloc_1:
                op.Code      = OpCodes.OpCodeREnum.Move;
                op.Register1 = (short)(locVarRegStart + 1);
                op.Register2 = --baseRegIdx;
                break;

            case Code.Stloc_2:
                op.Code      = OpCodes.OpCodeREnum.Move;
                op.Register1 = (short)(locVarRegStart + 2);
                op.Register2 = --baseRegIdx;
                break;

            case Code.Stloc_3:
                op.Code      = OpCodes.OpCodeREnum.Move;
                op.Register1 = (short)(locVarRegStart + 3);
                op.Register2 = --baseRegIdx;
                break;

            case Code.Stloc_S:
                op.Code      = OpCodes.OpCodeREnum.Move;
                op.Register1 = (short)(locVarRegStart + ((VariableDefinition)ins.Operand).Index);
                op.Register2 = --baseRegIdx;
                break;

            case Code.Ldloc_0:
                op.Code      = OpCodes.OpCodeREnum.Move;
                op.Register1 = baseRegIdx++;
                op.Register2 = locVarRegStart;
                break;

            case Code.Ldloc_1:
                op.Code      = OpCodes.OpCodeREnum.Move;
                op.Register1 = baseRegIdx++;
                op.Register2 = (short)(locVarRegStart + 1);
                break;

            case Code.Ldloc_2:
                op.Code      = OpCodes.OpCodeREnum.Move;
                op.Register1 = baseRegIdx++;
                op.Register2 = (short)(locVarRegStart + 2);
                break;

            case Code.Ldloc_3:
                op.Code      = OpCodes.OpCodeREnum.Move;
                op.Register1 = baseRegIdx++;
                op.Register2 = (short)(locVarRegStart + 3);
                break;

            case Code.Ldloc:
            case Code.Ldloc_S:
                op.Code      = OpCodes.OpCodeREnum.Move;
                op.Register1 = baseRegIdx++;
                op.Register2 = (short)(locVarRegStart + ((VariableDefinition)ins.Operand).Index);
                break;

            case Code.Ldloca:
            case Code.Ldloca_S:
                op.Register1 = baseRegIdx++;
                op.Register2 = (short)(locVarRegStart + ((VariableDefinition)ins.Operand).Index);
                break;

            case Code.Ldarg_0:
            case Code.Ldarg_1:
            case Code.Ldarg_2:
            case Code.Ldarg_3:
                op.Code      = OpCodes.OpCodeREnum.Move;
                op.Register1 = baseRegIdx++;
                op.Register2 = (short)(code.Code - (Code.Ldarg_0));
                break;

            case Code.Ldarg_S:
                op.Code      = OpCodes.OpCodeREnum.Move;
                op.Register1 = baseRegIdx++;
                op.Register2 = (short)((ParameterDefinition)ins.Operand).Index;
                if (def.HasThis)
                {
                    op.Register2++;
                }
                break;

            case Code.Ldarga:
            case Code.Ldarga_S:
                op.Register1 = baseRegIdx++;
                op.Register2 = (short)((ParameterDefinition)ins.Operand).Index;
                if (def.HasThis)
                {
                    op.Register2++;
                }
                break;

            case Code.Starg:
            case Code.Starg_S:
                op.Code      = OpCodes.OpCodeREnum.Move;
                op.Register2 = --baseRegIdx;
                op.Register1 = (short)((ParameterDefinition)ins.Operand).Index;
                if (def.HasThis)
                {
                    op.Register1++;
                }
                break;

            case Code.Newarr:
                op.Register1 = (short)(baseRegIdx - 1);
                op.Register2 = (short)(baseRegIdx - 1);
                op.Operand   = method.GetTypeTokenHashCode(token);
                break;

            case Code.Dup:
                op.Code      = OpCodes.OpCodeREnum.Move;
                op.Register2 = (short)(baseRegIdx - 1);
                op.Register1 = baseRegIdx++;
                break;

            case Code.Stelem_I:
            case Code.Stelem_I1:
            case Code.Stelem_I2:
            case Code.Stelem_I4:
            case Code.Stelem_I8:
            case Code.Stelem_R4:
            case Code.Stelem_R8:
            case Code.Stelem_Ref:
            case Code.Stelem_Any:
                op.Register1 = (short)(baseRegIdx - 3);
                op.Register2 = (short)(baseRegIdx - 2);
                op.Register3 = (short)(baseRegIdx - 1);
                baseRegIdx  -= 3;
                break;

            case Code.Stind_I:
            case Code.Stind_I1:
            case Code.Stind_I2:
            case Code.Stind_I4:
            case Code.Stind_I8:
            case Code.Stind_R4:
            case Code.Stind_R8:
            case Code.Stind_Ref:
                op.Register1 = (short)(baseRegIdx - 2);
                op.Register2 = (short)(baseRegIdx - 1);
                baseRegIdx  -= 2;
                break;

            case Code.Stobj:
                op.Register1 = (short)(baseRegIdx - 2);
                op.Register2 = (short)(baseRegIdx - 1);
                op.Operand   = method.GetTypeTokenHashCode(token);
                baseRegIdx  -= 2;
                break;

            case Code.Conv_I:
            case Code.Conv_I1:
            case Code.Conv_I2:
            case Code.Conv_I4:
            case Code.Conv_I8:
            case Code.Conv_Ovf_I:
            case Code.Conv_Ovf_I1:
            case Code.Conv_Ovf_I1_Un:
            case Code.Conv_Ovf_I2:
            case Code.Conv_Ovf_I2_Un:
            case Code.Conv_Ovf_I4:
            case Code.Conv_Ovf_I4_Un:
            case Code.Conv_Ovf_I8:
            case Code.Conv_Ovf_I8_Un:
            case Code.Conv_Ovf_I_Un:
            case Code.Conv_Ovf_U:
            case Code.Conv_Ovf_U1:
            case Code.Conv_Ovf_U1_Un:
            case Code.Conv_Ovf_U2:
            case Code.Conv_Ovf_U2_Un:
            case Code.Conv_Ovf_U4:
            case Code.Conv_Ovf_U4_Un:
            case Code.Conv_Ovf_U8:
            case Code.Conv_Ovf_U8_Un:
            case Code.Conv_Ovf_U_Un:
            case Code.Conv_R4:
            case Code.Conv_R8:
            case Code.Conv_R_Un:
            case Code.Conv_U:
            case Code.Conv_U1:
            case Code.Conv_U2:
            case Code.Conv_U4:
            case Code.Conv_U8:
            case Code.Ldlen:
            case Code.Ldind_I:
            case Code.Ldind_I2:
            case Code.Ldind_I4:
            case Code.Ldind_I8:
            case Code.Ldind_R4:
            case Code.Ldind_R8:
            case Code.Ldind_U1:
            case Code.Ldind_U2:
            case Code.Ldind_U4:
            case Code.Ldind_Ref:
            case Code.Neg:
            case Code.Not:
                op.Register1 = (short)(baseRegIdx - 1);
                op.Register2 = (short)(baseRegIdx - 1);
                break;

            case Code.Ldobj:
                op.Register1 = (short)(baseRegIdx - 1);
                op.Register2 = (short)(baseRegIdx - 1);
                op.Operand   = method.GetTypeTokenHashCode(token);
                break;

            case Code.Ldfld:
            case Code.Ldflda:
                op.Register1   = (short)(baseRegIdx - 1);
                op.Register2   = (short)(baseRegIdx - 1);
                op.OperandLong = appdomain.GetStaticFieldIndex(token, declaringType, method);
                break;

            case Code.Stfld:
                op.Register1   = (short)(baseRegIdx - 2);
                op.Register2   = (short)(baseRegIdx - 1);
                op.OperandLong = appdomain.GetStaticFieldIndex(token, declaringType, method);
                baseRegIdx    -= 2;
                break;

            case Code.Box:
            case Code.Unbox:
            case Code.Unbox_Any:
            case Code.Isinst:
                op.Register1 = (short)(baseRegIdx - 1);
                op.Register2 = (short)(baseRegIdx - 1);
                op.Operand   = method.GetTypeTokenHashCode(token);
                break;

            case Code.Constrained:
                op.Operand = method.GetTypeTokenHashCode(token);
                break;

            case Code.Ldtoken:
                op.Register1 = baseRegIdx++;
                if (token is FieldReference)
                {
                    op.Operand     = 0;
                    op.OperandLong = appdomain.GetStaticFieldIndex(token, declaringType, method);
                }
                else if (token is TypeReference)
                {
                    op.Operand     = 1;
                    op.OperandLong = method.GetTypeTokenHashCode(token);
                }
                else
                {
                    throw new NotImplementedException();
                }
                break;

            case Code.Ldftn:
            {
                op.Register1 = baseRegIdx++;
                bool     hasReturn, canInline, isILMethod;
                ILMethod toInline;
                IMethod  m;
                InitializeFunctionParam(ref op, token, out hasReturn, out canInline, out m, out toInline, out isILMethod);
            }
            break;

            case Code.Ldvirtftn:
            {
                bool     hasReturn, canInline, isILMethod;
                ILMethod toInline;
                IMethod  m;
                InitializeFunctionParam(ref op, token, out hasReturn, out canInline, out m, out toInline, out isILMethod);
                op.Register1 = (short)(baseRegIdx - 1);
                op.Register2 = (short)(baseRegIdx - 1);
            }
            break;

            case Code.Pop:
                baseRegIdx--;
                op.Code = OpCodeREnum.Nop;
                break;

            default:
                throw new NotImplementedException(string.Format("Unknown Opcode:{0}", code.Code));
            }
            RegisterVMSymbol s = new RegisterVMSymbol()
            {
                Instruction = ins,
                Method      = method
            };
            block.InstructionMapping.Add(lst.Count, s);
            lst.Add(op);
        }
示例#4
0
        public static bool GetOpcodeDestRegister(ref OpCodes.OpCodeR op, out short r1)
        {
            r1 = -1;
            switch (op.Code)
            {
            case OpCodes.OpCodeREnum.Move:
            case OpCodeREnum.Conv_I:
            case OpCodeREnum.Conv_I1:
            case OpCodeREnum.Conv_I2:
            case OpCodeREnum.Conv_I4:
            case OpCodeREnum.Conv_I8:
            case OpCodeREnum.Conv_Ovf_I:
            case OpCodeREnum.Conv_Ovf_I1:
            case OpCodeREnum.Conv_Ovf_I1_Un:
            case OpCodeREnum.Conv_Ovf_I2:
            case OpCodeREnum.Conv_Ovf_I2_Un:
            case OpCodeREnum.Conv_Ovf_I4:
            case OpCodeREnum.Conv_Ovf_I4_Un:
            case OpCodeREnum.Conv_Ovf_I8:
            case OpCodeREnum.Conv_Ovf_I8_Un:
            case OpCodeREnum.Conv_Ovf_I_Un:
            case OpCodeREnum.Conv_Ovf_U:
            case OpCodeREnum.Conv_Ovf_U1:
            case OpCodeREnum.Conv_Ovf_U1_Un:
            case OpCodeREnum.Conv_Ovf_U2:
            case OpCodeREnum.Conv_Ovf_U2_Un:
            case OpCodeREnum.Conv_Ovf_U4:
            case OpCodeREnum.Conv_Ovf_U4_Un:
            case OpCodeREnum.Conv_Ovf_U8:
            case OpCodeREnum.Conv_Ovf_U8_Un:
            case OpCodeREnum.Conv_Ovf_U_Un:
            case OpCodeREnum.Conv_R4:
            case OpCodeREnum.Conv_R8:
            case OpCodeREnum.Conv_R_Un:
            case OpCodeREnum.Conv_U:
            case OpCodeREnum.Conv_U1:
            case OpCodeREnum.Conv_U2:
            case OpCodeREnum.Conv_U4:
            case OpCodeREnum.Conv_U8:
            case OpCodeREnum.Not:
            case OpCodeREnum.Neg:
            case OpCodeREnum.Box:
            case OpCodeREnum.Unbox:
            case OpCodeREnum.Unbox_Any:
            case OpCodeREnum.Ldc_I4_0:
            case OpCodeREnum.Ldc_I4_1:
            case OpCodeREnum.Ldc_I4_2:
            case OpCodeREnum.Ldc_I4_3:
            case OpCodeREnum.Ldc_I4_4:
            case OpCodeREnum.Ldc_I4_5:
            case OpCodeREnum.Ldc_I4_6:
            case OpCodeREnum.Ldc_I4_7:
            case OpCodeREnum.Ldc_I4_8:
            case OpCodeREnum.Ldc_I4_M1:
            case OpCodeREnum.Ldnull:
            case OpCodeREnum.Ldc_I4:
            case OpCodeREnum.Ldc_I4_S:
            case OpCodeREnum.Ldc_I8:
            case OpCodeREnum.Ldc_R4:
            case OpCodeREnum.Ldc_R8:
            case OpCodeREnum.Ldstr:
            case OpCodeREnum.Callvirt:
            case OpCodeREnum.Call:
            case OpCodeREnum.Newobj:
            case OpCodeREnum.Ldind_I:
            case OpCodeREnum.Ldind_I1:
            case OpCodeREnum.Ldind_I2:
            case OpCodeREnum.Ldind_I4:
            case OpCodeREnum.Ldind_I8:
            case OpCodeREnum.Ldind_R4:
            case OpCodeREnum.Ldind_R8:
            case OpCodeREnum.Ldind_U1:
            case OpCodeREnum.Ldind_U2:
            case OpCodeREnum.Ldind_U4:
            case OpCodeREnum.Ldind_Ref:
            case OpCodeREnum.Ldobj:
            case OpCodeREnum.Ldloca:
            case OpCodeREnum.Ldloca_S:
            case OpCodeREnum.Ldarg_S:
            case OpCodeREnum.Ldarga:
            case OpCodeREnum.Ldarga_S:
            case OpCodeREnum.Ldlen:
            case OpCodeREnum.Newarr:
            case OpCodeREnum.Ldfld:
            case OpCodeREnum.Ldflda:
            case OpCodeREnum.Ldtoken:
            case OpCodeREnum.Isinst:
            case OpCodeREnum.Ldsfld:
            case OpCodeREnum.Ldsflda:
            case OpCodeREnum.Ldftn:
            case OpCodeREnum.Ldvirtftn:
            case OpCodeREnum.Ldelem_I1:
            case OpCodeREnum.Ldelem_U1:
            case OpCodeREnum.Ldelem_I2:
            case OpCodeREnum.Ldelem_U2:
            case OpCodeREnum.Ldelem_I4:
            case OpCodeREnum.Ldelem_U4:
            case OpCodeREnum.Ldelem_I8:
            case OpCodeREnum.Ldelem_R4:
            case OpCodeREnum.Ldelem_R8:
            case OpCodeREnum.Ldelem_Any:
            case OpCodeREnum.Ldelem_Ref:
            case OpCodeREnum.Ldelema:
                r1 = op.Register1;
                return(true);

            case OpCodeREnum.Br_S:
            case OpCodeREnum.Br:
            case OpCodeREnum.Brtrue:
            case OpCodeREnum.Brtrue_S:
            case OpCodeREnum.Brfalse:
            case OpCodeREnum.Brfalse_S:
            case OpCodeREnum.Switch:
            case OpCodeREnum.Blt:
            case OpCodeREnum.Blt_S:
            case OpCodeREnum.Blt_Un:
            case OpCodeREnum.Blt_Un_S:
            case OpCodeREnum.Ble:
            case OpCodeREnum.Ble_S:
            case OpCodeREnum.Ble_Un:
            case OpCodeREnum.Ble_Un_S:
            case OpCodeREnum.Bgt:
            case OpCodeREnum.Bgt_S:
            case OpCodeREnum.Bgt_Un:
            case OpCodeREnum.Bgt_Un_S:
            case OpCodeREnum.Bge:
            case OpCodeREnum.Bge_S:
            case OpCodeREnum.Bge_Un:
            case OpCodeREnum.Bge_Un_S:
            case OpCodeREnum.Beq:
            case OpCodeREnum.Beq_S:
            case OpCodeREnum.Bne_Un:
            case OpCodeREnum.Bne_Un_S:
            case OpCodeREnum.Nop:
            case OpCodeREnum.Constrained:
            case OpCodeREnum.Ret:
            case OpCodeREnum.Push:
            case OpCodeREnum.Initobj:
            case OpCodeREnum.InlineStart:
            case OpCodeREnum.InlineEnd:
            case OpCodeREnum.Stind_I:
            case OpCodeREnum.Stind_I1:
            case OpCodeREnum.Stind_I2:
            case OpCodeREnum.Stind_I4:
            case OpCodeREnum.Stind_I8:
            case OpCodeREnum.Stind_R4:
            case OpCodeREnum.Stind_R8:
            case OpCodeREnum.Stind_Ref:
            case OpCodeREnum.Stobj:
            case OpCodeREnum.Stelem_I:
            case OpCodeREnum.Stelem_I1:
            case OpCodeREnum.Stelem_I2:
            case OpCodeREnum.Stelem_I4:
            case OpCodeREnum.Stelem_I8:
            case OpCodeREnum.Stelem_R4:
            case OpCodeREnum.Stelem_R8:
            case OpCodeREnum.Stelem_Ref:
            case OpCodeREnum.Stelem_Any:
            case OpCodeREnum.Stfld:
            case OpCodeREnum.Stsfld:
            case OpCodeREnum.Throw:
            case OpCodeREnum.Castclass:
            case OpCodeREnum.Readonly:
            case OpCodeREnum.Leave:
            case OpCodeREnum.Leave_S:
            case OpCodeREnum.Endfinally:
            case OpCodeREnum.Volatile:
                return(false);

            case OpCodeREnum.Add:
            case OpCodeREnum.Add_Ovf:
            case OpCodeREnum.Add_Ovf_Un:
            case OpCodeREnum.Sub:
            case OpCodeREnum.Sub_Ovf:
            case OpCodeREnum.Sub_Ovf_Un:
            case OpCodeREnum.Mul:
            case OpCodeREnum.Mul_Ovf:
            case OpCodeREnum.Mul_Ovf_Un:
            case OpCodeREnum.Div:
            case OpCodeREnum.Div_Un:
            case OpCodeREnum.Rem:
            case OpCodeREnum.Rem_Un:
            case OpCodeREnum.Xor:
            case OpCodeREnum.And:
            case OpCodeREnum.Or:
            case OpCodeREnum.Shl:
            case OpCodeREnum.Shr:
            case OpCodeREnum.Shr_Un:
            case OpCodeREnum.Clt:
            case OpCodeREnum.Clt_Un:
            case OpCodeREnum.Cgt:
            case OpCodeREnum.Cgt_Un:
            case OpCodeREnum.Ceq:
                r1 = op.Register1;
                return(true);

            default:
                throw new NotImplementedException();
            }
        }
示例#5
0
        int InitializeFunctionParam(ref OpCodes.OpCodeR op, object token, out bool hasReturn, out bool canInline, out IMethod m, out ILMethod toInline, out bool isILMethod)
        {
            bool invalidToken;
            int  pCnt = 0;

            m            = appdomain.GetMethod(token, declaringType, method, out invalidToken);
            toInline     = null;
            canInline    = false;
            op.Register2 = -1;
            op.Register3 = -1;
            op.Register4 = -1;
            if (m != null)
            {
                if (invalidToken)
                {
                    op.Operand2 = m.GetHashCode();
                }
                else
                {
                    op.Operand2 = token.GetHashCode();
                }
                pCnt = m.ParameterCount;
                if (!m.IsStatic && op.Code != OpCodeREnum.Newobj)
                {
                    pCnt++;
                }
                hasReturn = m.ReturnType != appdomain.VoidType;
                if (m is ILMethod)
                {
                    isILMethod = !m.IsDelegateInvoke;
                    var  ilm                 = (ILMethod)m;
                    bool noJIT               = (ilm.JITFlags & ILRuntimeJITFlags.NoJIT) != ILRuntimeJITFlags.None;
                    bool forceInline         = (ilm.JITFlags & ILRuntimeJITFlags.ForceInline) != ILRuntimeJITFlags.None;
                    bool hasExceptionHandler = ilm.Definition.HasBody && ilm.Definition.Body.HasExceptionHandlers;
                    if (!ilm.IsDelegateInvoke && !ilm.IsVirtual && !noJIT && !hasExceptionHandler && !ilm.Compiling)
                    {
                        var  def        = ilm.Definition;
                        bool codeSizeOK = ilm.IsRegisterBodyReady ? ilm.BodyRegister.Length <= Optimizer.MaximalInlineInstructionCount : def.Body.Instructions.Count <= Optimizer.MaximalInlineInstructionCount;
                        if (!def.HasBody || forceInline || codeSizeOK)
                        {
                            canInline = true;
                            toInline  = ilm;
                        }
                    }
                }
                else
                {
                    isILMethod = false;
                }
            }
            else
            {
                isILMethod = false;
                //Cannot find method or the method is dummy
                MethodReference _ref = (MethodReference)token;
                pCnt = _ref.HasParameters ? _ref.Parameters.Count : 0;
                if (_ref.HasThis && op.Code != OpCodeREnum.Newobj)
                {
                    pCnt++;
                }
                op.Operand3 = pCnt;
                hasReturn   = false;
            }
            return(pCnt);
        }