private static void EmitMemoryCall(ILEmitterCtx context, string name, int rn = -1) { context.EmitLdarg(TranslatedSub.MemoryArgIdx); context.EmitLdarg(TranslatedSub.StateArgIdx); context.EmitCallPropGet(typeof(CpuThreadState), nameof(CpuThreadState.Core)); if (rn != -1) { context.EmitLdint(rn); } context.EmitCall(typeof(MemoryManager), name); }
public static void Mrs(ILEmitterCtx context) { OpCodeSystem64 op = (OpCodeSystem64)context.CurrOp; context.EmitLdarg(TranslatedSub.StateArgIdx); string propName; switch (GetPackedId(op)) { case 0b11_011_0000_0000_001: propName = nameof(CpuThreadState.CtrEl0); break; case 0b11_011_0000_0000_111: propName = nameof(CpuThreadState.DczidEl0); break; case 0b11_011_0100_0100_000: propName = nameof(CpuThreadState.Fpcr); break; case 0b11_011_0100_0100_001: propName = nameof(CpuThreadState.Fpsr); break; case 0b11_011_1101_0000_010: propName = nameof(CpuThreadState.TpidrEl0); break; case 0b11_011_1101_0000_011: propName = nameof(CpuThreadState.Tpidr); break; case 0b11_011_1110_0000_000: propName = nameof(CpuThreadState.CntfrqEl0); break; case 0b11_011_1110_0000_001: propName = nameof(CpuThreadState.CntpctEl0); break; default: throw new NotImplementedException($"Unknown MRS at {op.Position:x16}"); } context.EmitCallPropGet(typeof(CpuThreadState), propName); PropertyInfo propInfo = typeof(CpuThreadState).GetProperty(propName); if (propInfo.PropertyType != typeof(long) && propInfo.PropertyType != typeof(ulong)) { context.Emit(OpCodes.Conv_U8); } context.EmitStintzr(op.Rt); }
private static void EmitExceptionCall(ILEmitterCtx context, string mthdName) { OpCodeException64 op = (OpCodeException64)context.CurrOp; context.EmitStoreState(); context.EmitLdarg(TranslatedSub.StateArgIdx); context.EmitLdc_I8(op.Position); context.EmitLdc_I4(op.Id); context.EmitPrivateCall(typeof(CpuThreadState), mthdName); //Check if the thread should still be running, if it isn't then we return 0 //to force a return to the dispatcher and then exit the thread. context.EmitLdarg(TranslatedSub.StateArgIdx); context.EmitCallPropGet(typeof(CpuThreadState), nameof(CpuThreadState.Running)); ILLabel lblEnd = new ILLabel(); context.Emit(OpCodes.Brtrue_S, lblEnd); context.EmitLdc_I8(0); context.Emit(OpCodes.Ret); context.MarkLabel(lblEnd); if (context.CurrBlock.Next != null) { context.EmitLoadState(context.CurrBlock.Next); } else { context.EmitLdc_I8(op.Position + 4); context.Emit(OpCodes.Ret); } }