示例#1
0
        public TranslatedSub GetSubroutine(TranslationTier tier, bool isWorthOptimizing)
        {
            RegUsage = new RegisterUsage();

            RegUsage.BuildUses(_ilBlocks[0]);

            DynamicMethod method = new DynamicMethod(_subName, typeof(long), TranslatedSub.FixedArgTypes);

            long intNiRegsMask = RegUsage.GetIntNotInputs(_ilBlocks[0]);
            long vecNiRegsMask = RegUsage.GetVecNotInputs(_ilBlocks[0]);

            TranslatedSub subroutine = new TranslatedSub(
                method,
                intNiRegsMask,
                vecNiRegsMask,
                tier,
                isWorthOptimizing);

            _locals = new Dictionary <Register, int>();

            _localsCount = 0;

            Generator = method.GetILGenerator();

            foreach (ILBlock ilBlock in _ilBlocks)
            {
                ilBlock.Emit(this);
            }

            subroutine.PrepareMethod();

            return(subroutine);
        }
示例#2
0
        public void Emit(ILMethodBuilder context)
        {
            long intInputs = context.RegUsage.GetIntInputs(_block);
            long vecInputs = context.RegUsage.GetVecInputs(_block);

            if (Optimizations.AssumeStrictAbiCompliance && context.IsSubComplete)
            {
                intInputs = RegisterUsage.ClearCallerSavedIntRegs(intInputs, context.IsAarch64);
                vecInputs = RegisterUsage.ClearCallerSavedVecRegs(vecInputs, context.IsAarch64);
            }

            LoadLocals(context, intInputs, RegisterType.Int);
            LoadLocals(context, vecInputs, RegisterType.Vector);
        }
示例#3
0
        private void EmitStoreContext(ILGenerator generator, BasicBlock block)
        {
            RegisterMask outputs = _regUsage.GetOutputs(block);

            long intOutputs = outputs.IntMask;
            long vecOutputs = outputs.VecMask;

            if (Optimizations.AssumeStrictAbiCompliance && _isComplete)
            {
                intOutputs = RegisterUsage.ClearCallerSavedIntRegs(intOutputs, _mode);
                vecOutputs = RegisterUsage.ClearCallerSavedVecRegs(vecOutputs, _mode);
            }

            StoreLocals(generator, intOutputs, RegisterType.Int);
            StoreLocals(generator, vecOutputs, RegisterType.Vector);
        }
        public void Emit(ILMethodBuilder context)
        {
            long intOutputs = context.RegUsage.GetIntOutputs(_block);
            long vecOutputs = context.RegUsage.GetVecOutputs(_block);

            if (Optimizations.AssumeStrictAbiCompliance && context.IsSubComplete)
            {
                intOutputs = RegisterUsage.ClearCallerSavedIntRegs(intOutputs, context.IsAarch64);
                vecOutputs = RegisterUsage.ClearCallerSavedVecRegs(vecOutputs, context.IsAarch64);
            }

            if (_callSub != null)
            {
                //Those register are assigned on the callee function, without
                //reading it's value first. We don't need to write them because
                //they are not going to be read on the callee.
                intOutputs &= ~_callSub.IntNiRegsMask;
                vecOutputs &= ~_callSub.VecNiRegsMask;
            }

            StoreLocals(context, intOutputs, RegisterType.Int);
            StoreLocals(context, vecOutputs, RegisterType.Vector);
        }
示例#5
0
        public TranslatedSub Build(BasicBlock[] blocks, string name, TranslationTier tier, bool rejit = true)
        {
            _regUsage = new RegisterUsage(blocks[0], blocks.Length);

            DynamicMethod method = new DynamicMethod(name, typeof(long), TranslatedSub.FixedArgTypes);

            TranslatedSub subroutine = new TranslatedSub(method, tier, rejit);

            _locals = new Dictionary <Register, int>();

            Dictionary <ILLabel, Label> labels = new Dictionary <ILLabel, Label>();

            ILGenerator generator = method.GetILGenerator();

            Label GetLabel(ILLabel label)
            {
                if (!labels.TryGetValue(label, out Label ilLabel))
                {
                    ilLabel = generator.DefineLabel();

                    labels.Add(label, ilLabel);
                }

                return(ilLabel);
            }

            foreach (BasicBlock block in blocks)
            {
                for (int index = 0; index < block.Count; index++)
                {
                    Operation operation = block.GetOperation(index);

                    switch (operation.Type)
                    {
                    case OperationType.Call:
                        generator.Emit(OpCodes.Call, operation.GetArg <MethodInfo>(0));
                        break;

                    case OperationType.CallVirtual:
                        generator.Emit(OpCodes.Callvirt, operation.GetArg <MethodInfo>(0));
                        break;

                    case OperationType.IL:
                        generator.Emit(operation.GetArg <OpCode>(0));
                        break;

                    case OperationType.ILBranch:
                        generator.Emit(operation.GetArg <OpCode>(0), GetLabel(operation.GetArg <ILLabel>(1)));
                        break;

                    case OperationType.LoadArgument:
                        generator.EmitLdarg(operation.GetArg <int>(0));
                        break;

                    case OperationType.LoadConstant:
                        EmitLoadConstant(generator, operation.GetArg(0));
                        break;

                    case OperationType.LoadContext:
                        EmitLoadContext(generator, operation.Parent);
                        break;

                    case OperationType.LoadField:
                        generator.Emit(OpCodes.Ldfld, operation.GetArg <FieldInfo>(0));
                        break;

                    case OperationType.LoadLocal:
                        EmitLoadLocal(
                            generator,
                            operation.GetArg <int>(0),
                            operation.GetArg <RegisterType>(1),
                            operation.GetArg <RegisterSize>(2));
                        break;

                    case OperationType.MarkLabel:
                        generator.MarkLabel(GetLabel(operation.GetArg <ILLabel>(0)));
                        break;

                    case OperationType.StoreContext:
                        EmitStoreContext(generator, operation.Parent);
                        break;

                    case OperationType.StoreLocal:
                        EmitStoreLocal(
                            generator,
                            operation.GetArg <int>(0),
                            operation.GetArg <RegisterType>(1),
                            operation.GetArg <RegisterSize>(2));
                        break;
                    }
                }
            }

            subroutine.PrepareMethod();

            return(subroutine);
        }