예제 #1
0
        public void Emit(AILEmitter Context)
        {
            switch (Type)
            {
            case ConstType.Int32: Context.Generator.EmitLdc_I4(Value.I4); break;

            case ConstType.Int64:
            {
                if (Value.I8 >= int.MinValue &&
                    Value.I8 <= int.MaxValue)
                {
                    Context.Generator.EmitLdc_I4(Value.I4);

                    Context.Generator.Emit(OpCodes.Conv_I8);
                }
                else
                {
                    Context.Generator.Emit(OpCodes.Ldc_I8, Value.I8);
                }
                break;
            }

            case ConstType.Single: Context.Generator.Emit(OpCodes.Ldc_R4, Value.R4); break;

            case ConstType.Double: Context.Generator.Emit(OpCodes.Ldc_R8, Value.R8); break;
            }
        }
예제 #2
0
        private void EmitLdloc(AILEmitter Context, int Index, ARegisterType Type)
        {
            ARegister Reg = new ARegister(Index, Type);

            Context.Generator.EmitLdloc(Context.GetLocalIndex(Reg));

            AILConv.EmitConv(Context, Context.GetLocalType(Reg), OperType);
        }
예제 #3
0
        private void EmitLdfld(AILEmitter Context, int Index)
        {
            long IntInputs = Context.LocalAlloc.GetIntInputs(Context.GetILBlock(Index));
            long VecInputs = Context.LocalAlloc.GetVecInputs(Context.GetILBlock(Index));

            LoadLocals(Context, IntInputs, ARegisterType.Int);
            LoadLocals(Context, VecInputs, ARegisterType.Vector);
        }
예제 #4
0
        private void EmitStfld(AILEmitter Context, int Index)
        {
            long IntOutputs = Context.LocalAlloc.GetIntOutputs(Context.GetILBlock(Index));
            long VecOutputs = Context.LocalAlloc.GetVecOutputs(Context.GetILBlock(Index));

            StoreLocals(Context, IntOutputs, ARegisterType.Int);
            StoreLocals(Context, VecOutputs, ARegisterType.Vector);
        }
예제 #5
0
        private static void EmitMakeVec(AILEmitter Context, Type SrcType)
        {
            string MthdName = nameof(MakeScalar);

            Type[] MthdTypes = new Type[] { SrcType };

            MethodInfo MthdInfo = typeof(AILConv).GetMethod(MthdName, MthdTypes);

            Context.Generator.Emit(OpCodes.Call, MthdInfo);
        }
예제 #6
0
        public Label GetLabel(AILEmitter Context)
        {
            if (!HasLabel)
            {
                Lbl = Context.Generator.DefineLabel();

                HasLabel = true;
            }

            return(Lbl);
        }
예제 #7
0
        private void EmitLdloc(AILEmitter Context, int Index, ARegisterType RegisterType)
        {
            ARegister Reg = new ARegister(Index, RegisterType);

            Context.Generator.EmitLdloc(Context.GetLocalIndex(Reg));

            if (RegisterType == ARegisterType.Int &&
                RegisterSize == ARegisterSize.Int32)
            {
                Context.Generator.Emit(OpCodes.Conv_U4);
            }
        }
예제 #8
0
파일: AILBlock.cs 프로젝트: GDhex12/Ryujinx
        public void Add(IAILEmit ILEmitter)
        {
            if (ILEmitter is AILOpCodeLoad Ld && AILEmitter.IsRegIndex(Ld.Index))
            {
                switch (Ld.IoType)
                {
                case AIoType.Flag:   IntInputs |= ((1L << Ld.Index) << 32) & ~IntOutputs; break;

                case AIoType.Int:    IntInputs |= (1L << Ld.Index) & ~IntOutputs; break;

                case AIoType.Vector: VecInputs |= (1L << Ld.Index) & ~VecOutputs; break;
                }
            }
예제 #9
0
        public void Emit(AILEmitter Context)
        {
            switch (Type)
            {
            case ConstType.Int32:  Context.Generator.EmitLdc_I4(Value.I4);           break;

            case ConstType.Int64:  Context.Generator.Emit(OpCodes.Ldc_I8, Value.I8); break;

            case ConstType.Single: Context.Generator.Emit(OpCodes.Ldc_R4, Value.R4); break;

            case ConstType.Double: Context.Generator.Emit(OpCodes.Ldc_R8, Value.R8); break;
            }
        }
예제 #10
0
        public void Emit(AILEmitter Context)
        {
            switch (IoType & AIoType.Mask)
            {
            case AIoType.Arg:    EmitLdarg(Context, Index);                       break;

            case AIoType.Fields: EmitLdfld(Context, Index);                       break;

            case AIoType.Flag:   EmitLdloc(Context, Index, ARegisterType.Flag);   break;

            case AIoType.Int:    EmitLdloc(Context, Index, ARegisterType.Int);    break;

            case AIoType.Vector: EmitLdloc(Context, Index, ARegisterType.Vector); break;
            }
        }
예제 #11
0
        private void LoadLocals(AILEmitter Context, long Inputs, ARegisterType BaseType)
        {
            for (int Bit = 0; Bit < 64; Bit++)
            {
                long Mask = 1L << Bit;

                if ((Inputs & Mask) != 0)
                {
                    ARegister Reg = AILEmitter.GetRegFromBit(Bit, BaseType);

                    Context.Generator.EmitLdarg(ATranslatedSub.StateArgIdx);
                    Context.Generator.Emit(OpCodes.Ldfld, Reg.GetField());

                    Context.Generator.EmitStloc(Context.GetLocalIndex(Reg));
                }
            }
        }
예제 #12
0
        public AILEmitterCtx(ATranslator Translator, ABlock[] Graph, ABlock Root)
        {
            this.Translator = Translator;
            this.Graph      = Graph;
            this.Root       = Root;

            string SubName = $"Sub{Root.Position:X16}";

            Labels = new Dictionary <long, AILLabel>();

            Emitter = new AILEmitter(Graph, Root, SubName);

            ILBlock = Emitter.GetILBlock(0);

            OpcIndex = -1;

            if (!AdvanceOpCode())
            {
                throw new ArgumentException(nameof(Graph));
            }
        }
예제 #13
0
        public AILEmitterCtx(
            ATranslator Translator,
            ABlock[]    Graph,
            ABlock Root,
            string SubName)
        {
            if (Translator == null)
            {
                throw new ArgumentNullException(nameof(Translator));
            }

            if (Graph == null)
            {
                throw new ArgumentNullException(nameof(Graph));
            }

            if (Root == null)
            {
                throw new ArgumentNullException(nameof(Root));
            }

            this.Translator = Translator;
            this.Graph      = Graph;
            this.Root       = Root;

            Callees = new HashSet <long>();

            Labels = new Dictionary <long, AILLabel>();

            Emitter = new AILEmitter(Graph, Root, SubName);

            ILBlock = Emitter.GetILBlock(0);

            OpcIndex = -1;

            if (Graph.Length == 0 || !AdvanceOpCode())
            {
                throw new ArgumentException(nameof(Graph));
            }
        }
예제 #14
0
        private void StoreLocals(AILEmitter Context, long Outputs, ARegisterType BaseType)
        {
            for (int Bit = 0; Bit < 64; Bit++)
            {
                long Mask = 1L << Bit;

                if ((Outputs & Mask) != 0)
                {
                    ARegister Reg = AILEmitter.GetRegFromBit(Bit, BaseType);

                    Context.Generator.EmitLdarg(ATranslatedSub.RegistersArgIdx);
                    Context.Generator.EmitLdloc(Context.GetLocalIndex(Reg));

                    AILConv.EmitConv(
                        Context,
                        Context.GetLocalType(Reg),
                        Context.GetFieldType(Reg.Type));

                    Context.Generator.Emit(OpCodes.Stfld, Reg.GetField());
                }
            }
        }
예제 #15
0
        public void Add(IAILEmit ILEmitter)
        {
            if (ILEmitter is AILBarrier)
            {
                //Those barriers are used to separate the groups of CIL
                //opcodes emitted by each ARM instruction.
                //We can only consider the new outputs for doing input elimination
                //after all the CIL opcodes used by the instruction being emitted.
                IntAwOutputs = IntOutputs;
                VecAwOutputs = VecOutputs;
            }
            else if (ILEmitter is AILOpCodeLoad Ld && AILEmitter.IsRegIndex(Ld.Index))
            {
                switch (Ld.IoType)
                {
                case AIoType.Flag:   IntInputs |= ((1L << Ld.Index) << 32) & ~IntAwOutputs; break;

                case AIoType.Int:    IntInputs |= (1L << Ld.Index) & ~IntAwOutputs; break;

                case AIoType.Vector: VecInputs |= (1L << Ld.Index) & ~VecAwOutputs; break;
                }
            }
예제 #16
0
        public AILEmitterCtx(
            ATranslatorCache Cache,
            ABlock[]         Graph,
            ABlock Root,
            string SubName)
        {
            this.Cache = Cache ?? throw new ArgumentNullException(nameof(Cache));
            this.Graph = Graph ?? throw new ArgumentNullException(nameof(Graph));
            this.Root  = Root ?? throw new ArgumentNullException(nameof(Root));

            Labels = new Dictionary <long, AILLabel>();

            Emitter = new AILEmitter(Graph, Root, SubName);

            ILBlock = Emitter.GetILBlock(0);

            OpcIndex = -1;

            if (Graph.Length == 0 || !AdvanceOpCode())
            {
                throw new ArgumentException(nameof(Graph));
            }
        }
예제 #17
0
        public void Emit(AILEmitter Context)
        {
            switch (IoType)
            {
            case AIoType.Arg: Context.Generator.EmitLdarg(Index); break;

            case AIoType.Fields:
            {
                long IntInputs = Context.LocalAlloc.GetIntInputs(Context.GetILBlock(Index));
                long VecInputs = Context.LocalAlloc.GetVecInputs(Context.GetILBlock(Index));

                LoadLocals(Context, IntInputs, ARegisterType.Int);
                LoadLocals(Context, VecInputs, ARegisterType.Vector);

                break;
            }

            case AIoType.Flag:   EmitLdloc(Context, Index, ARegisterType.Flag);   break;

            case AIoType.Int:    EmitLdloc(Context, Index, ARegisterType.Int);    break;

            case AIoType.Vector: EmitLdloc(Context, Index, ARegisterType.Vector); break;
            }
        }
예제 #18
0
 private void EmitLdarg(AILEmitter Context, int Index)
 {
     Context.Generator.EmitLdarg(Index);
 }
예제 #19
0
 private static void EmitScalarLdfld(AILEmitter Context, string FldName)
 {
     Context.Generator.Emit(OpCodes.Ldfld, typeof(AVec).GetField(FldName));
 }
예제 #20
0
        public static void EmitConv(AILEmitter Context, Type SrcType, Type TgtType)
        {
            if (SrcType == TgtType)
            {
                //If both types are equal we don't need to cast anything.
                return;
            }

            if (SrcType.IsPrimitive)
            {
                if (TgtType == typeof(byte))
                {
                    Context.Generator.Emit(OpCodes.Conv_U1);
                }
                else if (TgtType == typeof(ushort))
                {
                    Context.Generator.Emit(OpCodes.Conv_U2);
                }
                else if (TgtType == typeof(uint))
                {
                    Context.Generator.Emit(OpCodes.Conv_U4);
                }
                else if (TgtType == typeof(ulong))
                {
                    Context.Generator.Emit(OpCodes.Conv_U8);
                }
                else if (TgtType == typeof(float))
                {
                    Context.Generator.Emit(OpCodes.Conv_R4);
                }
                else if (TgtType == typeof(double))
                {
                    Context.Generator.Emit(OpCodes.Conv_R8);
                }
                else if (TgtType == typeof(AVec))
                {
                    EmitMakeVec(Context, SrcType);
                }
                else
                {
                    throw new ArgumentException(nameof(TgtType));
                }
            }
            else if (SrcType == typeof(AVec))
            {
                if (TgtType == typeof(float))
                {
                    EmitScalarLdfld(Context, nameof(AVec.S0));
                }
                else if (TgtType == typeof(double))
                {
                    EmitScalarLdfld(Context, nameof(AVec.D0));
                }
                else if (TgtType == typeof(byte))
                {
                    EmitScalarLdfld(Context, nameof(AVec.B0));
                }
                else if (TgtType == typeof(ushort))
                {
                    EmitScalarLdfld(Context, nameof(AVec.H0));
                }
                else if (TgtType == typeof(uint))
                {
                    EmitScalarLdfld(Context, nameof(AVec.W0));
                }
                else if (TgtType == typeof(ulong))
                {
                    EmitScalarLdfld(Context, nameof(AVec.X0));
                }
                else
                {
                    throw new ArgumentException(nameof(TgtType));
                }
            }
            else
            {
                throw new ArgumentException(nameof(SrcType));
            }
        }
예제 #21
0
 public void Emit(AILEmitter Context)
 {
     Context.Generator.Emit(ILOp);
 }
예제 #22
0
 public void Emit(AILEmitter Context)
 {
     Context.Generator.MarkLabel(GetLabel(Context));
 }
예제 #23
0
 public void Emit(AILEmitter Context)
 {
     Context.Generator.Emit(OpCodes.Call, MthdInfo);
 }
예제 #24
0
 public void Emit(AILEmitter Context)
 {
     Context.Generator.Emit(ILOp, Label.GetLabel(Context));
 }