示例#1
0
 // Move From/to Vfpu (C?)_
 public void mfv()
 {
     MipsMethodEmiter.SaveGPR_F(RT, () =>
     {
         Load_VD(0, 1);
     });
 }
示例#2
0
        // Jump (And Link) (Register).
        public void j()
        {
            //Console.WriteLine("JUMP_ADDR: {0:X}", GetJumpAddress());
            MipsMethodEmiter.SavePC(() =>
            {
                MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ldc_I4, GetJumpAddress());
            });

            //Console.WriteLine("aaaaaaaaaaaaaa");

            if (CpuProcessor.PspConfig.TraceJal)
            {
                MipsMethodEmiter.ILGenerator.EmitWriteLine(String.Format("{0:X} : JAL 0x{0:X}", PC, GetJumpAddress()));
            }

            //MipsMethodEmiter.ILGenerator.Emit(OpCodes.Jmp);
            //MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ldarg_0);
            //MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ldobj, (object)CpuProcessor.CreateAndCacheDelegateForPC(MemoryStream, GetJumpAddress()));
            //var FieldBuilder = MipsMethodEmiter.TypeBuilder.DefineField("testField", typeof(int), FieldAttributes.Static);
            //FieldBuilder.SetValue(null, CpuProcessor.CreateAndCacheDelegateForPC(MemoryStream, GetJumpAddress()));
            //FieldBuilder.SetValue(null, 1);

            //MipsMethodEmiter.ILGenerator.Emit(OpCodes.Callvirt);


            MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ret);
        }
示例#3
0
 public CpuEmiter(MipsMethodEmiter MipsMethodEmiter, InstructionReader InstructionReader, Stream MemoryStream, CpuProcessor CpuProcessor)
 {
     this.MipsMethodEmiter = MipsMethodEmiter;
     this.InstructionReader = InstructionReader;
     this.MemoryStream = MemoryStream;
     this.CpuProcessor = CpuProcessor;
 }
示例#4
0
 public void abs_s()
 {
     MipsMethodEmiter.OP_2REG_F(FD, FS, () =>
     {
         MipsMethodEmiter.ILGenerator.Emit(OpCodes.Call, typeof(CpuEmiter).GetMethod("abs_s_impl"));
     });
 }
示例#5
0
 public CpuEmiter(MipsMethodEmiter MipsMethodEmiter, InstructionReader InstructionReader, Stream MemoryStream, CpuProcessor CpuProcessor)
 {
     this.MipsMethodEmiter  = MipsMethodEmiter;
     this.InstructionReader = InstructionReader;
     this.MemoryStream      = MemoryStream;
     this.CpuProcessor      = CpuProcessor;
 }
示例#6
0
        /*
         * if (enabled && prefix.enabled) {
         *      foreach (i, value; src) {
         *              if (prefix.mask(i)) continue;
         *
         *              switch (prefix.saturation(i)) {
         *                      case 1: value = clamp!(float)(value,  0.0, 1.0); break;
         *                      case 3: value = clamp!(float)(value, -1.0, 1.0); break;
         *                      default: break;
         *              }
         *
         * dst[i] = value;
         *      }
         *      prefix.enabled = false;
         * } else {
         *      foreach (i, value; src) *dst[i] = value;
         * }
         */

        private void VfpuSave_Register(uint Register, int Index, uint VectorSize, VfpuPrefix Prefix, Action Action, bool Debug = false)
        {
            CheckPrefixUsage(ref Prefix);
            _VfpuLoadVectorWithIndexPointer(Register, (uint)Index, VectorSize, Debug);
            {
                Action();
                if (Prefix.Enabled)
                {
                    if (!Prefix.DestinationMask(Index))
                    {
                        float Min = 0, Max = 0;
                        bool  DoClamp = false;
                        switch (Prefix.DestinationSaturation(Index))
                        {
                        case 1: DoClamp = true; Min = 0.0f; Max = 1.0f; break;

                        case 3: DoClamp = true; Min = -1.0f; Max = 1.0f; break;

                        default: break;
                        }
                        if (DoClamp)
                        {
                            MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ldc_R4, Min);
                            MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ldc_R4, Max);
                            MipsMethodEmiter.CallMethod(typeof(MathFloat), "Clamp");
                        }
                    }
                }
            }
            MipsMethodEmiter.ILGenerator.Emit(OpCodes.Stind_R4);
        }
示例#7
0
        /*
         * registers[instruction.RT] = (
         *     (registers[instruction.RT] & 0x_0000_FFFF) |
         *     ((memory.tread!(ushort)(registers[instruction.RS] + instruction.IMM - 1) << 16) & 0x_FFFF_0000)
         * );
         */
        public void lwl()
        {
            MipsMethodEmiter.SaveGPR(RT, () =>
            {
                // registers[instruction.RT] & 0x_0000_FFFF
                MipsMethodEmiter.LoadGPR_Unsigned(RT);
                MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ldc_I4, 0x0000FFFF);
                MipsMethodEmiter.ILGenerator.Emit(OpCodes.And);

                // ((memory.tread!(ushort)(registers[instruction.RS] + instruction.IMM - 1) << 16) & 0x_FFFF_0000)
                _save_pc();
                MipsMethodEmiter._getmemptr(() =>
                {
                    MipsMethodEmiter.LoadGPR_Unsigned(RS);
                    MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ldc_I4, IMM - 1);
                    MipsMethodEmiter.ILGenerator.Emit(OpCodes.Add);
                });
                MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ldind_I2);
                MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ldc_I4, 16);
                MipsMethodEmiter.ILGenerator.Emit(OpCodes.Shl);
                MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ldc_I4, 0xFFFF0000);
                MipsMethodEmiter.ILGenerator.Emit(OpCodes.And);

                // OR
                MipsMethodEmiter.ILGenerator.Emit(OpCodes.Or);
            });
        }
示例#8
0
 public void divu()
 {
     MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ldarg_0);
     MipsMethodEmiter.LoadGPR_Unsigned(RS);
     MipsMethodEmiter.LoadGPR_Unsigned(RT);
     MipsMethodEmiter.ILGenerator.Emit(OpCodes.Call, typeof(CpuEmiter).GetMethod("_divu_impl"));
 }
示例#9
0
 private void _save_pc()
 {
     if (!(MipsMethodEmiter.Processor.Memory is FastPspMemory))
     {
         MipsMethodEmiter.SavePC(PC);
     }
 }
示例#10
0
 public void bc1t()
 {
     MipsMethodEmiter.StoreBranchFlag(() =>
     {
         MipsMethodEmiter.LoadFCR31_CC();
     });
 }
示例#11
0
 public void _mult_common(OpCode ConvOp)
 {
     MipsMethodEmiter.SaveHI_LO(() =>
     {
         _mult_common_op(ConvOp);
     });
 }
示例#12
0
        private void lv_sv_l_r_q(bool left, bool save)
        {
            var vt  = Instruction.VT5 | (Instruction.VT1 << 5);
            var m   = (vt >> 2) & 7;
            var i   = (vt >> 0) & 3;
            var dir = (vt & 32) != 0;

            {
                MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ldarg_0);                 // CpuThreadState
                MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ldc_I4, m);
                MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ldc_I4, i);
                MipsMethodEmiter.LoadGPR_Unsigned(RS);
                MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ldc_I4, Instruction.IMM14 * 4);
                MipsMethodEmiter.ILGenerator.Emit(OpCodes.Add);
                MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ldc_I4, dir ? 1 : 0);
                MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ldc_I4, save ? 1 : 0);
            }

            if (left)
            {
                MipsMethodEmiter.CallMethod(this.GetType(), "_lvl_svl_q");
            }
            else
            {
                MipsMethodEmiter.CallMethod(this.GetType(), "_lvr_svr_q");
            }
        }
示例#13
0
 public void mtic()
 {
     //throw (new NotImplementedException());
     MipsMethodEmiter.SaveFieldI4(typeof(CpuThreadState).GetField("IC"), () =>
     {
         MipsMethodEmiter.LoadGPR_Unsigned(RT);
     });
 }
示例#14
0
 private void _save_i(OpCode OpCode)
 {
     _save_common(() =>
     {
         MipsMethodEmiter.LoadGPR_Unsigned(RT);
         MipsMethodEmiter.ILGenerator.Emit(OpCode);
     });
 }
示例#15
0
 public void swc1()
 {
     _save_common(() =>
     {
         MipsMethodEmiter.LoadFPR_I(FT);
         MipsMethodEmiter.ILGenerator.Emit(OpCodes.Stind_I4);
     });
 }
示例#16
0
 public void wsbw()
 {
     MipsMethodEmiter.SaveGPR(RD, () =>
     {
         MipsMethodEmiter.LoadGPR_Unsigned(RT);
         MipsMethodEmiter.ILGenerator.Emit(OpCodes.Call, typeof(CpuEmiter).GetMethod("_wsbw_impl"));
     });
 }
示例#17
0
 private void _link()
 {
     //Console.WriteLine("LINK: {0:X}", PC);
     MipsMethodEmiter.SaveGPR(31, () =>
     {
         MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ldc_I4, PC + 8);
     });
 }
示例#18
0
 public void ceil_w_s()
 {
     MipsMethodEmiter.SaveFPR_I(FD, () =>
     {
         MipsMethodEmiter.LoadFPR(FS);
         MipsMethodEmiter.CallMethod(typeof(MathFloat), "Ceil");
     });
 }
示例#19
0
 /////////////////////////////////////////////////////////////////////////////////////////////////
 // MULTiply (Unsigned).
 /////////////////////////////////////////////////////////////////////////////////////////////////
 public void _mult_common_op(OpCode ConvOp)
 {
     MipsMethodEmiter.LoadGPR_Signed(RS);
     MipsMethodEmiter.ILGenerator.Emit(ConvOp);
     MipsMethodEmiter.LoadGPR_Signed(RT);
     MipsMethodEmiter.ILGenerator.Emit(ConvOp);
     MipsMethodEmiter.ILGenerator.Emit(OpCodes.Mul);
 }
示例#20
0
 public void mtc1()
 {
     MipsMethodEmiter.SaveFPR(FS, () =>
     {
         MipsMethodEmiter.LoadGPR_Signed(RT);
         MipsMethodEmiter.ILGenerator.Emit(OpCodes.Call, typeof(MathFloat).GetMethod("ReinterpretIntAsFloat"));
     });
 }
示例#21
0
 // Move (from/to) float point registers (reinterpreted)
 public void mfc1()
 {
     MipsMethodEmiter.SaveGPR(RT, () =>
     {
         MipsMethodEmiter.LoadFPR(FS);
         MipsMethodEmiter.ILGenerator.Emit(OpCodes.Call, typeof(MathFloat).GetMethod("ReinterpretFloatAsInt"));
     });
 }
示例#22
0
 public void rotrv()
 {
     MipsMethodEmiter.SaveGPR(RD, () =>
     {
         MipsMethodEmiter.LoadGPR_Unsigned(RT);
         MipsMethodEmiter.LoadGPR_Unsigned(RS);
         MipsMethodEmiter.CallMethod(this.GetType(), "_rotr");
     });
 }
示例#23
0
 /////////////////////////////////////////////////////////////////////////////////////////////////
 // BIT REVerse.
 /////////////////////////////////////////////////////////////////////////////////////////////////
 public void bitrev()
 {
     MipsMethodEmiter.SaveGPR(RD, () =>
     {
         MipsMethodEmiter.LoadGPR_Unsigned(RT);
         MipsMethodEmiter.ILGenerator.Emit(OpCodes.Call, typeof(CpuEmiter).GetMethod("bitrev_impl"));
     });
     //throw (new NotImplementedException());
 }
示例#24
0
 // Branch on C1 False/True (Likely).
 public void bc1f()
 {
     MipsMethodEmiter.StoreBranchFlag(() =>
     {
         MipsMethodEmiter.LoadFCR31_CC();
         MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ldc_I4_0);
         MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ceq);
     });
 }
示例#25
0
 /// <summary>
 /// Convert FS register (stored as an int) to float and stores the result on FD.
 /// </summary>
 public void cvt_s_w()
 {
     MipsMethodEmiter.SaveFPR(FD, () =>
     {
         MipsMethodEmiter.LoadFPR(FS);
         MipsMethodEmiter.ILGenerator.Emit(OpCodes.Call, typeof(MathFloat).GetMethod("ReinterpretFloatAsInt"));
         MipsMethodEmiter.ILGenerator.Emit(OpCodes.Conv_R4);
     });
 }
示例#26
0
 // Move (From/To) IC
 public void mfic()
 {
     //throw (new NotImplementedException());
     MipsMethodEmiter.SaveGPR(RT, () =>
     {
         MipsMethodEmiter.LoadFieldPtr(typeof(CpuThreadState).GetField("IC"));
         MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ldind_I4);
     });
 }
示例#27
0
 public void seh()
 {
     MipsMethodEmiter.SaveGPR(RD, () =>
     {
         MipsMethodEmiter.LoadGPR_Unsigned(RT);
         MipsMethodEmiter.ILGenerator.Emit(OpCodes.Conv_I2);
         //MipsMethodEmiter.ILGenerator.Emit(OpCodes.Conv_I4);
     });
 }
示例#28
0
 private void _load_memory_imm14_index(uint Index)
 {
     MipsMethodEmiter._getmemptr(() =>
     {
         MipsMethodEmiter.LoadGPR_Unsigned(RS);
         MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ldc_I4, Instruction.IMM14 * 4 + Index * 4);
         MipsMethodEmiter.ILGenerator.Emit(OpCodes.Add);
     });
 }
示例#29
0
 public void rotr()
 {
     MipsMethodEmiter.SaveGPR(RD, () =>
     {
         MipsMethodEmiter.LoadGPR_Unsigned(RT);
         MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ldc_I4, Instruction.POS);
         MipsMethodEmiter.CallMethod(this.GetType(), "_rotr");
     });
     //$rd = ROTR($rt, $ps);
 }
示例#30
0
 public void ext()
 {
     MipsMethodEmiter.SaveGPR(RT, () =>
     {
         MipsMethodEmiter.LoadGPR_Unsigned(RS);
         MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ldc_I4, Instruction.POS);
         MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ldc_I4, Instruction.SIZE_E);
         MipsMethodEmiter.ILGenerator.Emit(OpCodes.Call, typeof(CpuEmiter).GetMethod("_ext_impl"));
     });
 }
示例#31
0
        /////////////////////////////////////////////////////////////////////////////////////////////////
        // Move if Zero/Non zero.
        /////////////////////////////////////////////////////////////////////////////////////////////////
        private void _movzn(OpCode OpCode)
        {
            var SkipMoveLabel = MipsMethodEmiter.ILGenerator.DefineLabel();

            MipsMethodEmiter.LoadGPR_Unsigned(RT);
            MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ldc_I4_0);
            MipsMethodEmiter.ILGenerator.Emit(OpCode, SkipMoveLabel);
            MipsMethodEmiter.SET_REG(RD, RS);
            MipsMethodEmiter.ILGenerator.MarkLabel(SkipMoveLabel);
        }
        public DynarecFunction CreateFunction(IInstructionReader InstructionReader, uint PC, Action<uint> ExploreNewPcCallback = null, bool DoDebug = false, bool DoLog = false)
        {
            DynarecFunction DynarecFunction;

            //var Stopwatch = new Logger.Stopwatch();
            //Stopwatch.Tick();

            var MipsMethodEmiter = new MipsMethodEmiter(CpuProcessor, PC, DoDebug, DoLog);
            var InternalFunctionCompiler = new InternalFunctionCompiler(CpuProcessor, MipsMethodEmiter, this, InstructionReader, ExploreNewPcCallback, PC, DoLog);
            DynarecFunction = InternalFunctionCompiler.CreateFunction();

            //Stopwatch.Tick();
            //Console.WriteLine("Function at PC 0x{0:X} generated in {1}", PC, Stopwatch);

            return DynarecFunction;
        }
示例#33
0
 public void CreateDelegateTest()
 {
     var PspConfig = new PspConfig();
     var PspEmulatorContext = new PspEmulatorContext(PspConfig);
     PspEmulatorContext.SetInstanceType<PspMemory, LazyPspMemory>();
     var Memory = PspEmulatorContext.GetInstance<PspMemory>();
     var Processor = PspEmulatorContext.GetInstance<CpuProcessor>();
     var CpuThreadState = new CpuThreadState(Processor);
     var MipsEmiter = new MipsMethodEmiter(new MipsEmiter(), Processor, 0);
     CpuThreadState.GPR[1] = 1;
     CpuThreadState.GPR[2] = 2;
     CpuThreadState.GPR[3] = 3;
     MipsEmiter.OP_3REG_Unsigned(1, 2, 2, () => { MipsEmiter.SafeILGenerator.BinaryOperation(SafeBinaryOperator.AdditionSigned); });
     MipsEmiter.OP_3REG_Unsigned(0, 2, 2, () => { MipsEmiter.SafeILGenerator.BinaryOperation(SafeBinaryOperator.AdditionSigned); });
     MipsEmiter.OP_2REG_IMM_Signed(10, 0, 1000, () => { MipsEmiter.SafeILGenerator.BinaryOperation(SafeBinaryOperator.AdditionSigned); });
     MipsEmiter.CreateDelegate()(CpuThreadState);
     Assert.AreEqual(4, CpuThreadState.GPR[1]);
     Assert.AreEqual(0, CpuThreadState.GPR[0]);
     Assert.AreEqual(1000, CpuThreadState.GPR[10]);
 }
示例#34
0
        private Action<CpuThreadState> CreateDelegateForMethodInfo(MethodInfo MethodInfo, HlePspFunctionAttribute HlePspFunctionAttribute)
        {
            var MipsMethodEmiter = new MipsMethodEmiter(HleState.MipsEmiter, HleState.CpuProcessor);
            int GprIndex = 4;
            int FprIndex = 0;

            var NotImplementedAttribute = (HlePspNotImplementedAttribute)MethodInfo.GetCustomAttributes(typeof(HlePspNotImplementedAttribute), true).FirstOrDefault();
            bool NotImplemented = (NotImplementedAttribute != null) ? NotImplementedAttribute.Notice : false;
            bool SkipLog = HlePspFunctionAttribute.SkipLog;

            var ParamInfoList = new List<ParamInfo>();

            Action CallAction = () =>
            {
                MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ldarg_0);
                MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ldfld, typeof(CpuThreadState).GetField("ModuleObject"));
                MipsMethodEmiter.ILGenerator.Emit(OpCodes.Castclass, this.GetType());
                foreach (var ParameterInfo in MethodInfo.GetParameters())
                {
                    var ParameterType = ParameterInfo.ParameterType;

                    // The CpuThreadState
                    if (ParameterType == typeof(CpuThreadState))
                    {
                        MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ldarg_0);
                    }
                    // A stringz
                    else if (ParameterType == typeof(string))
                    {
                        ParamInfoList.Add(new ParamInfo()
                        {
                            ParameterName = ParameterInfo.Name,
                            RegisterType = ParamInfo.RegisterTypeEnum.Gpr,
                            RegisterIndex = GprIndex,
                            ParameterType = ParameterType,
                        });
                        MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ldarg_0);
                        MipsMethodEmiter.LoadGPR_Unsigned(GprIndex);
                        MipsMethodEmiter.ILGenerator.Emit(OpCodes.Call, typeof(HleModuleHost).GetMethod("StringFromAddress"));
                        GprIndex++;
                    }
                    // A pointer
                    else if (ParameterType.IsPointer)
                    {
                        ParamInfoList.Add(new ParamInfo()
                        {
                            ParameterName = ParameterInfo.Name,
                            RegisterType = ParamInfo.RegisterTypeEnum.Gpr,
                            RegisterIndex = GprIndex,
                            ParameterType = typeof(uint),
                        });
                        MipsMethodEmiter._getmemptr(() =>
                        {
                            MipsMethodEmiter.LoadGPR_Unsigned(GprIndex);
                        }, Safe: true);
                        GprIndex++;
                    }
                    // A long type
                    else if (ParameterType == typeof(long) || ParameterType == typeof(ulong))
                    {
                        while (GprIndex % 2 != 0) GprIndex++;

                        ParamInfoList.Add(new ParamInfo()
                        {
                            ParameterName = ParameterInfo.Name,
                            RegisterType = ParamInfo.RegisterTypeEnum.Gpr,
                            RegisterIndex = GprIndex,
                            ParameterType = ParameterType,
                        });

                        MipsMethodEmiter.LoadGPRLong_Signed(GprIndex + 0);
                        /*
                        MipsMethodEmiter.LoadGPR_Unsigned(GprIndex + 0);
                        MipsMethodEmiter.LoadGPR_Unsigned(GprIndex + 1);
                        MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ldc_I4, 32);
                        MipsMethodEmiter.ILGenerator.Emit(OpCodes.Shl);
                        MipsMethodEmiter.ILGenerator.Emit(OpCodes.Or);
                        */
                        GprIndex += 2;
                    }
                    // A float register.
                    else if (ParameterType == typeof(float))
                    {
                        ParamInfoList.Add(new ParamInfo()
                        {
                            ParameterName = ParameterInfo.Name,
                            RegisterType = ParamInfo.RegisterTypeEnum.Fpr,
                            RegisterIndex = FprIndex,
                            ParameterType = ParameterType,
                        });

                        MipsMethodEmiter.LoadFPR(FprIndex);
                        FprIndex++;
                    }
                    // An integer register
                    else
                    {
                        ParamInfoList.Add(new ParamInfo()
                        {
                            ParameterName = ParameterInfo.Name,
                            RegisterType = ParamInfo.RegisterTypeEnum.Gpr,
                            RegisterIndex = GprIndex,
                            ParameterType = ParameterType,
                        });

                        MipsMethodEmiter.LoadGPR_Unsigned(GprIndex);
                        GprIndex++;
                    }
                    //MipsMethodEmiter.ILGenerator.Emit(OpCodes.ld
                }
                MipsMethodEmiter.ILGenerator.Emit(OpCodes.Call, MethodInfo);
            };

            if (MethodInfo.ReturnType == typeof(void))
            {
                CallAction();
            }
            else if (MethodInfo.ReturnType == typeof(long))
            {
                MipsMethodEmiter.SaveGPRLong(2, CallAction);
            }
            else
            {
                MipsMethodEmiter.SaveGPR(2, CallAction);
            }

            var Delegate = MipsMethodEmiter.CreateDelegate();
            return (CpuThreadState) =>
            {
                bool Trace = (!SkipLog && CpuThreadState.CpuProcessor.PspConfig.DebugSyscalls);

                if (NotImplemented)
                {
                    Trace = true;
                    ConsoleUtils.SaveRestoreConsoleState(() =>
                    {
                        Console.ForegroundColor = ConsoleColor.Yellow;
                        Console.WriteLine(
                            "Not implemented {0}.{1}",
                            MethodInfo.DeclaringType.Name, MethodInfo.Name
                        );
                    });
                }

                var Out = Console.Out;
                if (NotImplemented)
                {
                    Out = Console.Error;
                }

                if (Trace)
                {
                    if (HleState.ThreadManager.Current != null)
                    {
                        Out.Write(
                            "Thread({0}:'{1}') : RA(0x{2:X})",
                            HleState.ThreadManager.Current.Id,
                            HleState.ThreadManager.Current.Name,
                            HleState.ThreadManager.Current.CpuThreadState.RA
                        );
                    }
                    else
                    {
                        Out.Write("NoThread:");
                    }
                    Out.Write(" : {0}.{1}", MethodInfo.DeclaringType.Name, MethodInfo.Name);
                    Out.Write("(");
                    int Count = 0;
                    foreach (var ParamInfo in ParamInfoList)
                    {
                        if (Count > 0) Out.Write(", ");
                        Out.Write("{0}:", ParamInfo.ParameterName);
                        switch (ParamInfo.RegisterType)
                        {
                            case HleModuleHost.ParamInfo.RegisterTypeEnum.Fpr:
                            case HleModuleHost.ParamInfo.RegisterTypeEnum.Gpr:
                                uint Int4 = (uint)CpuThreadState.GPR[ParamInfo.RegisterIndex];
                                uint Float4 = (uint)CpuThreadState.FPR[ParamInfo.RegisterIndex];
                                Out.Write("{0}", ToNormalizedTypeString(ParamInfo.ParameterType, CpuThreadState, Int4, Float4));
                                break;
                            default:
                                throw(new NotImplementedException());
                        }
                        Count++;
                    }
                    Out.Write(")");
                    //Console.WriteLine("");
                }

                CpuThreadState.ModuleObject = this;
                try
                {
                    Delegate(CpuThreadState);
                }
                catch (SceKernelException SceKernelException)
                {
                    CpuThreadState.GPR[2] = (int)SceKernelException.SceKernelError;
                }
                catch (SceKernelSelfStopUnloadModuleException SceKernelSelfStopUnloadModuleException)
                {
                    throw (SceKernelSelfStopUnloadModuleException);
                }
                catch (Exception Exception)
                {
                    throw (new Exception(
                        String.Format("ERROR calling {0}.{1}!", MethodInfo.DeclaringType.Name, MethodInfo.Name),
                        Exception
                    ));
                }
                finally
                {
                    if (Trace)
                    {
                        Out.WriteLine(" : {0}", ToNormalizedTypeString(MethodInfo.ReturnType, CpuThreadState, (uint)CpuThreadState.GPR[2], (float)CpuThreadState.FPR[0]));
                        Out.WriteLine("");
                    }
                }
            };
        }
示例#35
0
        private Action<CpuThreadState> CreateDelegateForMethodInfo(MethodInfo MethodInfo, HlePspFunctionAttribute HlePspFunctionAttribute)
        {
            var MipsMethodEmiter = new MipsMethodEmiter(CpuProcessor, 0);
            int GprIndex = 4;
            int FprIndex = 0;

            var NotImplementedAttribute = (HlePspNotImplementedAttribute)MethodInfo.GetCustomAttributes(typeof(HlePspNotImplementedAttribute), true).FirstOrDefault();
            bool NotImplementedFunc = (NotImplementedAttribute != null) ? NotImplementedAttribute.Notice : false;
            bool SkipLog = HlePspFunctionAttribute.SkipLog;
            var SafeILGenerator = MipsMethodEmiter.SafeILGenerator;
            SafeILGenerator.Comment("HleModuleHost.CreateDelegateForMethodInfo(" + MethodInfo + ", " + HlePspFunctionAttribute + ")");

            var ParamInfoList = new List<ParamInfo>();

            Action CallAction = () =>
            {
                SafeILGenerator.LoadArgument0CpuThreadState();
                SafeILGenerator.LoadField(typeof(CpuThreadState).GetField("ModuleObject"));
                SafeILGenerator.CastClass(this.GetType());
                foreach (var ParameterInfo in MethodInfo.GetParameters())
                {
                    var ParameterType = ParameterInfo.ParameterType;

                    // The CpuThreadState
                    if (ParameterType == typeof(CpuThreadState))
                    {
                        SafeILGenerator.LoadArgument0CpuThreadState();
                    }
                    // A stringz
                    else if (ParameterType == typeof(string))
                    {
                        ParamInfoList.Add(new ParamInfo()
                        {
                            ParameterName = ParameterInfo.Name,
                            RegisterType = ParamInfo.RegisterTypeEnum.Gpr,
                            RegisterIndex = GprIndex,
                            ParameterType = ParameterType,
                        });
                        SafeILGenerator.LoadArgument0CpuThreadState();
                        MipsMethodEmiter.LoadGPR_Unsigned(GprIndex);
                        SafeILGenerator.Call(typeof(HleModuleHost).GetMethod("StringFromAddress"));
                        GprIndex++;
                    }
                    // A pointer or ref/out
                    else if (ParameterType.IsPointer || ParameterType.IsByRef)
                    {
                        ParamInfoList.Add(new ParamInfo()
                        {
                            ParameterName = ParameterInfo.Name,
                            RegisterType = ParamInfo.RegisterTypeEnum.Gpr,
                            RegisterIndex = GprIndex,
                            ParameterType = typeof(uint),
                        });
                        MipsMethodEmiter._getmemptr(() =>
                        {
                            MipsMethodEmiter.LoadGPR_Unsigned(GprIndex);
                        }, Safe: true, ErrorDescription: "Invalid Pointer for Argument '" + ParameterType.Name + " " + ParameterInfo.Name + "'");
                        GprIndex++;
                    }
                    /*
                    // An array
                    else if (ParameterType.IsArray)
                    {
                        ParamInfoList.Add(new ParamInfo()
                        {
                            ParameterName = ParameterInfo.Name,
                            RegisterType = ParamInfo.RegisterTypeEnum.Gpr,
                            RegisterIndex = GprIndex,
                            ParameterType = typeof(uint),
                        });
                        // Pointer
                        MipsMethodEmiter._getmemptr(() =>
                        {
                            MipsMethodEmiter.LoadGPR_Unsigned(GprIndex);
                        }, Safe: true, ErrorDescription: "Invalid Pointer for Argument '" + ParameterType.Name + " " + ParameterInfo.Name + "'");
                        GprIndex++;
                        // Array
                        MipsMethodEmiter.LoadGPR_Unsigned(GprIndex);
                        GprIndex++;
                        MipsMethodEmiter.CallMethod(HleModuleHost.PointerLengthToArrat);
                    }
                    */
                    // A long type
                    else if (ParameterType == typeof(long) || ParameterType == typeof(ulong))
                    {
                        while (GprIndex % 2 != 0) GprIndex++;

                        ParamInfoList.Add(new ParamInfo()
                        {
                            ParameterName = ParameterInfo.Name,
                            RegisterType = ParamInfo.RegisterTypeEnum.Gpr,
                            RegisterIndex = GprIndex,
                            ParameterType = ParameterType,
                        });

                        MipsMethodEmiter.LoadGPRLong_Signed(GprIndex + 0);
                        /*
                        MipsMethodEmiter.LoadGPR_Unsigned(GprIndex + 0);
                        MipsMethodEmiter.LoadGPR_Unsigned(GprIndex + 1);
                        SafeILGenerator.Push((int)32);
                        MipsMethodEmiter.ILGenerator.Emit(OpCodes.Shl);
                        MipsMethodEmiter.ILGenerator.Emit(OpCodes.Or);
                        */
                        GprIndex += 2;
                    }
                    // A float register.
                    else if (ParameterType == typeof(float))
                    {
                        ParamInfoList.Add(new ParamInfo()
                        {
                            ParameterName = ParameterInfo.Name,
                            RegisterType = ParamInfo.RegisterTypeEnum.Fpr,
                            RegisterIndex = FprIndex,
                            ParameterType = ParameterType,
                        });

                        MipsMethodEmiter.LoadFPR(FprIndex);
                        FprIndex++;
                    }
                    // Test
                    else if (ParameterType == typeof(PspPointer))
                    {
                        ParamInfoList.Add(new ParamInfo()
                        {
                            ParameterName = ParameterInfo.Name,
                            RegisterType = ParamInfo.RegisterTypeEnum.Gpr,
                            RegisterIndex = GprIndex,
                            ParameterType = ParameterType,
                        });

                        MipsMethodEmiter.LoadGPR_Unsigned(GprIndex);
                        MipsMethodEmiter.CallMethod(typeof(PspPointer).GetMethod("op_Implicit", new[] { typeof(uint) }));
                        GprIndex++;
                    }
                    // An integer register
                    else
                    {
                        ParamInfoList.Add(new ParamInfo()
                        {
                            ParameterName = ParameterInfo.Name,
                            RegisterType = ParamInfo.RegisterTypeEnum.Gpr,
                            RegisterIndex = GprIndex,
                            ParameterType = ParameterType,
                        });

                        MipsMethodEmiter.LoadGPR_Unsigned(GprIndex);
                        GprIndex++;
                    }
                    //MipsMethodEmiter.ILGenerator.Emit(OpCodes.ld
                }
                SafeILGenerator.Call(MethodInfo);
            };

            if (MethodInfo.ReturnType == typeof(void))
            {
                CallAction();
            }
            else if (MethodInfo.ReturnType == typeof(long))
            {
                MipsMethodEmiter.SaveGPRLong(2, CallAction);
            }
            else if (MethodInfo.ReturnType == typeof(float))
            {
                MipsMethodEmiter.SaveFPR(0, CallAction);
            }
            else
            {
                MipsMethodEmiter.SaveGPR(2, CallAction);
            }

            var Delegate = MipsMethodEmiter.CreateDelegate();
            return (CpuThreadState) =>
            {
                bool Trace = (!SkipLog && CpuThreadState.CpuProcessor.PspConfig.DebugSyscalls);
                bool NotImplemented = NotImplementedFunc && CpuThreadState.CpuProcessor.PspConfig.DebugNotImplemented;

                if (Trace && (MethodInfo.DeclaringType.Name == "Kernel_Library")) Trace = false;

                if (NotImplemented)
                {
                    Trace = true;
                    ConsoleUtils.SaveRestoreConsoleState(() =>
                    {
                        Console.ForegroundColor = ConsoleColor.Yellow;
                        Console.WriteLine(
                            "Not implemented {0}.{1}",
                            MethodInfo.DeclaringType.Name, MethodInfo.Name
                        );
                    });
                }

                var Out = Console.Out;
                if (NotImplemented)
                {
                    Out = Console.Error;
                }

                if (Trace)
                {
                    if (ThreadManager.Current != null)
                    {
                        Out.Write(
                            "Thread({0}:'{1}') : RA(0x{2:X})",
                            ThreadManager.Current.Id,
                            ThreadManager.Current.Name,
                            ThreadManager.Current.CpuThreadState.RA
                        );
                    }
                    else
                    {
                        Out.Write("NoThread:");
                    }
                    Out.Write(" : {0}.{1}", MethodInfo.DeclaringType.Name, MethodInfo.Name);
                    Out.Write("(");
                    int Count = 0;
                    foreach (var ParamInfo in ParamInfoList)
                    {
                        if (Count > 0) Out.Write(", ");
                        Out.Write("{0}:", ParamInfo.ParameterName);
                        switch (ParamInfo.RegisterType)
                        {
                            case HleModuleHost.ParamInfo.RegisterTypeEnum.Fpr:
                            case HleModuleHost.ParamInfo.RegisterTypeEnum.Gpr:
                                uint Int4 = (uint)CpuThreadState.GPR[ParamInfo.RegisterIndex];
                                uint Float4 = (uint)CpuThreadState.FPR[ParamInfo.RegisterIndex];
                                Out.Write("{0}", ToNormalizedTypeString(ParamInfo.ParameterType, CpuThreadState, Int4, Float4));
                                break;
                            default:
                                throw (new NotImplementedException());
                        }
                        Count++;
                    }
                    Out.Write(")");
                    //Console.WriteLine("");
                }

                CpuThreadState.ModuleObject = this;
                try
                {
                    Delegate(CpuThreadState);
                }
                catch (MemoryPartitionNoMemoryException)
                {
                    CpuThreadState.GPR[2] = (int)SceKernelErrors.ERROR_ERRNO_NO_MEMORY;
                }
                catch (SceKernelException SceKernelException)
                {
                    CpuThreadState.GPR[2] = (int)SceKernelException.SceKernelError;
                }
                catch (SceKernelSelfStopUnloadModuleException SceKernelSelfStopUnloadModuleException)
                {
                    throw (SceKernelSelfStopUnloadModuleException);
                }
            #if !DO_NOT_PROPAGATE_EXCEPTIONS
                catch (Exception Exception)
                {
                    throw (new Exception(
                        String.Format("ERROR calling {0}.{1}!", MethodInfo.DeclaringType.Name, MethodInfo.Name),
                        Exception
                    ));
                }
            #endif
                finally
                {
                    if (Trace)
                    {
                        Out.WriteLine(" : {0}", ToNormalizedTypeString(MethodInfo.ReturnType, CpuThreadState, (uint)CpuThreadState.GPR[2], (float)CpuThreadState.FPR[0]));
                        Out.WriteLine("");
                    }
                }
            };
        }
示例#36
0
 public CpuEmiter(MipsMethodEmiter MipsMethodEmiter, IInstructionReader InstructionReader, CpuProcessor CpuProcessor)
 {
     this.MipsMethodEmiter = MipsMethodEmiter;
     this.InstructionReader = InstructionReader;
     this.CpuProcessor = CpuProcessor;
 }