private static void EmitAsrC(ILEmitterCtx context, bool setCarry, int shift) { if ((uint)shift >= 32) { context.EmitAsr(31); if (setCarry) { context.Emit(OpCodes.Dup); context.EmitLdc_I4(1); context.Emit(OpCodes.And); context.EmitStflg((int)PState.CBit); } } else { if (setCarry) { context.Emit(OpCodes.Dup); context.EmitLsr(shift - 1); context.EmitLdc_I4(1); context.Emit(OpCodes.And); context.EmitStflg((int)PState.CBit); } context.EmitAsr(shift); } }
public static void EmitDataLoadOper2(ILEmitterCtx context) { switch (context.CurrOp) { case IOpCodeAluImm64 op: context.EmitLdc_I(op.Imm); break; case IOpCodeAluRs64 op: context.EmitLdintzr(op.Rm); switch (op.ShiftType) { case ShiftType.Lsl: context.EmitLsl(op.Shift); break; case ShiftType.Lsr: context.EmitLsr(op.Shift); break; case ShiftType.Asr: context.EmitAsr(op.Shift); break; case ShiftType.Ror: context.EmitRor(op.Shift); break; } break; case IOpCodeAluRx64 op: context.EmitLdintzr(op.Rm); context.EmitCast(op.IntType); context.EmitLsl(op.Shift); break; } }
public static void EmitAluLoadOper2(ILEmitterCtx context, bool setCarry = true) { switch (context.CurrOp) { // ARM32. case OpCode32AluImm op: context.EmitLdc_I4(op.Imm); if (op.SetFlags && op.IsRotated) { context.EmitLdc_I4((int)((uint)op.Imm >> 31)); context.EmitStflg((int)PState.CBit); } break; case OpCode32AluRsImm op: EmitLoadRmShiftedByImmediate(context, op, setCarry); break; case OpCodeT16AluImm8 op: context.EmitLdc_I4(op.Imm); break; // ARM64. case IOpCodeAluImm64 op: context.EmitLdc_I(op.Imm); break; case IOpCodeAluRs64 op: context.EmitLdintzr(op.Rm); switch (op.ShiftType) { case ShiftType.Lsl: context.EmitLsl(op.Shift); break; case ShiftType.Lsr: context.EmitLsr(op.Shift); break; case ShiftType.Asr: context.EmitAsr(op.Shift); break; case ShiftType.Ror: context.EmitRor(op.Shift); break; } break; case IOpCodeAluRx64 op: context.EmitLdintzr(op.Rm); context.EmitCast(op.IntType); context.EmitLsl(op.Shift); break; default: throw new InvalidOperationException(); } }
public static void Sbfm(ILEmitterCtx context) { OpCodeBfm64 op = (OpCodeBfm64)context.CurrOp; int bitsCount = op.GetBitsCount(); if (op.Pos + 1 == bitsCount) { EmitSbfmShift(context); } else if (op.Pos < op.Shift) { EmitSbfiz(context); } else if (op.Pos == 7 && op.Shift == 0) { EmitSbfmCast(context, OpCodes.Conv_I1); } else if (op.Pos == 15 && op.Shift == 0) { EmitSbfmCast(context, OpCodes.Conv_I2); } else if (op.Pos == 31 && op.Shift == 0) { EmitSbfmCast(context, OpCodes.Conv_I4); } else { EmitBfmLoadRn(context); context.EmitLdintzr(op.Rn); context.EmitLsl(bitsCount - 1 - op.Pos); context.EmitAsr(bitsCount - 1); context.EmitLdc_I(~op.TMask); context.Emit(OpCodes.And); context.Emit(OpCodes.Or); context.EmitStintzr(op.Rd); } }
private static void EmitBfiz(ILEmitterCtx context, bool signed) { OpCodeBfm64 op = (OpCodeBfm64)context.CurrOp; int width = op.Pos + 1; context.EmitLdintzr(op.Rn); context.EmitLsl(op.GetBitsCount() - width); if (signed) { context.EmitAsr(op.Shift - width); } else { context.EmitLsr(op.Shift - width); } context.EmitStintzr(op.Rd); }