private static void EmitCmpOp(ArmEmitterContext context, Func2I emitCmp, bool scalar) { OpCodeSimd op = (OpCodeSimd)context.CurrOp; Operand res = context.VectorZero(); int elems = !scalar?op.GetBytesCount() >> op.Size : 1; ulong szMask = ulong.MaxValue >> (64 - (8 << op.Size)); for (int index = 0; index < elems; index++) { Operand ne = EmitVectorExtractSx(context, op.Rn, index, op.Size); Operand me; if (op is OpCodeSimdReg binOp) { me = EmitVectorExtractSx(context, binOp.Rm, index, op.Size); } else { me = Const(0L); } Operand isTrue = emitCmp(ne, me); Operand mask = context.ConditionalSelect(isTrue, Const(szMask), Const(0L)); res = EmitVectorInsert(context, res, mask, index, op.Size); } context.Copy(GetVec(op.Rd), res); }
private static void EmitVectorCvtf(ArmEmitterContext context, bool signed) { OpCodeSimd op = (OpCodeSimd)context.CurrOp; Operand res = context.VectorZero(); int sizeF = op.Size & 1; int sizeI = sizeF + 2; int fBits = GetFBits(context); int elems = op.GetBytesCount() >> sizeI; for (int index = 0; index < elems; index++) { Operand ne = EmitVectorLongExtract(context, op.Rn, index, sizeI); Operand e = EmitFPConvert(context, ne, sizeF, signed); e = EmitI2fFBitsMul(context, e, fBits); res = context.VectorInsert(res, e, index); } context.Copy(GetVec(op.Rd), res); }
private static void EmitFcvtz(ArmEmitterContext context, bool signed, bool scalar) { OpCodeSimd op = (OpCodeSimd)context.CurrOp; Operand res = context.VectorZero(); Operand n = GetVec(op.Rn); int sizeF = op.Size & 1; int sizeI = sizeF + 2; OperandType type = sizeF == 0 ? OperandType.FP32 : OperandType.FP64; int fBits = GetFBits(context); int elems = !scalar?op.GetBytesCount() >> sizeI : 1; for (int index = 0; index < elems; index++) { Operand ne = context.VectorExtract(type, n, index); Operand e = EmitF2iFBitsMul(context, ne, fBits); if (sizeF == 0) { Delegate dlg = signed ? (Delegate) new _S32_F32(SoftFallback.SatF32ToS32) : (Delegate) new _U32_F32(SoftFallback.SatF32ToU32); e = context.Call(dlg, e); e = context.ZeroExtend32(OperandType.I64, e); } else /* if (sizeF == 1) */ { Delegate dlg = signed ? (Delegate) new _S64_F64(SoftFallback.SatF64ToS64) : (Delegate) new _U64_F64(SoftFallback.SatF64ToU64); e = context.Call(dlg, e); } res = EmitVectorInsert(context, res, e, index, sizeI); } context.Copy(GetVec(op.Rd), res); }
private static void EmitCmpOpF( ArmEmitterContext context, _F32_F32_F32 f32, _F64_F64_F64 f64, bool scalar, bool absolute = false) { OpCodeSimd op = (OpCodeSimd)context.CurrOp; Operand res = context.VectorZero(); int sizeF = op.Size & 1; OperandType type = sizeF != 0 ? OperandType.FP64 : OperandType.FP32; int elems = !scalar?op.GetBytesCount() >> sizeF + 2 : 1; for (int index = 0; index < elems; index++) { Operand ne = context.VectorExtract(type, GetVec(op.Rn), index); Operand me; if (op is OpCodeSimdReg binOp) { me = context.VectorExtract(type, GetVec(binOp.Rm), index); } else { me = sizeF == 0 ? ConstF(0f) : ConstF(0d); } if (absolute) { ne = EmitUnaryMathCall(context, MathF.Abs, Math.Abs, ne); me = EmitUnaryMathCall(context, MathF.Abs, Math.Abs, me); } Operand e = EmitSoftFloatCall(context, f32, f64, ne, me); res = context.VectorInsert(res, e, index); } context.Copy(GetVec(op.Rd), res); }
private static void EmitRev_V(ArmEmitterContext context, int containerSize) { OpCodeSimd op = (OpCodeSimd)context.CurrOp; Operand res = context.VectorZero(); int elems = op.GetBytesCount() >> op.Size; int containerMask = (1 << (containerSize - op.Size)) - 1; for (int index = 0; index < elems; index++) { int revIndex = index ^ containerMask; Operand ne = EmitVectorExtractZx(context, op.Rn, revIndex, op.Size); res = EmitVectorInsert(context, res, ne, index, op.Size); } context.Copy(GetVec(op.Rd), res); }