public static void Vext(ArmEmitterContext context) { OpCode32SimdExt op = (OpCode32SimdExt)context.CurrOp; int elems = op.GetBytesCount(); int byteOff = op.Immediate; Operand res = GetVecA32(op.Qd); for (int index = 0; index < elems; index++) { Operand extract; if (byteOff >= elems) { extract = EmitVectorExtractZx32(context, op.Qm, op.Im + (byteOff - elems), op.Size); } else { extract = EmitVectorExtractZx32(context, op.Qn, op.In + byteOff, op.Size); } byteOff++; res = EmitVectorInsert(context, res, extract, op.Id + index, op.Size); } context.Copy(GetVecA32(op.Qd), res); }
public static void Vext(ArmEmitterContext context) { OpCode32SimdExt op = (OpCode32SimdExt)context.CurrOp; int elems = op.GetBytesCount(); int byteOff = op.Immediate; if (Optimizations.UseSsse3) { EmitVectorBinaryOpSimd32(context, (n, m) => { // Writing low to high of d: start <imm> into n, overlap into m. // Then rotate n down by <imm>, m up by (elems)-imm. // Then OR them together for the result. (long nMaskHigh, long nMaskLow) = MaskHelperByteSequence(0, elems - byteOff, byteOff); (long mMaskHigh, long mMaskLow) = MaskHelperByteSequence(elems - byteOff, byteOff, 0); Operand nMask, mMask; if (!op.Q) { // Do the same operation to the bytes in the top doubleword too, as our target could be in either. nMaskHigh = nMaskLow + 0x0808080808080808L; mMaskHigh = mMaskLow + 0x0808080808080808L; } nMask = X86GetElements(context, nMaskHigh, nMaskLow); mMask = X86GetElements(context, mMaskHigh, mMaskLow); Operand nPart = context.AddIntrinsic(Intrinsic.X86Pshufb, n, nMask); Operand mPart = context.AddIntrinsic(Intrinsic.X86Pshufb, m, mMask); return(context.AddIntrinsic(Intrinsic.X86Por, nPart, mPart)); }); } else { Operand res = GetVecA32(op.Qd); for (int index = 0; index < elems; index++) { Operand extract; if (byteOff >= elems) { extract = EmitVectorExtractZx32(context, op.Qm, op.Im + (byteOff - elems), op.Size); } else { extract = EmitVectorExtractZx32(context, op.Qn, op.In + byteOff, op.Size); } byteOff++; res = EmitVectorInsert(context, res, extract, op.Id + index, op.Size); } context.Copy(GetVecA32(op.Qd), res); } }