public static void Fcsel_S(ArmEmitterContext context) { OpCodeSimdFcond op = (OpCodeSimdFcond)context.CurrOp; Operand lblTrue = Label(); Operand lblEnd = Label(); Operand isTrue = InstEmitFlowHelper.GetCondTrue(context, op.Cond); context.BranchIfTrue(lblTrue, isTrue); OperandType type = op.Size == 0 ? OperandType.FP32 : OperandType.FP64; Operand me = context.VectorExtract(type, GetVec(op.Rm), 0); context.Copy(GetVec(op.Rd), context.VectorInsert(context.VectorZero(), me, 0)); context.Branch(lblEnd); context.MarkLabel(lblTrue); Operand ne = context.VectorExtract(type, GetVec(op.Rn), 0); context.Copy(GetVec(op.Rd), context.VectorInsert(context.VectorZero(), ne, 0)); context.MarkLabel(lblEnd); }
public static void EmitBxWritePc(ArmEmitterContext context, Operand pc, int sourceRegister = 0) { bool isReturn = sourceRegister == RegisterAlias.Aarch32Lr || IsA32Return(context); Operand mode = context.BitwiseAnd(pc, Const(1)); SetFlag(context, PState.TFlag, mode); Operand addr = context.ConditionalSelect(mode, context.BitwiseAnd(pc, Const(~1)), context.BitwiseAnd(pc, Const(~3))); InstEmitFlowHelper.EmitVirtualJump(context, addr, isReturn); }
private static void EmitAluWritePc(ArmEmitterContext context, Operand value) { Debug.Assert(value.Type == OperandType.I32); if (IsThumb(context.CurrOp)) { context.StoreToContext(); bool isReturn = IsA32Return(context); Operand addr = context.BitwiseOr(value, Const(1)); InstEmitFlowHelper.EmitVirtualJump(context, addr, isReturn); } else { EmitBxWritePc(context, value); } }
private static void EmitAluWritePc(ArmEmitterContext context, Operand value) { Debug.Assert(value.Type == OperandType.I32); if (((OpCode32)context.CurrOp).IsThumb()) { bool isReturn = IsA32Return(context); if (!isReturn) { context.StoreToContext(); } InstEmitFlowHelper.EmitVirtualJump(context, value, isReturn); } else { EmitBxWritePc(context, value); } }
private static void EmitFccmpOrFccmpe(ArmEmitterContext context, bool signalNaNs) { OpCodeSimdFcond op = (OpCodeSimdFcond)context.CurrOp; Operand lblTrue = Label(); Operand lblEnd = Label(); context.BranchIfTrue(lblTrue, InstEmitFlowHelper.GetCondTrue(context, op.Cond)); EmitSetNzcv(context, op.Nzcv); context.Branch(lblEnd); context.MarkLabel(lblTrue); EmitFcmpOrFcmpe(context, signalNaNs); context.MarkLabel(lblEnd); }
private static void Blx(ArmEmitterContext context, bool x) { IOpCode32BImm op = (IOpCode32BImm)context.CurrOp; uint pc = op.GetPc(); bool isThumb = IsThumb(context.CurrOp); uint currentPc = isThumb ? op.GetPc() | 1 : op.GetPc() - 4; SetIntOrSP(context, GetBankedRegisterAlias(context.Mode, RegisterAlias.Aarch32Lr), Const(currentPc)); // If x is true, then this is a branch with link and exchange. // In this case we need to swap the mode between Arm <-> Thumb. if (x) { SetFlag(context, PState.TFlag, Const(isThumb ? 0 : 1)); } InstEmitFlowHelper.EmitCall(context, (ulong)op.Immediate); }