public static void Vshrn(ArmEmitterContext context) { OpCode32SimdShImm op = (OpCode32SimdShImm)context.CurrOp; int shift = GetImmShr(op); EmitVectorUnaryNarrowOp32(context, (op1) => context.ShiftRightUI(op1, Const(shift))); }
public static void Vshrn(ArmEmitterContext context) { OpCode32SimdShImm op = (OpCode32SimdShImm)context.CurrOp; int shift = (8 << op.Size) - op.Shift; // Shr amount is flipped. EmitVectorUnaryNarrowOp32(context, (op1) => context.ShiftRightUI(op1, Const(shift))); }
public static void Vrshr(ArmEmitterContext context) { OpCode32SimdShImm op = (OpCode32SimdShImm)context.CurrOp; int shift = GetImmShr(op); long roundConst = 1L << (shift - 1); if (op.U) { if (op.Size < 2) { EmitVectorUnaryOpZx32(context, (op1) => { op1 = context.Add(op1, Const(op1.Type, roundConst)); return(context.ShiftRightUI(op1, Const(shift))); }); } else if (op.Size == 2) { EmitVectorUnaryOpZx32(context, (op1) => { op1 = context.ZeroExtend32(OperandType.I64, op1); op1 = context.Add(op1, Const(op1.Type, roundConst)); return(context.ConvertI64ToI32(context.ShiftRightUI(op1, Const(shift)))); }); } else /* if (op.Size == 3) */ { EmitVectorUnaryOpZx32(context, (op1) => EmitShrImm64(context, op1, signed: false, roundConst, shift)); } } else { if (op.Size < 2) { EmitVectorUnaryOpSx32(context, (op1) => { op1 = context.Add(op1, Const(op1.Type, roundConst)); return(context.ShiftRightSI(op1, Const(shift))); }); } else if (op.Size == 2) { EmitVectorUnaryOpSx32(context, (op1) => { op1 = context.SignExtend32(OperandType.I64, op1); op1 = context.Add(op1, Const(op1.Type, roundConst)); return(context.ConvertI64ToI32(context.ShiftRightSI(op1, Const(shift)))); }); } else /* if (op.Size == 3) */ { EmitVectorUnaryOpZx32(context, (op1) => EmitShrImm64(context, op1, signed: true, roundConst, shift)); } } }
public static void Vshr(ArmEmitterContext context) { OpCode32SimdShImm op = (OpCode32SimdShImm)context.CurrOp; int shift = GetImmShr(op); int maxShift = (8 << op.Size) - 1; if (op.U) { EmitVectorUnaryOpZx32(context, (op1) => (shift > maxShift) ? Const(op1.Type, 0) : context.ShiftRightUI(op1, Const(shift))); } else { EmitVectorUnaryOpSx32(context, (op1) => context.ShiftRightSI(op1, Const(Math.Min(maxShift, shift)))); } }
public static void EmitVectorImmBinaryQdQmOpI32(ArmEmitterContext context, Func2I emit, bool signed) { OpCode32SimdShImm op = (OpCode32SimdShImm)context.CurrOp; Operand res = GetVecA32(op.Qd); int elems = op.GetBytesCount() >> op.Size; for (int index = 0; index < elems; index++) { Operand de = EmitVectorExtract32(context, op.Qd, op.Id + index, op.Size, signed); Operand me = EmitVectorExtract32(context, op.Qm, op.Im + index, op.Size, signed); res = EmitVectorInsert(context, res, emit(de, me), op.Id + index, op.Size); } context.Copy(GetVecA32(op.Qd), res); }
public static void Vsra(ArmEmitterContext context) { OpCode32SimdShImm op = (OpCode32SimdShImm)context.CurrOp; int shift = GetImmShr(op); int maxShift = (8 << op.Size) - 1; if (op.U) { EmitVectorImmBinaryQdQmOpZx32(context, (op1, op2) => { Operand shiftRes = shift > maxShift ? Const(op2.Type, 0) : context.ShiftRightUI(op2, Const(shift)); return(context.Add(op1, shiftRes)); }); } else { EmitVectorImmBinaryQdQmOpSx32(context, (op1, op2) => context.Add(op1, context.ShiftRightSI(op2, Const(Math.Min(maxShift, shift))))); } }
private static void EmitShrImmSaturatingNarrowOp(ArmEmitterContext context, ShrImmSaturatingNarrowFlags flags) { OpCode32SimdShImm op = (OpCode32SimdShImm)context.CurrOp; bool scalar = (flags & ShrImmSaturatingNarrowFlags.Scalar) != 0; bool signedSrc = (flags & ShrImmSaturatingNarrowFlags.SignedSrc) != 0; bool signedDst = (flags & ShrImmSaturatingNarrowFlags.SignedDst) != 0; bool round = (flags & ShrImmSaturatingNarrowFlags.Round) != 0; if (scalar) { // TODO: Support scalar operation. throw new NotImplementedException(); } int shift = GetImmShr(op); long roundConst = 1L << (shift - 1); EmitVectorUnaryNarrowOp32(context, (op1) => { if (op.Size <= 1 || !round) { if (round) { op1 = context.Add(op1, Const(op1.Type, roundConst)); } op1 = signedSrc ? context.ShiftRightSI(op1, Const(shift)) : context.ShiftRightUI(op1, Const(shift)); } else /* if (op.Size == 2 && round) */ { op1 = EmitShrImm64(context, op1, signedSrc, roundConst, shift); // shift <= 32 } return(EmitSatQ(context, op1, 8 << op.Size, signedDst)); }, signedSrc); }
public static void Vshl(ArmEmitterContext context) { OpCode32SimdShImm op = (OpCode32SimdShImm)context.CurrOp; EmitVectorUnaryOpZx32(context, (op1) => context.ShiftLeft(op1, Const(op.Shift))); }
private static int GetImmShr(OpCode32SimdShImm op) { return((8 << op.Size) - op.Shift); // Shr amount is flipped. }
public static void Vqshrn(ArmEmitterContext context) { OpCode32SimdShImm op = (OpCode32SimdShImm)context.CurrOp; EmitShrImmSaturatingNarrowOp(context, op.U ? ShrImmSaturatingNarrowFlags.VectorZxZx : ShrImmSaturatingNarrowFlags.VectorSxSx); }