public static void EmitAddsVCheck(AILEmitterCtx Context) { //V = (Rd ^ Rn) & ~(Rn ^ Rm) < 0 Context.Emit(OpCodes.Dup); EmitDataLoadRn(Context); Context.Emit(OpCodes.Xor); EmitDataLoadOpers(Context); Context.Emit(OpCodes.Xor); Context.Emit(OpCodes.Not); Context.Emit(OpCodes.And); Context.EmitLdc_I(0); Context.Emit(OpCodes.Clt); Context.EmitStflg((int)APState.VBit); }
private static void EmitLoad(AILEmitterCtx Context, AccessType AccType, bool Pair) { AOpCodeMemEx Op = (AOpCodeMemEx)Context.CurrOp; bool Ordered = (AccType & AccessType.Ordered) != 0; bool Exclusive = (AccType & AccessType.Exclusive) != 0; if (Ordered) { EmitBarrier(Context); } if (Exclusive) { EmitMemoryCall(Context, nameof(AMemory.SetExclusive), Op.Rn); } Context.EmitLdint(Op.Rn); Context.EmitSttmp(); Context.EmitLdarg(ATranslatedSub.MemoryArgIdx); Context.EmitLdtmp(); EmitReadZxCall(Context, Op.Size); Context.EmitStintzr(Op.Rt); if (Pair) { Context.EmitLdarg(ATranslatedSub.MemoryArgIdx); Context.EmitLdtmp(); Context.EmitLdc_I(8 << Op.Size); Context.Emit(OpCodes.Add); EmitReadZxCall(Context, Op.Size); Context.EmitStintzr(Op.Rt2); } }
public static void Bl(AILEmitterCtx Context) { AOpCodeBImmAl Op = (AOpCodeBImmAl)Context.CurrOp; Context.EmitLdc_I(Op.Position + 4); Context.EmitStint(AThreadState.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); AILLabel LblContinue = new AILLabel(); Context.Emit(OpCodes.Beq_S, LblContinue); Context.Emit(OpCodes.Ret); Context.MarkLabel(LblContinue); Context.Emit(OpCodes.Pop); if (Context.CurrBlock.Next != null) { Context.EmitLoadState(Context.CurrBlock.Next); } } else { Context.EmitLdc_I8(Op.Imm); Context.Emit(OpCodes.Ret); } }
private static void EmitCsel(AILEmitterCtx Context, CselOperation CselOp) { AOpCodeCsel Op = (AOpCodeCsel)Context.CurrOp; AILLabel LblTrue = new AILLabel(); AILLabel LblEnd = new AILLabel(); Context.EmitCondBranch(LblTrue, Op.Cond); Context.EmitLdintzr(Op.Rm); if (CselOp == CselOperation.Increment) { Context.EmitLdc_I(1); Context.Emit(OpCodes.Add); } else if (CselOp == CselOperation.Invert) { Context.Emit(OpCodes.Not); } else if (CselOp == CselOperation.Negate) { Context.Emit(OpCodes.Neg); } Context.EmitStintzr(Op.Rd); Context.Emit(OpCodes.Br_S, LblEnd); Context.MarkLabel(LblTrue); Context.EmitLdintzr(Op.Rn); Context.EmitStintzr(Op.Rd); Context.MarkLabel(LblEnd); }