public static void Vtbl(ArmEmitterContext context) { OpCode32SimdTbl op = (OpCode32SimdTbl)context.CurrOp; bool extension = op.Opc == 1; int elems = op.GetBytesCount() >> op.Size; int length = op.Length + 1; (int Qx, int Ix)[] tableTuples = new (int, int)[length];
public static void Vtbl(ArmEmitterContext context) { OpCode32SimdTbl op = (OpCode32SimdTbl)context.CurrOp; bool extension = op.Opc == 1; int length = op.Length + 1; if (Optimizations.UseSsse3) { Operand d = GetVecA32(op.Qd); Operand m = EmitMoveDoubleWordToSide(context, GetVecA32(op.Qm), op.Vm, 0); Operand res; Operand mask = X86GetAllElements(context, 0x0707070707070707L); // Fast path for single register table. { Operand n = EmitMoveDoubleWordToSide(context, GetVecA32(op.Qn), op.Vn, 0); Operand mMask = context.AddIntrinsic(Intrinsic.X86Pcmpgtb, m, mask); mMask = context.AddIntrinsic(Intrinsic.X86Por, mMask, m); res = context.AddIntrinsic(Intrinsic.X86Pshufb, n, mMask); } for (int index = 1; index < length; index++) { int newVn = (op.Vn + index) & 0x1F; (int qn, int ind) = GetQuadwordAndSubindex(newVn, op.RegisterSize); Operand ni = EmitMoveDoubleWordToSide(context, GetVecA32(qn), newVn, 0); Operand idxMask = X86GetAllElements(context, 0x0808080808080808L * index); Operand mSubMask = context.AddIntrinsic(Intrinsic.X86Psubb, m, idxMask); Operand mMask = context.AddIntrinsic(Intrinsic.X86Pcmpgtb, mSubMask, mask); mMask = context.AddIntrinsic(Intrinsic.X86Por, mMask, mSubMask); Operand res2 = context.AddIntrinsic(Intrinsic.X86Pshufb, ni, mMask); res = context.AddIntrinsic(Intrinsic.X86Por, res, res2); } if (extension) { Operand idxMask = X86GetAllElements(context, (0x0808080808080808L * length) - 0x0101010101010101L); Operand zeroMask = context.VectorZero(); Operand mPosMask = context.AddIntrinsic(Intrinsic.X86Pcmpgtb, m, idxMask); Operand mNegMask = context.AddIntrinsic(Intrinsic.X86Pcmpgtb, zeroMask, m); Operand mMask = context.AddIntrinsic(Intrinsic.X86Por, mPosMask, mNegMask); Operand dMask = context.AddIntrinsic(Intrinsic.X86Pand, EmitMoveDoubleWordToSide(context, d, op.Vd, 0), mMask); res = context.AddIntrinsic(Intrinsic.X86Por, res, dMask); } res = EmitMoveDoubleWordToSide(context, res, 0, op.Vd); context.Copy(d, EmitDoubleWordInsert(context, d, res, op.Vd)); } else { int elems = op.GetBytesCount() >> op.Size; (int Qx, int Ix)[] tableTuples = new (int, int)[length];