private static void EmitSimdMemWBack(ILEmitterCtx context, int offset) { OpCodeMemReg64 op = (OpCodeMemReg64)context.CurrOp; context.EmitLdint(op.Rn); if (op.Rm != RegisterAlias.Zr) { context.EmitLdint(op.Rm); } else { context.EmitLdc_I8(offset); } context.Emit(OpCodes.Add); context.EmitStint(op.Rn); }
private static void EmitAluStore(ILEmitterCtx context) { IOpCode32Alu op = (IOpCode32Alu)context.CurrOp; if (op.Rd == RegisterAlias.Aarch32Pc) { if (op.SetFlags) { // TODO: Load SPSR etc. context.EmitLdflg((int)PState.TBit); ILLabel lblThumb = new ILLabel(); ILLabel lblEnd = new ILLabel(); context.Emit(OpCodes.Brtrue_S, lblThumb); context.EmitLdc_I4(~3); context.Emit(OpCodes.Br_S, lblEnd); context.MarkLabel(lblThumb); context.EmitLdc_I4(~1); context.MarkLabel(lblEnd); context.Emit(OpCodes.And); context.Emit(OpCodes.Conv_U8); context.Emit(OpCodes.Ret); } else { EmitAluWritePc(context); } } else { context.EmitStint(GetRegisterAlias(context.Mode, op.Rd)); } }
public static void Bl(ILEmitterCtx context) { OpCodeBImmAl64 op = (OpCodeBImmAl64)context.CurrOp; context.EmitLdc_I(op.Position + 4); context.EmitStint(CpuThreadState.LrIndex); context.EmitStoreState(); if (context.TryOptEmitSubroutineCall()) { //Note: the return value of the called method will be placed //at the Stack, the return value is always a Int64 with the //return address of the function. We check if the address is //correct, if it isn't we keep returning until we reach the dispatcher. context.Emit(OpCodes.Dup); context.EmitLdc_I8(op.Position + 4); ILLabel lblContinue = new ILLabel(); context.Emit(OpCodes.Beq_S, lblContinue); context.Emit(OpCodes.Ret); context.MarkLabel(lblContinue); context.Emit(OpCodes.Pop); context.EmitLoadState(context.CurrBlock.Next); } else { context.EmitLdc_I8(op.Imm); context.Emit(OpCodes.Ret); } }
private static void EmitPtPointerLoad(ILEmitterCtx context, ILLabel lblFallbackPath) { context.EmitLdc_I8(context.Memory.PageTable.ToInt64()); context.Emit(OpCodes.Conv_I); int bit = MemoryManager.PageBits; do { context.EmitLdint(_tempIntAddress); if (context.CurrOp.RegisterSize == RegisterSize.Int32) { context.Emit(OpCodes.Conv_U8); } context.EmitLsr(bit); bit += context.Memory.PtLevelBits; if (bit < context.Memory.AddressSpaceBits) { context.EmitLdc_I8(context.Memory.PtLevelMask); context.Emit(OpCodes.And); } context.EmitLdc_I8(IntPtr.Size); context.Emit(OpCodes.Mul); context.Emit(OpCodes.Conv_I); context.Emit(OpCodes.Add); context.Emit(OpCodes.Ldind_I); }while (bit < context.Memory.AddressSpaceBits); if (!context.Memory.HasWriteWatchSupport) { context.Emit(OpCodes.Conv_U8); context.EmitStint(_tempIntPtAddr); context.EmitLdint(_tempIntPtAddr); context.EmitLdc_I8(MemoryManager.PteFlagsMask); context.Emit(OpCodes.And); context.Emit(OpCodes.Brtrue, lblFallbackPath); context.EmitLdint(_tempIntPtAddr); context.Emit(OpCodes.Conv_I); } context.EmitLdint(_tempIntAddress); context.EmitLdc_I(MemoryManager.PageMask); context.Emit(OpCodes.And); context.Emit(OpCodes.Conv_I); context.Emit(OpCodes.Add); }