private static void EmitBranch(AILEmitterCtx Context, ACond Cond) { AOpCodeBImm Op = (AOpCodeBImm)Context.CurrOp; if (Context.CurrBlock.Next != null && Context.CurrBlock.Branch != null) { Context.EmitCondBranch(Context.GetLabel(Op.Imm), Cond); } else { Context.EmitStoreState(); AILLabel LblTaken = new AILLabel(); Context.EmitCondBranch(LblTaken, Cond); Context.EmitLdc_I8(Op.Position + 4); Context.Emit(OpCodes.Ret); Context.MarkLabel(LblTaken); Context.EmitLdc_I8(Op.Imm); Context.Emit(OpCodes.Ret); } }
public static void Fccmp_S(AILEmitterCtx Context) { AOpCodeSimdFcond Op = (AOpCodeSimdFcond)Context.CurrOp; AILLabel LblTrue = new AILLabel(); AILLabel LblEnd = new AILLabel(); Context.EmitCondBranch(LblTrue, Op.Cond); //TODO: Share this logic with Ccmp. Context.EmitLdc_I4((Op.NZCV >> 0) & 1); Context.EmitStflg((int)APState.VBit); Context.EmitLdc_I4((Op.NZCV >> 1) & 1); Context.EmitStflg((int)APState.CBit); Context.EmitLdc_I4((Op.NZCV >> 2) & 1); Context.EmitStflg((int)APState.ZBit); Context.EmitLdc_I4((Op.NZCV >> 3) & 1); Context.EmitStflg((int)APState.NBit); Context.Emit(OpCodes.Br_S, LblEnd); Context.MarkLabel(LblTrue); Fcmp_S(Context); Context.MarkLabel(LblEnd); }
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.Emit(OpCodes.Br_S, LblEnd); Context.MarkLabel(LblTrue); Context.EmitLdintzr(Op.Rn); Context.MarkLabel(LblEnd); Context.EmitStintzr(Op.Rd); }
private static void EmitCcmp(AILEmitterCtx Context, CcmpOp CmpOp) { AOpCodeCcmp Op = (AOpCodeCcmp)Context.CurrOp; AILLabel LblTrue = new AILLabel(); AILLabel LblEnd = new AILLabel(); Context.EmitCondBranch(LblTrue, Op.Cond); Context.EmitLdc_I4((Op.NZCV >> 0) & 1); Context.EmitStflg((int)APState.VBit); Context.EmitLdc_I4((Op.NZCV >> 1) & 1); Context.EmitStflg((int)APState.CBit); Context.EmitLdc_I4((Op.NZCV >> 2) & 1); Context.EmitStflg((int)APState.ZBit); Context.EmitLdc_I4((Op.NZCV >> 3) & 1); Context.EmitStflg((int)APState.NBit); Context.Emit(OpCodes.Br_S, LblEnd); Context.MarkLabel(LblTrue); EmitDataLoadOpers(Context); if (CmpOp == CcmpOp.Cmp) { Context.Emit(OpCodes.Sub); Context.EmitZNFlagCheck(); EmitSubsCCheck(Context); EmitSubsVCheck(Context); } else if (CmpOp == CcmpOp.Cmn) { Context.Emit(OpCodes.Add); Context.EmitZNFlagCheck(); EmitAddsCCheck(Context); EmitAddsVCheck(Context); } else { throw new ArgumentException(nameof(CmpOp)); } Context.Emit(OpCodes.Pop); Context.MarkLabel(LblEnd); }
public static void Fccmp_S(AILEmitterCtx Context) { AOpCodeSimdFcond Op = (AOpCodeSimdFcond)Context.CurrOp; AILLabel LblTrue = new AILLabel(); AILLabel LblEnd = new AILLabel(); Context.EmitCondBranch(LblTrue, Op.Cond); EmitSetNZCV(Context, Op.NZCV); Context.Emit(OpCodes.Br, LblEnd); Context.MarkLabel(LblTrue); Fcmp_S(Context); Context.MarkLabel(LblEnd); }
public static void Fcsel_S(AILEmitterCtx Context) { AOpCodeSimdFcond Op = (AOpCodeSimdFcond)Context.CurrOp; AILLabel LblTrue = new AILLabel(); AILLabel LblEnd = new AILLabel(); Context.EmitCondBranch(LblTrue, Op.Cond); Context.EmitLdvecsf(Op.Rm); Context.EmitStvecsf(Op.Rd); Context.Emit(OpCodes.Br_S, LblEnd); Context.MarkLabel(LblTrue); Context.EmitLdvecsf(Op.Rn); Context.EmitStvecsf(Op.Rd); Context.MarkLabel(LblEnd); }
public static void Fcsel_S(AILEmitterCtx Context) { AOpCodeSimdFcond Op = (AOpCodeSimdFcond)Context.CurrOp; AILLabel LblTrue = new AILLabel(); AILLabel LblEnd = new AILLabel(); Context.EmitCondBranch(LblTrue, Op.Cond); EmitVectorExtractF(Context, Op.Rm, 0, Op.Size); Context.Emit(OpCodes.Br_S, LblEnd); Context.MarkLabel(LblTrue); EmitVectorExtractF(Context, Op.Rn, 0, Op.Size); Context.MarkLabel(LblEnd); EmitScalarSetF(Context, Op.Rd, Op.Size); }
public static void B_Cond(AILEmitterCtx Context) { AOpCodeBImmCond Op = (AOpCodeBImmCond)Context.CurrOp; Context.EmitCondBranch(Context.GetLabel(Op.Imm), Op.Cond); }