| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- using ChocolArm64.Decoders;
- using ChocolArm64.IntermediateRepresentation;
- using ChocolArm64.State;
- using ChocolArm64.Translation;
- using System;
- using System.Reflection.Emit;
- using static ChocolArm64.Instructions.InstEmitAluHelper;
- namespace ChocolArm64.Instructions
- {
- static partial class InstEmit
- {
- private enum CcmpOp
- {
- Cmp,
- Cmn
- }
- public static void Ccmn(ILEmitterCtx context) => EmitCcmp(context, CcmpOp.Cmn);
- public static void Ccmp(ILEmitterCtx context) => EmitCcmp(context, CcmpOp.Cmp);
- private static void EmitCcmp(ILEmitterCtx context, CcmpOp cmpOp)
- {
- OpCodeCcmp64 op = (OpCodeCcmp64)context.CurrOp;
- ILLabel lblTrue = new ILLabel();
- ILLabel lblEnd = new ILLabel();
- context.EmitCondBranch(lblTrue, op.Cond);
- context.EmitLdc_I4((op.Nzcv >> 0) & 1);
- context.EmitStflg((int)PState.VBit);
- context.EmitLdc_I4((op.Nzcv >> 1) & 1);
- context.EmitStflg((int)PState.CBit);
- context.EmitLdc_I4((op.Nzcv >> 2) & 1);
- context.EmitStflg((int)PState.ZBit);
- context.EmitLdc_I4((op.Nzcv >> 3) & 1);
- context.EmitStflg((int)PState.NBit);
- context.Emit(OpCodes.Br_S, lblEnd);
- context.MarkLabel(lblTrue);
- EmitAluLoadOpers(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);
- }
- }
- }
|