// Move From/to Vfpu (C?)_ public void mfv() { MipsMethodEmiter.SaveGPR_F(RT, () => { Load_VD(0, 1); }); }
// 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); }
public CpuEmiter(MipsMethodEmiter MipsMethodEmiter, InstructionReader InstructionReader, Stream MemoryStream, CpuProcessor CpuProcessor) { this.MipsMethodEmiter = MipsMethodEmiter; this.InstructionReader = InstructionReader; this.MemoryStream = MemoryStream; this.CpuProcessor = CpuProcessor; }
public void abs_s() { MipsMethodEmiter.OP_2REG_F(FD, FS, () => { MipsMethodEmiter.ILGenerator.Emit(OpCodes.Call, typeof(CpuEmiter).GetMethod("abs_s_impl")); }); }
/* * 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); }
/* * 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); }); }
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")); }
private void _save_pc() { if (!(MipsMethodEmiter.Processor.Memory is FastPspMemory)) { MipsMethodEmiter.SavePC(PC); } }
public void bc1t() { MipsMethodEmiter.StoreBranchFlag(() => { MipsMethodEmiter.LoadFCR31_CC(); }); }
public void _mult_common(OpCode ConvOp) { MipsMethodEmiter.SaveHI_LO(() => { _mult_common_op(ConvOp); }); }
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"); } }
public void mtic() { //throw (new NotImplementedException()); MipsMethodEmiter.SaveFieldI4(typeof(CpuThreadState).GetField("IC"), () => { MipsMethodEmiter.LoadGPR_Unsigned(RT); }); }
private void _save_i(OpCode OpCode) { _save_common(() => { MipsMethodEmiter.LoadGPR_Unsigned(RT); MipsMethodEmiter.ILGenerator.Emit(OpCode); }); }
public void swc1() { _save_common(() => { MipsMethodEmiter.LoadFPR_I(FT); MipsMethodEmiter.ILGenerator.Emit(OpCodes.Stind_I4); }); }
public void wsbw() { MipsMethodEmiter.SaveGPR(RD, () => { MipsMethodEmiter.LoadGPR_Unsigned(RT); MipsMethodEmiter.ILGenerator.Emit(OpCodes.Call, typeof(CpuEmiter).GetMethod("_wsbw_impl")); }); }
private void _link() { //Console.WriteLine("LINK: {0:X}", PC); MipsMethodEmiter.SaveGPR(31, () => { MipsMethodEmiter.ILGenerator.Emit(OpCodes.Ldc_I4, PC + 8); }); }
public void ceil_w_s() { MipsMethodEmiter.SaveFPR_I(FD, () => { MipsMethodEmiter.LoadFPR(FS); MipsMethodEmiter.CallMethod(typeof(MathFloat), "Ceil"); }); }
///////////////////////////////////////////////////////////////////////////////////////////////// // 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); }
public void mtc1() { MipsMethodEmiter.SaveFPR(FS, () => { MipsMethodEmiter.LoadGPR_Signed(RT); MipsMethodEmiter.ILGenerator.Emit(OpCodes.Call, typeof(MathFloat).GetMethod("ReinterpretIntAsFloat")); }); }
// 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")); }); }
public void rotrv() { MipsMethodEmiter.SaveGPR(RD, () => { MipsMethodEmiter.LoadGPR_Unsigned(RT); MipsMethodEmiter.LoadGPR_Unsigned(RS); MipsMethodEmiter.CallMethod(this.GetType(), "_rotr"); }); }
///////////////////////////////////////////////////////////////////////////////////////////////// // 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()); }
// 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); }); }
/// <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); }); }
// 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); }); }
public void seh() { MipsMethodEmiter.SaveGPR(RD, () => { MipsMethodEmiter.LoadGPR_Unsigned(RT); MipsMethodEmiter.ILGenerator.Emit(OpCodes.Conv_I2); //MipsMethodEmiter.ILGenerator.Emit(OpCodes.Conv_I4); }); }
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); }); }
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); }
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")); }); }
///////////////////////////////////////////////////////////////////////////////////////////////// // 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; }
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]); }
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(""); } } }; }
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(""); } } }; }
public CpuEmiter(MipsMethodEmiter MipsMethodEmiter, IInstructionReader InstructionReader, CpuProcessor CpuProcessor) { this.MipsMethodEmiter = MipsMethodEmiter; this.InstructionReader = InstructionReader; this.CpuProcessor = CpuProcessor; }